summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDidier Raboud <odyx@debian.org>2017-10-06 10:27:37 +0200
committerDidier Raboud <odyx@debian.org>2017-10-06 10:27:37 +0200
commitf6c998681f28b9211156828f09191ec3ac9c16c3 (patch)
treea0020344246a5f8549371ee2f11ef615b9f6bf72
Import cups-filters_1.17.9.orig.tar.xz
[dgit import orig cups-filters_1.17.9.orig.tar.xz]
-rw-r--r--AUTHORS12
-rw-r--r--COPYING365
-rw-r--r--ChangeLog0
-rw-r--r--INSTALL183
-rw-r--r--Makefile.am1061
-rw-r--r--Makefile.in5428
-rw-r--r--NEWS2306
-rw-r--r--README1805
-rw-r--r--aclocal.m41472
-rwxr-xr-xautogen.sh60
-rw-r--r--backend/backend-private.h81
-rw-r--r--backend/beh.c285
-rw-r--r--backend/cups-brf.c162
-rw-r--r--backend/ieee1284.c781
-rw-r--r--backend/implicitclass.c320
-rw-r--r--backend/parallel.c861
-rw-r--r--backend/serial.c1228
-rw-r--r--backend/test1284.c76
-rw-r--r--banners/classified4
-rw-r--r--banners/confidential4
-rw-r--r--banners/form4
-rw-r--r--banners/secret4
-rw-r--r--banners/standard4
-rw-r--r--banners/topsecret4
-rw-r--r--banners/unclassified4
-rw-r--r--charset/pdf.utf-8.heavy40
-rw-r--r--charset/pdf.utf-8.simple32
-rwxr-xr-xcompile347
-rwxr-xr-xconfig.guess1462
-rw-r--r--config.h.in270
-rwxr-xr-xconfig.sub1825
-rwxr-xr-xconfigure23911
-rw-r--r--configure.ac907
-rw-r--r--cupsfilters/attr.c104
-rw-r--r--cupsfilters/check.c104
-rw-r--r--cupsfilters/cmyk.c1950
-rw-r--r--cupsfilters/colord.c464
-rw-r--r--cupsfilters/colord.h49
-rw-r--r--cupsfilters/colormanager.c355
-rw-r--r--cupsfilters/colormanager.h87
-rw-r--r--cupsfilters/dither.c299
-rw-r--r--cupsfilters/driver.h243
-rw-r--r--cupsfilters/image-bmp.c537
-rw-r--r--cupsfilters/image-colorspace.c1558
-rw-r--r--cupsfilters/image-gif.c689
-rw-r--r--cupsfilters/image-jpeg.c313
-rw-r--r--cupsfilters/image-photocd.c324
-rw-r--r--cupsfilters/image-pix.c231
-rw-r--r--cupsfilters/image-png.c306
-rw-r--r--cupsfilters/image-pnm.c314
-rw-r--r--cupsfilters/image-private.h214
-rw-r--r--cupsfilters/image-sgi.c286
-rw-r--r--cupsfilters/image-sgi.h78
-rw-r--r--cupsfilters/image-sgilib.c884
-rw-r--r--cupsfilters/image-sun.c404
-rw-r--r--cupsfilters/image-tiff.c1711
-rw-r--r--cupsfilters/image-zoom.c352
-rw-r--r--cupsfilters/image.c809
-rw-r--r--cupsfilters/image.h122
-rw-r--r--cupsfilters/image.pgmbin0 -> 152380 bytes
-rw-r--r--cupsfilters/image.ppmbin0 -> 457020 bytes
-rw-r--r--cupsfilters/lut.c195
-rw-r--r--cupsfilters/pack.c300
-rw-r--r--cupsfilters/ppdgenerator.c2256
-rw-r--r--cupsfilters/ppdgenerator.h72
-rw-r--r--cupsfilters/raster.c1088
-rw-r--r--cupsfilters/raster.h55
-rw-r--r--cupsfilters/rgb.c551
-rw-r--r--cupsfilters/srgb.c72
-rw-r--r--cupsfilters/testcmyk.c432
-rw-r--r--cupsfilters/testdither.c186
-rw-r--r--cupsfilters/testimage.c90
-rw-r--r--cupsfilters/testrgb.c343
-rw-r--r--data/classified.pdfbin0 -> 979 bytes
-rw-r--r--data/confidential.pdfbin0 -> 981 bytes
-rw-r--r--data/default-testpage.pdfbin0 -> 39852 bytes
-rw-r--r--data/default.pdfbin0 -> 845 bytes
-rw-r--r--data/form_english.pdfbin0 -> 276070 bytes
-rw-r--r--data/form_english_in.odtbin0 -> 13661 bytes
-rw-r--r--data/form_russian.pdfbin0 -> 270261 bytes
-rw-r--r--data/form_russian_in.odtbin0 -> 13866 bytes
-rw-r--r--data/secret.pdfbin0 -> 975 bytes
-rw-r--r--data/standard.pdfbin0 -> 979 bytes
-rw-r--r--data/testprint4
-rw-r--r--data/topsecret.pdfbin0 -> 979 bytes
-rw-r--r--data/unclassified.pdfbin0 -> 981 bytes
-rwxr-xr-xdepcomp791
-rw-r--r--drv/cupsfilters.drv6262
-rw-r--r--drv/generic-brf.drv120
-rw-r--r--drv/generic-ubrl.drv112
-rw-r--r--drv/indexv3.drv132
-rw-r--r--drv/indexv4.drv139
-rw-r--r--filter/PDFError.h44
-rw-r--r--filter/banner.c211
-rw-r--r--filter/banner.h58
-rw-r--r--filter/bannertopdf.c564
-rw-r--r--filter/braille/drivers/common/fr-braille.po239
-rw-r--r--filter/braille/drivers/common/media-braille.defs30
-rwxr-xr-xfilter/braille/drivers/generic/brftoembosser.in91
-rwxr-xr-xfilter/braille/drivers/index/imageubrltoindexv3.in318
-rwxr-xr-xfilter/braille/drivers/index/imageubrltoindexv4.in319
-rw-r--r--filter/braille/drivers/index/index.defs125
-rw-r--r--filter/braille/drivers/index/index.sh.in124
-rw-r--r--filter/braille/drivers/index/indexv3.sh.in110
-rw-r--r--filter/braille/drivers/index/indexv4.sh.in81
-rwxr-xr-xfilter/braille/drivers/index/textbrftoindexv3.in96
-rw-r--r--filter/braille/drivers/index/ubrlto4dot.c40
-rw-r--r--filter/braille/filters/TODO.txt3
-rw-r--r--filter/braille/filters/braille.defs44
-rw-r--r--filter/braille/filters/cups-braille.sh.in384
-rw-r--r--filter/braille/filters/imagemagick.defs126
-rwxr-xr-xfilter/braille/filters/imagetobrf.in125
-rw-r--r--filter/braille/filters/liblouis.defs28
-rw-r--r--filter/braille/filters/liblouis1.defs.gen.in265
-rw-r--r--filter/braille/filters/musicxmltobrf.in56
-rwxr-xr-xfilter/braille/filters/texttobrf.in205
-rw-r--r--filter/braille/filters/vectortobrf.in72
-rw-r--r--filter/braille/filters/vectortopdf.in69
-rw-r--r--filter/commandtoescpx.c240
-rw-r--r--filter/commandtopclx.c167
-rw-r--r--filter/common.c632
-rw-r--r--filter/common.h72
-rw-r--r--filter/escp.h27
-rw-r--r--filter/foomatic-rip/foomatic-rip.1233
-rw-r--r--filter/foomatic-rip/foomatic-rip.1.in233
-rw-r--r--filter/foomatic-rip/foomaticrip.c1130
-rw-r--r--filter/foomatic-rip/foomaticrip.h120
-rw-r--r--filter/foomatic-rip/options.c2264
-rw-r--r--filter/foomatic-rip/options.h182
-rw-r--r--filter/foomatic-rip/pdf.c310
-rw-r--r--filter/foomatic-rip/pdf.h30
-rw-r--r--filter/foomatic-rip/postscript.c1207
-rw-r--r--filter/foomatic-rip/postscript.h30
-rw-r--r--filter/foomatic-rip/process.c229
-rw-r--r--filter/foomatic-rip/process.h48
-rw-r--r--filter/foomatic-rip/renderer.c491
-rw-r--r--filter/foomatic-rip/renderer.h31
-rw-r--r--filter/foomatic-rip/spooler.c225
-rw-r--r--filter/foomatic-rip/spooler.h35
-rw-r--r--filter/foomatic-rip/util.c1143
-rw-r--r--filter/foomatic-rip/util.h216
-rw-r--r--filter/getline.c122
-rw-r--r--filter/gstopdf25
-rw-r--r--filter/gstopxl25
-rw-r--r--filter/gstoraster.c971
-rw-r--r--filter/imagetopdf.c1820
-rw-r--r--filter/imagetops35
-rw-r--r--filter/imagetoraster.c4393
-rw-r--r--filter/mupdftoraster.c459
-rw-r--r--filter/pcl-common.c320
-rw-r--r--filter/pcl-common.h66
-rw-r--r--filter/pcl.h31
-rw-r--r--filter/pdf.cxx1807
-rw-r--r--filter/pdf.h53
-rw-r--r--filter/pdftoijs.cxx538
-rw-r--r--filter/pdftoopvp/99pdftoopvp.conf18
-rw-r--r--filter/pdftoopvp/OPVPError.h44
-rw-r--r--filter/pdftoopvp/OPVPOutputDev.cxx2003
-rw-r--r--filter/pdftoopvp/OPVPOutputDev.h250
-rw-r--r--filter/pdftoopvp/oprs/OPRS.cxx604
-rw-r--r--filter/pdftoopvp/oprs/OPRS.h188
-rw-r--r--filter/pdftoopvp/oprs/OPVPSplash.cxx2327
-rw-r--r--filter/pdftoopvp/oprs/OPVPSplash.h244
-rw-r--r--filter/pdftoopvp/oprs/OPVPSplashClip.cxx91
-rw-r--r--filter/pdftoopvp/oprs/OPVPSplashClip.h30
-rw-r--r--filter/pdftoopvp/oprs/OPVPSplashPath.cxx185
-rw-r--r--filter/pdftoopvp/oprs/OPVPSplashPath.h28
-rw-r--r--filter/pdftoopvp/oprs/OPVPSplashState.cxx178
-rw-r--r--filter/pdftoopvp/oprs/OPVPSplashState.h95
-rw-r--r--filter/pdftoopvp/oprs/OPVPSplashXPath.cxx426
-rw-r--r--filter/pdftoopvp/oprs/OPVPSplashXPath.h39
-rw-r--r--filter/pdftoopvp/oprs/OPVPWrapper.cxx910
-rw-r--r--filter/pdftoopvp/oprs/OPVPWrapper.h205
-rw-r--r--filter/pdftoopvp/oprs/OPVPWrapper_0_2.cxx1172
-rw-r--r--filter/pdftoopvp/oprs/OPVPWrapper_0_2.h127
-rw-r--r--filter/pdftoopvp/opvp/opvp.h292
-rw-r--r--filter/pdftoopvp/opvp/opvp_0_2_0.h298
-rw-r--r--filter/pdftoopvp/opvp/opvp_common.h54
-rw-r--r--filter/pdftoopvp/pdftoopvp.cxx791
-rw-r--r--filter/pdftopdf/intervalset.cc121
-rw-r--r--filter/pdftopdf/intervalset.h34
-rw-r--r--filter/pdftopdf/nup.cc265
-rw-r--r--filter/pdftopdf/nup.h91
-rw-r--r--filter/pdftopdf/pdftopdf.cc1207
-rw-r--r--filter/pdftopdf/pdftopdf_jcl.cc202
-rw-r--r--filter/pdftopdf/pdftopdf_jcl.h12
-rw-r--r--filter/pdftopdf/pdftopdf_processor.cc363
-rw-r--r--filter/pdftopdf/pdftopdf_processor.h162
-rw-r--r--filter/pdftopdf/pptypes.cc177
-rw-r--r--filter/pdftopdf/pptypes.h39
-rw-r--r--filter/pdftopdf/qpdf_cm.cc151
-rw-r--r--filter/pdftopdf/qpdf_cm.h12
-rw-r--r--filter/pdftopdf/qpdf_pdftopdf.cc225
-rw-r--r--filter/pdftopdf/qpdf_pdftopdf.h41
-rw-r--r--filter/pdftopdf/qpdf_pdftopdf_processor.cc663
-rw-r--r--filter/pdftopdf/qpdf_pdftopdf_processor.h73
-rw-r--r--filter/pdftopdf/qpdf_tools.cc69
-rw-r--r--filter/pdftopdf/qpdf_tools.h18
-rw-r--r--filter/pdftopdf/qpdf_xobject.cc170
-rw-r--r--filter/pdftopdf/qpdf_xobject.h8
-rw-r--r--filter/pdftops.c1667
-rw-r--r--filter/pdftoraster.cxx2195
-rw-r--r--filter/pdfutils.c431
-rw-r--r--filter/pdfutils.h80
-rw-r--r--filter/rastertoescpx.c1912
-rw-r--r--filter/rastertopclm25
-rw-r--r--filter/rastertopclx.c1963
-rw-r--r--filter/rastertopdf.cpp1533
-rw-r--r--filter/rastertops.c487
-rw-r--r--filter/strcasestr.c62
-rw-r--r--filter/sys5ippprinter.c902
-rwxr-xr-xfilter/test.sh14
-rw-r--r--filter/test_pdf1.c52
-rw-r--r--filter/test_pdf2.c102
-rw-r--r--filter/textcommon.c1271
-rw-r--r--filter/textcommon.h105
-rw-r--r--filter/texttopdf.c1212
-rw-r--r--filter/texttops35
-rw-r--r--filter/texttotext.c980
-rw-r--r--filter/unirast.h62
-rw-r--r--filter/urftopdf.cpp498
-rw-r--r--fontembed/README48
-rw-r--r--fontembed/aglfn13.c214
-rw-r--r--fontembed/bitset.h38
-rw-r--r--fontembed/dynstring.c105
-rw-r--r--fontembed/dynstring.h16
-rw-r--r--fontembed/embed.c260
-rw-r--r--fontembed/embed.h92
-rw-r--r--fontembed/embed_pdf.c597
-rw-r--r--fontembed/embed_pdf.h53
-rw-r--r--fontembed/embed_pdf_int.h10
-rw-r--r--fontembed/embed_sfnt.c677
-rw-r--r--fontembed/embed_sfnt_int.h18
-rw-r--r--fontembed/fontfile.c50
-rw-r--r--fontembed/fontfile.h22
-rw-r--r--fontembed/frequent.c83
-rw-r--r--fontembed/frequent.h17
-rw-r--r--fontembed/iofn.h6
-rw-r--r--fontembed/macroman.h32
-rw-r--r--fontembed/main.c170
-rw-r--r--fontembed/sfnt.c992
-rw-r--r--fontembed/sfnt.h64
-rw-r--r--fontembed/sfnt_int.h97
-rw-r--r--fontembed/sfnt_subset.c343
-rw-r--r--fontembed/test_analyze.c234
-rw-r--r--fontembed/test_pdf.c215
-rw-r--r--fontembed/test_ps.c89
-rwxr-xr-xinstall-sh220
-rw-r--r--libcupsfilters.pc.in12
-rw-r--r--libfontembed.pc.in11
-rw-r--r--ltmain.sh11156
-rw-r--r--m4/ac_define_dir.m434
-rw-r--r--m4/ax_compare_version.m4177
-rw-r--r--m4/ax_cxx_compile_stdcxx.m4982
-rw-r--r--m4/basic-directories.m4105
-rw-r--r--m4/libtool.m48387
-rw-r--r--m4/ltoptions.m4437
-rw-r--r--m4/ltsugar.m4124
-rw-r--r--m4/ltversion.m423
-rw-r--r--m4/lt~obsolete.m499
-rw-r--r--mime/braille.convs108
-rw-r--r--mime/braille.types65
-rw-r--r--mime/cupsfilters-ghostscript.convs21
-rw-r--r--mime/cupsfilters-mupdf.convs19
-rw-r--r--mime/cupsfilters-poppler.convs19
-rw-r--r--mime/cupsfilters.convs114
-rw-r--r--mime/cupsfilters.convs.in114
-rw-r--r--mime/cupsfilters.types105
-rwxr-xr-xmissing215
-rw-r--r--ppd/Fuji_Xerox-DocuPrint_CM305_df-PDF.ppd250
-rw-r--r--ppd/Generic-PDF_Printer-PDF.ppd245
-rw-r--r--ppd/HP-Color_LaserJet_CM3530_MFP-PDF.ppd415
-rw-r--r--ppd/HP-PhotoSmart_Pro_B8300-hpijs-pdftoijs.ppd342
-rw-r--r--ppd/Ricoh-PDF_Printer-PDF.ppd413
-rw-r--r--ppd/pxlcolor.ppd204
-rw-r--r--ppd/pxlmono.ppd197
-rw-r--r--scripting/perl/CUPS.pm144
-rw-r--r--scripting/perl/CUPS.xs270
-rw-r--r--scripting/perl/Makefile.PL17
-rw-r--r--scripting/perl/README35
-rw-r--r--scripting/perl/test.pl17
-rw-r--r--scripting/php/README154
-rw-r--r--scripting/php/phpcups.c480
-rw-r--r--scripting/php/phpcups.h60
-rwxr-xr-xscripting/php/phpcups.php54
-rwxr-xr-xtest-driver148
-rw-r--r--utils/cups-browsed-upstart.conf20
-rw-r--r--utils/cups-browsed.8107
-rw-r--r--utils/cups-browsed.c8266
-rw-r--r--utils/cups-browsed.conf.5882
-rw-r--r--utils/cups-browsed.conf.in673
-rw-r--r--utils/cups-browsed.in156
-rw-r--r--utils/cups-browsed.service11
-rw-r--r--utils/driverless.170
-rw-r--r--utils/driverless.c674
-rw-r--r--utils/org.cups.cupsd.Notifier.xml147
296 files changed, 166912 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 000000000..d47a3269b
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,12 @@
+Till Kamppeter, OpenPrinting/Canonical (till.kamppeter@gmail.com)
+Michael Sweet, Apple (msweet@apple.com)
+Koji Otani, BBR Inc. (sho@bbr.jp)
+Tobias Hoffmann (th55@gmx.de)
+Lars Übernickel, Canonical (lars@uebernic.de)
+Tim Waugh (twaugh@redhat.com)
+Tomáš Chvátal (tomas.chvatal@gmail.com)
+Franz Pförtsch (Franz.Pfoertsch@brose.com)
+Neil 'Superna' Armstrong (superna9999@gmail.com)
+Samuel Thibault (samuel.thibault@ens-lyon.org)
+Pranjal Bhor (bhor.pranjal@gmail.com)
+Sahil Arora (sahilarora.535@gmail.com)
diff --git a/COPYING b/COPYING
new file mode 100644
index 000000000..dcbb27311
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,365 @@
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: cups-filters
+Upstream-Contact: OpenPrinting <printing-architecture@lists.linux-foundation.org>
+Source: http://www.openprinting.org/download/cups-filters/
+
+Files: *
+Copyright: 1993-2007 Easy Software Products
+ 2007-2011 Apple Inc.
+ 2012 Canonical Ltd.
+ 2006-2012 BBR Inc.
+ 2008-2016 Till Kamppeter
+ 2008,2012 Tobias Hoffmann
+ 2003-2006 Red Hat, Inc.
+ 2003-2006 Tim Waugh
+ 2012 Franz Pförtsch
+ 2012 Tomáš Chvátal
+ 2010 Neil 'Superna' Armstrong
+ 2015-2016 Samuel Thibault
+ 2008 Lars Übernickel
+License: GPL-2+
+
+Files: backend/beh.c
+ backend/implicitclass.c
+Copyright: 2015, Till Kamppeter
+ 2008-2015, Apple Inc
+License: GPL-2
+
+Files: backend/parallel.c
+ backend/serial.c
+ backend/ieee1284.c
+ backend/test1284.c
+ backend/backend-private.h
+Copyright: 2007-2011, Apple Inc
+ 1993-2007, Easy Software Products
+License: GPL-2
+
+Files: cupsfilters/*
+Copyright: 2007-2016 Apple Inc
+ 1993-2007 by Easy Software Products
+ 2011-2013, Richard Hughes
+ 2011, Tim Waugh
+ 2013-2016, Till Kamppeter
+ 2014, Joseph Simon
+ 2017, Sahil Arora
+License: LGPL-2
+
+Files: cupsfilters/colord.c
+Copyright: 2011-2013, Richard Hughes
+ 2011, Tim Waugh
+License: Expat
+
+Files: cupsfilters/colord.h
+Copyright: 2011-2013, Richard Hughes
+License: Expat
+
+Files: cupsfilters/colormanager.c
+Copyright: 2014, Joseph Simon
+ 2011-2013, Richard Hughes
+License: Expat
+
+Files: cupsfilters/colormanager.h
+Copyright: 2014, Joseph Simon
+License: Expat
+
+Files: filter/PDFError.h
+ filter/pdftoraster.cxx
+Copyright: 2008-2012, BBR Inc.
+License: Expat
+
+Files: filter/banner.c
+ filter/banner.h
+ filter/pdf.h
+ banners/*
+ data/*
+Copyright: 2012, Canonical Ltd
+License: GPL-3
+
+Files: filter/bannertopdf.c
+ filter/pdf.cxx
+Copyright: 2013, ALT Linux, Andrew V. Stepanov <stanv@altlinux.com>
+ 2012, Canonical Ltd
+License: GPL-3
+
+Files: filter/braille/*
+ drv/generic-brf.drv
+ drv/indexv*.drv
+ mime/braille.*
+Copyright: 2015, Samuel Thibault <samuel.thibault@ens-lyon.org>
+License: Expat
+
+Files: filter/commandtoescpx.c
+ filter/commandtopclx.c
+ filter/imagetoraster.c
+ filter/rastertoescpx.c
+ filter/rastertopclx.c
+ filter/common.*
+ filter/pcl-common.*
+ filter/textcommon.*
+ filter/escp.h
+ filter/pcl.h
+ scripting/*
+Copyright: 2007-2011, Apple Inc
+ 1993-2007, Easy Software Products
+License: GPL-2
+
+Files: mime/cupsfilters*.convs*
+Copyright: 2007-2011, Apple Inc
+ 1997-2007, Easy Software Products
+ 2012-2016, Till Kamppeter
+ 2017, Sahil Arora
+License: GPL-2
+
+Files: filter/foomatic-rip/*
+Copyright: 2008, Till Kamppeter <till.kamppeter@gmail.com>
+ 2008, Lars Uebernickel <larsuebernickel@gmx.de>
+License: GPL-2+
+
+Files: filter/getline.c
+Copyright: 1993, 1996-2014, Free Software Foundation, Inc
+License: GPL-2+
+
+Files: ppd/pxlcolor.ppd ppd/pxlmono.ppd
+Copyright: 2001-2005 Easy Software Products
+License: GPL-2+
+
+Files: filter/gstoraster.c
+Copyright: 2011-2013, Richard Hughes
+ 2011, Tim Waugh
+ 2008-2016, Till Kamppeter
+License: Expat
+
+Files: filter/mupdftoraster.c
+Copyright: 2011-2013, Richard Hughes
+ 2011, Tim Waugh
+ 2008-2016, Till Kamppeter
+ 2016, Pranjal Bhor
+License: Expat
+
+Files: filter/imagetopdf*
+Copyright: 1993-2007, Easy Software Products
+License: GPL-2
+
+Files: filter/pdftoijs.cxx
+ ppd/HP-PhotoSmart_Pro_B8300-hpijs-pdftoijs.ppd
+Copyright: 2008, Tobias Hoffmann
+ 2008, BBR Inc.
+License: Expat
+
+Files: filter/pdftoopvp/*
+Copyright: 2003, 2004, 2005, 2006, AXE,Inc
+ 2007, 2008, ModifiedBBR Inc.
+ 2003, Glyph & Cog, LLC
+ 2006, Fuji Xerox Printing Systems Co., Ltd
+ 2006, Free Standards Group
+ 2006, Canon Inc
+License: Expat
+
+Files: filter/pdftopdf/*
+Copyright: 2012 Tobias Hoffmann
+ 2006-2011, BBR Inc
+License: Expat
+
+Files: ppd/*-PDF.ppd
+Copyright: 2012-2016 Till Kamppeter
+License: GPL-2+
+
+Files: filter/pdftops.c
+Copyright: 2011-2013 Till Kamppeter
+ 2007-2011 Apple Inc
+ 1997-2006 Easy Software Products
+License: GPL-2
+
+Files: filter/pdfutils.c
+ filter/pdfutils.h
+Copyright: 2008, Tobias Hoffmann
+License: GPL-2
+
+Files: filter/rastertopclm
+Copyright: 2017 Sahil Arora <sahilarora.535@gmail.com>
+License: GPL-3+
+
+Files: filter/rastertopdf.cpp
+Copyright: 2010, Neil 'Superna' Armstrong <superna9999@gmail.com>
+ 2012 Tobias Hoffmann <smilingthax@gmail.com>
+ 2014 Till Kamppeter <till.kamppeter@gmail.com>
+ 2017 Sahil Arora <sahilarora.535@gmail.com>
+License: GPL-3+
+
+Files: filter/rastertops.c
+Copyright: 2016 Pranjal Bhor <bhor.pranjal@gmail.com>
+ 2010 Neil 'Superna' Armstrong <superna9999@gmail.com>
+ 2012 Tobias Hoffmann <smilingthax@gmail.com>
+ 2014 Till Kamppeter <till.kamppeter@gmail.com>
+License: GPL-3+
+
+Files: filter/strcasestr.c
+Copyright: 1990, 1993, The Regents of the University of California
+License: BSD-4-clause
+
+Files: filter/sys5ippprinter.c
+Copyright: 2011-2013, Till Kamppeter
+ 2007-2011, Apple Inc
+ 1997-2006, Easy Software Products
+License: GPL-2
+
+Files: filter/texttotext.c
+Copyright: 2011-2013, Till Kamppeter
+ 2007-2011, Apple Inc
+ 1997-2006, Easy Software Products
+License: GPL-2
+
+Files: filter/texttopdf.c
+ charset/*
+ filter/test.sh
+ filter/test_pdf*.c
+Copyright: 2008, 2012, Tobias Hoffmann
+ 2007, Apple Inc
+ 1993-2007, Easy Software Products
+License: GPL-2
+
+Files: filter/texttops filter/imagetops filter/gstopxl filter/gstopdf
+Copyright: 2012 Till Kamppeter <till.kamppeter@gmail.com>
+License: GPL-2+
+
+Files: filter/unirast.h
+Copyright: 2010, Neil 'Superna' Armstrong <superna9999@gmail.com>
+License: GPL-3+
+
+Files: filter/urftopdf.cpp
+Copyright: 2010, Neil 'Superna' Armstrong <superna9999@gmail.com>
+ 2012 Tobias Hoffmann <smilingthax@gmail.com>
+License: GPL-3+
+
+Files: fontembed/*
+Copyright: 2008,2012 Tobias Hoffmann
+License: Expat
+
+Files: ltmain.sh
+Copyright: 1996-2001, 2003-2011 Free Software Foundation, Inc.
+License: GPL-2+
+
+Files: utils/cups-browsed*
+ org.cups.cupsd.Notifier.xml
+Copyright: 2012-2016 Till Kamppeter
+ 2013-2015 Tim Waugh
+License: LGPL-2.1+
+
+Files: utils/driverless*
+Copyright: 2012-2016 Till Kamppeter
+ 2007-2016 Apple Inc.
+ 2017 Sahil Arora
+License: LGPL-2.1+
+
+Files: drv/cupsfilters.drv
+ drv/custom-media-lines
+Copyright: 2012-2016 Till Kamppeter
+License: Expat
+
+License: Expat
+ The MIT License
+ .
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated
+ documentation files (the "Software"), to deal in the Software
+ without restriction, including without limitation the rights to
+ use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to
+ whom the Software is furnished to do so, subject to the
+ following conditions:
+ .
+ The above copyright notice and this permission notice shall
+ be included in all copies or substantial portions of the
+ Software.
+ .
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT
+ WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+ SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+License: GPL-2
+ 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; version 2 dated June, 1991.
+ .
+ On Debian systems, the complete text of version 2 of the GNU General
+ Public License can be found in '/usr/share/common-licenses/GPL-2'.
+
+License: GPL-2+
+ 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; version 2 dated June, 1991, or (at
+ your option) any later version.
+ .
+ On Debian systems, the complete text of version 2 of the GNU General
+ Public License can be found in '/usr/share/common-licenses/GPL-2'.
+
+License: GPL-3
+ 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; version 3 dated June, 2007.
+ .
+ On Debian systems, the complete text of version 3 of the GNU General
+ Public License can be found in '/usr/share/common-licenses/GPL-3'.
+
+License: GPL-3+
+ 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; version 3 dated June, 2007, or (at
+ your option) any later version.
+ .
+ On Debian systems, the complete text of version 3 of the GNU General
+ Public License can be found in '/usr/share/common-licenses/GPL-3'.
+
+License: LGPL-2
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by the
+ Free Software Foundation; version 2 of the License.
+ .
+ On Debian systems, the complete text of version 2 of the GNU Library
+ Public License can be found in `/usr/share/common-licenses/LGPL-2'.
+
+License: LGPL-2.1+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by the
+ Free Software Foundation; version 2.1 of the License, or (at
+ your option) any later version.
+ .
+ On Debian systems, the complete text of version 2.1 of the GNU Lesser
+ Public License can be found in `/usr/share/common-licenses/LGPL-2.1'.
+
+License: BSD-4-clause
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ This product includes software developed by the University of
+ California, Berkeley and its contributors.
+ 4. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ChangeLog
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 000000000..0a55ac851
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,183 @@
+INSTALL - OpenPrinting CUPS Filters v1.17.9 - 2017-10-05
+--------------------------------------------------------
+
+This file describes how to compile and install OpenPrinting CUPS
+Filters from source code. For more information on OpenPrinting CUPS
+Filters see the file called "README.txt". A complete change log can
+be found in "CHANGES.txt".
+
+**** IF YOU HAVE A NON-POSTSCRIPT PRINTER AND ARE NOT ****
+**** RUNNING MAC OS X, YOU WILL ALSO NEED TO INSTALL GPL ****
+**** GHOSTSCRIPT WITH THE "cups" DRIVER AFTER YOU INSTALL ****
+**** CUPS AND BEFORE YOU INSTALL THIS PACKAGE. ****
+
+
+BEFORE YOU BEGIN
+
+ You'll need ANSI-compliant C and C++ compilers, plus a make program and
+ POSIX-compliant shell (/bin/sh). The GNU compiler tools and Bash work well
+ and we have tested the current CUPS code against several versions of GCC
+ with excellent results.
+
+ The makefiles used by the project should work with most versions of make.
+ We've tested them with GNU make as well as the make programs shipped by
+ Compaq, HP, SGI, and Sun. BSD users should use GNU make (gmake) since BSD
+ make does not support "include".
+
+ Poppler, libijs, freetype, fontconfig, and liblcms (liblcms2 recommended)
+ must be installed to be able to compile this package.
+
+ Note that Poppler has to be compiled with the
+ "--enable-poppler-cpp" configure option (or the
+ "libpoppler-cpp-dev(el)" package has to be installed if the
+ Poppler packages from a Linux distribution are used).
+
+ Besides these tools you'll want the JPEG, PNG, TIFF, ZLIB libraries for
+ image support. CUPS Filters will compile and run without these, however
+ you'll miss out on many of the features provided by CUPS Filters.
+
+ To get cups-browsed, the daemon to browse Bonjour broadcasts of
+ remote CUPS queues and make the queues available locally, you also
+ need libavahi-common and libavahi-client.
+
+COMPILING THE BZR REPOSITORY CODE
+
+ The CUPS Filters BZR repository doesn't hold a copy of the pre-built
+ configure script. You'll need to run the GNU autoconf software (2.65 or
+ higher) to create it:
+
+ ./autogen.sh
+
+
+CONFIGURATION
+
+ CUPS Filters uses GNU autoconf, so you should find the usual "configure"
+ script in the main CUPS Filters source directory. To configure CUPS
+ Filters for your system, type:
+
+ ./configure
+
+ The default installation will put the CUPS Filters software in the
+ "/etc" and "/usr" directories on your system, which will overwrite
+ some of the original filters and their auxiliary files of CUPS
+ 1.5.x or earlier and the auxiliary files of bannertops in all CUPS
+ versions including version 1.6.x (see also the section "PACKAGING
+ THE SOFTWARE FOR OPERATING SYSTEM DISTRIBUTIONS" below). The
+ system will still have the same functionality as before, but CUPS
+ will not convert all incoming files into PostScript any more, it
+ will convert them into PDF instead and after applying page
+ management (N-up, selected pages, reverse order, ...) by the
+ pdftopdf filter and convert PDF into the printer's native format
+ then (PDF-based printing workflow). CUPS 1.6.x or later does not
+ contain any filters which this package provides. It requires the
+ installation of this package for printing with filters and drivers
+ under Linux (or other non-Mac-OS-X operation systems).
+
+ Use the "--prefix" option to install the CUPS Filters software in another
+ location:
+
+ ./configure --prefix=/some/directory
+
+ To see a complete list of configuration options, use the --help option:
+
+ ./configure --help
+
+ If any of the dependent libraries are not installed in a system default
+ location (typically "/usr/include" and "/usr/lib") you'll need to set the
+ CFLAGS, CPPFLAGS, CXXFLAGS, DSOFLAGS, and LDFLAGS environment variables
+ prior to running configure:
+
+ setenv CFLAGS "-I/some/directory"
+ setenv CPPFLAGS "-I/some/directory"
+ setenv CXXFLAGS "-I/some/directory"
+ setenv DSOFLAGS "-L/some/directory"
+ setenv LDFLAGS "-L/some/directory"
+ ./configure ...
+
+ or:
+
+ CFLAGS="-I/some/directory" \
+ CPPFLAGS="-I/some/directory" \
+ CXXFLAGS="-I/some/directory" \
+ DSOFLAGS="-L/some/directory" \
+ LDFLAGS="-L/some/directory" \
+ ./configure ...
+
+ Once you have configured things, just type:
+
+ make ENTER
+
+ or if you have FreeBSD, NetBSD, or OpenBSD type:
+
+ gmake ENTER
+
+ to build the software.
+
+
+INSTALLING THE SOFTWARE
+
+ Once you have built the software you need to install it. The "install"
+ target provides a quick way to install the software on your local system:
+
+ make install ENTER
+
+ or for FreeBSD, NetBSD, or OpenBSD:
+
+ gmake install ENTER
+
+PACKAGING THE SOFTWARE FOR OPERATING SYSTEM DISTRIBUTIONS
+
+ The use of cups-filters is supported for CUPS from version 1.5.x
+ on (to switch to the PDF-based printing workflow already now) and
+ required for CUPS 1.6.x (as it does not ship a complete filter set
+ any more). In both cases cups-filters ships some files which exist
+ also in CUPS, but the versions of cups-filters have to be used to
+ assure that printing works correctly. So in the packaging of CUPS
+ the files should be removed.
+
+ Use the alternatives facility (see update-alternatives(8)) only if
+ your CUPS version is 1.5.x and you want to make the use of
+ cups-filters optional. Note that then the files of cups-filters
+ need to have priority.
+
+ When using cups-filters with CUPS 1.5.x, many of the original CUPS
+ filters get replaced or at least useless. Please remove the
+ following files from your CUPS package:
+
+ /usr/lib/cups/backend/serial
+ /usr/lib/cups/backend/parallel
+ /usr/lib/cups/filter/bannertops
+ /usr/lib/cups/filter/commandtoescpx
+ /usr/lib/cups/filter/commandtopclx
+ /usr/lib/cups/filter/imagetops
+ /usr/lib/cups/filter/imagetoraster
+ /usr/lib/cups/filter/pdftops
+ /usr/lib/cups/filter/rastertoescpx
+ /usr/lib/cups/filter/rastertopclx
+ /usr/lib/cups/filter/texttops
+ /usr/share/cups/banners/*
+ /usr/share/cups/data/testprint
+ /usr/share/cups/data/psglyphs
+ /usr/share/cups/fonts/*
+
+ Also comment out all conversion rules which use any of the removed
+ filters. You can do it with the following command line:
+
+ perl -p -i -e 's:^(.*\s+(pdftops|texttops|imagetops|bannertops|imagetoraster)\s*)$:#\1:' /usr/share/cups/mime/mime.convs
+
+ If you use CUPS 1.6.x there is less to remove from the CUPS
+ package. It is only bannertops and its auxiliary files which are
+ in the way for bannertopdf:
+
+ /usr/lib/cups/filter/bannertops
+ /usr/share/cups/banners/*
+ /usr/share/cups/data/testprint
+
+ The conversion rules get commented out via:
+
+ perl -p -i -e 's:^(.*\s+bannertops\s*)$:#\1:' /usr/share/cups/mime/mime.convs
+
+ For CUPS 1.6.x a bug report/feature request is posted to ask for
+ (at least optional) removal of bannertops:
+
+ http://www.cups.org/str.php?L4120
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 000000000..d9592270f
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,1061 @@
+ACLOCAL_AMFLAGS = -I m4
+
+pkgconfdir = $(libdir)/pkgconfig
+pkgconf_DATA = \
+ libcupsfilters.pc \
+ libfontembed.pc
+
+doc_DATA = \
+ AUTHORS \
+ COPYING \
+ NEWS \
+ INSTALL \
+ README
+
+EXTRA_DIST = \
+ $(doc_DATA) \
+ autogen.sh \
+ libcupsfilters.pc.in \
+ libfontembed.pc.in \
+ utils/cups-browsed.service \
+ utils/cups-browsed-upstart.conf \
+ filter/braille/drivers/index/ubrlto4dot.c \
+ filter/braille/filters/TODO.txt
+
+# ========
+# Backends
+# ========
+pkgbackenddir = $(CUPS_SERVERBIN)/backend
+pkgbackend_PROGRAMS = parallel serial beh implicitclass
+
+check_PROGRAMS = test1284
+# We need ieee1284 up and running.
+# Leave it to the user to run if they have the bus.
+#TESTS = test1284
+
+parallel_SOURCES = \
+ backend/backend-private.h \
+ backend/ieee1284.c \
+ backend/parallel.c
+parallel_LDADD = $(CUPS_LIBS)
+parallel_CFLAGS = $(CUPS_CFLAGS)
+
+serial_SOURCES = \
+ backend/backend-private.h \
+ backend/serial.c
+serial_LDADD = $(CUPS_LIBS)
+serial_CFLAGS = $(CUPS_CFLAGS)
+
+beh_SOURCES = \
+ backend/backend-private.h \
+ backend/beh.c
+beh_LDADD = $(CUPS_LIBS)
+beh_CFLAGS = $(CUPS_CFLAGS)
+
+implicitclass_SOURCES = \
+ backend/backend-private.h \
+ backend/implicitclass.c
+implicitclass_LDADD = $(CUPS_LIBS)
+implicitclass_CFLAGS = $(CUPS_CFLAGS)
+
+test1284_SOURCES = \
+ backend/backend-private.h \
+ backend/ieee1284.c \
+ backend/test1284.c
+test1284_LDADD = $(CUPS_LIBS)
+test1284_CFLAGS = $(CUPS_CFLAGS)
+
+if ENABLE_BRAILLE
+pkgbackend_PROGRAMS += cups-brf
+
+cups_brf_SOURCES = \
+ backend/cups-brf.c
+endif
+
+# ==============
+# PPD Generators
+# ==============
+if ENABLE_DRIVERLESS
+pkgppdgendir = $(CUPS_SERVERBIN)/driver
+pkgppdgen_PROGRAMS = driverless
+
+driverless_SOURCES = \
+ utils/driverless.c
+driverless_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+driverless_CXXFLAGS = $(driverless_CFLAGS)
+driverless_LDADD = \
+ $(CUPS_LIBS) \
+ libcupsfilters.la
+endif
+
+# =======
+# Banners
+# =======
+pkgbannerdir = $(CUPS_DATADIR)/banners
+pkgbanner_DATA =
+if ENABLE_POPPLER
+pkgbanner_DATA += \
+ banners/classified \
+ banners/confidential \
+ banners/secret \
+ banners/standard \
+ banners/form \
+ banners/topsecret \
+ banners/unclassified
+endif
+EXTRA_DIST += $(pkgbanner_DATA)
+
+# ========
+# Charsets
+# ========
+pkgcharsetdir = $(CUPS_DATADIR)/charsets
+pkgcharset_DATA = \
+ charset/pdf.utf-8.heavy \
+ charset/pdf.utf-8.simple
+
+EXTRA_DIST += $(pkgcharset_DATA)
+
+# ====================
+# CUPS Filters library
+# ====================
+pkgfiltersincludedir = $(includedir)/cupsfilters
+pkgfiltersinclude_DATA = \
+ cupsfilters/colord.h \
+ cupsfilters/colormanager.h \
+ cupsfilters/driver.h \
+ cupsfilters/image.h \
+ cupsfilters/raster.h \
+ cupsfilters/ppdgenerator.h
+
+lib_LTLIBRARIES = libcupsfilters.la
+
+check_PROGRAMS += \
+ testcmyk \
+ testdither \
+ testimage \
+ testrgb
+TESTS = \
+ testdither
+# testcmyk # fails as it opens some image.ppm which is nowerhe to be found.
+# testimage # requires also some ppm file as argument
+# testrgb # same error
+# FIXME: run old testdither
+# ./testdither > test/0-255.pgm 2>test/0-255.log
+# ./testdither 0 127 255 > test/0-127-255.pgm 2>test/0-127-255.log
+# ./testdither 0 85 170 255 > test/0-85-170-255.pgm 2>test/0-85-170-255.log
+# ./testdither 0 63 127 170 198 227 255 > test/0-63-127-170-198-227-255.pgm 2>test/0-63-127-170-198-227-255.log
+# ./testdither 0 210 383 > test/0-210-383.pgm 2>test/0-210-383.log
+# ./testdither 0 82 255 > test/0-82-255.pgm 2>test/0-82-255.log
+# ./testdither 0 510 > test/0-510.pgm 2>test/0-510.log
+# ./testdither 0 1020 > test/0-1020.pgm 2>test/0-1020.log
+
+
+libcupsfilters_la_SOURCES = \
+ cupsfilters/attr.c \
+ cupsfilters/check.c \
+ cupsfilters/cmyk.c \
+ cupsfilters/colord.c \
+ cupsfilters/colormanager.c \
+ cupsfilters/dither.c \
+ cupsfilters/image.c \
+ cupsfilters/image-bmp.c \
+ cupsfilters/image-colorspace.c \
+ cupsfilters/image-gif.c \
+ cupsfilters/image-jpeg.c \
+ cupsfilters/image-photocd.c \
+ cupsfilters/image-pix.c \
+ cupsfilters/image-png.c \
+ cupsfilters/image-pnm.c \
+ cupsfilters/image-private.h \
+ cupsfilters/image-sgi.c \
+ cupsfilters/image-sgi.h \
+ cupsfilters/image-sgilib.c \
+ cupsfilters/image-sun.c \
+ cupsfilters/image-tiff.c \
+ cupsfilters/image-zoom.c \
+ cupsfilters/lut.c \
+ cupsfilters/pack.c \
+ cupsfilters/ppdgenerator.c \
+ cupsfilters/raster.c \
+ cupsfilters/rgb.c \
+ cupsfilters/srgb.c \
+ $(pkgfiltersinclude_DATA)
+libcupsfilters_la_LIBADD = \
+ $(CUPS_LIBS) \
+ $(LIBJPEG_LIBS) \
+ $(LIBPNG_LIBS) \
+ $(TIFF_LIBS) \
+ -lm
+libcupsfilters_la_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ $(LIBJPEG_CFLAGS) \
+ $(LIBPNG_CFLAGS) \
+ $(TIFF_CFLAGS)
+libcupsfilters_la_LDFLAGS = \
+ -no-undefined \
+ -version-info 1
+if BUILD_DBUS
+libcupsfilters_la_CFLAGS += $(DBUS_CFLAGS) -DHAVE_DBUS
+libcupsfilters_la_LIBADD += $(DBUS_LIBS)
+endif
+
+testcmyk_SOURCES = \
+ cupsfilters/testcmyk.c \
+ $(pkgfiltersinclude_DATA)
+testcmyk_LDADD = \
+ libcupsfilters.la \
+ -lm
+
+testdither_SOURCES = \
+ cupsfilters/testdither.c \
+ $(pkgfiltersinclude_DATA)
+testdither_LDADD = \
+ libcupsfilters.la \
+ -lm
+
+testimage_SOURCES = \
+ cupsfilters/testimage.c \
+ $(pkgfiltersinclude_DATA)
+testimage_LDADD = \
+ $(LIBJPEG_LIBS) \
+ $(LIBPNG_LIBS) \
+ $(TIFF_LIBS) \
+ libcupsfilters.la \
+ -lm
+testimage_CFLAGS = \
+ $(LIBJPEG_CFLAGS) \
+ $(LIBPNG_CFLAGS) \
+ $(TIFF_CFLAGS)
+
+testrgb_SOURCES = \
+ cupsfilters/testrgb.c \
+ $(pkgfiltersinclude_DATA)
+testrgb_LDADD = \
+ libcupsfilters.la \
+ -lm
+
+EXTRA_DIST += \
+ $(pkgfiltersinclude_DATA) \
+ cupsfilters/image.pgm \
+ cupsfilters/image.ppm
+
+# =========
+# CUPS Data
+# =========
+pkgcupsdatadir = $(CUPS_DATADIR)/data
+pkgcupsdata_DATA = \
+ data/default.pdf \
+ data/form_russian.pdf \
+ data/form_english.pdf \
+ data/form_english_in.odt \
+ data/form_russian_in.odt \
+ data/default-testpage.pdf \
+ data/testprint \
+ data/classified.pdf \
+ data/confidential.pdf \
+ data/secret.pdf \
+ data/standard.pdf \
+ data/topsecret.pdf \
+ data/unclassified.pdf
+
+EXTRA_DIST += $(pkgcupsdata_DATA)
+
+# ===========
+# CUPS Config
+# ===========
+pkgcupsserverrootdir = $(CUPS_SERVERROOT)
+pkgcupsserverroot_DATA = \
+ utils/cups-browsed.conf
+
+# =======
+# Drivers
+# =======
+pkgdriverdir = $(CUPS_DATADIR)/drv
+pkgdriver_DATA = \
+ drv/cupsfilters.drv
+if ENABLE_BRAILLE
+pkgdriver_DATA += \
+ drv/generic-brf.drv \
+ drv/generic-ubrl.drv \
+ drv/indexv3.drv \
+ drv/indexv4.drv
+endif
+
+EXTRA_DIST += $(pkgdriver_DATA)
+
+# =======
+# Definitions for drivers
+# =======
+pkgppdcdir = $(CUPS_DATADIR)/ppdc
+pkgppdc_DATA = \
+ filter/pcl.h \
+ filter/escp.h
+if ENABLE_BRAILLE
+GENERATED_LIBLOUIS = \
+ filter/braille/filters/liblouis2.defs \
+ filter/braille/filters/liblouis3.defs \
+ filter/braille/filters/liblouis4.defs
+GENERATED_DEFS= \
+ filter/braille/filters/liblouis1.defs \
+ $(GENERATED_LIBLOUIS)
+
+filter/braille/filters/liblouis1.defs: filter/braille/filters/liblouis1.defs.gen
+ $< > $@
+
+$(GENERATED_LIBLOUIS): filter/braille/filters/liblouis%.defs: filter/braille/filters/liblouis1.defs
+ sed -e "s/Braille transcription/Additional Braille transcription ($*)/" \
+ -e "s/^ \\*Choice / Choice /" \
+ -e "s/^ Choice \"None\// *Choice \"None\//" \
+ -e s/LibLouis/LibLouis$*/ \
+ < $< > $@
+
+pkgppdc_DATA += \
+ filter/braille/drivers/common/media-braille.defs \
+ filter/braille/drivers/index/index.defs \
+ filter/braille/filters/braille.defs \
+ filter/braille/filters/imagemagick.defs \
+ filter/braille/filters/liblouis.defs \
+ filter/braille/drivers/common/fr-braille.po
+nodist_pkgppdc_DATA = \
+ $(GENERATED_DEFS)
+
+EXTRA_DIST += filter/braille/filters/liblouis1.defs.gen.in
+endif
+
+EXTRA_DIST += $(pkgppdc_DATA)
+
+# =====
+# MIMEs
+# =====
+pkgmimedir = $(CUPS_DATADIR)/mime
+pkgmime_DATA = \
+ mime/cupsfilters.convs \
+ mime/cupsfilters.types
+if ENABLE_POPPLER
+pkgmime_DATA += \
+ mime/cupsfilters-poppler.convs
+endif
+if ENABLE_GHOSTSCRIPT
+pkgmime_DATA += \
+ mime/cupsfilters-ghostscript.convs
+endif
+if ENABLE_MUTOOL
+pkgmime_DATA += \
+ mime/cupsfilters-mupdf.convs
+endif
+if ENABLE_BRAILLE
+pkgmime_DATA += \
+ mime/braille.convs \
+ mime/braille.types
+endif
+
+EXTRA_DIST += $(pkgmime_DATA)
+
+# =================
+# Braille aux files
+# =================
+if ENABLE_BRAILLE
+pkgbrailledir = $(CUPS_DATADIR)/braille
+nodist_pkgbraille_SCRIPTS = \
+ filter/braille/drivers/index/indexv4.sh \
+ filter/braille/drivers/index/indexv3.sh \
+ filter/braille/drivers/index/index.sh \
+ filter/braille/filters/cups-braille.sh
+endif
+
+# =================
+# Fontembed library
+# =================
+pkgfontembedincludedir = $(includedir)/fontembed
+pkgfontembedinclude_DATA = \
+ fontembed/bitset.h \
+ fontembed/embed.h \
+ fontembed/fontfile.h \
+ fontembed/iofn.h \
+ fontembed/sfnt.h
+
+lib_LTLIBRARIES += libfontembed.la
+
+bin_PROGRAMS = ttfread
+
+check_PROGRAMS += \
+ test_analyze \
+ test_pdf \
+ test_ps
+TESTS += \
+ test_analyze \
+ test_pdf \
+ test_ps
+
+libfontembed_la_SOURCES = \
+ fontembed/aglfn13.c \
+ fontembed/bitset.h \
+ fontembed/dynstring.c \
+ fontembed/dynstring.h \
+ fontembed/embed.c \
+ fontembed/embed.h \
+ fontembed/embed_sfnt.c \
+ fontembed/embed_sfnt_int.h \
+ fontembed/embed_pdf.c \
+ fontembed/embed_pdf.h \
+ fontembed/embed_pdf_int.h \
+ fontembed/fontfile.c \
+ fontembed/fontfile.h \
+ fontembed/frequent.c \
+ fontembed/frequent.h \
+ fontembed/iofn.h \
+ fontembed/macroman.h \
+ fontembed/sfnt.c \
+ fontembed/sfnt.h \
+ fontembed/sfnt_int.h \
+ fontembed/sfnt_subset.c
+libfontembed_la_LDFLAGS = \
+ -no-undefined \
+ -version-info 1
+
+ttfread_SOURCES = fontembed/main.c
+ttfread_LDADD = libfontembed.la
+
+test_analyze_SOURCES = fontembed/test_analyze.c
+test_analyze_LDADD = libfontembed.la
+
+test_pdf_SOURCES = fontembed/test_pdf.c
+test_pdf_LDADD = libfontembed.la
+
+test_ps_SOURCES = fontembed/test_ps.c
+test_ps_LDADD = libfontembed.la
+
+EXTRA_DIST += \
+ $(pkgfontembedinclude_DATA) \
+ fontembed/README
+
+pkgfilter_PROGRAMS =
+
+# ===========
+# PDF to OPVP
+# ===========
+pkgfilterdir = $(CUPS_SERVERBIN)/filter
+if ENABLE_POPPLER
+pkgfilter_PROGRAMS += \
+ pdftoopvp
+endif
+
+pkgfontconfigdir = $(sysconfdir)/$(FONTDIR)
+pkgfontconfig_DATA = filter/pdftoopvp/99pdftoopvp.conf
+
+pdftoopvp_SOURCES = \
+ filter/pdftoopvp/oprs/OPRS.cxx \
+ filter/pdftoopvp/oprs/OPRS.h \
+ filter/pdftoopvp/oprs/OPVPSplashClip.cxx \
+ filter/pdftoopvp/oprs/OPVPSplashClip.h \
+ filter/pdftoopvp/oprs/OPVPSplash.cxx \
+ filter/pdftoopvp/oprs/OPVPSplash.h \
+ filter/pdftoopvp/oprs/OPVPSplashPath.cxx \
+ filter/pdftoopvp/oprs/OPVPSplashPath.h \
+ filter/pdftoopvp/oprs/OPVPSplashState.cxx \
+ filter/pdftoopvp/oprs/OPVPSplashState.h \
+ filter/pdftoopvp/oprs/OPVPSplashXPath.cxx \
+ filter/pdftoopvp/oprs/OPVPSplashXPath.h \
+ filter/pdftoopvp/oprs/OPVPWrapper.cxx \
+ filter/pdftoopvp/oprs/OPVPWrapper.h \
+ filter/pdftoopvp/oprs/OPVPWrapper_0_2.cxx \
+ filter/pdftoopvp/oprs/OPVPWrapper_0_2.h \
+ filter/pdftoopvp/OPVPError.h \
+ filter/pdftoopvp/opvp/opvp_common.h \
+ filter/pdftoopvp/opvp/opvp.h \
+ filter/pdftoopvp/opvp/opvp_0_2_0.h \
+ filter/pdftoopvp/OPVPOutputDev.cxx \
+ filter/pdftoopvp/OPVPOutputDev.h \
+ filter/pdftoopvp/pdftoopvp.cxx
+pdftoopvp_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ $(FREETYPE_CFLAGS) \
+ $(FONTCONFIG_CFLAGS) \
+ $(LIBPNG_CFLAGS) \
+ $(POPPLER_CFLAGS) \
+ -I$(srcdir)/filter/pdftoopvp/oprs \
+ -I$(srcdir)/filter/pdftoopvp/opvp
+pdftoopvp_CXXFLAGS = $(pdftoopvp_CFLAGS)
+pdftoopvp_LDADD = \
+ $(CUPS_LIBS) \
+ $(FREETYPE_LIBS) \
+ $(FONTCONFIG_LIBS) \
+ $(LIBPNG_LIBS) \
+ $(POPPLER_LIBS) \
+ $(DLOPEN_LIBS)
+
+EXTRA_DIST += $(pkgfontconfig_DATA)
+
+# ==========
+# PDF to PDF
+# ==========
+pkgfilter_PROGRAMS += pdftopdf
+
+pdftopdf_SOURCES = \
+ filter/pdftopdf/pdftopdf.cc \
+ filter/pdftopdf/pdftopdf_jcl.cc \
+ filter/pdftopdf/pdftopdf_jcl.h \
+ filter/pdftopdf/pdftopdf_processor.cc \
+ filter/pdftopdf/pdftopdf_processor.h \
+ filter/pdftopdf/qpdf_pdftopdf_processor.cc \
+ filter/pdftopdf/qpdf_pdftopdf_processor.h \
+ filter/pdftopdf/pptypes.cc \
+ filter/pdftopdf/pptypes.h \
+ filter/pdftopdf/nup.cc \
+ filter/pdftopdf/nup.h \
+ filter/pdftopdf/intervalset.cc \
+ filter/pdftopdf/intervalset.h \
+ filter/pdftopdf/qpdf_tools.cc \
+ filter/pdftopdf/qpdf_tools.h \
+ filter/pdftopdf/qpdf_xobject.cc \
+ filter/pdftopdf/qpdf_xobject.h \
+ filter/pdftopdf/qpdf_pdftopdf.cc \
+ filter/pdftopdf/qpdf_pdftopdf.h \
+ filter/pdftopdf/qpdf_cm.cc \
+ filter/pdftopdf/qpdf_cm.h
+pdftopdf_CFLAGS = \
+ $(LIBQPDF_CFLAGS) \
+ $(CUPS_CFLAGS)
+pdftopdf_CXXFLAGS = -std=c++0x $(pdftopdf_CFLAGS) # -std=c++11
+pdftopdf_LDADD = \
+ $(LIBQPDF_LIBS) \
+ $(CUPS_LIBS)
+
+# ======================
+# Simple filter binaries
+# ======================
+pkgfilter_SCRIPTS = \
+ filter/imagetops \
+ filter/texttops \
+ filter/rastertopclm
+if ENABLE_GHOSTSCRIPT
+pkgfilter_SCRIPTS += \
+ filter/gstopxl \
+ filter/gstopdf
+endif
+if ENABLE_BRAILLE
+nodist_pkgfilter_SCRIPTS = \
+ filter/braille/drivers/generic/brftoembosser \
+ filter/braille/drivers/index/imageubrltoindexv3 \
+ filter/braille/drivers/index/imageubrltoindexv4 \
+ filter/braille/drivers/index/textbrftoindexv3 \
+ filter/braille/filters/imagetobrf \
+ filter/braille/filters/vectortopdf \
+ filter/braille/filters/vectortobrf \
+ filter/braille/filters/texttobrf \
+ filter/braille/filters/musicxmltobrf
+endif
+pkgfilter_PROGRAMS += \
+ commandtoescpx \
+ commandtopclx \
+ sys5ippprinter \
+ texttotext \
+ pdftops \
+ rastertoescpx \
+ rastertopclx \
+ texttopdf \
+ rastertopdf \
+ rastertops
+if ENABLE_URFTOPDF
+pkgfilter_PROGRAMS += \
+ urftopdf
+endif
+if ENABLE_POPPLER
+pkgfilter_PROGRAMS += \
+ bannertopdf \
+ pdftoraster
+if ENABLE_IJS
+pkgfilter_PROGRAMS += \
+ pdftoijs
+endif
+endif
+if ENABLE_GHOSTSCRIPT
+pkgfilter_PROGRAMS += \
+ gstoraster
+endif
+if ENABLE_MUTOOL
+pkgfilter_PROGRAMS += \
+ mupdftoraster
+endif
+if ENABLE_FOOMATIC
+pkgfilter_PROGRAMS += \
+ foomatic-rip
+endif
+if ENABLE_IMAGEFILTERS
+pkgfilter_PROGRAMS += \
+ imagetopdf \
+ imagetoraster
+endif
+
+check_PROGRAMS += \
+ test_pdf1 \
+ test_pdf2
+
+TESTS += \
+ test_pdf1 \
+ test_pdf2
+
+bannertopdf_SOURCES = \
+ filter/banner.c \
+ filter/banner.h \
+ filter/bannertopdf.c \
+ filter/pdf.cxx \
+ filter/pdf.h \
+ fontembed/embed.h \
+ fontembed/sfnt.h
+EXTRA_bannertopdf_SOURCES = filter/getline.c
+bannertopdf_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ $(LIBJPEG_CFLAGS) \
+ $(LIBPNG_CFLAGS) \
+ $(POPPLER_CFLAGS) \
+ $(TIFF_CFLAGS) \
+ $(FONTCONFIG_CFLAGS) \
+ -I$(srcdir)/fontembed/
+
+bannertopdf_CXXFLAGS = $(bannertopdf_CFLAGS)
+bannertopdf_LDADD = \
+ $(GETLINE) \
+ $(CUPS_LIBS) \
+ $(LIBJPEG_LIBS) \
+ $(LIBPNG_LIBS) \
+ $(POPPLER_LIBS) \
+ $(TIFF_LIBS) \
+ $(FONTCONFIG_LIBS) \
+ libfontembed.la
+
+bannertopdf_DEPENDENCIES = \
+ $(GETLINE) \
+ libfontembed.la
+
+commandtoescpx_SOURCES = \
+ cupsfilters/driver.h \
+ filter/commandtoescpx.c \
+ filter/pcl.h
+commandtoescpx_CFLAGS= \
+ $(CUPS_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+commandtoescpx_LDADD = $(CUPS_LIBS)
+
+commandtopclx_SOURCES = \
+ cupsfilters/driver.h \
+ filter/commandtopclx.c \
+ filter/pcl.h
+commandtopclx_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+commandtopclx_LDADD = $(CUPS_LIBS)
+
+foomatic_rip_SOURCES = \
+ filter/foomatic-rip/foomaticrip.c \
+ filter/foomatic-rip/foomaticrip.h \
+ filter/foomatic-rip/options.c \
+ filter/foomatic-rip/options.h \
+ filter/foomatic-rip/pdf.c \
+ filter/foomatic-rip/pdf.h \
+ filter/foomatic-rip/postscript.c \
+ filter/foomatic-rip/postscript.h \
+ filter/foomatic-rip/process.c \
+ filter/foomatic-rip/process.h \
+ filter/foomatic-rip/renderer.c \
+ filter/foomatic-rip/renderer.h \
+ filter/foomatic-rip/spooler.c \
+ filter/foomatic-rip/spooler.h \
+ filter/foomatic-rip/util.c \
+ filter/foomatic-rip/util.h \
+ cupsfilters/colord.h
+foomatic_rip_CFLAGS = \
+ -DCONFIG_PATH='"$(sysconfdir)/foomatic"' \
+ -I$(srcdir)/cupsfilters/
+foomatic_rip_LDADD = \
+ $(CUPS_LIBS) \
+ -lm \
+ libcupsfilters.la
+
+gstoraster_SOURCES = \
+ filter/gstoraster.c \
+ cupsfilters/colord.h \
+ cupsfilters/raster.h
+gstoraster_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+gstoraster_LDADD = \
+ $(CUPS_LIBS) \
+ libcupsfilters.la
+
+imagetopdf_SOURCES = \
+ cupsfilters/image.h \
+ filter/common.c \
+ filter/common.h \
+ filter/imagetopdf.c
+imagetopdf_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ $(LIBJPEG_CFLAGS) \
+ $(LIBPNG_CFLAGS) \
+ $(TIFF_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+imagetopdf_LDADD = \
+ $(CUPS_LIBS) \
+ $(LIBJPEG_LIBS) \
+ $(LIBPNG_LIBS) \
+ $(TIFF_LIBS) \
+ -lm \
+ libcupsfilters.la
+
+imagetoraster_SOURCES = \
+ cupsfilters/image.h \
+ cupsfilters/image-private.h \
+ filter/common.c \
+ filter/common.h \
+ filter/imagetoraster.c
+imagetoraster_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+imagetoraster_LDADD = \
+ $(CUPS_LIBS) \
+ -lm \
+ libcupsfilters.la
+
+if ENABLE_URFTOPDF
+urftopdf_SOURCES = \
+ filter/urftopdf.cpp \
+ filter/unirast.h
+urftopdf_CXXFLAGS = \
+ $(LIBQPDF_CFLAGS)
+urftopdf_LDADD = \
+ $(LIBQPDF_LIBS)
+endif
+
+rastertopdf_SOURCES = \
+ filter/rastertopdf.cpp
+rastertopdf_CXXFLAGS = \
+ $(CUPS_CFLAGS) \
+ $(LCMS_CFLAGS) \
+ $(LIBQPDF_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+rastertopdf_LDADD = \
+ $(CUPS_LIBS) \
+ $(LCMS_LIBS) \
+ $(LIBQPDF_LIBS) \
+ libcupsfilters.la
+
+mupdftoraster_SOURCES = \
+ filter/mupdftoraster.c
+mupdftoraster_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+mupdftoraster_LDADD = \
+ $(CUPS_LIBS) \
+ libcupsfilters.la
+
+rastertops_SOURCES = \
+ filter/rastertops.c
+rastertops_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+rastertops_LDADD = \
+ $(CUPS_LIBS) \
+ -lz \
+ libcupsfilters.la
+
+pdftoijs_SOURCES = \
+ filter/pdftoijs.cxx \
+ filter/PDFError.h
+pdftoijs_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ $(IJS_CFLAGS) \
+ $(POPPLER_CFLAGS)
+pdftoijs_CXXFLAGS = $(pdftoijs_CFLAGS)
+pdftoijs_LDADD = \
+ $(CUPS_LIBS) \
+ $(IJS_LIBS) \
+ $(POPPLER_LIBS)
+
+sys5ippprinter_SOURCES = \
+ filter/common.c \
+ filter/common.h \
+ filter/sys5ippprinter.c
+EXTRA_sys5ippprinter_SOURCES = filter/strcasestr.c
+sys5ippprinter_CFLAGS = $(CUPS_CFLAGS)
+sys5ippprinter_LDADD = $(STRCASESTR) $(CUPS_LIBS)
+sys5ippprinter_DEPENDENCIES = $(STRCASESTR)
+
+texttotext_SOURCES = \
+ filter/texttotext.c
+EXTRA_texttotext_SOURCES = filter/strcasestr.c
+texttotext_CFLAGS = $(CUPS_CFLAGS)
+texttotext_LDADD = $(STRCASESTR) $(CUPS_LIBS)
+texttotext_DEPENDENCIES = $(STRCASESTR)
+
+pdftops_SOURCES = \
+ filter/common.c \
+ filter/common.h \
+ filter/pdftops.c
+EXTRA_pdftops_SOURCES = filter/strcasestr.c
+pdftops_CFLAGS = $(CUPS_CFLAGS)
+pdftops_LDADD = $(STRCASESTR) $(CUPS_LIBS)
+pdftops_DEPENDENCIES = $(STRCASESTR)
+
+pdftoraster_SOURCES = \
+ filter/pdftoraster.cxx \
+ filter/PDFError.h
+pdftoraster_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ $(LCMS_CFLAGS) \
+ $(LIBJPEG_CFLAGS) \
+ $(LIBPNG_CFLAGS) \
+ $(POPPLER_CFLAGS) \
+ $(TIFF_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+pdftoraster_CXXFLAGS = $(pdftoraster_CFLAGS)
+pdftoraster_LDADD = \
+ $(CUPS_LIBS) \
+ $(LCMS_LIBS) \
+ $(LIBJPEG_LIBS) \
+ $(LIBPNG_LIBS) \
+ $(POPPLER_LIBS) \
+ $(TIFF_LIBS) \
+ libcupsfilters.la
+
+rastertoescpx_SOURCES = \
+ cupsfilters/driver.h \
+ filter/escp.h \
+ filter/rastertoescpx.c
+rastertoescpx_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+rastertoescpx_LDADD = \
+ $(CUPS_LIBS) \
+ libcupsfilters.la
+
+rastertopclx_SOURCES = \
+ cupsfilters/driver.h \
+ filter/pcl.h \
+ filter/pcl-common.c \
+ filter/pcl-common.h \
+ filter/rastertopclx.c
+rastertopclx_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ $(LIBPNG_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+rastertopclx_LDADD = \
+ $(CUPS_LIBS) \
+ $(LIBPNG_LIBS) \
+ libcupsfilters.la
+
+test_pdf1_SOURCES = \
+ filter/pdfutils.c \
+ filter/pdfutils.h \
+ filter/test_pdf1.c \
+ fontembed/embed.h \
+ fontembed/sfnt.h
+test_pdf1_CFLAGS = -I$(srcdir)/fontembed/
+test_pdf1_LDADD = libfontembed.la
+
+test_pdf2_SOURCES = \
+ filter/pdfutils.c \
+ filter/pdfutils.h \
+ filter/test_pdf2.c \
+ fontembed/embed.h \
+ fontembed/sfnt.h
+test_pdf2_CFLAGS = -I$(srcdir)/fontembed/
+test_pdf2_LDADD = libfontembed.la
+
+texttopdf_SOURCES = \
+ filter/common.c \
+ filter/common.h \
+ filter/pdfutils.c \
+ filter/pdfutils.h \
+ filter/textcommon.c \
+ filter/textcommon.h \
+ filter/texttopdf.c \
+ fontembed/bitset.h \
+ fontembed/embed.h \
+ fontembed/fontfile.h \
+ fontembed/iofn.h \
+ fontembed/sfnt.h
+texttopdf_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ $(FONTCONFIG_CFLAGS) \
+ -I$(srcdir)/fontembed/
+texttopdf_LDADD = \
+ $(CUPS_LIBS) \
+ $(FONTCONFIG_LIBS) \
+ libfontembed.la
+
+# Not reliable bash script
+#TESTS += filter/test.sh
+
+EXTRA_DIST += \
+ $(pkgfilter_SCRIPTS) \
+ filter/test.sh
+
+# =====
+# UTILS
+# =====
+
+cups_notifier_sources = \
+ cups-notifier.c \
+ cups-notifier.h
+
+$(cups_notifier_sources): utils/org.cups.cupsd.Notifier.xml
+ gdbus-codegen \
+ --interface-prefix org.cups.cupsd \
+ --c-namespace Cups \
+ --generate-c-code cups-notifier \
+ utils/org.cups.cupsd.Notifier.xml
+
+sbin_PROGRAMS = \
+ cups-browsed
+cups_browsed_SOURCES = \
+ utils/cups-browsed.c
+nodist_cups_browsed_SOURCES = \
+ $(cups_notifier_sources)
+cups_browsed_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ $(AVAHI_CFLAGS) \
+ $(AVAHI_GLIB_CFLAGS) \
+ $(GLIB_CFLAGS) \
+ $(GIO_CFLAGS) \
+ $(GIO_UNIX_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+cups_browsed_CXXFLAGS = $(cups_browsed_CFLAGS)
+cups_browsed_LDADD = \
+ $(CUPS_LIBS) \
+ $(AVAHI_LIBS) \
+ $(AVAHI_GLIB_LIBS) \
+ $(GLIB_LIBS) \
+ $(GIO_LIBS) \
+ $(GIO_UNIX_LIBS) \
+ libcupsfilters.la
+initrcdir = $(INITDDIR)
+initrc_SCRIPTS = utils/cups-browsed
+man_MANS = \
+ utils/cups-browsed.8 \
+ utils/cups-browsed.conf.5
+if ENABLE_DRIVERLESS
+man_MANS += utils/driverless.1
+endif
+if ENABLE_FOOMATIC
+man_MANS += \
+ filter/foomatic-rip/foomatic-rip.1
+endif
+EXTRA_DIST += utils/cups-browsed.in \
+ $(man_MANS) \
+ utils/org.cups.cupsd.Notifier.xml
+BUILT_SOURCES = $(cups_notifier_sources)
+CLEANFILES = $(BUILT_SOURCES)
+
+# ===
+# PPD
+# ===
+ppddir = $(datadir)/ppd/cupsfilters
+ppd_DATA = \
+ ppd/Fuji_Xerox-DocuPrint_CM305_df-PDF.ppd \
+ ppd/Generic-PDF_Printer-PDF.ppd \
+ ppd/HP-Color_LaserJet_CM3530_MFP-PDF.ppd \
+ ppd/Ricoh-PDF_Printer-PDF.ppd
+if ENABLE_POPPLER
+if ENABLE_IJS
+ppd_DATA += \
+ ppd/HP-PhotoSmart_Pro_B8300-hpijs-pdftoijs.ppd
+endif
+endif
+if ENABLE_GHOSTSCRIPT
+ppd_DATA += \
+ ppd/pxlcolor.ppd \
+ ppd/pxlmono.ppd
+endif
+
+EXTRA_DIST += $(ppd_DATA)
+
+# =========
+# Scripting
+# =========
+if WITH_PHP
+phpextensiondir = $(PHPDIR)
+phpextension_LTLIBRARIES = libphpcups.la
+libphpcups_la_SOURCES = \
+ scripting/php/phpcups.c \
+ scripting/php/phpcups.h
+libphpcups_la_LIBADD = $(CUPS_LIBS)
+libphpcups_la_CFLAGS = $(CUPS_CFLAGS)
+libphpcups_la_LDFLAGS = -no-undefined
+endif # WITH_PHP
+
+EXTRA_DIST += \
+ scripting/perl \
+ scripting/php/README \
+ scripting/php/phpcups.php
+
+distclean-local:
+ rm -rf *.cache *~
+
+install-exec-hook:
+ $(INSTALL) -d -m 755 $(DESTDIR)$(bindir)
+ $(INSTALL) -d -m 755 $(DESTDIR)$(pkgfilterdir)
+ $(INSTALL) -d -m 755 $(DESTDIR)$(pkgbackenddir)
+if ENABLE_FOOMATIC
+ $(LN_S) -r -f $(DESTDIR)$(pkgfilterdir)/foomatic-rip $(DESTDIR)$(bindir)
+endif
+if ENABLE_DRIVERLESS
+ $(LN_S) -r -f $(DESTDIR)$(pkgppdgendir)/driverless $(DESTDIR)$(bindir)
+ $(LN_S) -r -f $(DESTDIR)$(pkgppdgendir)/driverless $(DESTDIR)$(pkgbackenddir)
+endif
+if ENABLE_BRAILLE
+ $(LN_S) -f imagetobrf $(DESTDIR)$(pkgfilterdir)/imagetoubrl
+ $(LN_S) -f vectortopdf $(DESTDIR)$(pkgfilterdir)/svgtopdf
+ $(LN_S) -f vectortopdf $(DESTDIR)$(pkgfilterdir)/xfigtopdf
+ $(LN_S) -f vectortopdf $(DESTDIR)$(pkgfilterdir)/wmftopdf
+ $(LN_S) -f vectortopdf $(DESTDIR)$(pkgfilterdir)/emftopdf
+ $(LN_S) -f vectortopdf $(DESTDIR)$(pkgfilterdir)/cgmtopdf
+ $(LN_S) -f vectortopdf $(DESTDIR)$(pkgfilterdir)/cmxtopdf
+ $(LN_S) -f vectortobrf $(DESTDIR)$(pkgfilterdir)/vectortoubrl
+ $(LN_S) -f textbrftoindexv3 $(DESTDIR)$(pkgfilterdir)/textbrftoindexv4
+endif
+
+install-data-hook:
+if RCLINKS
+ for level in $(RCLEVELS); do \
+ $(INSTALL) -d -m 755 $(DESTDIR)$(INITDIR)/rc$${level}.d; \
+ $(LN_S) -f ../init.d/cups-browsed $(DESTDIR)$(INITDIR)/rc$${level}.d/S$(RCSTART)cups-browsed; \
+ $(LN_S) -f ../init.d/cups-browsed $(DESTDIR)$(INITDIR)/rc$${level}.d/K$(RCSTOP)cups-browsed; \
+ done; \
+ $(INSTALL) -d -m 755 $(DESTDIR)$(INITDIR)/rc0.d; \
+ $(LN_S) -f ../init.d/cups-browsed $(DESTDIR)$(INITDIR)/rc0.d/K$(RCSTOP)cups-browsed;
+endif
+ $(LN_S) -f pdf.utf-8.simple \
+ $(DESTDIR)$(pkgcharsetdir)/pdf.utf-8
+if ENABLE_BRAILLE
+ chmod g-rwx,o-rwx $(DESTDIR)/$(pkgbackenddir)/cups-brf
+endif
+
+
+uninstall-hook:
+if RCLINKS
+ if test "x$(INITDIR)" != x; then \
+ $(RM) $(DESTDIR)$(BUILDROOT)$(INITDIR)/rc?.d/[SK]??cups-browsed || :; \
+ rmdir $(DESTDIR)$(BUILDROOT)$(INITDIR)/rc?.d || :;\
+ fi
+endif
+ $(RM) $(DESTDIR)$(pkgcharsetdir)/pdf.utf-8
+if ENABLE_FOOMATIC
+ $(RM) $(DESTDIR)$(bindir)/foomatic-rip
+endif
+if ENABLE_DRIVERLESS
+ $(RM) $(DESTDIR)$(bindir)/driverless
+ $(RM) $(DESTDIR)$(pkgbackenddir)/driverless
+endif
+if ENABLE_BRAILLE
+ $(RM) $(DESTDIR)$(pkgfilterdir)/imagetoubrl
+ $(RM) $(DESTDIR)$(pkgfilterdir)/svgtopdf
+ $(RM) $(DESTDIR)$(pkgfilterdir)/xfigtopdf
+ $(RM) $(DESTDIR)$(pkgfilterdir)/wmftopdf
+ $(RM) $(DESTDIR)$(pkgfilterdir)/emftopdf
+ $(RM) $(DESTDIR)$(pkgfilterdir)/cgmtopdf
+ $(RM) $(DESTDIR)$(pkgfilterdir)/cmxtopdf
+ $(RM) $(DESTDIR)$(pkgfilterdir)/vectortoubrl
+ $(RM) $(DESTDIR)$(pkgfilterdir)/textbrftoindexv4
+endif
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 000000000..9412e8e56
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,5428 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+pkgbackend_PROGRAMS = parallel$(EXEEXT) serial$(EXEEXT) beh$(EXEEXT) \
+ implicitclass$(EXEEXT) $(am__EXEEXT_1)
+check_PROGRAMS = test1284$(EXEEXT) testcmyk$(EXEEXT) \
+ testdither$(EXEEXT) testimage$(EXEEXT) testrgb$(EXEEXT) \
+ test_analyze$(EXEEXT) test_pdf$(EXEEXT) test_ps$(EXEEXT) \
+ test_pdf1$(EXEEXT) test_pdf2$(EXEEXT)
+@ENABLE_BRAILLE_TRUE@am__append_1 = cups-brf
+@ENABLE_DRIVERLESS_TRUE@pkgppdgen_PROGRAMS = driverless$(EXEEXT)
+@ENABLE_POPPLER_TRUE@am__append_2 = \
+@ENABLE_POPPLER_TRUE@ banners/classified \
+@ENABLE_POPPLER_TRUE@ banners/confidential \
+@ENABLE_POPPLER_TRUE@ banners/secret \
+@ENABLE_POPPLER_TRUE@ banners/standard \
+@ENABLE_POPPLER_TRUE@ banners/form \
+@ENABLE_POPPLER_TRUE@ banners/topsecret \
+@ENABLE_POPPLER_TRUE@ banners/unclassified
+
+TESTS = testdither$(EXEEXT) test_analyze$(EXEEXT) test_pdf$(EXEEXT) \
+ test_ps$(EXEEXT) test_pdf1$(EXEEXT) test_pdf2$(EXEEXT)
+@BUILD_DBUS_TRUE@am__append_3 = $(DBUS_CFLAGS) -DHAVE_DBUS
+@BUILD_DBUS_TRUE@am__append_4 = $(DBUS_LIBS)
+@ENABLE_BRAILLE_TRUE@am__append_5 = \
+@ENABLE_BRAILLE_TRUE@ drv/generic-brf.drv \
+@ENABLE_BRAILLE_TRUE@ drv/generic-ubrl.drv \
+@ENABLE_BRAILLE_TRUE@ drv/indexv3.drv \
+@ENABLE_BRAILLE_TRUE@ drv/indexv4.drv
+
+@ENABLE_BRAILLE_TRUE@am__append_6 = \
+@ENABLE_BRAILLE_TRUE@ filter/braille/drivers/common/media-braille.defs \
+@ENABLE_BRAILLE_TRUE@ filter/braille/drivers/index/index.defs \
+@ENABLE_BRAILLE_TRUE@ filter/braille/filters/braille.defs \
+@ENABLE_BRAILLE_TRUE@ filter/braille/filters/imagemagick.defs \
+@ENABLE_BRAILLE_TRUE@ filter/braille/filters/liblouis.defs \
+@ENABLE_BRAILLE_TRUE@ filter/braille/drivers/common/fr-braille.po
+
+@ENABLE_BRAILLE_TRUE@am__append_7 = filter/braille/filters/liblouis1.defs.gen.in
+@ENABLE_POPPLER_TRUE@am__append_8 = \
+@ENABLE_POPPLER_TRUE@ mime/cupsfilters-poppler.convs
+
+@ENABLE_GHOSTSCRIPT_TRUE@am__append_9 = \
+@ENABLE_GHOSTSCRIPT_TRUE@ mime/cupsfilters-ghostscript.convs
+
+@ENABLE_MUTOOL_TRUE@am__append_10 = \
+@ENABLE_MUTOOL_TRUE@ mime/cupsfilters-mupdf.convs
+
+@ENABLE_BRAILLE_TRUE@am__append_11 = \
+@ENABLE_BRAILLE_TRUE@ mime/braille.convs \
+@ENABLE_BRAILLE_TRUE@ mime/braille.types
+
+bin_PROGRAMS = ttfread$(EXEEXT)
+pkgfilter_PROGRAMS = $(am__EXEEXT_2) pdftopdf$(EXEEXT) \
+ commandtoescpx$(EXEEXT) commandtopclx$(EXEEXT) \
+ sys5ippprinter$(EXEEXT) texttotext$(EXEEXT) pdftops$(EXEEXT) \
+ rastertoescpx$(EXEEXT) rastertopclx$(EXEEXT) \
+ texttopdf$(EXEEXT) rastertopdf$(EXEEXT) rastertops$(EXEEXT) \
+ $(am__EXEEXT_3) $(am__EXEEXT_4) $(am__EXEEXT_5) \
+ $(am__EXEEXT_6) $(am__EXEEXT_7) $(am__EXEEXT_8) \
+ $(am__EXEEXT_9)
+@ENABLE_POPPLER_TRUE@am__append_12 = \
+@ENABLE_POPPLER_TRUE@ pdftoopvp
+
+@ENABLE_GHOSTSCRIPT_TRUE@am__append_13 = \
+@ENABLE_GHOSTSCRIPT_TRUE@ filter/gstopxl \
+@ENABLE_GHOSTSCRIPT_TRUE@ filter/gstopdf
+
+@ENABLE_URFTOPDF_TRUE@am__append_14 = \
+@ENABLE_URFTOPDF_TRUE@ urftopdf
+
+@ENABLE_POPPLER_TRUE@am__append_15 = \
+@ENABLE_POPPLER_TRUE@ bannertopdf \
+@ENABLE_POPPLER_TRUE@ pdftoraster
+
+@ENABLE_IJS_TRUE@@ENABLE_POPPLER_TRUE@am__append_16 = \
+@ENABLE_IJS_TRUE@@ENABLE_POPPLER_TRUE@ pdftoijs
+
+@ENABLE_GHOSTSCRIPT_TRUE@am__append_17 = \
+@ENABLE_GHOSTSCRIPT_TRUE@ gstoraster
+
+@ENABLE_MUTOOL_TRUE@am__append_18 = \
+@ENABLE_MUTOOL_TRUE@ mupdftoraster
+
+@ENABLE_FOOMATIC_TRUE@am__append_19 = \
+@ENABLE_FOOMATIC_TRUE@ foomatic-rip
+
+@ENABLE_IMAGEFILTERS_TRUE@am__append_20 = \
+@ENABLE_IMAGEFILTERS_TRUE@ imagetopdf \
+@ENABLE_IMAGEFILTERS_TRUE@ imagetoraster
+
+sbin_PROGRAMS = cups-browsed$(EXEEXT)
+@ENABLE_DRIVERLESS_TRUE@am__append_21 = utils/driverless.1
+@ENABLE_FOOMATIC_TRUE@am__append_22 = \
+@ENABLE_FOOMATIC_TRUE@ filter/foomatic-rip/foomatic-rip.1
+
+@ENABLE_IJS_TRUE@@ENABLE_POPPLER_TRUE@am__append_23 = \
+@ENABLE_IJS_TRUE@@ENABLE_POPPLER_TRUE@ ppd/HP-PhotoSmart_Pro_B8300-hpijs-pdftoijs.ppd
+
+@ENABLE_GHOSTSCRIPT_TRUE@am__append_24 = \
+@ENABLE_GHOSTSCRIPT_TRUE@ ppd/pxlcolor.ppd \
+@ENABLE_GHOSTSCRIPT_TRUE@ ppd/pxlmono.ppd
+
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/ac_define_dir.m4 \
+ $(top_srcdir)/m4/ax_compare_version.m4 \
+ $(top_srcdir)/m4/basic-directories.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
+ $(am__configure_deps) $(am__DIST_COMMON)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = libcupsfilters.pc libfontembed.pc \
+ utils/cups-browsed utils/cups-browsed.conf \
+ filter/foomatic-rip/foomatic-rip.1 \
+ filter/braille/drivers/index/indexv4.sh \
+ filter/braille/drivers/index/indexv3.sh \
+ filter/braille/drivers/index/index.sh \
+ filter/braille/drivers/index/textbrftoindexv3 \
+ filter/braille/drivers/index/imageubrltoindexv3 \
+ filter/braille/drivers/index/imageubrltoindexv4 \
+ filter/braille/drivers/generic/brftoembosser \
+ filter/braille/filters/cups-braille.sh \
+ filter/braille/filters/imagetobrf \
+ filter/braille/filters/texttobrf \
+ filter/braille/filters/vectortopdf \
+ filter/braille/filters/vectortobrf \
+ filter/braille/filters/musicxmltobrf \
+ filter/braille/filters/liblouis1.defs.gen \
+ mime/cupsfilters.convs
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(phpextensiondir)" \
+ "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgbackenddir)" \
+ "$(DESTDIR)$(pkgfilterdir)" "$(DESTDIR)$(pkgppdgendir)" \
+ "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(initrcdir)" \
+ "$(DESTDIR)$(pkgbrailledir)" "$(DESTDIR)$(pkgfilterdir)" \
+ "$(DESTDIR)$(pkgfilterdir)" "$(DESTDIR)$(man1dir)" \
+ "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" \
+ "$(DESTDIR)$(docdir)" "$(DESTDIR)$(pkgppdcdir)" \
+ "$(DESTDIR)$(pkgbannerdir)" "$(DESTDIR)$(pkgcharsetdir)" \
+ "$(DESTDIR)$(pkgconfdir)" "$(DESTDIR)$(pkgcupsdatadir)" \
+ "$(DESTDIR)$(pkgcupsserverrootdir)" \
+ "$(DESTDIR)$(pkgdriverdir)" \
+ "$(DESTDIR)$(pkgfiltersincludedir)" \
+ "$(DESTDIR)$(pkgfontconfigdir)" \
+ "$(DESTDIR)$(pkgfontembedincludedir)" \
+ "$(DESTDIR)$(pkgmimedir)" "$(DESTDIR)$(pkgppdcdir)" \
+ "$(DESTDIR)$(ppddir)"
+LTLIBRARIES = $(lib_LTLIBRARIES) $(phpextension_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+@BUILD_DBUS_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
+libcupsfilters_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_2)
+am__objects_1 =
+am_libcupsfilters_la_OBJECTS = libcupsfilters_la-attr.lo \
+ libcupsfilters_la-check.lo libcupsfilters_la-cmyk.lo \
+ libcupsfilters_la-colord.lo libcupsfilters_la-colormanager.lo \
+ libcupsfilters_la-dither.lo libcupsfilters_la-image.lo \
+ libcupsfilters_la-image-bmp.lo \
+ libcupsfilters_la-image-colorspace.lo \
+ libcupsfilters_la-image-gif.lo libcupsfilters_la-image-jpeg.lo \
+ libcupsfilters_la-image-photocd.lo \
+ libcupsfilters_la-image-pix.lo libcupsfilters_la-image-png.lo \
+ libcupsfilters_la-image-pnm.lo libcupsfilters_la-image-sgi.lo \
+ libcupsfilters_la-image-sgilib.lo \
+ libcupsfilters_la-image-sun.lo libcupsfilters_la-image-tiff.lo \
+ libcupsfilters_la-image-zoom.lo libcupsfilters_la-lut.lo \
+ libcupsfilters_la-pack.lo libcupsfilters_la-ppdgenerator.lo \
+ libcupsfilters_la-raster.lo libcupsfilters_la-rgb.lo \
+ libcupsfilters_la-srgb.lo $(am__objects_1)
+libcupsfilters_la_OBJECTS = $(am_libcupsfilters_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+libcupsfilters_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(libcupsfilters_la_CFLAGS) $(CFLAGS) \
+ $(libcupsfilters_la_LDFLAGS) $(LDFLAGS) -o $@
+libfontembed_la_LIBADD =
+am_libfontembed_la_OBJECTS = aglfn13.lo dynstring.lo embed.lo \
+ embed_sfnt.lo embed_pdf.lo fontfile.lo frequent.lo sfnt.lo \
+ sfnt_subset.lo
+libfontembed_la_OBJECTS = $(am_libfontembed_la_OBJECTS)
+libfontembed_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libfontembed_la_LDFLAGS) $(LDFLAGS) \
+ -o $@
+@WITH_PHP_TRUE@libphpcups_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am__libphpcups_la_SOURCES_DIST = scripting/php/phpcups.c \
+ scripting/php/phpcups.h
+@WITH_PHP_TRUE@am_libphpcups_la_OBJECTS = libphpcups_la-phpcups.lo
+libphpcups_la_OBJECTS = $(am_libphpcups_la_OBJECTS)
+libphpcups_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libphpcups_la_CFLAGS) \
+ $(CFLAGS) $(libphpcups_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_PHP_TRUE@am_libphpcups_la_rpath = -rpath $(phpextensiondir)
+@ENABLE_BRAILLE_TRUE@am__EXEEXT_1 = cups-brf$(EXEEXT)
+@ENABLE_POPPLER_TRUE@am__EXEEXT_2 = pdftoopvp$(EXEEXT)
+@ENABLE_URFTOPDF_TRUE@am__EXEEXT_3 = urftopdf$(EXEEXT)
+@ENABLE_POPPLER_TRUE@am__EXEEXT_4 = bannertopdf$(EXEEXT) \
+@ENABLE_POPPLER_TRUE@ pdftoraster$(EXEEXT)
+@ENABLE_IJS_TRUE@@ENABLE_POPPLER_TRUE@am__EXEEXT_5 = \
+@ENABLE_IJS_TRUE@@ENABLE_POPPLER_TRUE@ pdftoijs$(EXEEXT)
+@ENABLE_GHOSTSCRIPT_TRUE@am__EXEEXT_6 = gstoraster$(EXEEXT)
+@ENABLE_MUTOOL_TRUE@am__EXEEXT_7 = mupdftoraster$(EXEEXT)
+@ENABLE_FOOMATIC_TRUE@am__EXEEXT_8 = foomatic-rip$(EXEEXT)
+@ENABLE_IMAGEFILTERS_TRUE@am__EXEEXT_9 = imagetopdf$(EXEEXT) \
+@ENABLE_IMAGEFILTERS_TRUE@ imagetoraster$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS) $(pkgbackend_PROGRAMS) \
+ $(pkgfilter_PROGRAMS) $(pkgppdgen_PROGRAMS) $(sbin_PROGRAMS)
+am_bannertopdf_OBJECTS = bannertopdf-banner.$(OBJEXT) \
+ bannertopdf-bannertopdf.$(OBJEXT) bannertopdf-pdf.$(OBJEXT)
+bannertopdf_OBJECTS = $(am_bannertopdf_OBJECTS)
+bannertopdf_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(bannertopdf_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_beh_OBJECTS = beh-beh.$(OBJEXT)
+beh_OBJECTS = $(am_beh_OBJECTS)
+beh_DEPENDENCIES = $(am__DEPENDENCIES_1)
+beh_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(beh_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_commandtoescpx_OBJECTS = commandtoescpx-commandtoescpx.$(OBJEXT)
+commandtoescpx_OBJECTS = $(am_commandtoescpx_OBJECTS)
+commandtoescpx_DEPENDENCIES = $(am__DEPENDENCIES_1)
+commandtoescpx_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(commandtoescpx_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \
+ $@
+am_commandtopclx_OBJECTS = commandtopclx-commandtopclx.$(OBJEXT)
+commandtopclx_OBJECTS = $(am_commandtopclx_OBJECTS)
+commandtopclx_DEPENDENCIES = $(am__DEPENDENCIES_1)
+commandtopclx_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(commandtopclx_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am__cups_brf_SOURCES_DIST = backend/cups-brf.c
+@ENABLE_BRAILLE_TRUE@am_cups_brf_OBJECTS = cups-brf.$(OBJEXT)
+cups_brf_OBJECTS = $(am_cups_brf_OBJECTS)
+cups_brf_LDADD = $(LDADD)
+am_cups_browsed_OBJECTS = cups_browsed-cups-browsed.$(OBJEXT)
+am__objects_2 = cups_browsed-cups-notifier.$(OBJEXT)
+nodist_cups_browsed_OBJECTS = $(am__objects_2)
+cups_browsed_OBJECTS = $(am_cups_browsed_OBJECTS) \
+ $(nodist_cups_browsed_OBJECTS)
+cups_browsed_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) libcupsfilters.la
+cups_browsed_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(cups_browsed_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am__driverless_SOURCES_DIST = utils/driverless.c
+@ENABLE_DRIVERLESS_TRUE@am_driverless_OBJECTS = \
+@ENABLE_DRIVERLESS_TRUE@ driverless-driverless.$(OBJEXT)
+driverless_OBJECTS = $(am_driverless_OBJECTS)
+@ENABLE_DRIVERLESS_TRUE@driverless_DEPENDENCIES = \
+@ENABLE_DRIVERLESS_TRUE@ $(am__DEPENDENCIES_1) \
+@ENABLE_DRIVERLESS_TRUE@ libcupsfilters.la
+driverless_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(driverless_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_foomatic_rip_OBJECTS = foomatic_rip-foomaticrip.$(OBJEXT) \
+ foomatic_rip-options.$(OBJEXT) foomatic_rip-pdf.$(OBJEXT) \
+ foomatic_rip-postscript.$(OBJEXT) \
+ foomatic_rip-process.$(OBJEXT) foomatic_rip-renderer.$(OBJEXT) \
+ foomatic_rip-spooler.$(OBJEXT) foomatic_rip-util.$(OBJEXT)
+foomatic_rip_OBJECTS = $(am_foomatic_rip_OBJECTS)
+foomatic_rip_DEPENDENCIES = $(am__DEPENDENCIES_1) libcupsfilters.la
+foomatic_rip_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(foomatic_rip_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_gstoraster_OBJECTS = gstoraster-gstoraster.$(OBJEXT)
+gstoraster_OBJECTS = $(am_gstoraster_OBJECTS)
+gstoraster_DEPENDENCIES = $(am__DEPENDENCIES_1) libcupsfilters.la
+gstoraster_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(gstoraster_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_imagetopdf_OBJECTS = imagetopdf-common.$(OBJEXT) \
+ imagetopdf-imagetopdf.$(OBJEXT)
+imagetopdf_OBJECTS = $(am_imagetopdf_OBJECTS)
+imagetopdf_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) libcupsfilters.la
+imagetopdf_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(imagetopdf_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_imagetoraster_OBJECTS = imagetoraster-common.$(OBJEXT) \
+ imagetoraster-imagetoraster.$(OBJEXT)
+imagetoraster_OBJECTS = $(am_imagetoraster_OBJECTS)
+imagetoraster_DEPENDENCIES = $(am__DEPENDENCIES_1) libcupsfilters.la
+imagetoraster_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(imagetoraster_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_implicitclass_OBJECTS = implicitclass-implicitclass.$(OBJEXT)
+implicitclass_OBJECTS = $(am_implicitclass_OBJECTS)
+implicitclass_DEPENDENCIES = $(am__DEPENDENCIES_1)
+implicitclass_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(implicitclass_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_mupdftoraster_OBJECTS = mupdftoraster-mupdftoraster.$(OBJEXT)
+mupdftoraster_OBJECTS = $(am_mupdftoraster_OBJECTS)
+mupdftoraster_DEPENDENCIES = $(am__DEPENDENCIES_1) libcupsfilters.la
+mupdftoraster_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(mupdftoraster_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_parallel_OBJECTS = parallel-ieee1284.$(OBJEXT) \
+ parallel-parallel.$(OBJEXT)
+parallel_OBJECTS = $(am_parallel_OBJECTS)
+parallel_DEPENDENCIES = $(am__DEPENDENCIES_1)
+parallel_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(parallel_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_pdftoijs_OBJECTS = pdftoijs-pdftoijs.$(OBJEXT)
+pdftoijs_OBJECTS = $(am_pdftoijs_OBJECTS)
+pdftoijs_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+pdftoijs_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(pdftoijs_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_pdftoopvp_OBJECTS = pdftoopvp-OPRS.$(OBJEXT) \
+ pdftoopvp-OPVPSplashClip.$(OBJEXT) \
+ pdftoopvp-OPVPSplash.$(OBJEXT) \
+ pdftoopvp-OPVPSplashPath.$(OBJEXT) \
+ pdftoopvp-OPVPSplashState.$(OBJEXT) \
+ pdftoopvp-OPVPSplashXPath.$(OBJEXT) \
+ pdftoopvp-OPVPWrapper.$(OBJEXT) \
+ pdftoopvp-OPVPWrapper_0_2.$(OBJEXT) \
+ pdftoopvp-OPVPOutputDev.$(OBJEXT) \
+ pdftoopvp-pdftoopvp.$(OBJEXT)
+pdftoopvp_OBJECTS = $(am_pdftoopvp_OBJECTS)
+pdftoopvp_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+pdftoopvp_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(pdftoopvp_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_pdftopdf_OBJECTS = pdftopdf-pdftopdf.$(OBJEXT) \
+ pdftopdf-pdftopdf_jcl.$(OBJEXT) \
+ pdftopdf-pdftopdf_processor.$(OBJEXT) \
+ pdftopdf-qpdf_pdftopdf_processor.$(OBJEXT) \
+ pdftopdf-pptypes.$(OBJEXT) pdftopdf-nup.$(OBJEXT) \
+ pdftopdf-intervalset.$(OBJEXT) pdftopdf-qpdf_tools.$(OBJEXT) \
+ pdftopdf-qpdf_xobject.$(OBJEXT) \
+ pdftopdf-qpdf_pdftopdf.$(OBJEXT) pdftopdf-qpdf_cm.$(OBJEXT)
+pdftopdf_OBJECTS = $(am_pdftopdf_OBJECTS)
+pdftopdf_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+pdftopdf_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(pdftopdf_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_pdftops_OBJECTS = pdftops-common.$(OBJEXT) \
+ pdftops-pdftops.$(OBJEXT)
+pdftops_OBJECTS = $(am_pdftops_OBJECTS)
+pdftops_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(pdftops_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_pdftoraster_OBJECTS = pdftoraster-pdftoraster.$(OBJEXT)
+pdftoraster_OBJECTS = $(am_pdftoraster_OBJECTS)
+pdftoraster_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) libcupsfilters.la
+pdftoraster_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(pdftoraster_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_rastertoescpx_OBJECTS = rastertoescpx-rastertoescpx.$(OBJEXT)
+rastertoescpx_OBJECTS = $(am_rastertoescpx_OBJECTS)
+rastertoescpx_DEPENDENCIES = $(am__DEPENDENCIES_1) libcupsfilters.la
+rastertoescpx_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(rastertoescpx_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_rastertopclx_OBJECTS = rastertopclx-pcl-common.$(OBJEXT) \
+ rastertopclx-rastertopclx.$(OBJEXT)
+rastertopclx_OBJECTS = $(am_rastertopclx_OBJECTS)
+rastertopclx_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) libcupsfilters.la
+rastertopclx_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(rastertopclx_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_rastertopdf_OBJECTS = rastertopdf-rastertopdf.$(OBJEXT)
+rastertopdf_OBJECTS = $(am_rastertopdf_OBJECTS)
+rastertopdf_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) libcupsfilters.la
+rastertopdf_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(rastertopdf_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_rastertops_OBJECTS = rastertops-rastertops.$(OBJEXT)
+rastertops_OBJECTS = $(am_rastertops_OBJECTS)
+rastertops_DEPENDENCIES = $(am__DEPENDENCIES_1) libcupsfilters.la
+rastertops_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(rastertops_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_serial_OBJECTS = serial-serial.$(OBJEXT)
+serial_OBJECTS = $(am_serial_OBJECTS)
+serial_DEPENDENCIES = $(am__DEPENDENCIES_1)
+serial_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(serial_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_sys5ippprinter_OBJECTS = sys5ippprinter-common.$(OBJEXT) \
+ sys5ippprinter-sys5ippprinter.$(OBJEXT)
+sys5ippprinter_OBJECTS = $(am_sys5ippprinter_OBJECTS)
+sys5ippprinter_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(sys5ippprinter_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \
+ $@
+am_test1284_OBJECTS = test1284-ieee1284.$(OBJEXT) \
+ test1284-test1284.$(OBJEXT)
+test1284_OBJECTS = $(am_test1284_OBJECTS)
+test1284_DEPENDENCIES = $(am__DEPENDENCIES_1)
+test1284_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test1284_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_test_analyze_OBJECTS = test_analyze.$(OBJEXT)
+test_analyze_OBJECTS = $(am_test_analyze_OBJECTS)
+test_analyze_DEPENDENCIES = libfontembed.la
+am_test_pdf_OBJECTS = test_pdf.$(OBJEXT)
+test_pdf_OBJECTS = $(am_test_pdf_OBJECTS)
+test_pdf_DEPENDENCIES = libfontembed.la
+am_test_pdf1_OBJECTS = test_pdf1-pdfutils.$(OBJEXT) \
+ test_pdf1-test_pdf1.$(OBJEXT)
+test_pdf1_OBJECTS = $(am_test_pdf1_OBJECTS)
+test_pdf1_DEPENDENCIES = libfontembed.la
+test_pdf1_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_pdf1_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_test_pdf2_OBJECTS = test_pdf2-pdfutils.$(OBJEXT) \
+ test_pdf2-test_pdf2.$(OBJEXT)
+test_pdf2_OBJECTS = $(am_test_pdf2_OBJECTS)
+test_pdf2_DEPENDENCIES = libfontembed.la
+test_pdf2_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_pdf2_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_test_ps_OBJECTS = test_ps.$(OBJEXT)
+test_ps_OBJECTS = $(am_test_ps_OBJECTS)
+test_ps_DEPENDENCIES = libfontembed.la
+am_testcmyk_OBJECTS = testcmyk.$(OBJEXT) $(am__objects_1)
+testcmyk_OBJECTS = $(am_testcmyk_OBJECTS)
+testcmyk_DEPENDENCIES = libcupsfilters.la
+am_testdither_OBJECTS = testdither.$(OBJEXT) $(am__objects_1)
+testdither_OBJECTS = $(am_testdither_OBJECTS)
+testdither_DEPENDENCIES = libcupsfilters.la
+am_testimage_OBJECTS = testimage-testimage.$(OBJEXT) $(am__objects_1)
+testimage_OBJECTS = $(am_testimage_OBJECTS)
+testimage_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ libcupsfilters.la
+testimage_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(testimage_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_testrgb_OBJECTS = testrgb.$(OBJEXT) $(am__objects_1)
+testrgb_OBJECTS = $(am_testrgb_OBJECTS)
+testrgb_DEPENDENCIES = libcupsfilters.la
+am_texttopdf_OBJECTS = texttopdf-common.$(OBJEXT) \
+ texttopdf-pdfutils.$(OBJEXT) texttopdf-textcommon.$(OBJEXT) \
+ texttopdf-texttopdf.$(OBJEXT)
+texttopdf_OBJECTS = $(am_texttopdf_OBJECTS)
+texttopdf_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ libfontembed.la
+texttopdf_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(texttopdf_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_texttotext_OBJECTS = texttotext-texttotext.$(OBJEXT)
+texttotext_OBJECTS = $(am_texttotext_OBJECTS)
+texttotext_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(texttotext_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_ttfread_OBJECTS = main.$(OBJEXT)
+ttfread_OBJECTS = $(am_ttfread_OBJECTS)
+ttfread_DEPENDENCIES = libfontembed.la
+am__urftopdf_SOURCES_DIST = filter/urftopdf.cpp filter/unirast.h
+@ENABLE_URFTOPDF_TRUE@am_urftopdf_OBJECTS = \
+@ENABLE_URFTOPDF_TRUE@ urftopdf-urftopdf.$(OBJEXT)
+urftopdf_OBJECTS = $(am_urftopdf_OBJECTS)
+@ENABLE_URFTOPDF_TRUE@urftopdf_DEPENDENCIES = $(am__DEPENDENCIES_1)
+urftopdf_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(urftopdf_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SCRIPTS = $(initrc_SCRIPTS) $(nodist_pkgbraille_SCRIPTS) \
+ $(nodist_pkgfilter_SCRIPTS) $(pkgfilter_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo " CXX " $@;
+am__v_CXX_1 =
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo " CXXLD " $@;
+am__v_CXXLD_1 =
+SOURCES = $(libcupsfilters_la_SOURCES) $(libfontembed_la_SOURCES) \
+ $(libphpcups_la_SOURCES) $(bannertopdf_SOURCES) \
+ $(EXTRA_bannertopdf_SOURCES) $(beh_SOURCES) \
+ $(commandtoescpx_SOURCES) $(commandtopclx_SOURCES) \
+ $(cups_brf_SOURCES) $(cups_browsed_SOURCES) \
+ $(nodist_cups_browsed_SOURCES) $(driverless_SOURCES) \
+ $(foomatic_rip_SOURCES) $(gstoraster_SOURCES) \
+ $(imagetopdf_SOURCES) $(imagetoraster_SOURCES) \
+ $(implicitclass_SOURCES) $(mupdftoraster_SOURCES) \
+ $(parallel_SOURCES) $(pdftoijs_SOURCES) $(pdftoopvp_SOURCES) \
+ $(pdftopdf_SOURCES) $(pdftops_SOURCES) \
+ $(EXTRA_pdftops_SOURCES) $(pdftoraster_SOURCES) \
+ $(rastertoescpx_SOURCES) $(rastertopclx_SOURCES) \
+ $(rastertopdf_SOURCES) $(rastertops_SOURCES) $(serial_SOURCES) \
+ $(sys5ippprinter_SOURCES) $(EXTRA_sys5ippprinter_SOURCES) \
+ $(test1284_SOURCES) $(test_analyze_SOURCES) \
+ $(test_pdf_SOURCES) $(test_pdf1_SOURCES) $(test_pdf2_SOURCES) \
+ $(test_ps_SOURCES) $(testcmyk_SOURCES) $(testdither_SOURCES) \
+ $(testimage_SOURCES) $(testrgb_SOURCES) $(texttopdf_SOURCES) \
+ $(texttotext_SOURCES) $(EXTRA_texttotext_SOURCES) \
+ $(ttfread_SOURCES) $(urftopdf_SOURCES)
+DIST_SOURCES = $(libcupsfilters_la_SOURCES) $(libfontembed_la_SOURCES) \
+ $(am__libphpcups_la_SOURCES_DIST) $(bannertopdf_SOURCES) \
+ $(EXTRA_bannertopdf_SOURCES) $(beh_SOURCES) \
+ $(commandtoescpx_SOURCES) $(commandtopclx_SOURCES) \
+ $(am__cups_brf_SOURCES_DIST) $(cups_browsed_SOURCES) \
+ $(am__driverless_SOURCES_DIST) $(foomatic_rip_SOURCES) \
+ $(gstoraster_SOURCES) $(imagetopdf_SOURCES) \
+ $(imagetoraster_SOURCES) $(implicitclass_SOURCES) \
+ $(mupdftoraster_SOURCES) $(parallel_SOURCES) \
+ $(pdftoijs_SOURCES) $(pdftoopvp_SOURCES) $(pdftopdf_SOURCES) \
+ $(pdftops_SOURCES) $(EXTRA_pdftops_SOURCES) \
+ $(pdftoraster_SOURCES) $(rastertoescpx_SOURCES) \
+ $(rastertopclx_SOURCES) $(rastertopdf_SOURCES) \
+ $(rastertops_SOURCES) $(serial_SOURCES) \
+ $(sys5ippprinter_SOURCES) $(EXTRA_sys5ippprinter_SOURCES) \
+ $(test1284_SOURCES) $(test_analyze_SOURCES) \
+ $(test_pdf_SOURCES) $(test_pdf1_SOURCES) $(test_pdf2_SOURCES) \
+ $(test_ps_SOURCES) $(testcmyk_SOURCES) $(testdither_SOURCES) \
+ $(testimage_SOURCES) $(testrgb_SOURCES) $(texttopdf_SOURCES) \
+ $(texttotext_SOURCES) $(EXTRA_texttotext_SOURCES) \
+ $(ttfread_SOURCES) $(am__urftopdf_SOURCES_DIST)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man1dir = $(mandir)/man1
+man5dir = $(mandir)/man5
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(man_MANS)
+DATA = $(doc_DATA) $(nodist_pkgppdc_DATA) $(pkgbanner_DATA) \
+ $(pkgcharset_DATA) $(pkgconf_DATA) $(pkgcupsdata_DATA) \
+ $(pkgcupsserverroot_DATA) $(pkgdriver_DATA) \
+ $(pkgfiltersinclude_DATA) $(pkgfontconfig_DATA) \
+ $(pkgfontembedinclude_DATA) $(pkgmime_DATA) $(pkgppdc_DATA) \
+ $(ppd_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+ $(LISP)config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+AM_RECURSIVE_TARGETS = cscope check recheck
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
+ $(srcdir)/libcupsfilters.pc.in $(srcdir)/libfontembed.pc.in \
+ $(top_srcdir)/filter/braille/drivers/generic/brftoembosser.in \
+ $(top_srcdir)/filter/braille/drivers/index/imageubrltoindexv3.in \
+ $(top_srcdir)/filter/braille/drivers/index/imageubrltoindexv4.in \
+ $(top_srcdir)/filter/braille/drivers/index/index.sh.in \
+ $(top_srcdir)/filter/braille/drivers/index/indexv3.sh.in \
+ $(top_srcdir)/filter/braille/drivers/index/indexv4.sh.in \
+ $(top_srcdir)/filter/braille/drivers/index/textbrftoindexv3.in \
+ $(top_srcdir)/filter/braille/filters/cups-braille.sh.in \
+ $(top_srcdir)/filter/braille/filters/imagetobrf.in \
+ $(top_srcdir)/filter/braille/filters/liblouis1.defs.gen.in \
+ $(top_srcdir)/filter/braille/filters/musicxmltobrf.in \
+ $(top_srcdir)/filter/braille/filters/texttobrf.in \
+ $(top_srcdir)/filter/braille/filters/vectortobrf.in \
+ $(top_srcdir)/filter/braille/filters/vectortopdf.in \
+ $(top_srcdir)/filter/foomatic-rip/foomatic-rip.1.in \
+ $(top_srcdir)/mime/cupsfilters.convs.in \
+ $(top_srcdir)/utils/cups-browsed.conf.in \
+ $(top_srcdir)/utils/cups-browsed.in AUTHORS COPYING ChangeLog \
+ INSTALL NEWS README compile config.guess config.sub depcomp \
+ install-sh ltmain.sh missing test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ if test -d "$(distdir)"; then \
+ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -rf "$(distdir)" \
+ || { sleep 5 && rm -rf "$(distdir)"; }; \
+ else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
+DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).tar.xz
+GZIP_ENV = --best
+DIST_TARGETS = dist-xz dist-bzip2 dist-gzip
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+APPLE_RASTER_FILTER = @APPLE_RASTER_FILTER@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AVAHI_CFLAGS = @AVAHI_CFLAGS@
+AVAHI_GLIB_CFLAGS = @AVAHI_GLIB_CFLAGS@
+AVAHI_GLIB_LIBS = @AVAHI_GLIB_LIBS@
+AVAHI_LIBS = @AVAHI_LIBS@
+AWK = @AWK@
+BANNERTOPDF_DATADIR = @BANNERTOPDF_DATADIR@
+BROWSEREMOTEPROTOCOLS = @BROWSEREMOTEPROTOCOLS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CUPSCONFIG = @CUPSCONFIG@
+CUPS_CFLAGS = @CUPS_CFLAGS@
+CUPS_DATADIR = @CUPS_DATADIR@
+CUPS_DEFAULT_DOMAINSOCKET = @CUPS_DEFAULT_DOMAINSOCKET@
+CUPS_FONTPATH = @CUPS_FONTPATH@
+CUPS_GHOSTSCRIPT = @CUPS_GHOSTSCRIPT@
+CUPS_LIBS = @CUPS_LIBS@
+CUPS_MUTOOL = @CUPS_MUTOOL@
+CUPS_PDFTOPS = @CUPS_PDFTOPS@
+CUPS_SERVERBIN = @CUPS_SERVERBIN@
+CUPS_SERVERROOT = @CUPS_SERVERROOT@
+CUPS_STATEDIR = @CUPS_STATEDIR@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DLOPEN_LIBS = @DLOPEN_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FONTCONFIG_CFLAGS = @FONTCONFIG_CFLAGS@
+FONTCONFIG_LIBS = @FONTCONFIG_LIBS@
+FONTDIR = @FONTDIR@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+GETLINE = @GETLINE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GIO_UNIX_CFLAGS = @GIO_UNIX_CFLAGS@
+GIO_UNIX_LIBS = @GIO_UNIX_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_LIBS = @GLIB_LIBS@
+GREP = @GREP@
+HAVE_CXX11 = @HAVE_CXX11@
+IJS_CFLAGS = @IJS_CFLAGS@
+IJS_LIBS = @IJS_LIBS@
+INITDDIR = @INITDDIR@
+INITDIR = @INITDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LARGEFILE = @LARGEFILE@
+LCMS_CFLAGS = @LCMS_CFLAGS@
+LCMS_LIBS = @LCMS_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBJPEG_LIBS = @LIBJPEG_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBPNG_CFLAGS = @LIBPNG_CFLAGS@
+LIBPNG_LIBS = @LIBPNG_LIBS@
+LIBQPDF_CFLAGS = @LIBQPDF_CFLAGS@
+LIBQPDF_LIBS = @LIBQPDF_LIBS@
+LIBS = @LIBS@
+LIBTIFF_LIBS = @LIBTIFF_LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PHPCONFIG = @PHPCONFIG@
+PHPDIR = @PHPDIR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POPPLER_CFLAGS = @POPPLER_CFLAGS@
+POPPLER_LIBS = @POPPLER_LIBS@
+QPDF_NO_PCLM = @QPDF_NO_PCLM@
+RANLIB = @RANLIB@
+RCLEVELS = @RCLEVELS@
+RCSTART = @RCSTART@
+RCSTOP = @RCSTOP@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRCASESTR = @STRCASESTR@
+STRIP = @STRIP@
+TABLESDIR = @TABLESDIR@
+VERSION = @VERSION@
+ZLIB_CFLAGS = @ZLIB_CFLAGS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I m4
+pkgconfdir = $(libdir)/pkgconfig
+pkgconf_DATA = \
+ libcupsfilters.pc \
+ libfontembed.pc
+
+doc_DATA = \
+ AUTHORS \
+ COPYING \
+ NEWS \
+ INSTALL \
+ README
+
+
+# Not reliable bash script
+#TESTS += filter/test.sh
+EXTRA_DIST = $(doc_DATA) autogen.sh libcupsfilters.pc.in \
+ libfontembed.pc.in utils/cups-browsed.service \
+ utils/cups-browsed-upstart.conf \
+ filter/braille/drivers/index/ubrlto4dot.c \
+ filter/braille/filters/TODO.txt $(pkgbanner_DATA) \
+ $(pkgcharset_DATA) $(pkgfiltersinclude_DATA) \
+ cupsfilters/image.pgm cupsfilters/image.ppm \
+ $(pkgcupsdata_DATA) $(pkgdriver_DATA) $(am__append_7) \
+ $(pkgppdc_DATA) $(pkgmime_DATA) $(pkgfontembedinclude_DATA) \
+ fontembed/README $(pkgfontconfig_DATA) $(pkgfilter_SCRIPTS) \
+ filter/test.sh utils/cups-browsed.in $(man_MANS) \
+ utils/org.cups.cupsd.Notifier.xml $(ppd_DATA) scripting/perl \
+ scripting/php/README scripting/php/phpcups.php
+
+# ========
+# Backends
+# ========
+pkgbackenddir = $(CUPS_SERVERBIN)/backend
+# We need ieee1284 up and running.
+# Leave it to the user to run if they have the bus.
+#TESTS = test1284
+parallel_SOURCES = \
+ backend/backend-private.h \
+ backend/ieee1284.c \
+ backend/parallel.c
+
+parallel_LDADD = $(CUPS_LIBS)
+parallel_CFLAGS = $(CUPS_CFLAGS)
+serial_SOURCES = \
+ backend/backend-private.h \
+ backend/serial.c
+
+serial_LDADD = $(CUPS_LIBS)
+serial_CFLAGS = $(CUPS_CFLAGS)
+beh_SOURCES = \
+ backend/backend-private.h \
+ backend/beh.c
+
+beh_LDADD = $(CUPS_LIBS)
+beh_CFLAGS = $(CUPS_CFLAGS)
+implicitclass_SOURCES = \
+ backend/backend-private.h \
+ backend/implicitclass.c
+
+implicitclass_LDADD = $(CUPS_LIBS)
+implicitclass_CFLAGS = $(CUPS_CFLAGS)
+test1284_SOURCES = \
+ backend/backend-private.h \
+ backend/ieee1284.c \
+ backend/test1284.c
+
+test1284_LDADD = $(CUPS_LIBS)
+test1284_CFLAGS = $(CUPS_CFLAGS)
+@ENABLE_BRAILLE_TRUE@cups_brf_SOURCES = \
+@ENABLE_BRAILLE_TRUE@ backend/cups-brf.c
+
+
+# ==============
+# PPD Generators
+# ==============
+@ENABLE_DRIVERLESS_TRUE@pkgppdgendir = $(CUPS_SERVERBIN)/driver
+@ENABLE_DRIVERLESS_TRUE@driverless_SOURCES = \
+@ENABLE_DRIVERLESS_TRUE@ utils/driverless.c
+
+@ENABLE_DRIVERLESS_TRUE@driverless_CFLAGS = \
+@ENABLE_DRIVERLESS_TRUE@ $(CUPS_CFLAGS) \
+@ENABLE_DRIVERLESS_TRUE@ -I$(srcdir)/cupsfilters/
+
+@ENABLE_DRIVERLESS_TRUE@driverless_CXXFLAGS = $(driverless_CFLAGS)
+@ENABLE_DRIVERLESS_TRUE@driverless_LDADD = \
+@ENABLE_DRIVERLESS_TRUE@ $(CUPS_LIBS) \
+@ENABLE_DRIVERLESS_TRUE@ libcupsfilters.la
+
+
+# =======
+# Banners
+# =======
+pkgbannerdir = $(CUPS_DATADIR)/banners
+pkgbanner_DATA = $(am__append_2)
+
+# ========
+# Charsets
+# ========
+pkgcharsetdir = $(CUPS_DATADIR)/charsets
+pkgcharset_DATA = \
+ charset/pdf.utf-8.heavy \
+ charset/pdf.utf-8.simple
+
+
+# ====================
+# CUPS Filters library
+# ====================
+pkgfiltersincludedir = $(includedir)/cupsfilters
+pkgfiltersinclude_DATA = \
+ cupsfilters/colord.h \
+ cupsfilters/colormanager.h \
+ cupsfilters/driver.h \
+ cupsfilters/image.h \
+ cupsfilters/raster.h \
+ cupsfilters/ppdgenerator.h
+
+lib_LTLIBRARIES = libcupsfilters.la libfontembed.la
+# testcmyk # fails as it opens some image.ppm which is nowerhe to be found.
+# testimage # requires also some ppm file as argument
+# testrgb # same error
+# FIXME: run old testdither
+# ./testdither > test/0-255.pgm 2>test/0-255.log
+# ./testdither 0 127 255 > test/0-127-255.pgm 2>test/0-127-255.log
+# ./testdither 0 85 170 255 > test/0-85-170-255.pgm 2>test/0-85-170-255.log
+# ./testdither 0 63 127 170 198 227 255 > test/0-63-127-170-198-227-255.pgm 2>test/0-63-127-170-198-227-255.log
+# ./testdither 0 210 383 > test/0-210-383.pgm 2>test/0-210-383.log
+# ./testdither 0 82 255 > test/0-82-255.pgm 2>test/0-82-255.log
+# ./testdither 0 510 > test/0-510.pgm 2>test/0-510.log
+# ./testdither 0 1020 > test/0-1020.pgm 2>test/0-1020.log
+libcupsfilters_la_SOURCES = \
+ cupsfilters/attr.c \
+ cupsfilters/check.c \
+ cupsfilters/cmyk.c \
+ cupsfilters/colord.c \
+ cupsfilters/colormanager.c \
+ cupsfilters/dither.c \
+ cupsfilters/image.c \
+ cupsfilters/image-bmp.c \
+ cupsfilters/image-colorspace.c \
+ cupsfilters/image-gif.c \
+ cupsfilters/image-jpeg.c \
+ cupsfilters/image-photocd.c \
+ cupsfilters/image-pix.c \
+ cupsfilters/image-png.c \
+ cupsfilters/image-pnm.c \
+ cupsfilters/image-private.h \
+ cupsfilters/image-sgi.c \
+ cupsfilters/image-sgi.h \
+ cupsfilters/image-sgilib.c \
+ cupsfilters/image-sun.c \
+ cupsfilters/image-tiff.c \
+ cupsfilters/image-zoom.c \
+ cupsfilters/lut.c \
+ cupsfilters/pack.c \
+ cupsfilters/ppdgenerator.c \
+ cupsfilters/raster.c \
+ cupsfilters/rgb.c \
+ cupsfilters/srgb.c \
+ $(pkgfiltersinclude_DATA)
+
+libcupsfilters_la_LIBADD = $(CUPS_LIBS) $(LIBJPEG_LIBS) $(LIBPNG_LIBS) \
+ $(TIFF_LIBS) -lm $(am__append_4)
+libcupsfilters_la_CFLAGS = $(CUPS_CFLAGS) $(LIBJPEG_CFLAGS) \
+ $(LIBPNG_CFLAGS) $(TIFF_CFLAGS) $(am__append_3)
+libcupsfilters_la_LDFLAGS = \
+ -no-undefined \
+ -version-info 1
+
+testcmyk_SOURCES = \
+ cupsfilters/testcmyk.c \
+ $(pkgfiltersinclude_DATA)
+
+testcmyk_LDADD = \
+ libcupsfilters.la \
+ -lm
+
+testdither_SOURCES = \
+ cupsfilters/testdither.c \
+ $(pkgfiltersinclude_DATA)
+
+testdither_LDADD = \
+ libcupsfilters.la \
+ -lm
+
+testimage_SOURCES = \
+ cupsfilters/testimage.c \
+ $(pkgfiltersinclude_DATA)
+
+testimage_LDADD = \
+ $(LIBJPEG_LIBS) \
+ $(LIBPNG_LIBS) \
+ $(TIFF_LIBS) \
+ libcupsfilters.la \
+ -lm
+
+testimage_CFLAGS = \
+ $(LIBJPEG_CFLAGS) \
+ $(LIBPNG_CFLAGS) \
+ $(TIFF_CFLAGS)
+
+testrgb_SOURCES = \
+ cupsfilters/testrgb.c \
+ $(pkgfiltersinclude_DATA)
+
+testrgb_LDADD = \
+ libcupsfilters.la \
+ -lm
+
+
+# =========
+# CUPS Data
+# =========
+pkgcupsdatadir = $(CUPS_DATADIR)/data
+pkgcupsdata_DATA = \
+ data/default.pdf \
+ data/form_russian.pdf \
+ data/form_english.pdf \
+ data/form_english_in.odt \
+ data/form_russian_in.odt \
+ data/default-testpage.pdf \
+ data/testprint \
+ data/classified.pdf \
+ data/confidential.pdf \
+ data/secret.pdf \
+ data/standard.pdf \
+ data/topsecret.pdf \
+ data/unclassified.pdf
+
+
+# ===========
+# CUPS Config
+# ===========
+pkgcupsserverrootdir = $(CUPS_SERVERROOT)
+pkgcupsserverroot_DATA = \
+ utils/cups-browsed.conf
+
+
+# =======
+# Drivers
+# =======
+pkgdriverdir = $(CUPS_DATADIR)/drv
+pkgdriver_DATA = drv/cupsfilters.drv $(am__append_5)
+
+# =======
+# Definitions for drivers
+# =======
+pkgppdcdir = $(CUPS_DATADIR)/ppdc
+pkgppdc_DATA = filter/pcl.h filter/escp.h $(am__append_6)
+@ENABLE_BRAILLE_TRUE@GENERATED_LIBLOUIS = \
+@ENABLE_BRAILLE_TRUE@ filter/braille/filters/liblouis2.defs \
+@ENABLE_BRAILLE_TRUE@ filter/braille/filters/liblouis3.defs \
+@ENABLE_BRAILLE_TRUE@ filter/braille/filters/liblouis4.defs
+
+@ENABLE_BRAILLE_TRUE@GENERATED_DEFS = \
+@ENABLE_BRAILLE_TRUE@ filter/braille/filters/liblouis1.defs \
+@ENABLE_BRAILLE_TRUE@ $(GENERATED_LIBLOUIS)
+
+@ENABLE_BRAILLE_TRUE@nodist_pkgppdc_DATA = \
+@ENABLE_BRAILLE_TRUE@ $(GENERATED_DEFS)
+
+
+# =====
+# MIMEs
+# =====
+pkgmimedir = $(CUPS_DATADIR)/mime
+pkgmime_DATA = mime/cupsfilters.convs mime/cupsfilters.types \
+ $(am__append_8) $(am__append_9) $(am__append_10) \
+ $(am__append_11)
+
+# =================
+# Braille aux files
+# =================
+@ENABLE_BRAILLE_TRUE@pkgbrailledir = $(CUPS_DATADIR)/braille
+@ENABLE_BRAILLE_TRUE@nodist_pkgbraille_SCRIPTS = \
+@ENABLE_BRAILLE_TRUE@ filter/braille/drivers/index/indexv4.sh \
+@ENABLE_BRAILLE_TRUE@ filter/braille/drivers/index/indexv3.sh \
+@ENABLE_BRAILLE_TRUE@ filter/braille/drivers/index/index.sh \
+@ENABLE_BRAILLE_TRUE@ filter/braille/filters/cups-braille.sh
+
+
+# =================
+# Fontembed library
+# =================
+pkgfontembedincludedir = $(includedir)/fontembed
+pkgfontembedinclude_DATA = \
+ fontembed/bitset.h \
+ fontembed/embed.h \
+ fontembed/fontfile.h \
+ fontembed/iofn.h \
+ fontembed/sfnt.h
+
+libfontembed_la_SOURCES = \
+ fontembed/aglfn13.c \
+ fontembed/bitset.h \
+ fontembed/dynstring.c \
+ fontembed/dynstring.h \
+ fontembed/embed.c \
+ fontembed/embed.h \
+ fontembed/embed_sfnt.c \
+ fontembed/embed_sfnt_int.h \
+ fontembed/embed_pdf.c \
+ fontembed/embed_pdf.h \
+ fontembed/embed_pdf_int.h \
+ fontembed/fontfile.c \
+ fontembed/fontfile.h \
+ fontembed/frequent.c \
+ fontembed/frequent.h \
+ fontembed/iofn.h \
+ fontembed/macroman.h \
+ fontembed/sfnt.c \
+ fontembed/sfnt.h \
+ fontembed/sfnt_int.h \
+ fontembed/sfnt_subset.c
+
+libfontembed_la_LDFLAGS = \
+ -no-undefined \
+ -version-info 1
+
+ttfread_SOURCES = fontembed/main.c
+ttfread_LDADD = libfontembed.la
+test_analyze_SOURCES = fontembed/test_analyze.c
+test_analyze_LDADD = libfontembed.la
+test_pdf_SOURCES = fontembed/test_pdf.c
+test_pdf_LDADD = libfontembed.la
+test_ps_SOURCES = fontembed/test_ps.c
+test_ps_LDADD = libfontembed.la
+
+# ===========
+# PDF to OPVP
+# ===========
+pkgfilterdir = $(CUPS_SERVERBIN)/filter
+pkgfontconfigdir = $(sysconfdir)/$(FONTDIR)
+pkgfontconfig_DATA = filter/pdftoopvp/99pdftoopvp.conf
+pdftoopvp_SOURCES = \
+ filter/pdftoopvp/oprs/OPRS.cxx \
+ filter/pdftoopvp/oprs/OPRS.h \
+ filter/pdftoopvp/oprs/OPVPSplashClip.cxx \
+ filter/pdftoopvp/oprs/OPVPSplashClip.h \
+ filter/pdftoopvp/oprs/OPVPSplash.cxx \
+ filter/pdftoopvp/oprs/OPVPSplash.h \
+ filter/pdftoopvp/oprs/OPVPSplashPath.cxx \
+ filter/pdftoopvp/oprs/OPVPSplashPath.h \
+ filter/pdftoopvp/oprs/OPVPSplashState.cxx \
+ filter/pdftoopvp/oprs/OPVPSplashState.h \
+ filter/pdftoopvp/oprs/OPVPSplashXPath.cxx \
+ filter/pdftoopvp/oprs/OPVPSplashXPath.h \
+ filter/pdftoopvp/oprs/OPVPWrapper.cxx \
+ filter/pdftoopvp/oprs/OPVPWrapper.h \
+ filter/pdftoopvp/oprs/OPVPWrapper_0_2.cxx \
+ filter/pdftoopvp/oprs/OPVPWrapper_0_2.h \
+ filter/pdftoopvp/OPVPError.h \
+ filter/pdftoopvp/opvp/opvp_common.h \
+ filter/pdftoopvp/opvp/opvp.h \
+ filter/pdftoopvp/opvp/opvp_0_2_0.h \
+ filter/pdftoopvp/OPVPOutputDev.cxx \
+ filter/pdftoopvp/OPVPOutputDev.h \
+ filter/pdftoopvp/pdftoopvp.cxx
+
+pdftoopvp_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ $(FREETYPE_CFLAGS) \
+ $(FONTCONFIG_CFLAGS) \
+ $(LIBPNG_CFLAGS) \
+ $(POPPLER_CFLAGS) \
+ -I$(srcdir)/filter/pdftoopvp/oprs \
+ -I$(srcdir)/filter/pdftoopvp/opvp
+
+pdftoopvp_CXXFLAGS = $(pdftoopvp_CFLAGS)
+pdftoopvp_LDADD = \
+ $(CUPS_LIBS) \
+ $(FREETYPE_LIBS) \
+ $(FONTCONFIG_LIBS) \
+ $(LIBPNG_LIBS) \
+ $(POPPLER_LIBS) \
+ $(DLOPEN_LIBS)
+
+pdftopdf_SOURCES = \
+ filter/pdftopdf/pdftopdf.cc \
+ filter/pdftopdf/pdftopdf_jcl.cc \
+ filter/pdftopdf/pdftopdf_jcl.h \
+ filter/pdftopdf/pdftopdf_processor.cc \
+ filter/pdftopdf/pdftopdf_processor.h \
+ filter/pdftopdf/qpdf_pdftopdf_processor.cc \
+ filter/pdftopdf/qpdf_pdftopdf_processor.h \
+ filter/pdftopdf/pptypes.cc \
+ filter/pdftopdf/pptypes.h \
+ filter/pdftopdf/nup.cc \
+ filter/pdftopdf/nup.h \
+ filter/pdftopdf/intervalset.cc \
+ filter/pdftopdf/intervalset.h \
+ filter/pdftopdf/qpdf_tools.cc \
+ filter/pdftopdf/qpdf_tools.h \
+ filter/pdftopdf/qpdf_xobject.cc \
+ filter/pdftopdf/qpdf_xobject.h \
+ filter/pdftopdf/qpdf_pdftopdf.cc \
+ filter/pdftopdf/qpdf_pdftopdf.h \
+ filter/pdftopdf/qpdf_cm.cc \
+ filter/pdftopdf/qpdf_cm.h
+
+pdftopdf_CFLAGS = \
+ $(LIBQPDF_CFLAGS) \
+ $(CUPS_CFLAGS)
+
+pdftopdf_CXXFLAGS = -std=c++0x $(pdftopdf_CFLAGS) # -std=c++11
+pdftopdf_LDADD = \
+ $(LIBQPDF_LIBS) \
+ $(CUPS_LIBS)
+
+
+# ======================
+# Simple filter binaries
+# ======================
+pkgfilter_SCRIPTS = filter/imagetops filter/texttops \
+ filter/rastertopclm $(am__append_13)
+@ENABLE_BRAILLE_TRUE@nodist_pkgfilter_SCRIPTS = \
+@ENABLE_BRAILLE_TRUE@ filter/braille/drivers/generic/brftoembosser \
+@ENABLE_BRAILLE_TRUE@ filter/braille/drivers/index/imageubrltoindexv3 \
+@ENABLE_BRAILLE_TRUE@ filter/braille/drivers/index/imageubrltoindexv4 \
+@ENABLE_BRAILLE_TRUE@ filter/braille/drivers/index/textbrftoindexv3 \
+@ENABLE_BRAILLE_TRUE@ filter/braille/filters/imagetobrf \
+@ENABLE_BRAILLE_TRUE@ filter/braille/filters/vectortopdf \
+@ENABLE_BRAILLE_TRUE@ filter/braille/filters/vectortobrf \
+@ENABLE_BRAILLE_TRUE@ filter/braille/filters/texttobrf \
+@ENABLE_BRAILLE_TRUE@ filter/braille/filters/musicxmltobrf
+
+bannertopdf_SOURCES = \
+ filter/banner.c \
+ filter/banner.h \
+ filter/bannertopdf.c \
+ filter/pdf.cxx \
+ filter/pdf.h \
+ fontembed/embed.h \
+ fontembed/sfnt.h
+
+EXTRA_bannertopdf_SOURCES = filter/getline.c
+bannertopdf_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ $(LIBJPEG_CFLAGS) \
+ $(LIBPNG_CFLAGS) \
+ $(POPPLER_CFLAGS) \
+ $(TIFF_CFLAGS) \
+ $(FONTCONFIG_CFLAGS) \
+ -I$(srcdir)/fontembed/
+
+bannertopdf_CXXFLAGS = $(bannertopdf_CFLAGS)
+bannertopdf_LDADD = \
+ $(GETLINE) \
+ $(CUPS_LIBS) \
+ $(LIBJPEG_LIBS) \
+ $(LIBPNG_LIBS) \
+ $(POPPLER_LIBS) \
+ $(TIFF_LIBS) \
+ $(FONTCONFIG_LIBS) \
+ libfontembed.la
+
+bannertopdf_DEPENDENCIES = \
+ $(GETLINE) \
+ libfontembed.la
+
+commandtoescpx_SOURCES = \
+ cupsfilters/driver.h \
+ filter/commandtoescpx.c \
+ filter/pcl.h
+
+commandtoescpx_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+
+commandtoescpx_LDADD = $(CUPS_LIBS)
+commandtopclx_SOURCES = \
+ cupsfilters/driver.h \
+ filter/commandtopclx.c \
+ filter/pcl.h
+
+commandtopclx_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+
+commandtopclx_LDADD = $(CUPS_LIBS)
+foomatic_rip_SOURCES = \
+ filter/foomatic-rip/foomaticrip.c \
+ filter/foomatic-rip/foomaticrip.h \
+ filter/foomatic-rip/options.c \
+ filter/foomatic-rip/options.h \
+ filter/foomatic-rip/pdf.c \
+ filter/foomatic-rip/pdf.h \
+ filter/foomatic-rip/postscript.c \
+ filter/foomatic-rip/postscript.h \
+ filter/foomatic-rip/process.c \
+ filter/foomatic-rip/process.h \
+ filter/foomatic-rip/renderer.c \
+ filter/foomatic-rip/renderer.h \
+ filter/foomatic-rip/spooler.c \
+ filter/foomatic-rip/spooler.h \
+ filter/foomatic-rip/util.c \
+ filter/foomatic-rip/util.h \
+ cupsfilters/colord.h
+
+foomatic_rip_CFLAGS = \
+ -DCONFIG_PATH='"$(sysconfdir)/foomatic"' \
+ -I$(srcdir)/cupsfilters/
+
+foomatic_rip_LDADD = \
+ $(CUPS_LIBS) \
+ -lm \
+ libcupsfilters.la
+
+gstoraster_SOURCES = \
+ filter/gstoraster.c \
+ cupsfilters/colord.h \
+ cupsfilters/raster.h
+
+gstoraster_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+
+gstoraster_LDADD = \
+ $(CUPS_LIBS) \
+ libcupsfilters.la
+
+imagetopdf_SOURCES = \
+ cupsfilters/image.h \
+ filter/common.c \
+ filter/common.h \
+ filter/imagetopdf.c
+
+imagetopdf_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ $(LIBJPEG_CFLAGS) \
+ $(LIBPNG_CFLAGS) \
+ $(TIFF_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+
+imagetopdf_LDADD = \
+ $(CUPS_LIBS) \
+ $(LIBJPEG_LIBS) \
+ $(LIBPNG_LIBS) \
+ $(TIFF_LIBS) \
+ -lm \
+ libcupsfilters.la
+
+imagetoraster_SOURCES = \
+ cupsfilters/image.h \
+ cupsfilters/image-private.h \
+ filter/common.c \
+ filter/common.h \
+ filter/imagetoraster.c
+
+imagetoraster_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+
+imagetoraster_LDADD = \
+ $(CUPS_LIBS) \
+ -lm \
+ libcupsfilters.la
+
+@ENABLE_URFTOPDF_TRUE@urftopdf_SOURCES = \
+@ENABLE_URFTOPDF_TRUE@ filter/urftopdf.cpp \
+@ENABLE_URFTOPDF_TRUE@ filter/unirast.h
+
+@ENABLE_URFTOPDF_TRUE@urftopdf_CXXFLAGS = \
+@ENABLE_URFTOPDF_TRUE@ $(LIBQPDF_CFLAGS)
+
+@ENABLE_URFTOPDF_TRUE@urftopdf_LDADD = \
+@ENABLE_URFTOPDF_TRUE@ $(LIBQPDF_LIBS)
+
+rastertopdf_SOURCES = \
+ filter/rastertopdf.cpp
+
+rastertopdf_CXXFLAGS = \
+ $(CUPS_CFLAGS) \
+ $(LCMS_CFLAGS) \
+ $(LIBQPDF_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+
+rastertopdf_LDADD = \
+ $(CUPS_LIBS) \
+ $(LCMS_LIBS) \
+ $(LIBQPDF_LIBS) \
+ libcupsfilters.la
+
+mupdftoraster_SOURCES = \
+ filter/mupdftoraster.c
+
+mupdftoraster_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+
+mupdftoraster_LDADD = \
+ $(CUPS_LIBS) \
+ libcupsfilters.la
+
+rastertops_SOURCES = \
+ filter/rastertops.c
+
+rastertops_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+
+rastertops_LDADD = \
+ $(CUPS_LIBS) \
+ -lz \
+ libcupsfilters.la
+
+pdftoijs_SOURCES = \
+ filter/pdftoijs.cxx \
+ filter/PDFError.h
+
+pdftoijs_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ $(IJS_CFLAGS) \
+ $(POPPLER_CFLAGS)
+
+pdftoijs_CXXFLAGS = $(pdftoijs_CFLAGS)
+pdftoijs_LDADD = \
+ $(CUPS_LIBS) \
+ $(IJS_LIBS) \
+ $(POPPLER_LIBS)
+
+sys5ippprinter_SOURCES = \
+ filter/common.c \
+ filter/common.h \
+ filter/sys5ippprinter.c
+
+EXTRA_sys5ippprinter_SOURCES = filter/strcasestr.c
+sys5ippprinter_CFLAGS = $(CUPS_CFLAGS)
+sys5ippprinter_LDADD = $(STRCASESTR) $(CUPS_LIBS)
+sys5ippprinter_DEPENDENCIES = $(STRCASESTR)
+texttotext_SOURCES = \
+ filter/texttotext.c
+
+EXTRA_texttotext_SOURCES = filter/strcasestr.c
+texttotext_CFLAGS = $(CUPS_CFLAGS)
+texttotext_LDADD = $(STRCASESTR) $(CUPS_LIBS)
+texttotext_DEPENDENCIES = $(STRCASESTR)
+pdftops_SOURCES = \
+ filter/common.c \
+ filter/common.h \
+ filter/pdftops.c
+
+EXTRA_pdftops_SOURCES = filter/strcasestr.c
+pdftops_CFLAGS = $(CUPS_CFLAGS)
+pdftops_LDADD = $(STRCASESTR) $(CUPS_LIBS)
+pdftops_DEPENDENCIES = $(STRCASESTR)
+pdftoraster_SOURCES = \
+ filter/pdftoraster.cxx \
+ filter/PDFError.h
+
+pdftoraster_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ $(LCMS_CFLAGS) \
+ $(LIBJPEG_CFLAGS) \
+ $(LIBPNG_CFLAGS) \
+ $(POPPLER_CFLAGS) \
+ $(TIFF_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+
+pdftoraster_CXXFLAGS = $(pdftoraster_CFLAGS)
+pdftoraster_LDADD = \
+ $(CUPS_LIBS) \
+ $(LCMS_LIBS) \
+ $(LIBJPEG_LIBS) \
+ $(LIBPNG_LIBS) \
+ $(POPPLER_LIBS) \
+ $(TIFF_LIBS) \
+ libcupsfilters.la
+
+rastertoescpx_SOURCES = \
+ cupsfilters/driver.h \
+ filter/escp.h \
+ filter/rastertoescpx.c
+
+rastertoescpx_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+
+rastertoescpx_LDADD = \
+ $(CUPS_LIBS) \
+ libcupsfilters.la
+
+rastertopclx_SOURCES = \
+ cupsfilters/driver.h \
+ filter/pcl.h \
+ filter/pcl-common.c \
+ filter/pcl-common.h \
+ filter/rastertopclx.c
+
+rastertopclx_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ $(LIBPNG_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+
+rastertopclx_LDADD = \
+ $(CUPS_LIBS) \
+ $(LIBPNG_LIBS) \
+ libcupsfilters.la
+
+test_pdf1_SOURCES = \
+ filter/pdfutils.c \
+ filter/pdfutils.h \
+ filter/test_pdf1.c \
+ fontembed/embed.h \
+ fontembed/sfnt.h
+
+test_pdf1_CFLAGS = -I$(srcdir)/fontembed/
+test_pdf1_LDADD = libfontembed.la
+test_pdf2_SOURCES = \
+ filter/pdfutils.c \
+ filter/pdfutils.h \
+ filter/test_pdf2.c \
+ fontembed/embed.h \
+ fontembed/sfnt.h
+
+test_pdf2_CFLAGS = -I$(srcdir)/fontembed/
+test_pdf2_LDADD = libfontembed.la
+texttopdf_SOURCES = \
+ filter/common.c \
+ filter/common.h \
+ filter/pdfutils.c \
+ filter/pdfutils.h \
+ filter/textcommon.c \
+ filter/textcommon.h \
+ filter/texttopdf.c \
+ fontembed/bitset.h \
+ fontembed/embed.h \
+ fontembed/fontfile.h \
+ fontembed/iofn.h \
+ fontembed/sfnt.h
+
+texttopdf_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ $(FONTCONFIG_CFLAGS) \
+ -I$(srcdir)/fontembed/
+
+texttopdf_LDADD = \
+ $(CUPS_LIBS) \
+ $(FONTCONFIG_LIBS) \
+ libfontembed.la
+
+
+# =====
+# UTILS
+# =====
+cups_notifier_sources = \
+ cups-notifier.c \
+ cups-notifier.h
+
+cups_browsed_SOURCES = \
+ utils/cups-browsed.c
+
+nodist_cups_browsed_SOURCES = \
+ $(cups_notifier_sources)
+
+cups_browsed_CFLAGS = \
+ $(CUPS_CFLAGS) \
+ $(AVAHI_CFLAGS) \
+ $(AVAHI_GLIB_CFLAGS) \
+ $(GLIB_CFLAGS) \
+ $(GIO_CFLAGS) \
+ $(GIO_UNIX_CFLAGS) \
+ -I$(srcdir)/cupsfilters/
+
+cups_browsed_CXXFLAGS = $(cups_browsed_CFLAGS)
+cups_browsed_LDADD = \
+ $(CUPS_LIBS) \
+ $(AVAHI_LIBS) \
+ $(AVAHI_GLIB_LIBS) \
+ $(GLIB_LIBS) \
+ $(GIO_LIBS) \
+ $(GIO_UNIX_LIBS) \
+ libcupsfilters.la
+
+initrcdir = $(INITDDIR)
+initrc_SCRIPTS = utils/cups-browsed
+man_MANS = utils/cups-browsed.8 utils/cups-browsed.conf.5 \
+ $(am__append_21) $(am__append_22)
+BUILT_SOURCES = $(cups_notifier_sources)
+CLEANFILES = $(BUILT_SOURCES)
+
+# ===
+# PPD
+# ===
+ppddir = $(datadir)/ppd/cupsfilters
+ppd_DATA = ppd/Fuji_Xerox-DocuPrint_CM305_df-PDF.ppd \
+ ppd/Generic-PDF_Printer-PDF.ppd \
+ ppd/HP-Color_LaserJet_CM3530_MFP-PDF.ppd \
+ ppd/Ricoh-PDF_Printer-PDF.ppd $(am__append_23) \
+ $(am__append_24)
+
+# =========
+# Scripting
+# =========
+@WITH_PHP_TRUE@phpextensiondir = $(PHPDIR)
+@WITH_PHP_TRUE@phpextension_LTLIBRARIES = libphpcups.la
+@WITH_PHP_TRUE@libphpcups_la_SOURCES = \
+@WITH_PHP_TRUE@ scripting/php/phpcups.c \
+@WITH_PHP_TRUE@ scripting/php/phpcups.h
+
+@WITH_PHP_TRUE@libphpcups_la_LIBADD = $(CUPS_LIBS)
+@WITH_PHP_TRUE@libphpcups_la_CFLAGS = $(CUPS_CFLAGS)
+@WITH_PHP_TRUE@libphpcups_la_LDFLAGS = -no-undefined
+all: $(BUILT_SOURCES) config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .cc .cpp .cxx .lo .log .o .obj .test .test$(EXEEXT) .trs
+am--refresh: Makefile
+ @:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+config.h: stamp-h1
+ @test -f $@ || rm -f stamp-h1
+ @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+ @rm -f stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.h.in: $(am__configure_deps)
+ ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+ rm -f stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+libcupsfilters.pc: $(top_builddir)/config.status $(srcdir)/libcupsfilters.pc.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+libfontembed.pc: $(top_builddir)/config.status $(srcdir)/libfontembed.pc.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+utils/cups-browsed: $(top_builddir)/config.status $(top_srcdir)/utils/cups-browsed.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+utils/cups-browsed.conf: $(top_builddir)/config.status $(top_srcdir)/utils/cups-browsed.conf.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+filter/foomatic-rip/foomatic-rip.1: $(top_builddir)/config.status $(top_srcdir)/filter/foomatic-rip/foomatic-rip.1.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+filter/braille/drivers/index/indexv4.sh: $(top_builddir)/config.status $(top_srcdir)/filter/braille/drivers/index/indexv4.sh.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+filter/braille/drivers/index/indexv3.sh: $(top_builddir)/config.status $(top_srcdir)/filter/braille/drivers/index/indexv3.sh.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+filter/braille/drivers/index/index.sh: $(top_builddir)/config.status $(top_srcdir)/filter/braille/drivers/index/index.sh.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+filter/braille/drivers/index/textbrftoindexv3: $(top_builddir)/config.status $(top_srcdir)/filter/braille/drivers/index/textbrftoindexv3.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+filter/braille/drivers/index/imageubrltoindexv3: $(top_builddir)/config.status $(top_srcdir)/filter/braille/drivers/index/imageubrltoindexv3.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+filter/braille/drivers/index/imageubrltoindexv4: $(top_builddir)/config.status $(top_srcdir)/filter/braille/drivers/index/imageubrltoindexv4.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+filter/braille/drivers/generic/brftoembosser: $(top_builddir)/config.status $(top_srcdir)/filter/braille/drivers/generic/brftoembosser.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+filter/braille/filters/cups-braille.sh: $(top_builddir)/config.status $(top_srcdir)/filter/braille/filters/cups-braille.sh.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+filter/braille/filters/imagetobrf: $(top_builddir)/config.status $(top_srcdir)/filter/braille/filters/imagetobrf.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+filter/braille/filters/texttobrf: $(top_builddir)/config.status $(top_srcdir)/filter/braille/filters/texttobrf.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+filter/braille/filters/vectortopdf: $(top_builddir)/config.status $(top_srcdir)/filter/braille/filters/vectortopdf.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+filter/braille/filters/vectortobrf: $(top_builddir)/config.status $(top_srcdir)/filter/braille/filters/vectortobrf.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+filter/braille/filters/musicxmltobrf: $(top_builddir)/config.status $(top_srcdir)/filter/braille/filters/musicxmltobrf.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+filter/braille/filters/liblouis1.defs.gen: $(top_builddir)/config.status $(top_srcdir)/filter/braille/filters/liblouis1.defs.gen.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+mime/cupsfilters.convs: $(top_builddir)/config.status $(top_srcdir)/mime/cupsfilters.convs.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+install-phpextensionLTLIBRARIES: $(phpextension_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(phpextension_LTLIBRARIES)'; test -n "$(phpextensiondir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(phpextensiondir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(phpextensiondir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(phpextensiondir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(phpextensiondir)"; \
+ }
+
+uninstall-phpextensionLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(phpextension_LTLIBRARIES)'; test -n "$(phpextensiondir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(phpextensiondir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(phpextensiondir)/$$f"; \
+ done
+
+clean-phpextensionLTLIBRARIES:
+ -test -z "$(phpextension_LTLIBRARIES)" || rm -f $(phpextension_LTLIBRARIES)
+ @list='$(phpextension_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libcupsfilters.la: $(libcupsfilters_la_OBJECTS) $(libcupsfilters_la_DEPENDENCIES) $(EXTRA_libcupsfilters_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libcupsfilters_la_LINK) -rpath $(libdir) $(libcupsfilters_la_OBJECTS) $(libcupsfilters_la_LIBADD) $(LIBS)
+
+libfontembed.la: $(libfontembed_la_OBJECTS) $(libfontembed_la_DEPENDENCIES) $(EXTRA_libfontembed_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libfontembed_la_LINK) -rpath $(libdir) $(libfontembed_la_OBJECTS) $(libfontembed_la_LIBADD) $(LIBS)
+
+libphpcups.la: $(libphpcups_la_OBJECTS) $(libphpcups_la_DEPENDENCIES) $(EXTRA_libphpcups_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libphpcups_la_LINK) $(am_libphpcups_la_rpath) $(libphpcups_la_OBJECTS) $(libphpcups_la_LIBADD) $(LIBS)
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+install-pkgbackendPROGRAMS: $(pkgbackend_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgbackend_PROGRAMS)'; test -n "$(pkgbackenddir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgbackenddir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgbackenddir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(pkgbackenddir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(pkgbackenddir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-pkgbackendPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgbackend_PROGRAMS)'; test -n "$(pkgbackenddir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(pkgbackenddir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(pkgbackenddir)" && rm -f $$files
+
+clean-pkgbackendPROGRAMS:
+ @list='$(pkgbackend_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+install-pkgfilterPROGRAMS: $(pkgfilter_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgfilter_PROGRAMS)'; test -n "$(pkgfilterdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgfilterdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgfilterdir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(pkgfilterdir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(pkgfilterdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-pkgfilterPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgfilter_PROGRAMS)'; test -n "$(pkgfilterdir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(pkgfilterdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(pkgfilterdir)" && rm -f $$files
+
+clean-pkgfilterPROGRAMS:
+ @list='$(pkgfilter_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+install-pkgppdgenPROGRAMS: $(pkgppdgen_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgppdgen_PROGRAMS)'; test -n "$(pkgppdgendir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgppdgendir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgppdgendir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(pkgppdgendir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(pkgppdgendir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-pkgppdgenPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgppdgen_PROGRAMS)'; test -n "$(pkgppdgendir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(pkgppdgendir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(pkgppdgendir)" && rm -f $$files
+
+clean-pkgppdgenPROGRAMS:
+ @list='$(pkgppdgen_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(sbindir)" && rm -f $$files
+
+clean-sbinPROGRAMS:
+ @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+bannertopdf$(EXEEXT): $(bannertopdf_OBJECTS) $(bannertopdf_DEPENDENCIES) $(EXTRA_bannertopdf_DEPENDENCIES)
+ @rm -f bannertopdf$(EXEEXT)
+ $(AM_V_CXXLD)$(bannertopdf_LINK) $(bannertopdf_OBJECTS) $(bannertopdf_LDADD) $(LIBS)
+
+beh$(EXEEXT): $(beh_OBJECTS) $(beh_DEPENDENCIES) $(EXTRA_beh_DEPENDENCIES)
+ @rm -f beh$(EXEEXT)
+ $(AM_V_CCLD)$(beh_LINK) $(beh_OBJECTS) $(beh_LDADD) $(LIBS)
+
+commandtoescpx$(EXEEXT): $(commandtoescpx_OBJECTS) $(commandtoescpx_DEPENDENCIES) $(EXTRA_commandtoescpx_DEPENDENCIES)
+ @rm -f commandtoescpx$(EXEEXT)
+ $(AM_V_CCLD)$(commandtoescpx_LINK) $(commandtoescpx_OBJECTS) $(commandtoescpx_LDADD) $(LIBS)
+
+commandtopclx$(EXEEXT): $(commandtopclx_OBJECTS) $(commandtopclx_DEPENDENCIES) $(EXTRA_commandtopclx_DEPENDENCIES)
+ @rm -f commandtopclx$(EXEEXT)
+ $(AM_V_CCLD)$(commandtopclx_LINK) $(commandtopclx_OBJECTS) $(commandtopclx_LDADD) $(LIBS)
+
+cups-brf$(EXEEXT): $(cups_brf_OBJECTS) $(cups_brf_DEPENDENCIES) $(EXTRA_cups_brf_DEPENDENCIES)
+ @rm -f cups-brf$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(cups_brf_OBJECTS) $(cups_brf_LDADD) $(LIBS)
+
+cups-browsed$(EXEEXT): $(cups_browsed_OBJECTS) $(cups_browsed_DEPENDENCIES) $(EXTRA_cups_browsed_DEPENDENCIES)
+ @rm -f cups-browsed$(EXEEXT)
+ $(AM_V_CCLD)$(cups_browsed_LINK) $(cups_browsed_OBJECTS) $(cups_browsed_LDADD) $(LIBS)
+
+driverless$(EXEEXT): $(driverless_OBJECTS) $(driverless_DEPENDENCIES) $(EXTRA_driverless_DEPENDENCIES)
+ @rm -f driverless$(EXEEXT)
+ $(AM_V_CCLD)$(driverless_LINK) $(driverless_OBJECTS) $(driverless_LDADD) $(LIBS)
+
+foomatic-rip$(EXEEXT): $(foomatic_rip_OBJECTS) $(foomatic_rip_DEPENDENCIES) $(EXTRA_foomatic_rip_DEPENDENCIES)
+ @rm -f foomatic-rip$(EXEEXT)
+ $(AM_V_CCLD)$(foomatic_rip_LINK) $(foomatic_rip_OBJECTS) $(foomatic_rip_LDADD) $(LIBS)
+
+gstoraster$(EXEEXT): $(gstoraster_OBJECTS) $(gstoraster_DEPENDENCIES) $(EXTRA_gstoraster_DEPENDENCIES)
+ @rm -f gstoraster$(EXEEXT)
+ $(AM_V_CCLD)$(gstoraster_LINK) $(gstoraster_OBJECTS) $(gstoraster_LDADD) $(LIBS)
+
+imagetopdf$(EXEEXT): $(imagetopdf_OBJECTS) $(imagetopdf_DEPENDENCIES) $(EXTRA_imagetopdf_DEPENDENCIES)
+ @rm -f imagetopdf$(EXEEXT)
+ $(AM_V_CCLD)$(imagetopdf_LINK) $(imagetopdf_OBJECTS) $(imagetopdf_LDADD) $(LIBS)
+
+imagetoraster$(EXEEXT): $(imagetoraster_OBJECTS) $(imagetoraster_DEPENDENCIES) $(EXTRA_imagetoraster_DEPENDENCIES)
+ @rm -f imagetoraster$(EXEEXT)
+ $(AM_V_CCLD)$(imagetoraster_LINK) $(imagetoraster_OBJECTS) $(imagetoraster_LDADD) $(LIBS)
+
+implicitclass$(EXEEXT): $(implicitclass_OBJECTS) $(implicitclass_DEPENDENCIES) $(EXTRA_implicitclass_DEPENDENCIES)
+ @rm -f implicitclass$(EXEEXT)
+ $(AM_V_CCLD)$(implicitclass_LINK) $(implicitclass_OBJECTS) $(implicitclass_LDADD) $(LIBS)
+
+mupdftoraster$(EXEEXT): $(mupdftoraster_OBJECTS) $(mupdftoraster_DEPENDENCIES) $(EXTRA_mupdftoraster_DEPENDENCIES)
+ @rm -f mupdftoraster$(EXEEXT)
+ $(AM_V_CCLD)$(mupdftoraster_LINK) $(mupdftoraster_OBJECTS) $(mupdftoraster_LDADD) $(LIBS)
+
+parallel$(EXEEXT): $(parallel_OBJECTS) $(parallel_DEPENDENCIES) $(EXTRA_parallel_DEPENDENCIES)
+ @rm -f parallel$(EXEEXT)
+ $(AM_V_CCLD)$(parallel_LINK) $(parallel_OBJECTS) $(parallel_LDADD) $(LIBS)
+
+pdftoijs$(EXEEXT): $(pdftoijs_OBJECTS) $(pdftoijs_DEPENDENCIES) $(EXTRA_pdftoijs_DEPENDENCIES)
+ @rm -f pdftoijs$(EXEEXT)
+ $(AM_V_CXXLD)$(pdftoijs_LINK) $(pdftoijs_OBJECTS) $(pdftoijs_LDADD) $(LIBS)
+
+pdftoopvp$(EXEEXT): $(pdftoopvp_OBJECTS) $(pdftoopvp_DEPENDENCIES) $(EXTRA_pdftoopvp_DEPENDENCIES)
+ @rm -f pdftoopvp$(EXEEXT)
+ $(AM_V_CXXLD)$(pdftoopvp_LINK) $(pdftoopvp_OBJECTS) $(pdftoopvp_LDADD) $(LIBS)
+
+pdftopdf$(EXEEXT): $(pdftopdf_OBJECTS) $(pdftopdf_DEPENDENCIES) $(EXTRA_pdftopdf_DEPENDENCIES)
+ @rm -f pdftopdf$(EXEEXT)
+ $(AM_V_CXXLD)$(pdftopdf_LINK) $(pdftopdf_OBJECTS) $(pdftopdf_LDADD) $(LIBS)
+
+pdftops$(EXEEXT): $(pdftops_OBJECTS) $(pdftops_DEPENDENCIES) $(EXTRA_pdftops_DEPENDENCIES)
+ @rm -f pdftops$(EXEEXT)
+ $(AM_V_CCLD)$(pdftops_LINK) $(pdftops_OBJECTS) $(pdftops_LDADD) $(LIBS)
+
+pdftoraster$(EXEEXT): $(pdftoraster_OBJECTS) $(pdftoraster_DEPENDENCIES) $(EXTRA_pdftoraster_DEPENDENCIES)
+ @rm -f pdftoraster$(EXEEXT)
+ $(AM_V_CXXLD)$(pdftoraster_LINK) $(pdftoraster_OBJECTS) $(pdftoraster_LDADD) $(LIBS)
+
+rastertoescpx$(EXEEXT): $(rastertoescpx_OBJECTS) $(rastertoescpx_DEPENDENCIES) $(EXTRA_rastertoescpx_DEPENDENCIES)
+ @rm -f rastertoescpx$(EXEEXT)
+ $(AM_V_CCLD)$(rastertoescpx_LINK) $(rastertoescpx_OBJECTS) $(rastertoescpx_LDADD) $(LIBS)
+
+rastertopclx$(EXEEXT): $(rastertopclx_OBJECTS) $(rastertopclx_DEPENDENCIES) $(EXTRA_rastertopclx_DEPENDENCIES)
+ @rm -f rastertopclx$(EXEEXT)
+ $(AM_V_CCLD)$(rastertopclx_LINK) $(rastertopclx_OBJECTS) $(rastertopclx_LDADD) $(LIBS)
+
+rastertopdf$(EXEEXT): $(rastertopdf_OBJECTS) $(rastertopdf_DEPENDENCIES) $(EXTRA_rastertopdf_DEPENDENCIES)
+ @rm -f rastertopdf$(EXEEXT)
+ $(AM_V_CXXLD)$(rastertopdf_LINK) $(rastertopdf_OBJECTS) $(rastertopdf_LDADD) $(LIBS)
+
+rastertops$(EXEEXT): $(rastertops_OBJECTS) $(rastertops_DEPENDENCIES) $(EXTRA_rastertops_DEPENDENCIES)
+ @rm -f rastertops$(EXEEXT)
+ $(AM_V_CCLD)$(rastertops_LINK) $(rastertops_OBJECTS) $(rastertops_LDADD) $(LIBS)
+
+serial$(EXEEXT): $(serial_OBJECTS) $(serial_DEPENDENCIES) $(EXTRA_serial_DEPENDENCIES)
+ @rm -f serial$(EXEEXT)
+ $(AM_V_CCLD)$(serial_LINK) $(serial_OBJECTS) $(serial_LDADD) $(LIBS)
+
+sys5ippprinter$(EXEEXT): $(sys5ippprinter_OBJECTS) $(sys5ippprinter_DEPENDENCIES) $(EXTRA_sys5ippprinter_DEPENDENCIES)
+ @rm -f sys5ippprinter$(EXEEXT)
+ $(AM_V_CCLD)$(sys5ippprinter_LINK) $(sys5ippprinter_OBJECTS) $(sys5ippprinter_LDADD) $(LIBS)
+
+test1284$(EXEEXT): $(test1284_OBJECTS) $(test1284_DEPENDENCIES) $(EXTRA_test1284_DEPENDENCIES)
+ @rm -f test1284$(EXEEXT)
+ $(AM_V_CCLD)$(test1284_LINK) $(test1284_OBJECTS) $(test1284_LDADD) $(LIBS)
+
+test_analyze$(EXEEXT): $(test_analyze_OBJECTS) $(test_analyze_DEPENDENCIES) $(EXTRA_test_analyze_DEPENDENCIES)
+ @rm -f test_analyze$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_analyze_OBJECTS) $(test_analyze_LDADD) $(LIBS)
+
+test_pdf$(EXEEXT): $(test_pdf_OBJECTS) $(test_pdf_DEPENDENCIES) $(EXTRA_test_pdf_DEPENDENCIES)
+ @rm -f test_pdf$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_pdf_OBJECTS) $(test_pdf_LDADD) $(LIBS)
+
+test_pdf1$(EXEEXT): $(test_pdf1_OBJECTS) $(test_pdf1_DEPENDENCIES) $(EXTRA_test_pdf1_DEPENDENCIES)
+ @rm -f test_pdf1$(EXEEXT)
+ $(AM_V_CCLD)$(test_pdf1_LINK) $(test_pdf1_OBJECTS) $(test_pdf1_LDADD) $(LIBS)
+
+test_pdf2$(EXEEXT): $(test_pdf2_OBJECTS) $(test_pdf2_DEPENDENCIES) $(EXTRA_test_pdf2_DEPENDENCIES)
+ @rm -f test_pdf2$(EXEEXT)
+ $(AM_V_CCLD)$(test_pdf2_LINK) $(test_pdf2_OBJECTS) $(test_pdf2_LDADD) $(LIBS)
+
+test_ps$(EXEEXT): $(test_ps_OBJECTS) $(test_ps_DEPENDENCIES) $(EXTRA_test_ps_DEPENDENCIES)
+ @rm -f test_ps$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ps_OBJECTS) $(test_ps_LDADD) $(LIBS)
+
+testcmyk$(EXEEXT): $(testcmyk_OBJECTS) $(testcmyk_DEPENDENCIES) $(EXTRA_testcmyk_DEPENDENCIES)
+ @rm -f testcmyk$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(testcmyk_OBJECTS) $(testcmyk_LDADD) $(LIBS)
+
+testdither$(EXEEXT): $(testdither_OBJECTS) $(testdither_DEPENDENCIES) $(EXTRA_testdither_DEPENDENCIES)
+ @rm -f testdither$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(testdither_OBJECTS) $(testdither_LDADD) $(LIBS)
+
+testimage$(EXEEXT): $(testimage_OBJECTS) $(testimage_DEPENDENCIES) $(EXTRA_testimage_DEPENDENCIES)
+ @rm -f testimage$(EXEEXT)
+ $(AM_V_CCLD)$(testimage_LINK) $(testimage_OBJECTS) $(testimage_LDADD) $(LIBS)
+
+testrgb$(EXEEXT): $(testrgb_OBJECTS) $(testrgb_DEPENDENCIES) $(EXTRA_testrgb_DEPENDENCIES)
+ @rm -f testrgb$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(testrgb_OBJECTS) $(testrgb_LDADD) $(LIBS)
+
+texttopdf$(EXEEXT): $(texttopdf_OBJECTS) $(texttopdf_DEPENDENCIES) $(EXTRA_texttopdf_DEPENDENCIES)
+ @rm -f texttopdf$(EXEEXT)
+ $(AM_V_CCLD)$(texttopdf_LINK) $(texttopdf_OBJECTS) $(texttopdf_LDADD) $(LIBS)
+
+texttotext$(EXEEXT): $(texttotext_OBJECTS) $(texttotext_DEPENDENCIES) $(EXTRA_texttotext_DEPENDENCIES)
+ @rm -f texttotext$(EXEEXT)
+ $(AM_V_CCLD)$(texttotext_LINK) $(texttotext_OBJECTS) $(texttotext_LDADD) $(LIBS)
+
+ttfread$(EXEEXT): $(ttfread_OBJECTS) $(ttfread_DEPENDENCIES) $(EXTRA_ttfread_DEPENDENCIES)
+ @rm -f ttfread$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(ttfread_OBJECTS) $(ttfread_LDADD) $(LIBS)
+
+urftopdf$(EXEEXT): $(urftopdf_OBJECTS) $(urftopdf_DEPENDENCIES) $(EXTRA_urftopdf_DEPENDENCIES)
+ @rm -f urftopdf$(EXEEXT)
+ $(AM_V_CXXLD)$(urftopdf_LINK) $(urftopdf_OBJECTS) $(urftopdf_LDADD) $(LIBS)
+install-initrcSCRIPTS: $(initrc_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ @list='$(initrc_SCRIPTS)'; test -n "$(initrcdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(initrcdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(initrcdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n' \
+ -e 'h;s|.*|.|' \
+ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+ if (++n[d] == $(am__install_max)) { \
+ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+ else { print "f", d "/" $$4, $$1 } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(initrcdir)$$dir'"; \
+ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(initrcdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-initrcSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(initrc_SCRIPTS)'; test -n "$(initrcdir)" || exit 0; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 's,.*/,,;$(transform)'`; \
+ dir='$(DESTDIR)$(initrcdir)'; $(am__uninstall_files_from_dir)
+install-nodist_pkgbrailleSCRIPTS: $(nodist_pkgbraille_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ @list='$(nodist_pkgbraille_SCRIPTS)'; test -n "$(pkgbrailledir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgbrailledir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgbrailledir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n' \
+ -e 'h;s|.*|.|' \
+ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+ if (++n[d] == $(am__install_max)) { \
+ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+ else { print "f", d "/" $$4, $$1 } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(pkgbrailledir)$$dir'"; \
+ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(pkgbrailledir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-nodist_pkgbrailleSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(nodist_pkgbraille_SCRIPTS)'; test -n "$(pkgbrailledir)" || exit 0; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 's,.*/,,;$(transform)'`; \
+ dir='$(DESTDIR)$(pkgbrailledir)'; $(am__uninstall_files_from_dir)
+install-nodist_pkgfilterSCRIPTS: $(nodist_pkgfilter_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ @list='$(nodist_pkgfilter_SCRIPTS)'; test -n "$(pkgfilterdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgfilterdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgfilterdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n' \
+ -e 'h;s|.*|.|' \
+ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+ if (++n[d] == $(am__install_max)) { \
+ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+ else { print "f", d "/" $$4, $$1 } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(pkgfilterdir)$$dir'"; \
+ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(pkgfilterdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-nodist_pkgfilterSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(nodist_pkgfilter_SCRIPTS)'; test -n "$(pkgfilterdir)" || exit 0; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 's,.*/,,;$(transform)'`; \
+ dir='$(DESTDIR)$(pkgfilterdir)'; $(am__uninstall_files_from_dir)
+install-pkgfilterSCRIPTS: $(pkgfilter_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgfilter_SCRIPTS)'; test -n "$(pkgfilterdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgfilterdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgfilterdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n' \
+ -e 'h;s|.*|.|' \
+ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+ if (++n[d] == $(am__install_max)) { \
+ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+ else { print "f", d "/" $$4, $$1 } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(pkgfilterdir)$$dir'"; \
+ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(pkgfilterdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-pkgfilterSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgfilter_SCRIPTS)'; test -n "$(pkgfilterdir)" || exit 0; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 's,.*/,,;$(transform)'`; \
+ dir='$(DESTDIR)$(pkgfilterdir)'; $(am__uninstall_files_from_dir)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aglfn13.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bannertopdf-banner.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bannertopdf-bannertopdf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bannertopdf-getline.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bannertopdf-pdf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/beh-beh.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/commandtoescpx-commandtoescpx.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/commandtopclx-commandtopclx.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cups-brf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cups_browsed-cups-browsed.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cups_browsed-cups-notifier.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driverless-driverless.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dynstring.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/embed.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/embed_pdf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/embed_sfnt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fontfile.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foomatic_rip-foomaticrip.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foomatic_rip-options.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foomatic_rip-pdf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foomatic_rip-postscript.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foomatic_rip-process.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foomatic_rip-renderer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foomatic_rip-spooler.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foomatic_rip-util.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frequent.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gstoraster-gstoraster.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imagetopdf-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imagetopdf-imagetopdf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imagetoraster-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imagetoraster-imagetoraster.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/implicitclass-implicitclass.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-attr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-check.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-cmyk.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-colord.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-colormanager.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-dither.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-image-bmp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-image-colorspace.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-image-gif.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-image-jpeg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-image-photocd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-image-pix.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-image-png.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-image-pnm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-image-sgi.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-image-sgilib.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-image-sun.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-image-tiff.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-image-zoom.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-image.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-lut.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-pack.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-ppdgenerator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-raster.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-rgb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-srgb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libphpcups_la-phpcups.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mupdftoraster-mupdftoraster.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parallel-ieee1284.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parallel-parallel.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftoijs-pdftoijs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftoopvp-OPRS.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftoopvp-OPVPOutputDev.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftoopvp-OPVPSplash.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftoopvp-OPVPSplashClip.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftoopvp-OPVPSplashPath.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftoopvp-OPVPSplashState.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftoopvp-OPVPSplashXPath.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftoopvp-OPVPWrapper.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftoopvp-OPVPWrapper_0_2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftoopvp-pdftoopvp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftopdf-intervalset.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftopdf-nup.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftopdf-pdftopdf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftopdf-pdftopdf_jcl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftopdf-pdftopdf_processor.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftopdf-pptypes.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftopdf-qpdf_cm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftopdf-qpdf_pdftopdf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftopdf-qpdf_pdftopdf_processor.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftopdf-qpdf_tools.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftopdf-qpdf_xobject.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftops-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftops-pdftops.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftops-strcasestr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdftoraster-pdftoraster.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rastertoescpx-rastertoescpx.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rastertopclx-pcl-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rastertopclx-rastertopclx.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rastertopdf-rastertopdf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rastertops-rastertops.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/serial-serial.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sfnt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sfnt_subset.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sys5ippprinter-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sys5ippprinter-strcasestr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sys5ippprinter-sys5ippprinter.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test1284-ieee1284.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test1284-test1284.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_analyze.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_pdf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_pdf1-pdfutils.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_pdf1-test_pdf1.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_pdf2-pdfutils.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_pdf2-test_pdf2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ps.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testcmyk.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testdither.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testimage-testimage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testrgb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texttopdf-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texttopdf-pdfutils.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texttopdf-textcommon.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texttopdf-texttopdf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texttotext-strcasestr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texttotext-texttotext.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/urftopdf-urftopdf.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+libcupsfilters_la-attr.lo: cupsfilters/attr.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-attr.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-attr.Tpo -c -o libcupsfilters_la-attr.lo `test -f 'cupsfilters/attr.c' || echo '$(srcdir)/'`cupsfilters/attr.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-attr.Tpo $(DEPDIR)/libcupsfilters_la-attr.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/attr.c' object='libcupsfilters_la-attr.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-attr.lo `test -f 'cupsfilters/attr.c' || echo '$(srcdir)/'`cupsfilters/attr.c
+
+libcupsfilters_la-check.lo: cupsfilters/check.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-check.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-check.Tpo -c -o libcupsfilters_la-check.lo `test -f 'cupsfilters/check.c' || echo '$(srcdir)/'`cupsfilters/check.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-check.Tpo $(DEPDIR)/libcupsfilters_la-check.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/check.c' object='libcupsfilters_la-check.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-check.lo `test -f 'cupsfilters/check.c' || echo '$(srcdir)/'`cupsfilters/check.c
+
+libcupsfilters_la-cmyk.lo: cupsfilters/cmyk.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-cmyk.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-cmyk.Tpo -c -o libcupsfilters_la-cmyk.lo `test -f 'cupsfilters/cmyk.c' || echo '$(srcdir)/'`cupsfilters/cmyk.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-cmyk.Tpo $(DEPDIR)/libcupsfilters_la-cmyk.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/cmyk.c' object='libcupsfilters_la-cmyk.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-cmyk.lo `test -f 'cupsfilters/cmyk.c' || echo '$(srcdir)/'`cupsfilters/cmyk.c
+
+libcupsfilters_la-colord.lo: cupsfilters/colord.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-colord.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-colord.Tpo -c -o libcupsfilters_la-colord.lo `test -f 'cupsfilters/colord.c' || echo '$(srcdir)/'`cupsfilters/colord.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-colord.Tpo $(DEPDIR)/libcupsfilters_la-colord.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/colord.c' object='libcupsfilters_la-colord.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-colord.lo `test -f 'cupsfilters/colord.c' || echo '$(srcdir)/'`cupsfilters/colord.c
+
+libcupsfilters_la-colormanager.lo: cupsfilters/colormanager.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-colormanager.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-colormanager.Tpo -c -o libcupsfilters_la-colormanager.lo `test -f 'cupsfilters/colormanager.c' || echo '$(srcdir)/'`cupsfilters/colormanager.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-colormanager.Tpo $(DEPDIR)/libcupsfilters_la-colormanager.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/colormanager.c' object='libcupsfilters_la-colormanager.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-colormanager.lo `test -f 'cupsfilters/colormanager.c' || echo '$(srcdir)/'`cupsfilters/colormanager.c
+
+libcupsfilters_la-dither.lo: cupsfilters/dither.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-dither.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-dither.Tpo -c -o libcupsfilters_la-dither.lo `test -f 'cupsfilters/dither.c' || echo '$(srcdir)/'`cupsfilters/dither.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-dither.Tpo $(DEPDIR)/libcupsfilters_la-dither.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/dither.c' object='libcupsfilters_la-dither.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-dither.lo `test -f 'cupsfilters/dither.c' || echo '$(srcdir)/'`cupsfilters/dither.c
+
+libcupsfilters_la-image.lo: cupsfilters/image.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-image.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-image.Tpo -c -o libcupsfilters_la-image.lo `test -f 'cupsfilters/image.c' || echo '$(srcdir)/'`cupsfilters/image.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-image.Tpo $(DEPDIR)/libcupsfilters_la-image.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/image.c' object='libcupsfilters_la-image.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-image.lo `test -f 'cupsfilters/image.c' || echo '$(srcdir)/'`cupsfilters/image.c
+
+libcupsfilters_la-image-bmp.lo: cupsfilters/image-bmp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-image-bmp.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-image-bmp.Tpo -c -o libcupsfilters_la-image-bmp.lo `test -f 'cupsfilters/image-bmp.c' || echo '$(srcdir)/'`cupsfilters/image-bmp.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-image-bmp.Tpo $(DEPDIR)/libcupsfilters_la-image-bmp.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/image-bmp.c' object='libcupsfilters_la-image-bmp.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-image-bmp.lo `test -f 'cupsfilters/image-bmp.c' || echo '$(srcdir)/'`cupsfilters/image-bmp.c
+
+libcupsfilters_la-image-colorspace.lo: cupsfilters/image-colorspace.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-image-colorspace.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-image-colorspace.Tpo -c -o libcupsfilters_la-image-colorspace.lo `test -f 'cupsfilters/image-colorspace.c' || echo '$(srcdir)/'`cupsfilters/image-colorspace.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-image-colorspace.Tpo $(DEPDIR)/libcupsfilters_la-image-colorspace.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/image-colorspace.c' object='libcupsfilters_la-image-colorspace.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-image-colorspace.lo `test -f 'cupsfilters/image-colorspace.c' || echo '$(srcdir)/'`cupsfilters/image-colorspace.c
+
+libcupsfilters_la-image-gif.lo: cupsfilters/image-gif.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-image-gif.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-image-gif.Tpo -c -o libcupsfilters_la-image-gif.lo `test -f 'cupsfilters/image-gif.c' || echo '$(srcdir)/'`cupsfilters/image-gif.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-image-gif.Tpo $(DEPDIR)/libcupsfilters_la-image-gif.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/image-gif.c' object='libcupsfilters_la-image-gif.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-image-gif.lo `test -f 'cupsfilters/image-gif.c' || echo '$(srcdir)/'`cupsfilters/image-gif.c
+
+libcupsfilters_la-image-jpeg.lo: cupsfilters/image-jpeg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-image-jpeg.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-image-jpeg.Tpo -c -o libcupsfilters_la-image-jpeg.lo `test -f 'cupsfilters/image-jpeg.c' || echo '$(srcdir)/'`cupsfilters/image-jpeg.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-image-jpeg.Tpo $(DEPDIR)/libcupsfilters_la-image-jpeg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/image-jpeg.c' object='libcupsfilters_la-image-jpeg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-image-jpeg.lo `test -f 'cupsfilters/image-jpeg.c' || echo '$(srcdir)/'`cupsfilters/image-jpeg.c
+
+libcupsfilters_la-image-photocd.lo: cupsfilters/image-photocd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-image-photocd.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-image-photocd.Tpo -c -o libcupsfilters_la-image-photocd.lo `test -f 'cupsfilters/image-photocd.c' || echo '$(srcdir)/'`cupsfilters/image-photocd.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-image-photocd.Tpo $(DEPDIR)/libcupsfilters_la-image-photocd.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/image-photocd.c' object='libcupsfilters_la-image-photocd.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-image-photocd.lo `test -f 'cupsfilters/image-photocd.c' || echo '$(srcdir)/'`cupsfilters/image-photocd.c
+
+libcupsfilters_la-image-pix.lo: cupsfilters/image-pix.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-image-pix.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-image-pix.Tpo -c -o libcupsfilters_la-image-pix.lo `test -f 'cupsfilters/image-pix.c' || echo '$(srcdir)/'`cupsfilters/image-pix.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-image-pix.Tpo $(DEPDIR)/libcupsfilters_la-image-pix.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/image-pix.c' object='libcupsfilters_la-image-pix.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-image-pix.lo `test -f 'cupsfilters/image-pix.c' || echo '$(srcdir)/'`cupsfilters/image-pix.c
+
+libcupsfilters_la-image-png.lo: cupsfilters/image-png.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-image-png.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-image-png.Tpo -c -o libcupsfilters_la-image-png.lo `test -f 'cupsfilters/image-png.c' || echo '$(srcdir)/'`cupsfilters/image-png.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-image-png.Tpo $(DEPDIR)/libcupsfilters_la-image-png.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/image-png.c' object='libcupsfilters_la-image-png.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-image-png.lo `test -f 'cupsfilters/image-png.c' || echo '$(srcdir)/'`cupsfilters/image-png.c
+
+libcupsfilters_la-image-pnm.lo: cupsfilters/image-pnm.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-image-pnm.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-image-pnm.Tpo -c -o libcupsfilters_la-image-pnm.lo `test -f 'cupsfilters/image-pnm.c' || echo '$(srcdir)/'`cupsfilters/image-pnm.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-image-pnm.Tpo $(DEPDIR)/libcupsfilters_la-image-pnm.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/image-pnm.c' object='libcupsfilters_la-image-pnm.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-image-pnm.lo `test -f 'cupsfilters/image-pnm.c' || echo '$(srcdir)/'`cupsfilters/image-pnm.c
+
+libcupsfilters_la-image-sgi.lo: cupsfilters/image-sgi.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-image-sgi.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-image-sgi.Tpo -c -o libcupsfilters_la-image-sgi.lo `test -f 'cupsfilters/image-sgi.c' || echo '$(srcdir)/'`cupsfilters/image-sgi.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-image-sgi.Tpo $(DEPDIR)/libcupsfilters_la-image-sgi.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/image-sgi.c' object='libcupsfilters_la-image-sgi.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-image-sgi.lo `test -f 'cupsfilters/image-sgi.c' || echo '$(srcdir)/'`cupsfilters/image-sgi.c
+
+libcupsfilters_la-image-sgilib.lo: cupsfilters/image-sgilib.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-image-sgilib.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-image-sgilib.Tpo -c -o libcupsfilters_la-image-sgilib.lo `test -f 'cupsfilters/image-sgilib.c' || echo '$(srcdir)/'`cupsfilters/image-sgilib.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-image-sgilib.Tpo $(DEPDIR)/libcupsfilters_la-image-sgilib.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/image-sgilib.c' object='libcupsfilters_la-image-sgilib.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-image-sgilib.lo `test -f 'cupsfilters/image-sgilib.c' || echo '$(srcdir)/'`cupsfilters/image-sgilib.c
+
+libcupsfilters_la-image-sun.lo: cupsfilters/image-sun.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-image-sun.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-image-sun.Tpo -c -o libcupsfilters_la-image-sun.lo `test -f 'cupsfilters/image-sun.c' || echo '$(srcdir)/'`cupsfilters/image-sun.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-image-sun.Tpo $(DEPDIR)/libcupsfilters_la-image-sun.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/image-sun.c' object='libcupsfilters_la-image-sun.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-image-sun.lo `test -f 'cupsfilters/image-sun.c' || echo '$(srcdir)/'`cupsfilters/image-sun.c
+
+libcupsfilters_la-image-tiff.lo: cupsfilters/image-tiff.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-image-tiff.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-image-tiff.Tpo -c -o libcupsfilters_la-image-tiff.lo `test -f 'cupsfilters/image-tiff.c' || echo '$(srcdir)/'`cupsfilters/image-tiff.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-image-tiff.Tpo $(DEPDIR)/libcupsfilters_la-image-tiff.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/image-tiff.c' object='libcupsfilters_la-image-tiff.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-image-tiff.lo `test -f 'cupsfilters/image-tiff.c' || echo '$(srcdir)/'`cupsfilters/image-tiff.c
+
+libcupsfilters_la-image-zoom.lo: cupsfilters/image-zoom.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-image-zoom.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-image-zoom.Tpo -c -o libcupsfilters_la-image-zoom.lo `test -f 'cupsfilters/image-zoom.c' || echo '$(srcdir)/'`cupsfilters/image-zoom.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-image-zoom.Tpo $(DEPDIR)/libcupsfilters_la-image-zoom.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/image-zoom.c' object='libcupsfilters_la-image-zoom.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-image-zoom.lo `test -f 'cupsfilters/image-zoom.c' || echo '$(srcdir)/'`cupsfilters/image-zoom.c
+
+libcupsfilters_la-lut.lo: cupsfilters/lut.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-lut.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-lut.Tpo -c -o libcupsfilters_la-lut.lo `test -f 'cupsfilters/lut.c' || echo '$(srcdir)/'`cupsfilters/lut.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-lut.Tpo $(DEPDIR)/libcupsfilters_la-lut.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/lut.c' object='libcupsfilters_la-lut.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-lut.lo `test -f 'cupsfilters/lut.c' || echo '$(srcdir)/'`cupsfilters/lut.c
+
+libcupsfilters_la-pack.lo: cupsfilters/pack.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-pack.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-pack.Tpo -c -o libcupsfilters_la-pack.lo `test -f 'cupsfilters/pack.c' || echo '$(srcdir)/'`cupsfilters/pack.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-pack.Tpo $(DEPDIR)/libcupsfilters_la-pack.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/pack.c' object='libcupsfilters_la-pack.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-pack.lo `test -f 'cupsfilters/pack.c' || echo '$(srcdir)/'`cupsfilters/pack.c
+
+libcupsfilters_la-ppdgenerator.lo: cupsfilters/ppdgenerator.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-ppdgenerator.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-ppdgenerator.Tpo -c -o libcupsfilters_la-ppdgenerator.lo `test -f 'cupsfilters/ppdgenerator.c' || echo '$(srcdir)/'`cupsfilters/ppdgenerator.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-ppdgenerator.Tpo $(DEPDIR)/libcupsfilters_la-ppdgenerator.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/ppdgenerator.c' object='libcupsfilters_la-ppdgenerator.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-ppdgenerator.lo `test -f 'cupsfilters/ppdgenerator.c' || echo '$(srcdir)/'`cupsfilters/ppdgenerator.c
+
+libcupsfilters_la-raster.lo: cupsfilters/raster.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-raster.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-raster.Tpo -c -o libcupsfilters_la-raster.lo `test -f 'cupsfilters/raster.c' || echo '$(srcdir)/'`cupsfilters/raster.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-raster.Tpo $(DEPDIR)/libcupsfilters_la-raster.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/raster.c' object='libcupsfilters_la-raster.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-raster.lo `test -f 'cupsfilters/raster.c' || echo '$(srcdir)/'`cupsfilters/raster.c
+
+libcupsfilters_la-rgb.lo: cupsfilters/rgb.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-rgb.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-rgb.Tpo -c -o libcupsfilters_la-rgb.lo `test -f 'cupsfilters/rgb.c' || echo '$(srcdir)/'`cupsfilters/rgb.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-rgb.Tpo $(DEPDIR)/libcupsfilters_la-rgb.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/rgb.c' object='libcupsfilters_la-rgb.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-rgb.lo `test -f 'cupsfilters/rgb.c' || echo '$(srcdir)/'`cupsfilters/rgb.c
+
+libcupsfilters_la-srgb.lo: cupsfilters/srgb.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-srgb.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-srgb.Tpo -c -o libcupsfilters_la-srgb.lo `test -f 'cupsfilters/srgb.c' || echo '$(srcdir)/'`cupsfilters/srgb.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-srgb.Tpo $(DEPDIR)/libcupsfilters_la-srgb.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/srgb.c' object='libcupsfilters_la-srgb.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-srgb.lo `test -f 'cupsfilters/srgb.c' || echo '$(srcdir)/'`cupsfilters/srgb.c
+
+aglfn13.lo: fontembed/aglfn13.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT aglfn13.lo -MD -MP -MF $(DEPDIR)/aglfn13.Tpo -c -o aglfn13.lo `test -f 'fontembed/aglfn13.c' || echo '$(srcdir)/'`fontembed/aglfn13.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/aglfn13.Tpo $(DEPDIR)/aglfn13.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fontembed/aglfn13.c' object='aglfn13.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o aglfn13.lo `test -f 'fontembed/aglfn13.c' || echo '$(srcdir)/'`fontembed/aglfn13.c
+
+dynstring.lo: fontembed/dynstring.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dynstring.lo -MD -MP -MF $(DEPDIR)/dynstring.Tpo -c -o dynstring.lo `test -f 'fontembed/dynstring.c' || echo '$(srcdir)/'`fontembed/dynstring.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dynstring.Tpo $(DEPDIR)/dynstring.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fontembed/dynstring.c' object='dynstring.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dynstring.lo `test -f 'fontembed/dynstring.c' || echo '$(srcdir)/'`fontembed/dynstring.c
+
+embed.lo: fontembed/embed.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT embed.lo -MD -MP -MF $(DEPDIR)/embed.Tpo -c -o embed.lo `test -f 'fontembed/embed.c' || echo '$(srcdir)/'`fontembed/embed.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/embed.Tpo $(DEPDIR)/embed.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fontembed/embed.c' object='embed.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o embed.lo `test -f 'fontembed/embed.c' || echo '$(srcdir)/'`fontembed/embed.c
+
+embed_sfnt.lo: fontembed/embed_sfnt.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT embed_sfnt.lo -MD -MP -MF $(DEPDIR)/embed_sfnt.Tpo -c -o embed_sfnt.lo `test -f 'fontembed/embed_sfnt.c' || echo '$(srcdir)/'`fontembed/embed_sfnt.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/embed_sfnt.Tpo $(DEPDIR)/embed_sfnt.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fontembed/embed_sfnt.c' object='embed_sfnt.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o embed_sfnt.lo `test -f 'fontembed/embed_sfnt.c' || echo '$(srcdir)/'`fontembed/embed_sfnt.c
+
+embed_pdf.lo: fontembed/embed_pdf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT embed_pdf.lo -MD -MP -MF $(DEPDIR)/embed_pdf.Tpo -c -o embed_pdf.lo `test -f 'fontembed/embed_pdf.c' || echo '$(srcdir)/'`fontembed/embed_pdf.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/embed_pdf.Tpo $(DEPDIR)/embed_pdf.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fontembed/embed_pdf.c' object='embed_pdf.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o embed_pdf.lo `test -f 'fontembed/embed_pdf.c' || echo '$(srcdir)/'`fontembed/embed_pdf.c
+
+fontfile.lo: fontembed/fontfile.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fontfile.lo -MD -MP -MF $(DEPDIR)/fontfile.Tpo -c -o fontfile.lo `test -f 'fontembed/fontfile.c' || echo '$(srcdir)/'`fontembed/fontfile.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fontfile.Tpo $(DEPDIR)/fontfile.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fontembed/fontfile.c' object='fontfile.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fontfile.lo `test -f 'fontembed/fontfile.c' || echo '$(srcdir)/'`fontembed/fontfile.c
+
+frequent.lo: fontembed/frequent.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT frequent.lo -MD -MP -MF $(DEPDIR)/frequent.Tpo -c -o frequent.lo `test -f 'fontembed/frequent.c' || echo '$(srcdir)/'`fontembed/frequent.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/frequent.Tpo $(DEPDIR)/frequent.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fontembed/frequent.c' object='frequent.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o frequent.lo `test -f 'fontembed/frequent.c' || echo '$(srcdir)/'`fontembed/frequent.c
+
+sfnt.lo: fontembed/sfnt.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sfnt.lo -MD -MP -MF $(DEPDIR)/sfnt.Tpo -c -o sfnt.lo `test -f 'fontembed/sfnt.c' || echo '$(srcdir)/'`fontembed/sfnt.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/sfnt.Tpo $(DEPDIR)/sfnt.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fontembed/sfnt.c' object='sfnt.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sfnt.lo `test -f 'fontembed/sfnt.c' || echo '$(srcdir)/'`fontembed/sfnt.c
+
+sfnt_subset.lo: fontembed/sfnt_subset.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sfnt_subset.lo -MD -MP -MF $(DEPDIR)/sfnt_subset.Tpo -c -o sfnt_subset.lo `test -f 'fontembed/sfnt_subset.c' || echo '$(srcdir)/'`fontembed/sfnt_subset.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/sfnt_subset.Tpo $(DEPDIR)/sfnt_subset.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fontembed/sfnt_subset.c' object='sfnt_subset.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sfnt_subset.lo `test -f 'fontembed/sfnt_subset.c' || echo '$(srcdir)/'`fontembed/sfnt_subset.c
+
+libphpcups_la-phpcups.lo: scripting/php/phpcups.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libphpcups_la_CFLAGS) $(CFLAGS) -MT libphpcups_la-phpcups.lo -MD -MP -MF $(DEPDIR)/libphpcups_la-phpcups.Tpo -c -o libphpcups_la-phpcups.lo `test -f 'scripting/php/phpcups.c' || echo '$(srcdir)/'`scripting/php/phpcups.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libphpcups_la-phpcups.Tpo $(DEPDIR)/libphpcups_la-phpcups.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scripting/php/phpcups.c' object='libphpcups_la-phpcups.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libphpcups_la_CFLAGS) $(CFLAGS) -c -o libphpcups_la-phpcups.lo `test -f 'scripting/php/phpcups.c' || echo '$(srcdir)/'`scripting/php/phpcups.c
+
+bannertopdf-banner.o: filter/banner.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bannertopdf_CFLAGS) $(CFLAGS) -MT bannertopdf-banner.o -MD -MP -MF $(DEPDIR)/bannertopdf-banner.Tpo -c -o bannertopdf-banner.o `test -f 'filter/banner.c' || echo '$(srcdir)/'`filter/banner.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bannertopdf-banner.Tpo $(DEPDIR)/bannertopdf-banner.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/banner.c' object='bannertopdf-banner.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bannertopdf_CFLAGS) $(CFLAGS) -c -o bannertopdf-banner.o `test -f 'filter/banner.c' || echo '$(srcdir)/'`filter/banner.c
+
+bannertopdf-banner.obj: filter/banner.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bannertopdf_CFLAGS) $(CFLAGS) -MT bannertopdf-banner.obj -MD -MP -MF $(DEPDIR)/bannertopdf-banner.Tpo -c -o bannertopdf-banner.obj `if test -f 'filter/banner.c'; then $(CYGPATH_W) 'filter/banner.c'; else $(CYGPATH_W) '$(srcdir)/filter/banner.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bannertopdf-banner.Tpo $(DEPDIR)/bannertopdf-banner.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/banner.c' object='bannertopdf-banner.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bannertopdf_CFLAGS) $(CFLAGS) -c -o bannertopdf-banner.obj `if test -f 'filter/banner.c'; then $(CYGPATH_W) 'filter/banner.c'; else $(CYGPATH_W) '$(srcdir)/filter/banner.c'; fi`
+
+bannertopdf-bannertopdf.o: filter/bannertopdf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bannertopdf_CFLAGS) $(CFLAGS) -MT bannertopdf-bannertopdf.o -MD -MP -MF $(DEPDIR)/bannertopdf-bannertopdf.Tpo -c -o bannertopdf-bannertopdf.o `test -f 'filter/bannertopdf.c' || echo '$(srcdir)/'`filter/bannertopdf.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bannertopdf-bannertopdf.Tpo $(DEPDIR)/bannertopdf-bannertopdf.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/bannertopdf.c' object='bannertopdf-bannertopdf.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bannertopdf_CFLAGS) $(CFLAGS) -c -o bannertopdf-bannertopdf.o `test -f 'filter/bannertopdf.c' || echo '$(srcdir)/'`filter/bannertopdf.c
+
+bannertopdf-bannertopdf.obj: filter/bannertopdf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bannertopdf_CFLAGS) $(CFLAGS) -MT bannertopdf-bannertopdf.obj -MD -MP -MF $(DEPDIR)/bannertopdf-bannertopdf.Tpo -c -o bannertopdf-bannertopdf.obj `if test -f 'filter/bannertopdf.c'; then $(CYGPATH_W) 'filter/bannertopdf.c'; else $(CYGPATH_W) '$(srcdir)/filter/bannertopdf.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bannertopdf-bannertopdf.Tpo $(DEPDIR)/bannertopdf-bannertopdf.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/bannertopdf.c' object='bannertopdf-bannertopdf.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bannertopdf_CFLAGS) $(CFLAGS) -c -o bannertopdf-bannertopdf.obj `if test -f 'filter/bannertopdf.c'; then $(CYGPATH_W) 'filter/bannertopdf.c'; else $(CYGPATH_W) '$(srcdir)/filter/bannertopdf.c'; fi`
+
+bannertopdf-getline.o: filter/getline.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bannertopdf_CFLAGS) $(CFLAGS) -MT bannertopdf-getline.o -MD -MP -MF $(DEPDIR)/bannertopdf-getline.Tpo -c -o bannertopdf-getline.o `test -f 'filter/getline.c' || echo '$(srcdir)/'`filter/getline.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bannertopdf-getline.Tpo $(DEPDIR)/bannertopdf-getline.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/getline.c' object='bannertopdf-getline.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bannertopdf_CFLAGS) $(CFLAGS) -c -o bannertopdf-getline.o `test -f 'filter/getline.c' || echo '$(srcdir)/'`filter/getline.c
+
+bannertopdf-getline.obj: filter/getline.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bannertopdf_CFLAGS) $(CFLAGS) -MT bannertopdf-getline.obj -MD -MP -MF $(DEPDIR)/bannertopdf-getline.Tpo -c -o bannertopdf-getline.obj `if test -f 'filter/getline.c'; then $(CYGPATH_W) 'filter/getline.c'; else $(CYGPATH_W) '$(srcdir)/filter/getline.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bannertopdf-getline.Tpo $(DEPDIR)/bannertopdf-getline.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/getline.c' object='bannertopdf-getline.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bannertopdf_CFLAGS) $(CFLAGS) -c -o bannertopdf-getline.obj `if test -f 'filter/getline.c'; then $(CYGPATH_W) 'filter/getline.c'; else $(CYGPATH_W) '$(srcdir)/filter/getline.c'; fi`
+
+beh-beh.o: backend/beh.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(beh_CFLAGS) $(CFLAGS) -MT beh-beh.o -MD -MP -MF $(DEPDIR)/beh-beh.Tpo -c -o beh-beh.o `test -f 'backend/beh.c' || echo '$(srcdir)/'`backend/beh.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/beh-beh.Tpo $(DEPDIR)/beh-beh.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend/beh.c' object='beh-beh.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(beh_CFLAGS) $(CFLAGS) -c -o beh-beh.o `test -f 'backend/beh.c' || echo '$(srcdir)/'`backend/beh.c
+
+beh-beh.obj: backend/beh.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(beh_CFLAGS) $(CFLAGS) -MT beh-beh.obj -MD -MP -MF $(DEPDIR)/beh-beh.Tpo -c -o beh-beh.obj `if test -f 'backend/beh.c'; then $(CYGPATH_W) 'backend/beh.c'; else $(CYGPATH_W) '$(srcdir)/backend/beh.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/beh-beh.Tpo $(DEPDIR)/beh-beh.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend/beh.c' object='beh-beh.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(beh_CFLAGS) $(CFLAGS) -c -o beh-beh.obj `if test -f 'backend/beh.c'; then $(CYGPATH_W) 'backend/beh.c'; else $(CYGPATH_W) '$(srcdir)/backend/beh.c'; fi`
+
+commandtoescpx-commandtoescpx.o: filter/commandtoescpx.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(commandtoescpx_CFLAGS) $(CFLAGS) -MT commandtoescpx-commandtoescpx.o -MD -MP -MF $(DEPDIR)/commandtoescpx-commandtoescpx.Tpo -c -o commandtoescpx-commandtoescpx.o `test -f 'filter/commandtoescpx.c' || echo '$(srcdir)/'`filter/commandtoescpx.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/commandtoescpx-commandtoescpx.Tpo $(DEPDIR)/commandtoescpx-commandtoescpx.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/commandtoescpx.c' object='commandtoescpx-commandtoescpx.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(commandtoescpx_CFLAGS) $(CFLAGS) -c -o commandtoescpx-commandtoescpx.o `test -f 'filter/commandtoescpx.c' || echo '$(srcdir)/'`filter/commandtoescpx.c
+
+commandtoescpx-commandtoescpx.obj: filter/commandtoescpx.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(commandtoescpx_CFLAGS) $(CFLAGS) -MT commandtoescpx-commandtoescpx.obj -MD -MP -MF $(DEPDIR)/commandtoescpx-commandtoescpx.Tpo -c -o commandtoescpx-commandtoescpx.obj `if test -f 'filter/commandtoescpx.c'; then $(CYGPATH_W) 'filter/commandtoescpx.c'; else $(CYGPATH_W) '$(srcdir)/filter/commandtoescpx.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/commandtoescpx-commandtoescpx.Tpo $(DEPDIR)/commandtoescpx-commandtoescpx.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/commandtoescpx.c' object='commandtoescpx-commandtoescpx.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(commandtoescpx_CFLAGS) $(CFLAGS) -c -o commandtoescpx-commandtoescpx.obj `if test -f 'filter/commandtoescpx.c'; then $(CYGPATH_W) 'filter/commandtoescpx.c'; else $(CYGPATH_W) '$(srcdir)/filter/commandtoescpx.c'; fi`
+
+commandtopclx-commandtopclx.o: filter/commandtopclx.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(commandtopclx_CFLAGS) $(CFLAGS) -MT commandtopclx-commandtopclx.o -MD -MP -MF $(DEPDIR)/commandtopclx-commandtopclx.Tpo -c -o commandtopclx-commandtopclx.o `test -f 'filter/commandtopclx.c' || echo '$(srcdir)/'`filter/commandtopclx.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/commandtopclx-commandtopclx.Tpo $(DEPDIR)/commandtopclx-commandtopclx.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/commandtopclx.c' object='commandtopclx-commandtopclx.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(commandtopclx_CFLAGS) $(CFLAGS) -c -o commandtopclx-commandtopclx.o `test -f 'filter/commandtopclx.c' || echo '$(srcdir)/'`filter/commandtopclx.c
+
+commandtopclx-commandtopclx.obj: filter/commandtopclx.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(commandtopclx_CFLAGS) $(CFLAGS) -MT commandtopclx-commandtopclx.obj -MD -MP -MF $(DEPDIR)/commandtopclx-commandtopclx.Tpo -c -o commandtopclx-commandtopclx.obj `if test -f 'filter/commandtopclx.c'; then $(CYGPATH_W) 'filter/commandtopclx.c'; else $(CYGPATH_W) '$(srcdir)/filter/commandtopclx.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/commandtopclx-commandtopclx.Tpo $(DEPDIR)/commandtopclx-commandtopclx.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/commandtopclx.c' object='commandtopclx-commandtopclx.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(commandtopclx_CFLAGS) $(CFLAGS) -c -o commandtopclx-commandtopclx.obj `if test -f 'filter/commandtopclx.c'; then $(CYGPATH_W) 'filter/commandtopclx.c'; else $(CYGPATH_W) '$(srcdir)/filter/commandtopclx.c'; fi`
+
+cups-brf.o: backend/cups-brf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cups-brf.o -MD -MP -MF $(DEPDIR)/cups-brf.Tpo -c -o cups-brf.o `test -f 'backend/cups-brf.c' || echo '$(srcdir)/'`backend/cups-brf.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cups-brf.Tpo $(DEPDIR)/cups-brf.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend/cups-brf.c' object='cups-brf.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cups-brf.o `test -f 'backend/cups-brf.c' || echo '$(srcdir)/'`backend/cups-brf.c
+
+cups-brf.obj: backend/cups-brf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cups-brf.obj -MD -MP -MF $(DEPDIR)/cups-brf.Tpo -c -o cups-brf.obj `if test -f 'backend/cups-brf.c'; then $(CYGPATH_W) 'backend/cups-brf.c'; else $(CYGPATH_W) '$(srcdir)/backend/cups-brf.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cups-brf.Tpo $(DEPDIR)/cups-brf.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend/cups-brf.c' object='cups-brf.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cups-brf.obj `if test -f 'backend/cups-brf.c'; then $(CYGPATH_W) 'backend/cups-brf.c'; else $(CYGPATH_W) '$(srcdir)/backend/cups-brf.c'; fi`
+
+cups_browsed-cups-browsed.o: utils/cups-browsed.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cups_browsed_CFLAGS) $(CFLAGS) -MT cups_browsed-cups-browsed.o -MD -MP -MF $(DEPDIR)/cups_browsed-cups-browsed.Tpo -c -o cups_browsed-cups-browsed.o `test -f 'utils/cups-browsed.c' || echo '$(srcdir)/'`utils/cups-browsed.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cups_browsed-cups-browsed.Tpo $(DEPDIR)/cups_browsed-cups-browsed.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils/cups-browsed.c' object='cups_browsed-cups-browsed.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cups_browsed_CFLAGS) $(CFLAGS) -c -o cups_browsed-cups-browsed.o `test -f 'utils/cups-browsed.c' || echo '$(srcdir)/'`utils/cups-browsed.c
+
+cups_browsed-cups-browsed.obj: utils/cups-browsed.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cups_browsed_CFLAGS) $(CFLAGS) -MT cups_browsed-cups-browsed.obj -MD -MP -MF $(DEPDIR)/cups_browsed-cups-browsed.Tpo -c -o cups_browsed-cups-browsed.obj `if test -f 'utils/cups-browsed.c'; then $(CYGPATH_W) 'utils/cups-browsed.c'; else $(CYGPATH_W) '$(srcdir)/utils/cups-browsed.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cups_browsed-cups-browsed.Tpo $(DEPDIR)/cups_browsed-cups-browsed.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils/cups-browsed.c' object='cups_browsed-cups-browsed.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cups_browsed_CFLAGS) $(CFLAGS) -c -o cups_browsed-cups-browsed.obj `if test -f 'utils/cups-browsed.c'; then $(CYGPATH_W) 'utils/cups-browsed.c'; else $(CYGPATH_W) '$(srcdir)/utils/cups-browsed.c'; fi`
+
+cups_browsed-cups-notifier.o: cups-notifier.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cups_browsed_CFLAGS) $(CFLAGS) -MT cups_browsed-cups-notifier.o -MD -MP -MF $(DEPDIR)/cups_browsed-cups-notifier.Tpo -c -o cups_browsed-cups-notifier.o `test -f 'cups-notifier.c' || echo '$(srcdir)/'`cups-notifier.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cups_browsed-cups-notifier.Tpo $(DEPDIR)/cups_browsed-cups-notifier.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cups-notifier.c' object='cups_browsed-cups-notifier.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cups_browsed_CFLAGS) $(CFLAGS) -c -o cups_browsed-cups-notifier.o `test -f 'cups-notifier.c' || echo '$(srcdir)/'`cups-notifier.c
+
+cups_browsed-cups-notifier.obj: cups-notifier.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cups_browsed_CFLAGS) $(CFLAGS) -MT cups_browsed-cups-notifier.obj -MD -MP -MF $(DEPDIR)/cups_browsed-cups-notifier.Tpo -c -o cups_browsed-cups-notifier.obj `if test -f 'cups-notifier.c'; then $(CYGPATH_W) 'cups-notifier.c'; else $(CYGPATH_W) '$(srcdir)/cups-notifier.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cups_browsed-cups-notifier.Tpo $(DEPDIR)/cups_browsed-cups-notifier.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cups-notifier.c' object='cups_browsed-cups-notifier.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cups_browsed_CFLAGS) $(CFLAGS) -c -o cups_browsed-cups-notifier.obj `if test -f 'cups-notifier.c'; then $(CYGPATH_W) 'cups-notifier.c'; else $(CYGPATH_W) '$(srcdir)/cups-notifier.c'; fi`
+
+driverless-driverless.o: utils/driverless.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driverless_CFLAGS) $(CFLAGS) -MT driverless-driverless.o -MD -MP -MF $(DEPDIR)/driverless-driverless.Tpo -c -o driverless-driverless.o `test -f 'utils/driverless.c' || echo '$(srcdir)/'`utils/driverless.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/driverless-driverless.Tpo $(DEPDIR)/driverless-driverless.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils/driverless.c' object='driverless-driverless.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driverless_CFLAGS) $(CFLAGS) -c -o driverless-driverless.o `test -f 'utils/driverless.c' || echo '$(srcdir)/'`utils/driverless.c
+
+driverless-driverless.obj: utils/driverless.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driverless_CFLAGS) $(CFLAGS) -MT driverless-driverless.obj -MD -MP -MF $(DEPDIR)/driverless-driverless.Tpo -c -o driverless-driverless.obj `if test -f 'utils/driverless.c'; then $(CYGPATH_W) 'utils/driverless.c'; else $(CYGPATH_W) '$(srcdir)/utils/driverless.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/driverless-driverless.Tpo $(DEPDIR)/driverless-driverless.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils/driverless.c' object='driverless-driverless.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driverless_CFLAGS) $(CFLAGS) -c -o driverless-driverless.obj `if test -f 'utils/driverless.c'; then $(CYGPATH_W) 'utils/driverless.c'; else $(CYGPATH_W) '$(srcdir)/utils/driverless.c'; fi`
+
+foomatic_rip-foomaticrip.o: filter/foomatic-rip/foomaticrip.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-foomaticrip.o -MD -MP -MF $(DEPDIR)/foomatic_rip-foomaticrip.Tpo -c -o foomatic_rip-foomaticrip.o `test -f 'filter/foomatic-rip/foomaticrip.c' || echo '$(srcdir)/'`filter/foomatic-rip/foomaticrip.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/foomatic_rip-foomaticrip.Tpo $(DEPDIR)/foomatic_rip-foomaticrip.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/foomatic-rip/foomaticrip.c' object='foomatic_rip-foomaticrip.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-foomaticrip.o `test -f 'filter/foomatic-rip/foomaticrip.c' || echo '$(srcdir)/'`filter/foomatic-rip/foomaticrip.c
+
+foomatic_rip-foomaticrip.obj: filter/foomatic-rip/foomaticrip.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-foomaticrip.obj -MD -MP -MF $(DEPDIR)/foomatic_rip-foomaticrip.Tpo -c -o foomatic_rip-foomaticrip.obj `if test -f 'filter/foomatic-rip/foomaticrip.c'; then $(CYGPATH_W) 'filter/foomatic-rip/foomaticrip.c'; else $(CYGPATH_W) '$(srcdir)/filter/foomatic-rip/foomaticrip.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/foomatic_rip-foomaticrip.Tpo $(DEPDIR)/foomatic_rip-foomaticrip.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/foomatic-rip/foomaticrip.c' object='foomatic_rip-foomaticrip.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-foomaticrip.obj `if test -f 'filter/foomatic-rip/foomaticrip.c'; then $(CYGPATH_W) 'filter/foomatic-rip/foomaticrip.c'; else $(CYGPATH_W) '$(srcdir)/filter/foomatic-rip/foomaticrip.c'; fi`
+
+foomatic_rip-options.o: filter/foomatic-rip/options.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-options.o -MD -MP -MF $(DEPDIR)/foomatic_rip-options.Tpo -c -o foomatic_rip-options.o `test -f 'filter/foomatic-rip/options.c' || echo '$(srcdir)/'`filter/foomatic-rip/options.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/foomatic_rip-options.Tpo $(DEPDIR)/foomatic_rip-options.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/foomatic-rip/options.c' object='foomatic_rip-options.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-options.o `test -f 'filter/foomatic-rip/options.c' || echo '$(srcdir)/'`filter/foomatic-rip/options.c
+
+foomatic_rip-options.obj: filter/foomatic-rip/options.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-options.obj -MD -MP -MF $(DEPDIR)/foomatic_rip-options.Tpo -c -o foomatic_rip-options.obj `if test -f 'filter/foomatic-rip/options.c'; then $(CYGPATH_W) 'filter/foomatic-rip/options.c'; else $(CYGPATH_W) '$(srcdir)/filter/foomatic-rip/options.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/foomatic_rip-options.Tpo $(DEPDIR)/foomatic_rip-options.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/foomatic-rip/options.c' object='foomatic_rip-options.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-options.obj `if test -f 'filter/foomatic-rip/options.c'; then $(CYGPATH_W) 'filter/foomatic-rip/options.c'; else $(CYGPATH_W) '$(srcdir)/filter/foomatic-rip/options.c'; fi`
+
+foomatic_rip-pdf.o: filter/foomatic-rip/pdf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-pdf.o -MD -MP -MF $(DEPDIR)/foomatic_rip-pdf.Tpo -c -o foomatic_rip-pdf.o `test -f 'filter/foomatic-rip/pdf.c' || echo '$(srcdir)/'`filter/foomatic-rip/pdf.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/foomatic_rip-pdf.Tpo $(DEPDIR)/foomatic_rip-pdf.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/foomatic-rip/pdf.c' object='foomatic_rip-pdf.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-pdf.o `test -f 'filter/foomatic-rip/pdf.c' || echo '$(srcdir)/'`filter/foomatic-rip/pdf.c
+
+foomatic_rip-pdf.obj: filter/foomatic-rip/pdf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-pdf.obj -MD -MP -MF $(DEPDIR)/foomatic_rip-pdf.Tpo -c -o foomatic_rip-pdf.obj `if test -f 'filter/foomatic-rip/pdf.c'; then $(CYGPATH_W) 'filter/foomatic-rip/pdf.c'; else $(CYGPATH_W) '$(srcdir)/filter/foomatic-rip/pdf.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/foomatic_rip-pdf.Tpo $(DEPDIR)/foomatic_rip-pdf.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/foomatic-rip/pdf.c' object='foomatic_rip-pdf.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-pdf.obj `if test -f 'filter/foomatic-rip/pdf.c'; then $(CYGPATH_W) 'filter/foomatic-rip/pdf.c'; else $(CYGPATH_W) '$(srcdir)/filter/foomatic-rip/pdf.c'; fi`
+
+foomatic_rip-postscript.o: filter/foomatic-rip/postscript.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-postscript.o -MD -MP -MF $(DEPDIR)/foomatic_rip-postscript.Tpo -c -o foomatic_rip-postscript.o `test -f 'filter/foomatic-rip/postscript.c' || echo '$(srcdir)/'`filter/foomatic-rip/postscript.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/foomatic_rip-postscript.Tpo $(DEPDIR)/foomatic_rip-postscript.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/foomatic-rip/postscript.c' object='foomatic_rip-postscript.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-postscript.o `test -f 'filter/foomatic-rip/postscript.c' || echo '$(srcdir)/'`filter/foomatic-rip/postscript.c
+
+foomatic_rip-postscript.obj: filter/foomatic-rip/postscript.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-postscript.obj -MD -MP -MF $(DEPDIR)/foomatic_rip-postscript.Tpo -c -o foomatic_rip-postscript.obj `if test -f 'filter/foomatic-rip/postscript.c'; then $(CYGPATH_W) 'filter/foomatic-rip/postscript.c'; else $(CYGPATH_W) '$(srcdir)/filter/foomatic-rip/postscript.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/foomatic_rip-postscript.Tpo $(DEPDIR)/foomatic_rip-postscript.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/foomatic-rip/postscript.c' object='foomatic_rip-postscript.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-postscript.obj `if test -f 'filter/foomatic-rip/postscript.c'; then $(CYGPATH_W) 'filter/foomatic-rip/postscript.c'; else $(CYGPATH_W) '$(srcdir)/filter/foomatic-rip/postscript.c'; fi`
+
+foomatic_rip-process.o: filter/foomatic-rip/process.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-process.o -MD -MP -MF $(DEPDIR)/foomatic_rip-process.Tpo -c -o foomatic_rip-process.o `test -f 'filter/foomatic-rip/process.c' || echo '$(srcdir)/'`filter/foomatic-rip/process.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/foomatic_rip-process.Tpo $(DEPDIR)/foomatic_rip-process.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/foomatic-rip/process.c' object='foomatic_rip-process.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-process.o `test -f 'filter/foomatic-rip/process.c' || echo '$(srcdir)/'`filter/foomatic-rip/process.c
+
+foomatic_rip-process.obj: filter/foomatic-rip/process.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-process.obj -MD -MP -MF $(DEPDIR)/foomatic_rip-process.Tpo -c -o foomatic_rip-process.obj `if test -f 'filter/foomatic-rip/process.c'; then $(CYGPATH_W) 'filter/foomatic-rip/process.c'; else $(CYGPATH_W) '$(srcdir)/filter/foomatic-rip/process.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/foomatic_rip-process.Tpo $(DEPDIR)/foomatic_rip-process.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/foomatic-rip/process.c' object='foomatic_rip-process.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-process.obj `if test -f 'filter/foomatic-rip/process.c'; then $(CYGPATH_W) 'filter/foomatic-rip/process.c'; else $(CYGPATH_W) '$(srcdir)/filter/foomatic-rip/process.c'; fi`
+
+foomatic_rip-renderer.o: filter/foomatic-rip/renderer.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-renderer.o -MD -MP -MF $(DEPDIR)/foomatic_rip-renderer.Tpo -c -o foomatic_rip-renderer.o `test -f 'filter/foomatic-rip/renderer.c' || echo '$(srcdir)/'`filter/foomatic-rip/renderer.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/foomatic_rip-renderer.Tpo $(DEPDIR)/foomatic_rip-renderer.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/foomatic-rip/renderer.c' object='foomatic_rip-renderer.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-renderer.o `test -f 'filter/foomatic-rip/renderer.c' || echo '$(srcdir)/'`filter/foomatic-rip/renderer.c
+
+foomatic_rip-renderer.obj: filter/foomatic-rip/renderer.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-renderer.obj -MD -MP -MF $(DEPDIR)/foomatic_rip-renderer.Tpo -c -o foomatic_rip-renderer.obj `if test -f 'filter/foomatic-rip/renderer.c'; then $(CYGPATH_W) 'filter/foomatic-rip/renderer.c'; else $(CYGPATH_W) '$(srcdir)/filter/foomatic-rip/renderer.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/foomatic_rip-renderer.Tpo $(DEPDIR)/foomatic_rip-renderer.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/foomatic-rip/renderer.c' object='foomatic_rip-renderer.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-renderer.obj `if test -f 'filter/foomatic-rip/renderer.c'; then $(CYGPATH_W) 'filter/foomatic-rip/renderer.c'; else $(CYGPATH_W) '$(srcdir)/filter/foomatic-rip/renderer.c'; fi`
+
+foomatic_rip-spooler.o: filter/foomatic-rip/spooler.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-spooler.o -MD -MP -MF $(DEPDIR)/foomatic_rip-spooler.Tpo -c -o foomatic_rip-spooler.o `test -f 'filter/foomatic-rip/spooler.c' || echo '$(srcdir)/'`filter/foomatic-rip/spooler.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/foomatic_rip-spooler.Tpo $(DEPDIR)/foomatic_rip-spooler.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/foomatic-rip/spooler.c' object='foomatic_rip-spooler.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-spooler.o `test -f 'filter/foomatic-rip/spooler.c' || echo '$(srcdir)/'`filter/foomatic-rip/spooler.c
+
+foomatic_rip-spooler.obj: filter/foomatic-rip/spooler.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-spooler.obj -MD -MP -MF $(DEPDIR)/foomatic_rip-spooler.Tpo -c -o foomatic_rip-spooler.obj `if test -f 'filter/foomatic-rip/spooler.c'; then $(CYGPATH_W) 'filter/foomatic-rip/spooler.c'; else $(CYGPATH_W) '$(srcdir)/filter/foomatic-rip/spooler.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/foomatic_rip-spooler.Tpo $(DEPDIR)/foomatic_rip-spooler.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/foomatic-rip/spooler.c' object='foomatic_rip-spooler.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-spooler.obj `if test -f 'filter/foomatic-rip/spooler.c'; then $(CYGPATH_W) 'filter/foomatic-rip/spooler.c'; else $(CYGPATH_W) '$(srcdir)/filter/foomatic-rip/spooler.c'; fi`
+
+foomatic_rip-util.o: filter/foomatic-rip/util.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-util.o -MD -MP -MF $(DEPDIR)/foomatic_rip-util.Tpo -c -o foomatic_rip-util.o `test -f 'filter/foomatic-rip/util.c' || echo '$(srcdir)/'`filter/foomatic-rip/util.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/foomatic_rip-util.Tpo $(DEPDIR)/foomatic_rip-util.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/foomatic-rip/util.c' object='foomatic_rip-util.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-util.o `test -f 'filter/foomatic-rip/util.c' || echo '$(srcdir)/'`filter/foomatic-rip/util.c
+
+foomatic_rip-util.obj: filter/foomatic-rip/util.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -MT foomatic_rip-util.obj -MD -MP -MF $(DEPDIR)/foomatic_rip-util.Tpo -c -o foomatic_rip-util.obj `if test -f 'filter/foomatic-rip/util.c'; then $(CYGPATH_W) 'filter/foomatic-rip/util.c'; else $(CYGPATH_W) '$(srcdir)/filter/foomatic-rip/util.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/foomatic_rip-util.Tpo $(DEPDIR)/foomatic_rip-util.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/foomatic-rip/util.c' object='foomatic_rip-util.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(foomatic_rip_CFLAGS) $(CFLAGS) -c -o foomatic_rip-util.obj `if test -f 'filter/foomatic-rip/util.c'; then $(CYGPATH_W) 'filter/foomatic-rip/util.c'; else $(CYGPATH_W) '$(srcdir)/filter/foomatic-rip/util.c'; fi`
+
+gstoraster-gstoraster.o: filter/gstoraster.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gstoraster_CFLAGS) $(CFLAGS) -MT gstoraster-gstoraster.o -MD -MP -MF $(DEPDIR)/gstoraster-gstoraster.Tpo -c -o gstoraster-gstoraster.o `test -f 'filter/gstoraster.c' || echo '$(srcdir)/'`filter/gstoraster.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gstoraster-gstoraster.Tpo $(DEPDIR)/gstoraster-gstoraster.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/gstoraster.c' object='gstoraster-gstoraster.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gstoraster_CFLAGS) $(CFLAGS) -c -o gstoraster-gstoraster.o `test -f 'filter/gstoraster.c' || echo '$(srcdir)/'`filter/gstoraster.c
+
+gstoraster-gstoraster.obj: filter/gstoraster.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gstoraster_CFLAGS) $(CFLAGS) -MT gstoraster-gstoraster.obj -MD -MP -MF $(DEPDIR)/gstoraster-gstoraster.Tpo -c -o gstoraster-gstoraster.obj `if test -f 'filter/gstoraster.c'; then $(CYGPATH_W) 'filter/gstoraster.c'; else $(CYGPATH_W) '$(srcdir)/filter/gstoraster.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gstoraster-gstoraster.Tpo $(DEPDIR)/gstoraster-gstoraster.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/gstoraster.c' object='gstoraster-gstoraster.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gstoraster_CFLAGS) $(CFLAGS) -c -o gstoraster-gstoraster.obj `if test -f 'filter/gstoraster.c'; then $(CYGPATH_W) 'filter/gstoraster.c'; else $(CYGPATH_W) '$(srcdir)/filter/gstoraster.c'; fi`
+
+imagetopdf-common.o: filter/common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imagetopdf_CFLAGS) $(CFLAGS) -MT imagetopdf-common.o -MD -MP -MF $(DEPDIR)/imagetopdf-common.Tpo -c -o imagetopdf-common.o `test -f 'filter/common.c' || echo '$(srcdir)/'`filter/common.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imagetopdf-common.Tpo $(DEPDIR)/imagetopdf-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/common.c' object='imagetopdf-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imagetopdf_CFLAGS) $(CFLAGS) -c -o imagetopdf-common.o `test -f 'filter/common.c' || echo '$(srcdir)/'`filter/common.c
+
+imagetopdf-common.obj: filter/common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imagetopdf_CFLAGS) $(CFLAGS) -MT imagetopdf-common.obj -MD -MP -MF $(DEPDIR)/imagetopdf-common.Tpo -c -o imagetopdf-common.obj `if test -f 'filter/common.c'; then $(CYGPATH_W) 'filter/common.c'; else $(CYGPATH_W) '$(srcdir)/filter/common.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imagetopdf-common.Tpo $(DEPDIR)/imagetopdf-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/common.c' object='imagetopdf-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imagetopdf_CFLAGS) $(CFLAGS) -c -o imagetopdf-common.obj `if test -f 'filter/common.c'; then $(CYGPATH_W) 'filter/common.c'; else $(CYGPATH_W) '$(srcdir)/filter/common.c'; fi`
+
+imagetopdf-imagetopdf.o: filter/imagetopdf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imagetopdf_CFLAGS) $(CFLAGS) -MT imagetopdf-imagetopdf.o -MD -MP -MF $(DEPDIR)/imagetopdf-imagetopdf.Tpo -c -o imagetopdf-imagetopdf.o `test -f 'filter/imagetopdf.c' || echo '$(srcdir)/'`filter/imagetopdf.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imagetopdf-imagetopdf.Tpo $(DEPDIR)/imagetopdf-imagetopdf.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/imagetopdf.c' object='imagetopdf-imagetopdf.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imagetopdf_CFLAGS) $(CFLAGS) -c -o imagetopdf-imagetopdf.o `test -f 'filter/imagetopdf.c' || echo '$(srcdir)/'`filter/imagetopdf.c
+
+imagetopdf-imagetopdf.obj: filter/imagetopdf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imagetopdf_CFLAGS) $(CFLAGS) -MT imagetopdf-imagetopdf.obj -MD -MP -MF $(DEPDIR)/imagetopdf-imagetopdf.Tpo -c -o imagetopdf-imagetopdf.obj `if test -f 'filter/imagetopdf.c'; then $(CYGPATH_W) 'filter/imagetopdf.c'; else $(CYGPATH_W) '$(srcdir)/filter/imagetopdf.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imagetopdf-imagetopdf.Tpo $(DEPDIR)/imagetopdf-imagetopdf.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/imagetopdf.c' object='imagetopdf-imagetopdf.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imagetopdf_CFLAGS) $(CFLAGS) -c -o imagetopdf-imagetopdf.obj `if test -f 'filter/imagetopdf.c'; then $(CYGPATH_W) 'filter/imagetopdf.c'; else $(CYGPATH_W) '$(srcdir)/filter/imagetopdf.c'; fi`
+
+imagetoraster-common.o: filter/common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imagetoraster_CFLAGS) $(CFLAGS) -MT imagetoraster-common.o -MD -MP -MF $(DEPDIR)/imagetoraster-common.Tpo -c -o imagetoraster-common.o `test -f 'filter/common.c' || echo '$(srcdir)/'`filter/common.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imagetoraster-common.Tpo $(DEPDIR)/imagetoraster-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/common.c' object='imagetoraster-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imagetoraster_CFLAGS) $(CFLAGS) -c -o imagetoraster-common.o `test -f 'filter/common.c' || echo '$(srcdir)/'`filter/common.c
+
+imagetoraster-common.obj: filter/common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imagetoraster_CFLAGS) $(CFLAGS) -MT imagetoraster-common.obj -MD -MP -MF $(DEPDIR)/imagetoraster-common.Tpo -c -o imagetoraster-common.obj `if test -f 'filter/common.c'; then $(CYGPATH_W) 'filter/common.c'; else $(CYGPATH_W) '$(srcdir)/filter/common.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imagetoraster-common.Tpo $(DEPDIR)/imagetoraster-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/common.c' object='imagetoraster-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imagetoraster_CFLAGS) $(CFLAGS) -c -o imagetoraster-common.obj `if test -f 'filter/common.c'; then $(CYGPATH_W) 'filter/common.c'; else $(CYGPATH_W) '$(srcdir)/filter/common.c'; fi`
+
+imagetoraster-imagetoraster.o: filter/imagetoraster.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imagetoraster_CFLAGS) $(CFLAGS) -MT imagetoraster-imagetoraster.o -MD -MP -MF $(DEPDIR)/imagetoraster-imagetoraster.Tpo -c -o imagetoraster-imagetoraster.o `test -f 'filter/imagetoraster.c' || echo '$(srcdir)/'`filter/imagetoraster.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imagetoraster-imagetoraster.Tpo $(DEPDIR)/imagetoraster-imagetoraster.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/imagetoraster.c' object='imagetoraster-imagetoraster.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imagetoraster_CFLAGS) $(CFLAGS) -c -o imagetoraster-imagetoraster.o `test -f 'filter/imagetoraster.c' || echo '$(srcdir)/'`filter/imagetoraster.c
+
+imagetoraster-imagetoraster.obj: filter/imagetoraster.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imagetoraster_CFLAGS) $(CFLAGS) -MT imagetoraster-imagetoraster.obj -MD -MP -MF $(DEPDIR)/imagetoraster-imagetoraster.Tpo -c -o imagetoraster-imagetoraster.obj `if test -f 'filter/imagetoraster.c'; then $(CYGPATH_W) 'filter/imagetoraster.c'; else $(CYGPATH_W) '$(srcdir)/filter/imagetoraster.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imagetoraster-imagetoraster.Tpo $(DEPDIR)/imagetoraster-imagetoraster.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/imagetoraster.c' object='imagetoraster-imagetoraster.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imagetoraster_CFLAGS) $(CFLAGS) -c -o imagetoraster-imagetoraster.obj `if test -f 'filter/imagetoraster.c'; then $(CYGPATH_W) 'filter/imagetoraster.c'; else $(CYGPATH_W) '$(srcdir)/filter/imagetoraster.c'; fi`
+
+implicitclass-implicitclass.o: backend/implicitclass.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(implicitclass_CFLAGS) $(CFLAGS) -MT implicitclass-implicitclass.o -MD -MP -MF $(DEPDIR)/implicitclass-implicitclass.Tpo -c -o implicitclass-implicitclass.o `test -f 'backend/implicitclass.c' || echo '$(srcdir)/'`backend/implicitclass.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/implicitclass-implicitclass.Tpo $(DEPDIR)/implicitclass-implicitclass.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend/implicitclass.c' object='implicitclass-implicitclass.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(implicitclass_CFLAGS) $(CFLAGS) -c -o implicitclass-implicitclass.o `test -f 'backend/implicitclass.c' || echo '$(srcdir)/'`backend/implicitclass.c
+
+implicitclass-implicitclass.obj: backend/implicitclass.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(implicitclass_CFLAGS) $(CFLAGS) -MT implicitclass-implicitclass.obj -MD -MP -MF $(DEPDIR)/implicitclass-implicitclass.Tpo -c -o implicitclass-implicitclass.obj `if test -f 'backend/implicitclass.c'; then $(CYGPATH_W) 'backend/implicitclass.c'; else $(CYGPATH_W) '$(srcdir)/backend/implicitclass.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/implicitclass-implicitclass.Tpo $(DEPDIR)/implicitclass-implicitclass.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend/implicitclass.c' object='implicitclass-implicitclass.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(implicitclass_CFLAGS) $(CFLAGS) -c -o implicitclass-implicitclass.obj `if test -f 'backend/implicitclass.c'; then $(CYGPATH_W) 'backend/implicitclass.c'; else $(CYGPATH_W) '$(srcdir)/backend/implicitclass.c'; fi`
+
+mupdftoraster-mupdftoraster.o: filter/mupdftoraster.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mupdftoraster_CFLAGS) $(CFLAGS) -MT mupdftoraster-mupdftoraster.o -MD -MP -MF $(DEPDIR)/mupdftoraster-mupdftoraster.Tpo -c -o mupdftoraster-mupdftoraster.o `test -f 'filter/mupdftoraster.c' || echo '$(srcdir)/'`filter/mupdftoraster.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mupdftoraster-mupdftoraster.Tpo $(DEPDIR)/mupdftoraster-mupdftoraster.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/mupdftoraster.c' object='mupdftoraster-mupdftoraster.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mupdftoraster_CFLAGS) $(CFLAGS) -c -o mupdftoraster-mupdftoraster.o `test -f 'filter/mupdftoraster.c' || echo '$(srcdir)/'`filter/mupdftoraster.c
+
+mupdftoraster-mupdftoraster.obj: filter/mupdftoraster.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mupdftoraster_CFLAGS) $(CFLAGS) -MT mupdftoraster-mupdftoraster.obj -MD -MP -MF $(DEPDIR)/mupdftoraster-mupdftoraster.Tpo -c -o mupdftoraster-mupdftoraster.obj `if test -f 'filter/mupdftoraster.c'; then $(CYGPATH_W) 'filter/mupdftoraster.c'; else $(CYGPATH_W) '$(srcdir)/filter/mupdftoraster.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mupdftoraster-mupdftoraster.Tpo $(DEPDIR)/mupdftoraster-mupdftoraster.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/mupdftoraster.c' object='mupdftoraster-mupdftoraster.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mupdftoraster_CFLAGS) $(CFLAGS) -c -o mupdftoraster-mupdftoraster.obj `if test -f 'filter/mupdftoraster.c'; then $(CYGPATH_W) 'filter/mupdftoraster.c'; else $(CYGPATH_W) '$(srcdir)/filter/mupdftoraster.c'; fi`
+
+parallel-ieee1284.o: backend/ieee1284.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(parallel_CFLAGS) $(CFLAGS) -MT parallel-ieee1284.o -MD -MP -MF $(DEPDIR)/parallel-ieee1284.Tpo -c -o parallel-ieee1284.o `test -f 'backend/ieee1284.c' || echo '$(srcdir)/'`backend/ieee1284.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/parallel-ieee1284.Tpo $(DEPDIR)/parallel-ieee1284.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend/ieee1284.c' object='parallel-ieee1284.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(parallel_CFLAGS) $(CFLAGS) -c -o parallel-ieee1284.o `test -f 'backend/ieee1284.c' || echo '$(srcdir)/'`backend/ieee1284.c
+
+parallel-ieee1284.obj: backend/ieee1284.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(parallel_CFLAGS) $(CFLAGS) -MT parallel-ieee1284.obj -MD -MP -MF $(DEPDIR)/parallel-ieee1284.Tpo -c -o parallel-ieee1284.obj `if test -f 'backend/ieee1284.c'; then $(CYGPATH_W) 'backend/ieee1284.c'; else $(CYGPATH_W) '$(srcdir)/backend/ieee1284.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/parallel-ieee1284.Tpo $(DEPDIR)/parallel-ieee1284.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend/ieee1284.c' object='parallel-ieee1284.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(parallel_CFLAGS) $(CFLAGS) -c -o parallel-ieee1284.obj `if test -f 'backend/ieee1284.c'; then $(CYGPATH_W) 'backend/ieee1284.c'; else $(CYGPATH_W) '$(srcdir)/backend/ieee1284.c'; fi`
+
+parallel-parallel.o: backend/parallel.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(parallel_CFLAGS) $(CFLAGS) -MT parallel-parallel.o -MD -MP -MF $(DEPDIR)/parallel-parallel.Tpo -c -o parallel-parallel.o `test -f 'backend/parallel.c' || echo '$(srcdir)/'`backend/parallel.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/parallel-parallel.Tpo $(DEPDIR)/parallel-parallel.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend/parallel.c' object='parallel-parallel.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(parallel_CFLAGS) $(CFLAGS) -c -o parallel-parallel.o `test -f 'backend/parallel.c' || echo '$(srcdir)/'`backend/parallel.c
+
+parallel-parallel.obj: backend/parallel.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(parallel_CFLAGS) $(CFLAGS) -MT parallel-parallel.obj -MD -MP -MF $(DEPDIR)/parallel-parallel.Tpo -c -o parallel-parallel.obj `if test -f 'backend/parallel.c'; then $(CYGPATH_W) 'backend/parallel.c'; else $(CYGPATH_W) '$(srcdir)/backend/parallel.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/parallel-parallel.Tpo $(DEPDIR)/parallel-parallel.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend/parallel.c' object='parallel-parallel.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(parallel_CFLAGS) $(CFLAGS) -c -o parallel-parallel.obj `if test -f 'backend/parallel.c'; then $(CYGPATH_W) 'backend/parallel.c'; else $(CYGPATH_W) '$(srcdir)/backend/parallel.c'; fi`
+
+pdftops-common.o: filter/common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftops_CFLAGS) $(CFLAGS) -MT pdftops-common.o -MD -MP -MF $(DEPDIR)/pdftops-common.Tpo -c -o pdftops-common.o `test -f 'filter/common.c' || echo '$(srcdir)/'`filter/common.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftops-common.Tpo $(DEPDIR)/pdftops-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/common.c' object='pdftops-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftops_CFLAGS) $(CFLAGS) -c -o pdftops-common.o `test -f 'filter/common.c' || echo '$(srcdir)/'`filter/common.c
+
+pdftops-common.obj: filter/common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftops_CFLAGS) $(CFLAGS) -MT pdftops-common.obj -MD -MP -MF $(DEPDIR)/pdftops-common.Tpo -c -o pdftops-common.obj `if test -f 'filter/common.c'; then $(CYGPATH_W) 'filter/common.c'; else $(CYGPATH_W) '$(srcdir)/filter/common.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftops-common.Tpo $(DEPDIR)/pdftops-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/common.c' object='pdftops-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftops_CFLAGS) $(CFLAGS) -c -o pdftops-common.obj `if test -f 'filter/common.c'; then $(CYGPATH_W) 'filter/common.c'; else $(CYGPATH_W) '$(srcdir)/filter/common.c'; fi`
+
+pdftops-pdftops.o: filter/pdftops.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftops_CFLAGS) $(CFLAGS) -MT pdftops-pdftops.o -MD -MP -MF $(DEPDIR)/pdftops-pdftops.Tpo -c -o pdftops-pdftops.o `test -f 'filter/pdftops.c' || echo '$(srcdir)/'`filter/pdftops.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftops-pdftops.Tpo $(DEPDIR)/pdftops-pdftops.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/pdftops.c' object='pdftops-pdftops.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftops_CFLAGS) $(CFLAGS) -c -o pdftops-pdftops.o `test -f 'filter/pdftops.c' || echo '$(srcdir)/'`filter/pdftops.c
+
+pdftops-pdftops.obj: filter/pdftops.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftops_CFLAGS) $(CFLAGS) -MT pdftops-pdftops.obj -MD -MP -MF $(DEPDIR)/pdftops-pdftops.Tpo -c -o pdftops-pdftops.obj `if test -f 'filter/pdftops.c'; then $(CYGPATH_W) 'filter/pdftops.c'; else $(CYGPATH_W) '$(srcdir)/filter/pdftops.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftops-pdftops.Tpo $(DEPDIR)/pdftops-pdftops.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/pdftops.c' object='pdftops-pdftops.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftops_CFLAGS) $(CFLAGS) -c -o pdftops-pdftops.obj `if test -f 'filter/pdftops.c'; then $(CYGPATH_W) 'filter/pdftops.c'; else $(CYGPATH_W) '$(srcdir)/filter/pdftops.c'; fi`
+
+pdftops-strcasestr.o: filter/strcasestr.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftops_CFLAGS) $(CFLAGS) -MT pdftops-strcasestr.o -MD -MP -MF $(DEPDIR)/pdftops-strcasestr.Tpo -c -o pdftops-strcasestr.o `test -f 'filter/strcasestr.c' || echo '$(srcdir)/'`filter/strcasestr.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftops-strcasestr.Tpo $(DEPDIR)/pdftops-strcasestr.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/strcasestr.c' object='pdftops-strcasestr.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftops_CFLAGS) $(CFLAGS) -c -o pdftops-strcasestr.o `test -f 'filter/strcasestr.c' || echo '$(srcdir)/'`filter/strcasestr.c
+
+pdftops-strcasestr.obj: filter/strcasestr.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftops_CFLAGS) $(CFLAGS) -MT pdftops-strcasestr.obj -MD -MP -MF $(DEPDIR)/pdftops-strcasestr.Tpo -c -o pdftops-strcasestr.obj `if test -f 'filter/strcasestr.c'; then $(CYGPATH_W) 'filter/strcasestr.c'; else $(CYGPATH_W) '$(srcdir)/filter/strcasestr.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftops-strcasestr.Tpo $(DEPDIR)/pdftops-strcasestr.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/strcasestr.c' object='pdftops-strcasestr.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftops_CFLAGS) $(CFLAGS) -c -o pdftops-strcasestr.obj `if test -f 'filter/strcasestr.c'; then $(CYGPATH_W) 'filter/strcasestr.c'; else $(CYGPATH_W) '$(srcdir)/filter/strcasestr.c'; fi`
+
+rastertoescpx-rastertoescpx.o: filter/rastertoescpx.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rastertoescpx_CFLAGS) $(CFLAGS) -MT rastertoescpx-rastertoescpx.o -MD -MP -MF $(DEPDIR)/rastertoescpx-rastertoescpx.Tpo -c -o rastertoescpx-rastertoescpx.o `test -f 'filter/rastertoescpx.c' || echo '$(srcdir)/'`filter/rastertoescpx.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rastertoescpx-rastertoescpx.Tpo $(DEPDIR)/rastertoescpx-rastertoescpx.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/rastertoescpx.c' object='rastertoescpx-rastertoescpx.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rastertoescpx_CFLAGS) $(CFLAGS) -c -o rastertoescpx-rastertoescpx.o `test -f 'filter/rastertoescpx.c' || echo '$(srcdir)/'`filter/rastertoescpx.c
+
+rastertoescpx-rastertoescpx.obj: filter/rastertoescpx.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rastertoescpx_CFLAGS) $(CFLAGS) -MT rastertoescpx-rastertoescpx.obj -MD -MP -MF $(DEPDIR)/rastertoescpx-rastertoescpx.Tpo -c -o rastertoescpx-rastertoescpx.obj `if test -f 'filter/rastertoescpx.c'; then $(CYGPATH_W) 'filter/rastertoescpx.c'; else $(CYGPATH_W) '$(srcdir)/filter/rastertoescpx.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rastertoescpx-rastertoescpx.Tpo $(DEPDIR)/rastertoescpx-rastertoescpx.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/rastertoescpx.c' object='rastertoescpx-rastertoescpx.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rastertoescpx_CFLAGS) $(CFLAGS) -c -o rastertoescpx-rastertoescpx.obj `if test -f 'filter/rastertoescpx.c'; then $(CYGPATH_W) 'filter/rastertoescpx.c'; else $(CYGPATH_W) '$(srcdir)/filter/rastertoescpx.c'; fi`
+
+rastertopclx-pcl-common.o: filter/pcl-common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rastertopclx_CFLAGS) $(CFLAGS) -MT rastertopclx-pcl-common.o -MD -MP -MF $(DEPDIR)/rastertopclx-pcl-common.Tpo -c -o rastertopclx-pcl-common.o `test -f 'filter/pcl-common.c' || echo '$(srcdir)/'`filter/pcl-common.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rastertopclx-pcl-common.Tpo $(DEPDIR)/rastertopclx-pcl-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/pcl-common.c' object='rastertopclx-pcl-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rastertopclx_CFLAGS) $(CFLAGS) -c -o rastertopclx-pcl-common.o `test -f 'filter/pcl-common.c' || echo '$(srcdir)/'`filter/pcl-common.c
+
+rastertopclx-pcl-common.obj: filter/pcl-common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rastertopclx_CFLAGS) $(CFLAGS) -MT rastertopclx-pcl-common.obj -MD -MP -MF $(DEPDIR)/rastertopclx-pcl-common.Tpo -c -o rastertopclx-pcl-common.obj `if test -f 'filter/pcl-common.c'; then $(CYGPATH_W) 'filter/pcl-common.c'; else $(CYGPATH_W) '$(srcdir)/filter/pcl-common.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rastertopclx-pcl-common.Tpo $(DEPDIR)/rastertopclx-pcl-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/pcl-common.c' object='rastertopclx-pcl-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rastertopclx_CFLAGS) $(CFLAGS) -c -o rastertopclx-pcl-common.obj `if test -f 'filter/pcl-common.c'; then $(CYGPATH_W) 'filter/pcl-common.c'; else $(CYGPATH_W) '$(srcdir)/filter/pcl-common.c'; fi`
+
+rastertopclx-rastertopclx.o: filter/rastertopclx.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rastertopclx_CFLAGS) $(CFLAGS) -MT rastertopclx-rastertopclx.o -MD -MP -MF $(DEPDIR)/rastertopclx-rastertopclx.Tpo -c -o rastertopclx-rastertopclx.o `test -f 'filter/rastertopclx.c' || echo '$(srcdir)/'`filter/rastertopclx.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rastertopclx-rastertopclx.Tpo $(DEPDIR)/rastertopclx-rastertopclx.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/rastertopclx.c' object='rastertopclx-rastertopclx.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rastertopclx_CFLAGS) $(CFLAGS) -c -o rastertopclx-rastertopclx.o `test -f 'filter/rastertopclx.c' || echo '$(srcdir)/'`filter/rastertopclx.c
+
+rastertopclx-rastertopclx.obj: filter/rastertopclx.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rastertopclx_CFLAGS) $(CFLAGS) -MT rastertopclx-rastertopclx.obj -MD -MP -MF $(DEPDIR)/rastertopclx-rastertopclx.Tpo -c -o rastertopclx-rastertopclx.obj `if test -f 'filter/rastertopclx.c'; then $(CYGPATH_W) 'filter/rastertopclx.c'; else $(CYGPATH_W) '$(srcdir)/filter/rastertopclx.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rastertopclx-rastertopclx.Tpo $(DEPDIR)/rastertopclx-rastertopclx.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/rastertopclx.c' object='rastertopclx-rastertopclx.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rastertopclx_CFLAGS) $(CFLAGS) -c -o rastertopclx-rastertopclx.obj `if test -f 'filter/rastertopclx.c'; then $(CYGPATH_W) 'filter/rastertopclx.c'; else $(CYGPATH_W) '$(srcdir)/filter/rastertopclx.c'; fi`
+
+rastertops-rastertops.o: filter/rastertops.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rastertops_CFLAGS) $(CFLAGS) -MT rastertops-rastertops.o -MD -MP -MF $(DEPDIR)/rastertops-rastertops.Tpo -c -o rastertops-rastertops.o `test -f 'filter/rastertops.c' || echo '$(srcdir)/'`filter/rastertops.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rastertops-rastertops.Tpo $(DEPDIR)/rastertops-rastertops.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/rastertops.c' object='rastertops-rastertops.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rastertops_CFLAGS) $(CFLAGS) -c -o rastertops-rastertops.o `test -f 'filter/rastertops.c' || echo '$(srcdir)/'`filter/rastertops.c
+
+rastertops-rastertops.obj: filter/rastertops.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rastertops_CFLAGS) $(CFLAGS) -MT rastertops-rastertops.obj -MD -MP -MF $(DEPDIR)/rastertops-rastertops.Tpo -c -o rastertops-rastertops.obj `if test -f 'filter/rastertops.c'; then $(CYGPATH_W) 'filter/rastertops.c'; else $(CYGPATH_W) '$(srcdir)/filter/rastertops.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rastertops-rastertops.Tpo $(DEPDIR)/rastertops-rastertops.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/rastertops.c' object='rastertops-rastertops.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rastertops_CFLAGS) $(CFLAGS) -c -o rastertops-rastertops.obj `if test -f 'filter/rastertops.c'; then $(CYGPATH_W) 'filter/rastertops.c'; else $(CYGPATH_W) '$(srcdir)/filter/rastertops.c'; fi`
+
+serial-serial.o: backend/serial.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(serial_CFLAGS) $(CFLAGS) -MT serial-serial.o -MD -MP -MF $(DEPDIR)/serial-serial.Tpo -c -o serial-serial.o `test -f 'backend/serial.c' || echo '$(srcdir)/'`backend/serial.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/serial-serial.Tpo $(DEPDIR)/serial-serial.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend/serial.c' object='serial-serial.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(serial_CFLAGS) $(CFLAGS) -c -o serial-serial.o `test -f 'backend/serial.c' || echo '$(srcdir)/'`backend/serial.c
+
+serial-serial.obj: backend/serial.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(serial_CFLAGS) $(CFLAGS) -MT serial-serial.obj -MD -MP -MF $(DEPDIR)/serial-serial.Tpo -c -o serial-serial.obj `if test -f 'backend/serial.c'; then $(CYGPATH_W) 'backend/serial.c'; else $(CYGPATH_W) '$(srcdir)/backend/serial.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/serial-serial.Tpo $(DEPDIR)/serial-serial.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend/serial.c' object='serial-serial.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(serial_CFLAGS) $(CFLAGS) -c -o serial-serial.obj `if test -f 'backend/serial.c'; then $(CYGPATH_W) 'backend/serial.c'; else $(CYGPATH_W) '$(srcdir)/backend/serial.c'; fi`
+
+sys5ippprinter-common.o: filter/common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sys5ippprinter_CFLAGS) $(CFLAGS) -MT sys5ippprinter-common.o -MD -MP -MF $(DEPDIR)/sys5ippprinter-common.Tpo -c -o sys5ippprinter-common.o `test -f 'filter/common.c' || echo '$(srcdir)/'`filter/common.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/sys5ippprinter-common.Tpo $(DEPDIR)/sys5ippprinter-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/common.c' object='sys5ippprinter-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sys5ippprinter_CFLAGS) $(CFLAGS) -c -o sys5ippprinter-common.o `test -f 'filter/common.c' || echo '$(srcdir)/'`filter/common.c
+
+sys5ippprinter-common.obj: filter/common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sys5ippprinter_CFLAGS) $(CFLAGS) -MT sys5ippprinter-common.obj -MD -MP -MF $(DEPDIR)/sys5ippprinter-common.Tpo -c -o sys5ippprinter-common.obj `if test -f 'filter/common.c'; then $(CYGPATH_W) 'filter/common.c'; else $(CYGPATH_W) '$(srcdir)/filter/common.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/sys5ippprinter-common.Tpo $(DEPDIR)/sys5ippprinter-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/common.c' object='sys5ippprinter-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sys5ippprinter_CFLAGS) $(CFLAGS) -c -o sys5ippprinter-common.obj `if test -f 'filter/common.c'; then $(CYGPATH_W) 'filter/common.c'; else $(CYGPATH_W) '$(srcdir)/filter/common.c'; fi`
+
+sys5ippprinter-sys5ippprinter.o: filter/sys5ippprinter.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sys5ippprinter_CFLAGS) $(CFLAGS) -MT sys5ippprinter-sys5ippprinter.o -MD -MP -MF $(DEPDIR)/sys5ippprinter-sys5ippprinter.Tpo -c -o sys5ippprinter-sys5ippprinter.o `test -f 'filter/sys5ippprinter.c' || echo '$(srcdir)/'`filter/sys5ippprinter.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/sys5ippprinter-sys5ippprinter.Tpo $(DEPDIR)/sys5ippprinter-sys5ippprinter.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/sys5ippprinter.c' object='sys5ippprinter-sys5ippprinter.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sys5ippprinter_CFLAGS) $(CFLAGS) -c -o sys5ippprinter-sys5ippprinter.o `test -f 'filter/sys5ippprinter.c' || echo '$(srcdir)/'`filter/sys5ippprinter.c
+
+sys5ippprinter-sys5ippprinter.obj: filter/sys5ippprinter.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sys5ippprinter_CFLAGS) $(CFLAGS) -MT sys5ippprinter-sys5ippprinter.obj -MD -MP -MF $(DEPDIR)/sys5ippprinter-sys5ippprinter.Tpo -c -o sys5ippprinter-sys5ippprinter.obj `if test -f 'filter/sys5ippprinter.c'; then $(CYGPATH_W) 'filter/sys5ippprinter.c'; else $(CYGPATH_W) '$(srcdir)/filter/sys5ippprinter.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/sys5ippprinter-sys5ippprinter.Tpo $(DEPDIR)/sys5ippprinter-sys5ippprinter.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/sys5ippprinter.c' object='sys5ippprinter-sys5ippprinter.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sys5ippprinter_CFLAGS) $(CFLAGS) -c -o sys5ippprinter-sys5ippprinter.obj `if test -f 'filter/sys5ippprinter.c'; then $(CYGPATH_W) 'filter/sys5ippprinter.c'; else $(CYGPATH_W) '$(srcdir)/filter/sys5ippprinter.c'; fi`
+
+sys5ippprinter-strcasestr.o: filter/strcasestr.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sys5ippprinter_CFLAGS) $(CFLAGS) -MT sys5ippprinter-strcasestr.o -MD -MP -MF $(DEPDIR)/sys5ippprinter-strcasestr.Tpo -c -o sys5ippprinter-strcasestr.o `test -f 'filter/strcasestr.c' || echo '$(srcdir)/'`filter/strcasestr.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/sys5ippprinter-strcasestr.Tpo $(DEPDIR)/sys5ippprinter-strcasestr.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/strcasestr.c' object='sys5ippprinter-strcasestr.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sys5ippprinter_CFLAGS) $(CFLAGS) -c -o sys5ippprinter-strcasestr.o `test -f 'filter/strcasestr.c' || echo '$(srcdir)/'`filter/strcasestr.c
+
+sys5ippprinter-strcasestr.obj: filter/strcasestr.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sys5ippprinter_CFLAGS) $(CFLAGS) -MT sys5ippprinter-strcasestr.obj -MD -MP -MF $(DEPDIR)/sys5ippprinter-strcasestr.Tpo -c -o sys5ippprinter-strcasestr.obj `if test -f 'filter/strcasestr.c'; then $(CYGPATH_W) 'filter/strcasestr.c'; else $(CYGPATH_W) '$(srcdir)/filter/strcasestr.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/sys5ippprinter-strcasestr.Tpo $(DEPDIR)/sys5ippprinter-strcasestr.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/strcasestr.c' object='sys5ippprinter-strcasestr.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sys5ippprinter_CFLAGS) $(CFLAGS) -c -o sys5ippprinter-strcasestr.obj `if test -f 'filter/strcasestr.c'; then $(CYGPATH_W) 'filter/strcasestr.c'; else $(CYGPATH_W) '$(srcdir)/filter/strcasestr.c'; fi`
+
+test1284-ieee1284.o: backend/ieee1284.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test1284_CFLAGS) $(CFLAGS) -MT test1284-ieee1284.o -MD -MP -MF $(DEPDIR)/test1284-ieee1284.Tpo -c -o test1284-ieee1284.o `test -f 'backend/ieee1284.c' || echo '$(srcdir)/'`backend/ieee1284.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test1284-ieee1284.Tpo $(DEPDIR)/test1284-ieee1284.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend/ieee1284.c' object='test1284-ieee1284.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test1284_CFLAGS) $(CFLAGS) -c -o test1284-ieee1284.o `test -f 'backend/ieee1284.c' || echo '$(srcdir)/'`backend/ieee1284.c
+
+test1284-ieee1284.obj: backend/ieee1284.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test1284_CFLAGS) $(CFLAGS) -MT test1284-ieee1284.obj -MD -MP -MF $(DEPDIR)/test1284-ieee1284.Tpo -c -o test1284-ieee1284.obj `if test -f 'backend/ieee1284.c'; then $(CYGPATH_W) 'backend/ieee1284.c'; else $(CYGPATH_W) '$(srcdir)/backend/ieee1284.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test1284-ieee1284.Tpo $(DEPDIR)/test1284-ieee1284.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend/ieee1284.c' object='test1284-ieee1284.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test1284_CFLAGS) $(CFLAGS) -c -o test1284-ieee1284.obj `if test -f 'backend/ieee1284.c'; then $(CYGPATH_W) 'backend/ieee1284.c'; else $(CYGPATH_W) '$(srcdir)/backend/ieee1284.c'; fi`
+
+test1284-test1284.o: backend/test1284.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test1284_CFLAGS) $(CFLAGS) -MT test1284-test1284.o -MD -MP -MF $(DEPDIR)/test1284-test1284.Tpo -c -o test1284-test1284.o `test -f 'backend/test1284.c' || echo '$(srcdir)/'`backend/test1284.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test1284-test1284.Tpo $(DEPDIR)/test1284-test1284.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend/test1284.c' object='test1284-test1284.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test1284_CFLAGS) $(CFLAGS) -c -o test1284-test1284.o `test -f 'backend/test1284.c' || echo '$(srcdir)/'`backend/test1284.c
+
+test1284-test1284.obj: backend/test1284.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test1284_CFLAGS) $(CFLAGS) -MT test1284-test1284.obj -MD -MP -MF $(DEPDIR)/test1284-test1284.Tpo -c -o test1284-test1284.obj `if test -f 'backend/test1284.c'; then $(CYGPATH_W) 'backend/test1284.c'; else $(CYGPATH_W) '$(srcdir)/backend/test1284.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test1284-test1284.Tpo $(DEPDIR)/test1284-test1284.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backend/test1284.c' object='test1284-test1284.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test1284_CFLAGS) $(CFLAGS) -c -o test1284-test1284.obj `if test -f 'backend/test1284.c'; then $(CYGPATH_W) 'backend/test1284.c'; else $(CYGPATH_W) '$(srcdir)/backend/test1284.c'; fi`
+
+test_analyze.o: fontembed/test_analyze.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_analyze.o -MD -MP -MF $(DEPDIR)/test_analyze.Tpo -c -o test_analyze.o `test -f 'fontembed/test_analyze.c' || echo '$(srcdir)/'`fontembed/test_analyze.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_analyze.Tpo $(DEPDIR)/test_analyze.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fontembed/test_analyze.c' object='test_analyze.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_analyze.o `test -f 'fontembed/test_analyze.c' || echo '$(srcdir)/'`fontembed/test_analyze.c
+
+test_analyze.obj: fontembed/test_analyze.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_analyze.obj -MD -MP -MF $(DEPDIR)/test_analyze.Tpo -c -o test_analyze.obj `if test -f 'fontembed/test_analyze.c'; then $(CYGPATH_W) 'fontembed/test_analyze.c'; else $(CYGPATH_W) '$(srcdir)/fontembed/test_analyze.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_analyze.Tpo $(DEPDIR)/test_analyze.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fontembed/test_analyze.c' object='test_analyze.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_analyze.obj `if test -f 'fontembed/test_analyze.c'; then $(CYGPATH_W) 'fontembed/test_analyze.c'; else $(CYGPATH_W) '$(srcdir)/fontembed/test_analyze.c'; fi`
+
+test_pdf.o: fontembed/test_pdf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_pdf.o -MD -MP -MF $(DEPDIR)/test_pdf.Tpo -c -o test_pdf.o `test -f 'fontembed/test_pdf.c' || echo '$(srcdir)/'`fontembed/test_pdf.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_pdf.Tpo $(DEPDIR)/test_pdf.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fontembed/test_pdf.c' object='test_pdf.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_pdf.o `test -f 'fontembed/test_pdf.c' || echo '$(srcdir)/'`fontembed/test_pdf.c
+
+test_pdf.obj: fontembed/test_pdf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_pdf.obj -MD -MP -MF $(DEPDIR)/test_pdf.Tpo -c -o test_pdf.obj `if test -f 'fontembed/test_pdf.c'; then $(CYGPATH_W) 'fontembed/test_pdf.c'; else $(CYGPATH_W) '$(srcdir)/fontembed/test_pdf.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_pdf.Tpo $(DEPDIR)/test_pdf.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fontembed/test_pdf.c' object='test_pdf.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_pdf.obj `if test -f 'fontembed/test_pdf.c'; then $(CYGPATH_W) 'fontembed/test_pdf.c'; else $(CYGPATH_W) '$(srcdir)/fontembed/test_pdf.c'; fi`
+
+test_pdf1-pdfutils.o: filter/pdfutils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_pdf1_CFLAGS) $(CFLAGS) -MT test_pdf1-pdfutils.o -MD -MP -MF $(DEPDIR)/test_pdf1-pdfutils.Tpo -c -o test_pdf1-pdfutils.o `test -f 'filter/pdfutils.c' || echo '$(srcdir)/'`filter/pdfutils.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_pdf1-pdfutils.Tpo $(DEPDIR)/test_pdf1-pdfutils.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/pdfutils.c' object='test_pdf1-pdfutils.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_pdf1_CFLAGS) $(CFLAGS) -c -o test_pdf1-pdfutils.o `test -f 'filter/pdfutils.c' || echo '$(srcdir)/'`filter/pdfutils.c
+
+test_pdf1-pdfutils.obj: filter/pdfutils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_pdf1_CFLAGS) $(CFLAGS) -MT test_pdf1-pdfutils.obj -MD -MP -MF $(DEPDIR)/test_pdf1-pdfutils.Tpo -c -o test_pdf1-pdfutils.obj `if test -f 'filter/pdfutils.c'; then $(CYGPATH_W) 'filter/pdfutils.c'; else $(CYGPATH_W) '$(srcdir)/filter/pdfutils.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_pdf1-pdfutils.Tpo $(DEPDIR)/test_pdf1-pdfutils.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/pdfutils.c' object='test_pdf1-pdfutils.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_pdf1_CFLAGS) $(CFLAGS) -c -o test_pdf1-pdfutils.obj `if test -f 'filter/pdfutils.c'; then $(CYGPATH_W) 'filter/pdfutils.c'; else $(CYGPATH_W) '$(srcdir)/filter/pdfutils.c'; fi`
+
+test_pdf1-test_pdf1.o: filter/test_pdf1.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_pdf1_CFLAGS) $(CFLAGS) -MT test_pdf1-test_pdf1.o -MD -MP -MF $(DEPDIR)/test_pdf1-test_pdf1.Tpo -c -o test_pdf1-test_pdf1.o `test -f 'filter/test_pdf1.c' || echo '$(srcdir)/'`filter/test_pdf1.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_pdf1-test_pdf1.Tpo $(DEPDIR)/test_pdf1-test_pdf1.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/test_pdf1.c' object='test_pdf1-test_pdf1.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_pdf1_CFLAGS) $(CFLAGS) -c -o test_pdf1-test_pdf1.o `test -f 'filter/test_pdf1.c' || echo '$(srcdir)/'`filter/test_pdf1.c
+
+test_pdf1-test_pdf1.obj: filter/test_pdf1.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_pdf1_CFLAGS) $(CFLAGS) -MT test_pdf1-test_pdf1.obj -MD -MP -MF $(DEPDIR)/test_pdf1-test_pdf1.Tpo -c -o test_pdf1-test_pdf1.obj `if test -f 'filter/test_pdf1.c'; then $(CYGPATH_W) 'filter/test_pdf1.c'; else $(CYGPATH_W) '$(srcdir)/filter/test_pdf1.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_pdf1-test_pdf1.Tpo $(DEPDIR)/test_pdf1-test_pdf1.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/test_pdf1.c' object='test_pdf1-test_pdf1.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_pdf1_CFLAGS) $(CFLAGS) -c -o test_pdf1-test_pdf1.obj `if test -f 'filter/test_pdf1.c'; then $(CYGPATH_W) 'filter/test_pdf1.c'; else $(CYGPATH_W) '$(srcdir)/filter/test_pdf1.c'; fi`
+
+test_pdf2-pdfutils.o: filter/pdfutils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_pdf2_CFLAGS) $(CFLAGS) -MT test_pdf2-pdfutils.o -MD -MP -MF $(DEPDIR)/test_pdf2-pdfutils.Tpo -c -o test_pdf2-pdfutils.o `test -f 'filter/pdfutils.c' || echo '$(srcdir)/'`filter/pdfutils.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_pdf2-pdfutils.Tpo $(DEPDIR)/test_pdf2-pdfutils.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/pdfutils.c' object='test_pdf2-pdfutils.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_pdf2_CFLAGS) $(CFLAGS) -c -o test_pdf2-pdfutils.o `test -f 'filter/pdfutils.c' || echo '$(srcdir)/'`filter/pdfutils.c
+
+test_pdf2-pdfutils.obj: filter/pdfutils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_pdf2_CFLAGS) $(CFLAGS) -MT test_pdf2-pdfutils.obj -MD -MP -MF $(DEPDIR)/test_pdf2-pdfutils.Tpo -c -o test_pdf2-pdfutils.obj `if test -f 'filter/pdfutils.c'; then $(CYGPATH_W) 'filter/pdfutils.c'; else $(CYGPATH_W) '$(srcdir)/filter/pdfutils.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_pdf2-pdfutils.Tpo $(DEPDIR)/test_pdf2-pdfutils.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/pdfutils.c' object='test_pdf2-pdfutils.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_pdf2_CFLAGS) $(CFLAGS) -c -o test_pdf2-pdfutils.obj `if test -f 'filter/pdfutils.c'; then $(CYGPATH_W) 'filter/pdfutils.c'; else $(CYGPATH_W) '$(srcdir)/filter/pdfutils.c'; fi`
+
+test_pdf2-test_pdf2.o: filter/test_pdf2.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_pdf2_CFLAGS) $(CFLAGS) -MT test_pdf2-test_pdf2.o -MD -MP -MF $(DEPDIR)/test_pdf2-test_pdf2.Tpo -c -o test_pdf2-test_pdf2.o `test -f 'filter/test_pdf2.c' || echo '$(srcdir)/'`filter/test_pdf2.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_pdf2-test_pdf2.Tpo $(DEPDIR)/test_pdf2-test_pdf2.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/test_pdf2.c' object='test_pdf2-test_pdf2.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_pdf2_CFLAGS) $(CFLAGS) -c -o test_pdf2-test_pdf2.o `test -f 'filter/test_pdf2.c' || echo '$(srcdir)/'`filter/test_pdf2.c
+
+test_pdf2-test_pdf2.obj: filter/test_pdf2.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_pdf2_CFLAGS) $(CFLAGS) -MT test_pdf2-test_pdf2.obj -MD -MP -MF $(DEPDIR)/test_pdf2-test_pdf2.Tpo -c -o test_pdf2-test_pdf2.obj `if test -f 'filter/test_pdf2.c'; then $(CYGPATH_W) 'filter/test_pdf2.c'; else $(CYGPATH_W) '$(srcdir)/filter/test_pdf2.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_pdf2-test_pdf2.Tpo $(DEPDIR)/test_pdf2-test_pdf2.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/test_pdf2.c' object='test_pdf2-test_pdf2.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_pdf2_CFLAGS) $(CFLAGS) -c -o test_pdf2-test_pdf2.obj `if test -f 'filter/test_pdf2.c'; then $(CYGPATH_W) 'filter/test_pdf2.c'; else $(CYGPATH_W) '$(srcdir)/filter/test_pdf2.c'; fi`
+
+test_ps.o: fontembed/test_ps.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_ps.o -MD -MP -MF $(DEPDIR)/test_ps.Tpo -c -o test_ps.o `test -f 'fontembed/test_ps.c' || echo '$(srcdir)/'`fontembed/test_ps.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_ps.Tpo $(DEPDIR)/test_ps.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fontembed/test_ps.c' object='test_ps.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_ps.o `test -f 'fontembed/test_ps.c' || echo '$(srcdir)/'`fontembed/test_ps.c
+
+test_ps.obj: fontembed/test_ps.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_ps.obj -MD -MP -MF $(DEPDIR)/test_ps.Tpo -c -o test_ps.obj `if test -f 'fontembed/test_ps.c'; then $(CYGPATH_W) 'fontembed/test_ps.c'; else $(CYGPATH_W) '$(srcdir)/fontembed/test_ps.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_ps.Tpo $(DEPDIR)/test_ps.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fontembed/test_ps.c' object='test_ps.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_ps.obj `if test -f 'fontembed/test_ps.c'; then $(CYGPATH_W) 'fontembed/test_ps.c'; else $(CYGPATH_W) '$(srcdir)/fontembed/test_ps.c'; fi`
+
+testcmyk.o: cupsfilters/testcmyk.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT testcmyk.o -MD -MP -MF $(DEPDIR)/testcmyk.Tpo -c -o testcmyk.o `test -f 'cupsfilters/testcmyk.c' || echo '$(srcdir)/'`cupsfilters/testcmyk.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/testcmyk.Tpo $(DEPDIR)/testcmyk.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/testcmyk.c' object='testcmyk.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o testcmyk.o `test -f 'cupsfilters/testcmyk.c' || echo '$(srcdir)/'`cupsfilters/testcmyk.c
+
+testcmyk.obj: cupsfilters/testcmyk.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT testcmyk.obj -MD -MP -MF $(DEPDIR)/testcmyk.Tpo -c -o testcmyk.obj `if test -f 'cupsfilters/testcmyk.c'; then $(CYGPATH_W) 'cupsfilters/testcmyk.c'; else $(CYGPATH_W) '$(srcdir)/cupsfilters/testcmyk.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/testcmyk.Tpo $(DEPDIR)/testcmyk.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/testcmyk.c' object='testcmyk.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o testcmyk.obj `if test -f 'cupsfilters/testcmyk.c'; then $(CYGPATH_W) 'cupsfilters/testcmyk.c'; else $(CYGPATH_W) '$(srcdir)/cupsfilters/testcmyk.c'; fi`
+
+testdither.o: cupsfilters/testdither.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT testdither.o -MD -MP -MF $(DEPDIR)/testdither.Tpo -c -o testdither.o `test -f 'cupsfilters/testdither.c' || echo '$(srcdir)/'`cupsfilters/testdither.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/testdither.Tpo $(DEPDIR)/testdither.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/testdither.c' object='testdither.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o testdither.o `test -f 'cupsfilters/testdither.c' || echo '$(srcdir)/'`cupsfilters/testdither.c
+
+testdither.obj: cupsfilters/testdither.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT testdither.obj -MD -MP -MF $(DEPDIR)/testdither.Tpo -c -o testdither.obj `if test -f 'cupsfilters/testdither.c'; then $(CYGPATH_W) 'cupsfilters/testdither.c'; else $(CYGPATH_W) '$(srcdir)/cupsfilters/testdither.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/testdither.Tpo $(DEPDIR)/testdither.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/testdither.c' object='testdither.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o testdither.obj `if test -f 'cupsfilters/testdither.c'; then $(CYGPATH_W) 'cupsfilters/testdither.c'; else $(CYGPATH_W) '$(srcdir)/cupsfilters/testdither.c'; fi`
+
+testimage-testimage.o: cupsfilters/testimage.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testimage_CFLAGS) $(CFLAGS) -MT testimage-testimage.o -MD -MP -MF $(DEPDIR)/testimage-testimage.Tpo -c -o testimage-testimage.o `test -f 'cupsfilters/testimage.c' || echo '$(srcdir)/'`cupsfilters/testimage.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/testimage-testimage.Tpo $(DEPDIR)/testimage-testimage.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/testimage.c' object='testimage-testimage.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testimage_CFLAGS) $(CFLAGS) -c -o testimage-testimage.o `test -f 'cupsfilters/testimage.c' || echo '$(srcdir)/'`cupsfilters/testimage.c
+
+testimage-testimage.obj: cupsfilters/testimage.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testimage_CFLAGS) $(CFLAGS) -MT testimage-testimage.obj -MD -MP -MF $(DEPDIR)/testimage-testimage.Tpo -c -o testimage-testimage.obj `if test -f 'cupsfilters/testimage.c'; then $(CYGPATH_W) 'cupsfilters/testimage.c'; else $(CYGPATH_W) '$(srcdir)/cupsfilters/testimage.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/testimage-testimage.Tpo $(DEPDIR)/testimage-testimage.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/testimage.c' object='testimage-testimage.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testimage_CFLAGS) $(CFLAGS) -c -o testimage-testimage.obj `if test -f 'cupsfilters/testimage.c'; then $(CYGPATH_W) 'cupsfilters/testimage.c'; else $(CYGPATH_W) '$(srcdir)/cupsfilters/testimage.c'; fi`
+
+testrgb.o: cupsfilters/testrgb.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT testrgb.o -MD -MP -MF $(DEPDIR)/testrgb.Tpo -c -o testrgb.o `test -f 'cupsfilters/testrgb.c' || echo '$(srcdir)/'`cupsfilters/testrgb.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/testrgb.Tpo $(DEPDIR)/testrgb.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/testrgb.c' object='testrgb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o testrgb.o `test -f 'cupsfilters/testrgb.c' || echo '$(srcdir)/'`cupsfilters/testrgb.c
+
+testrgb.obj: cupsfilters/testrgb.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT testrgb.obj -MD -MP -MF $(DEPDIR)/testrgb.Tpo -c -o testrgb.obj `if test -f 'cupsfilters/testrgb.c'; then $(CYGPATH_W) 'cupsfilters/testrgb.c'; else $(CYGPATH_W) '$(srcdir)/cupsfilters/testrgb.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/testrgb.Tpo $(DEPDIR)/testrgb.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/testrgb.c' object='testrgb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o testrgb.obj `if test -f 'cupsfilters/testrgb.c'; then $(CYGPATH_W) 'cupsfilters/testrgb.c'; else $(CYGPATH_W) '$(srcdir)/cupsfilters/testrgb.c'; fi`
+
+texttopdf-common.o: filter/common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttopdf_CFLAGS) $(CFLAGS) -MT texttopdf-common.o -MD -MP -MF $(DEPDIR)/texttopdf-common.Tpo -c -o texttopdf-common.o `test -f 'filter/common.c' || echo '$(srcdir)/'`filter/common.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/texttopdf-common.Tpo $(DEPDIR)/texttopdf-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/common.c' object='texttopdf-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttopdf_CFLAGS) $(CFLAGS) -c -o texttopdf-common.o `test -f 'filter/common.c' || echo '$(srcdir)/'`filter/common.c
+
+texttopdf-common.obj: filter/common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttopdf_CFLAGS) $(CFLAGS) -MT texttopdf-common.obj -MD -MP -MF $(DEPDIR)/texttopdf-common.Tpo -c -o texttopdf-common.obj `if test -f 'filter/common.c'; then $(CYGPATH_W) 'filter/common.c'; else $(CYGPATH_W) '$(srcdir)/filter/common.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/texttopdf-common.Tpo $(DEPDIR)/texttopdf-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/common.c' object='texttopdf-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttopdf_CFLAGS) $(CFLAGS) -c -o texttopdf-common.obj `if test -f 'filter/common.c'; then $(CYGPATH_W) 'filter/common.c'; else $(CYGPATH_W) '$(srcdir)/filter/common.c'; fi`
+
+texttopdf-pdfutils.o: filter/pdfutils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttopdf_CFLAGS) $(CFLAGS) -MT texttopdf-pdfutils.o -MD -MP -MF $(DEPDIR)/texttopdf-pdfutils.Tpo -c -o texttopdf-pdfutils.o `test -f 'filter/pdfutils.c' || echo '$(srcdir)/'`filter/pdfutils.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/texttopdf-pdfutils.Tpo $(DEPDIR)/texttopdf-pdfutils.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/pdfutils.c' object='texttopdf-pdfutils.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttopdf_CFLAGS) $(CFLAGS) -c -o texttopdf-pdfutils.o `test -f 'filter/pdfutils.c' || echo '$(srcdir)/'`filter/pdfutils.c
+
+texttopdf-pdfutils.obj: filter/pdfutils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttopdf_CFLAGS) $(CFLAGS) -MT texttopdf-pdfutils.obj -MD -MP -MF $(DEPDIR)/texttopdf-pdfutils.Tpo -c -o texttopdf-pdfutils.obj `if test -f 'filter/pdfutils.c'; then $(CYGPATH_W) 'filter/pdfutils.c'; else $(CYGPATH_W) '$(srcdir)/filter/pdfutils.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/texttopdf-pdfutils.Tpo $(DEPDIR)/texttopdf-pdfutils.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/pdfutils.c' object='texttopdf-pdfutils.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttopdf_CFLAGS) $(CFLAGS) -c -o texttopdf-pdfutils.obj `if test -f 'filter/pdfutils.c'; then $(CYGPATH_W) 'filter/pdfutils.c'; else $(CYGPATH_W) '$(srcdir)/filter/pdfutils.c'; fi`
+
+texttopdf-textcommon.o: filter/textcommon.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttopdf_CFLAGS) $(CFLAGS) -MT texttopdf-textcommon.o -MD -MP -MF $(DEPDIR)/texttopdf-textcommon.Tpo -c -o texttopdf-textcommon.o `test -f 'filter/textcommon.c' || echo '$(srcdir)/'`filter/textcommon.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/texttopdf-textcommon.Tpo $(DEPDIR)/texttopdf-textcommon.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/textcommon.c' object='texttopdf-textcommon.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttopdf_CFLAGS) $(CFLAGS) -c -o texttopdf-textcommon.o `test -f 'filter/textcommon.c' || echo '$(srcdir)/'`filter/textcommon.c
+
+texttopdf-textcommon.obj: filter/textcommon.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttopdf_CFLAGS) $(CFLAGS) -MT texttopdf-textcommon.obj -MD -MP -MF $(DEPDIR)/texttopdf-textcommon.Tpo -c -o texttopdf-textcommon.obj `if test -f 'filter/textcommon.c'; then $(CYGPATH_W) 'filter/textcommon.c'; else $(CYGPATH_W) '$(srcdir)/filter/textcommon.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/texttopdf-textcommon.Tpo $(DEPDIR)/texttopdf-textcommon.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/textcommon.c' object='texttopdf-textcommon.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttopdf_CFLAGS) $(CFLAGS) -c -o texttopdf-textcommon.obj `if test -f 'filter/textcommon.c'; then $(CYGPATH_W) 'filter/textcommon.c'; else $(CYGPATH_W) '$(srcdir)/filter/textcommon.c'; fi`
+
+texttopdf-texttopdf.o: filter/texttopdf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttopdf_CFLAGS) $(CFLAGS) -MT texttopdf-texttopdf.o -MD -MP -MF $(DEPDIR)/texttopdf-texttopdf.Tpo -c -o texttopdf-texttopdf.o `test -f 'filter/texttopdf.c' || echo '$(srcdir)/'`filter/texttopdf.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/texttopdf-texttopdf.Tpo $(DEPDIR)/texttopdf-texttopdf.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/texttopdf.c' object='texttopdf-texttopdf.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttopdf_CFLAGS) $(CFLAGS) -c -o texttopdf-texttopdf.o `test -f 'filter/texttopdf.c' || echo '$(srcdir)/'`filter/texttopdf.c
+
+texttopdf-texttopdf.obj: filter/texttopdf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttopdf_CFLAGS) $(CFLAGS) -MT texttopdf-texttopdf.obj -MD -MP -MF $(DEPDIR)/texttopdf-texttopdf.Tpo -c -o texttopdf-texttopdf.obj `if test -f 'filter/texttopdf.c'; then $(CYGPATH_W) 'filter/texttopdf.c'; else $(CYGPATH_W) '$(srcdir)/filter/texttopdf.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/texttopdf-texttopdf.Tpo $(DEPDIR)/texttopdf-texttopdf.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/texttopdf.c' object='texttopdf-texttopdf.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttopdf_CFLAGS) $(CFLAGS) -c -o texttopdf-texttopdf.obj `if test -f 'filter/texttopdf.c'; then $(CYGPATH_W) 'filter/texttopdf.c'; else $(CYGPATH_W) '$(srcdir)/filter/texttopdf.c'; fi`
+
+texttotext-texttotext.o: filter/texttotext.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttotext_CFLAGS) $(CFLAGS) -MT texttotext-texttotext.o -MD -MP -MF $(DEPDIR)/texttotext-texttotext.Tpo -c -o texttotext-texttotext.o `test -f 'filter/texttotext.c' || echo '$(srcdir)/'`filter/texttotext.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/texttotext-texttotext.Tpo $(DEPDIR)/texttotext-texttotext.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/texttotext.c' object='texttotext-texttotext.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttotext_CFLAGS) $(CFLAGS) -c -o texttotext-texttotext.o `test -f 'filter/texttotext.c' || echo '$(srcdir)/'`filter/texttotext.c
+
+texttotext-texttotext.obj: filter/texttotext.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttotext_CFLAGS) $(CFLAGS) -MT texttotext-texttotext.obj -MD -MP -MF $(DEPDIR)/texttotext-texttotext.Tpo -c -o texttotext-texttotext.obj `if test -f 'filter/texttotext.c'; then $(CYGPATH_W) 'filter/texttotext.c'; else $(CYGPATH_W) '$(srcdir)/filter/texttotext.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/texttotext-texttotext.Tpo $(DEPDIR)/texttotext-texttotext.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/texttotext.c' object='texttotext-texttotext.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttotext_CFLAGS) $(CFLAGS) -c -o texttotext-texttotext.obj `if test -f 'filter/texttotext.c'; then $(CYGPATH_W) 'filter/texttotext.c'; else $(CYGPATH_W) '$(srcdir)/filter/texttotext.c'; fi`
+
+texttotext-strcasestr.o: filter/strcasestr.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttotext_CFLAGS) $(CFLAGS) -MT texttotext-strcasestr.o -MD -MP -MF $(DEPDIR)/texttotext-strcasestr.Tpo -c -o texttotext-strcasestr.o `test -f 'filter/strcasestr.c' || echo '$(srcdir)/'`filter/strcasestr.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/texttotext-strcasestr.Tpo $(DEPDIR)/texttotext-strcasestr.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/strcasestr.c' object='texttotext-strcasestr.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttotext_CFLAGS) $(CFLAGS) -c -o texttotext-strcasestr.o `test -f 'filter/strcasestr.c' || echo '$(srcdir)/'`filter/strcasestr.c
+
+texttotext-strcasestr.obj: filter/strcasestr.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttotext_CFLAGS) $(CFLAGS) -MT texttotext-strcasestr.obj -MD -MP -MF $(DEPDIR)/texttotext-strcasestr.Tpo -c -o texttotext-strcasestr.obj `if test -f 'filter/strcasestr.c'; then $(CYGPATH_W) 'filter/strcasestr.c'; else $(CYGPATH_W) '$(srcdir)/filter/strcasestr.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/texttotext-strcasestr.Tpo $(DEPDIR)/texttotext-strcasestr.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter/strcasestr.c' object='texttotext-strcasestr.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(texttotext_CFLAGS) $(CFLAGS) -c -o texttotext-strcasestr.obj `if test -f 'filter/strcasestr.c'; then $(CYGPATH_W) 'filter/strcasestr.c'; else $(CYGPATH_W) '$(srcdir)/filter/strcasestr.c'; fi`
+
+main.o: fontembed/main.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT main.o -MD -MP -MF $(DEPDIR)/main.Tpo -c -o main.o `test -f 'fontembed/main.c' || echo '$(srcdir)/'`fontembed/main.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/main.Tpo $(DEPDIR)/main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fontembed/main.c' object='main.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o main.o `test -f 'fontembed/main.c' || echo '$(srcdir)/'`fontembed/main.c
+
+main.obj: fontembed/main.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT main.obj -MD -MP -MF $(DEPDIR)/main.Tpo -c -o main.obj `if test -f 'fontembed/main.c'; then $(CYGPATH_W) 'fontembed/main.c'; else $(CYGPATH_W) '$(srcdir)/fontembed/main.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/main.Tpo $(DEPDIR)/main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fontembed/main.c' object='main.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o main.obj `if test -f 'fontembed/main.c'; then $(CYGPATH_W) 'fontembed/main.c'; else $(CYGPATH_W) '$(srcdir)/fontembed/main.c'; fi`
+
+.cc.o:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+bannertopdf-pdf.o: filter/pdf.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bannertopdf_CXXFLAGS) $(CXXFLAGS) -MT bannertopdf-pdf.o -MD -MP -MF $(DEPDIR)/bannertopdf-pdf.Tpo -c -o bannertopdf-pdf.o `test -f 'filter/pdf.cxx' || echo '$(srcdir)/'`filter/pdf.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bannertopdf-pdf.Tpo $(DEPDIR)/bannertopdf-pdf.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdf.cxx' object='bannertopdf-pdf.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bannertopdf_CXXFLAGS) $(CXXFLAGS) -c -o bannertopdf-pdf.o `test -f 'filter/pdf.cxx' || echo '$(srcdir)/'`filter/pdf.cxx
+
+bannertopdf-pdf.obj: filter/pdf.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bannertopdf_CXXFLAGS) $(CXXFLAGS) -MT bannertopdf-pdf.obj -MD -MP -MF $(DEPDIR)/bannertopdf-pdf.Tpo -c -o bannertopdf-pdf.obj `if test -f 'filter/pdf.cxx'; then $(CYGPATH_W) 'filter/pdf.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdf.cxx'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bannertopdf-pdf.Tpo $(DEPDIR)/bannertopdf-pdf.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdf.cxx' object='bannertopdf-pdf.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bannertopdf_CXXFLAGS) $(CXXFLAGS) -c -o bannertopdf-pdf.obj `if test -f 'filter/pdf.cxx'; then $(CYGPATH_W) 'filter/pdf.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdf.cxx'; fi`
+
+pdftoijs-pdftoijs.o: filter/pdftoijs.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoijs_CXXFLAGS) $(CXXFLAGS) -MT pdftoijs-pdftoijs.o -MD -MP -MF $(DEPDIR)/pdftoijs-pdftoijs.Tpo -c -o pdftoijs-pdftoijs.o `test -f 'filter/pdftoijs.cxx' || echo '$(srcdir)/'`filter/pdftoijs.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoijs-pdftoijs.Tpo $(DEPDIR)/pdftoijs-pdftoijs.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoijs.cxx' object='pdftoijs-pdftoijs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoijs_CXXFLAGS) $(CXXFLAGS) -c -o pdftoijs-pdftoijs.o `test -f 'filter/pdftoijs.cxx' || echo '$(srcdir)/'`filter/pdftoijs.cxx
+
+pdftoijs-pdftoijs.obj: filter/pdftoijs.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoijs_CXXFLAGS) $(CXXFLAGS) -MT pdftoijs-pdftoijs.obj -MD -MP -MF $(DEPDIR)/pdftoijs-pdftoijs.Tpo -c -o pdftoijs-pdftoijs.obj `if test -f 'filter/pdftoijs.cxx'; then $(CYGPATH_W) 'filter/pdftoijs.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoijs.cxx'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoijs-pdftoijs.Tpo $(DEPDIR)/pdftoijs-pdftoijs.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoijs.cxx' object='pdftoijs-pdftoijs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoijs_CXXFLAGS) $(CXXFLAGS) -c -o pdftoijs-pdftoijs.obj `if test -f 'filter/pdftoijs.cxx'; then $(CYGPATH_W) 'filter/pdftoijs.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoijs.cxx'; fi`
+
+pdftoopvp-OPRS.o: filter/pdftoopvp/oprs/OPRS.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -MT pdftoopvp-OPRS.o -MD -MP -MF $(DEPDIR)/pdftoopvp-OPRS.Tpo -c -o pdftoopvp-OPRS.o `test -f 'filter/pdftoopvp/oprs/OPRS.cxx' || echo '$(srcdir)/'`filter/pdftoopvp/oprs/OPRS.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoopvp-OPRS.Tpo $(DEPDIR)/pdftoopvp-OPRS.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoopvp/oprs/OPRS.cxx' object='pdftoopvp-OPRS.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -c -o pdftoopvp-OPRS.o `test -f 'filter/pdftoopvp/oprs/OPRS.cxx' || echo '$(srcdir)/'`filter/pdftoopvp/oprs/OPRS.cxx
+
+pdftoopvp-OPRS.obj: filter/pdftoopvp/oprs/OPRS.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -MT pdftoopvp-OPRS.obj -MD -MP -MF $(DEPDIR)/pdftoopvp-OPRS.Tpo -c -o pdftoopvp-OPRS.obj `if test -f 'filter/pdftoopvp/oprs/OPRS.cxx'; then $(CYGPATH_W) 'filter/pdftoopvp/oprs/OPRS.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoopvp/oprs/OPRS.cxx'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoopvp-OPRS.Tpo $(DEPDIR)/pdftoopvp-OPRS.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoopvp/oprs/OPRS.cxx' object='pdftoopvp-OPRS.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -c -o pdftoopvp-OPRS.obj `if test -f 'filter/pdftoopvp/oprs/OPRS.cxx'; then $(CYGPATH_W) 'filter/pdftoopvp/oprs/OPRS.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoopvp/oprs/OPRS.cxx'; fi`
+
+pdftoopvp-OPVPSplashClip.o: filter/pdftoopvp/oprs/OPVPSplashClip.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -MT pdftoopvp-OPVPSplashClip.o -MD -MP -MF $(DEPDIR)/pdftoopvp-OPVPSplashClip.Tpo -c -o pdftoopvp-OPVPSplashClip.o `test -f 'filter/pdftoopvp/oprs/OPVPSplashClip.cxx' || echo '$(srcdir)/'`filter/pdftoopvp/oprs/OPVPSplashClip.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoopvp-OPVPSplashClip.Tpo $(DEPDIR)/pdftoopvp-OPVPSplashClip.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoopvp/oprs/OPVPSplashClip.cxx' object='pdftoopvp-OPVPSplashClip.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -c -o pdftoopvp-OPVPSplashClip.o `test -f 'filter/pdftoopvp/oprs/OPVPSplashClip.cxx' || echo '$(srcdir)/'`filter/pdftoopvp/oprs/OPVPSplashClip.cxx
+
+pdftoopvp-OPVPSplashClip.obj: filter/pdftoopvp/oprs/OPVPSplashClip.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -MT pdftoopvp-OPVPSplashClip.obj -MD -MP -MF $(DEPDIR)/pdftoopvp-OPVPSplashClip.Tpo -c -o pdftoopvp-OPVPSplashClip.obj `if test -f 'filter/pdftoopvp/oprs/OPVPSplashClip.cxx'; then $(CYGPATH_W) 'filter/pdftoopvp/oprs/OPVPSplashClip.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoopvp/oprs/OPVPSplashClip.cxx'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoopvp-OPVPSplashClip.Tpo $(DEPDIR)/pdftoopvp-OPVPSplashClip.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoopvp/oprs/OPVPSplashClip.cxx' object='pdftoopvp-OPVPSplashClip.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -c -o pdftoopvp-OPVPSplashClip.obj `if test -f 'filter/pdftoopvp/oprs/OPVPSplashClip.cxx'; then $(CYGPATH_W) 'filter/pdftoopvp/oprs/OPVPSplashClip.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoopvp/oprs/OPVPSplashClip.cxx'; fi`
+
+pdftoopvp-OPVPSplash.o: filter/pdftoopvp/oprs/OPVPSplash.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -MT pdftoopvp-OPVPSplash.o -MD -MP -MF $(DEPDIR)/pdftoopvp-OPVPSplash.Tpo -c -o pdftoopvp-OPVPSplash.o `test -f 'filter/pdftoopvp/oprs/OPVPSplash.cxx' || echo '$(srcdir)/'`filter/pdftoopvp/oprs/OPVPSplash.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoopvp-OPVPSplash.Tpo $(DEPDIR)/pdftoopvp-OPVPSplash.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoopvp/oprs/OPVPSplash.cxx' object='pdftoopvp-OPVPSplash.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -c -o pdftoopvp-OPVPSplash.o `test -f 'filter/pdftoopvp/oprs/OPVPSplash.cxx' || echo '$(srcdir)/'`filter/pdftoopvp/oprs/OPVPSplash.cxx
+
+pdftoopvp-OPVPSplash.obj: filter/pdftoopvp/oprs/OPVPSplash.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -MT pdftoopvp-OPVPSplash.obj -MD -MP -MF $(DEPDIR)/pdftoopvp-OPVPSplash.Tpo -c -o pdftoopvp-OPVPSplash.obj `if test -f 'filter/pdftoopvp/oprs/OPVPSplash.cxx'; then $(CYGPATH_W) 'filter/pdftoopvp/oprs/OPVPSplash.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoopvp/oprs/OPVPSplash.cxx'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoopvp-OPVPSplash.Tpo $(DEPDIR)/pdftoopvp-OPVPSplash.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoopvp/oprs/OPVPSplash.cxx' object='pdftoopvp-OPVPSplash.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -c -o pdftoopvp-OPVPSplash.obj `if test -f 'filter/pdftoopvp/oprs/OPVPSplash.cxx'; then $(CYGPATH_W) 'filter/pdftoopvp/oprs/OPVPSplash.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoopvp/oprs/OPVPSplash.cxx'; fi`
+
+pdftoopvp-OPVPSplashPath.o: filter/pdftoopvp/oprs/OPVPSplashPath.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -MT pdftoopvp-OPVPSplashPath.o -MD -MP -MF $(DEPDIR)/pdftoopvp-OPVPSplashPath.Tpo -c -o pdftoopvp-OPVPSplashPath.o `test -f 'filter/pdftoopvp/oprs/OPVPSplashPath.cxx' || echo '$(srcdir)/'`filter/pdftoopvp/oprs/OPVPSplashPath.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoopvp-OPVPSplashPath.Tpo $(DEPDIR)/pdftoopvp-OPVPSplashPath.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoopvp/oprs/OPVPSplashPath.cxx' object='pdftoopvp-OPVPSplashPath.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -c -o pdftoopvp-OPVPSplashPath.o `test -f 'filter/pdftoopvp/oprs/OPVPSplashPath.cxx' || echo '$(srcdir)/'`filter/pdftoopvp/oprs/OPVPSplashPath.cxx
+
+pdftoopvp-OPVPSplashPath.obj: filter/pdftoopvp/oprs/OPVPSplashPath.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -MT pdftoopvp-OPVPSplashPath.obj -MD -MP -MF $(DEPDIR)/pdftoopvp-OPVPSplashPath.Tpo -c -o pdftoopvp-OPVPSplashPath.obj `if test -f 'filter/pdftoopvp/oprs/OPVPSplashPath.cxx'; then $(CYGPATH_W) 'filter/pdftoopvp/oprs/OPVPSplashPath.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoopvp/oprs/OPVPSplashPath.cxx'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoopvp-OPVPSplashPath.Tpo $(DEPDIR)/pdftoopvp-OPVPSplashPath.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoopvp/oprs/OPVPSplashPath.cxx' object='pdftoopvp-OPVPSplashPath.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -c -o pdftoopvp-OPVPSplashPath.obj `if test -f 'filter/pdftoopvp/oprs/OPVPSplashPath.cxx'; then $(CYGPATH_W) 'filter/pdftoopvp/oprs/OPVPSplashPath.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoopvp/oprs/OPVPSplashPath.cxx'; fi`
+
+pdftoopvp-OPVPSplashState.o: filter/pdftoopvp/oprs/OPVPSplashState.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -MT pdftoopvp-OPVPSplashState.o -MD -MP -MF $(DEPDIR)/pdftoopvp-OPVPSplashState.Tpo -c -o pdftoopvp-OPVPSplashState.o `test -f 'filter/pdftoopvp/oprs/OPVPSplashState.cxx' || echo '$(srcdir)/'`filter/pdftoopvp/oprs/OPVPSplashState.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoopvp-OPVPSplashState.Tpo $(DEPDIR)/pdftoopvp-OPVPSplashState.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoopvp/oprs/OPVPSplashState.cxx' object='pdftoopvp-OPVPSplashState.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -c -o pdftoopvp-OPVPSplashState.o `test -f 'filter/pdftoopvp/oprs/OPVPSplashState.cxx' || echo '$(srcdir)/'`filter/pdftoopvp/oprs/OPVPSplashState.cxx
+
+pdftoopvp-OPVPSplashState.obj: filter/pdftoopvp/oprs/OPVPSplashState.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -MT pdftoopvp-OPVPSplashState.obj -MD -MP -MF $(DEPDIR)/pdftoopvp-OPVPSplashState.Tpo -c -o pdftoopvp-OPVPSplashState.obj `if test -f 'filter/pdftoopvp/oprs/OPVPSplashState.cxx'; then $(CYGPATH_W) 'filter/pdftoopvp/oprs/OPVPSplashState.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoopvp/oprs/OPVPSplashState.cxx'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoopvp-OPVPSplashState.Tpo $(DEPDIR)/pdftoopvp-OPVPSplashState.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoopvp/oprs/OPVPSplashState.cxx' object='pdftoopvp-OPVPSplashState.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -c -o pdftoopvp-OPVPSplashState.obj `if test -f 'filter/pdftoopvp/oprs/OPVPSplashState.cxx'; then $(CYGPATH_W) 'filter/pdftoopvp/oprs/OPVPSplashState.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoopvp/oprs/OPVPSplashState.cxx'; fi`
+
+pdftoopvp-OPVPSplashXPath.o: filter/pdftoopvp/oprs/OPVPSplashXPath.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -MT pdftoopvp-OPVPSplashXPath.o -MD -MP -MF $(DEPDIR)/pdftoopvp-OPVPSplashXPath.Tpo -c -o pdftoopvp-OPVPSplashXPath.o `test -f 'filter/pdftoopvp/oprs/OPVPSplashXPath.cxx' || echo '$(srcdir)/'`filter/pdftoopvp/oprs/OPVPSplashXPath.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoopvp-OPVPSplashXPath.Tpo $(DEPDIR)/pdftoopvp-OPVPSplashXPath.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoopvp/oprs/OPVPSplashXPath.cxx' object='pdftoopvp-OPVPSplashXPath.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -c -o pdftoopvp-OPVPSplashXPath.o `test -f 'filter/pdftoopvp/oprs/OPVPSplashXPath.cxx' || echo '$(srcdir)/'`filter/pdftoopvp/oprs/OPVPSplashXPath.cxx
+
+pdftoopvp-OPVPSplashXPath.obj: filter/pdftoopvp/oprs/OPVPSplashXPath.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -MT pdftoopvp-OPVPSplashXPath.obj -MD -MP -MF $(DEPDIR)/pdftoopvp-OPVPSplashXPath.Tpo -c -o pdftoopvp-OPVPSplashXPath.obj `if test -f 'filter/pdftoopvp/oprs/OPVPSplashXPath.cxx'; then $(CYGPATH_W) 'filter/pdftoopvp/oprs/OPVPSplashXPath.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoopvp/oprs/OPVPSplashXPath.cxx'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoopvp-OPVPSplashXPath.Tpo $(DEPDIR)/pdftoopvp-OPVPSplashXPath.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoopvp/oprs/OPVPSplashXPath.cxx' object='pdftoopvp-OPVPSplashXPath.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -c -o pdftoopvp-OPVPSplashXPath.obj `if test -f 'filter/pdftoopvp/oprs/OPVPSplashXPath.cxx'; then $(CYGPATH_W) 'filter/pdftoopvp/oprs/OPVPSplashXPath.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoopvp/oprs/OPVPSplashXPath.cxx'; fi`
+
+pdftoopvp-OPVPWrapper.o: filter/pdftoopvp/oprs/OPVPWrapper.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -MT pdftoopvp-OPVPWrapper.o -MD -MP -MF $(DEPDIR)/pdftoopvp-OPVPWrapper.Tpo -c -o pdftoopvp-OPVPWrapper.o `test -f 'filter/pdftoopvp/oprs/OPVPWrapper.cxx' || echo '$(srcdir)/'`filter/pdftoopvp/oprs/OPVPWrapper.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoopvp-OPVPWrapper.Tpo $(DEPDIR)/pdftoopvp-OPVPWrapper.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoopvp/oprs/OPVPWrapper.cxx' object='pdftoopvp-OPVPWrapper.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -c -o pdftoopvp-OPVPWrapper.o `test -f 'filter/pdftoopvp/oprs/OPVPWrapper.cxx' || echo '$(srcdir)/'`filter/pdftoopvp/oprs/OPVPWrapper.cxx
+
+pdftoopvp-OPVPWrapper.obj: filter/pdftoopvp/oprs/OPVPWrapper.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -MT pdftoopvp-OPVPWrapper.obj -MD -MP -MF $(DEPDIR)/pdftoopvp-OPVPWrapper.Tpo -c -o pdftoopvp-OPVPWrapper.obj `if test -f 'filter/pdftoopvp/oprs/OPVPWrapper.cxx'; then $(CYGPATH_W) 'filter/pdftoopvp/oprs/OPVPWrapper.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoopvp/oprs/OPVPWrapper.cxx'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoopvp-OPVPWrapper.Tpo $(DEPDIR)/pdftoopvp-OPVPWrapper.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoopvp/oprs/OPVPWrapper.cxx' object='pdftoopvp-OPVPWrapper.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -c -o pdftoopvp-OPVPWrapper.obj `if test -f 'filter/pdftoopvp/oprs/OPVPWrapper.cxx'; then $(CYGPATH_W) 'filter/pdftoopvp/oprs/OPVPWrapper.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoopvp/oprs/OPVPWrapper.cxx'; fi`
+
+pdftoopvp-OPVPWrapper_0_2.o: filter/pdftoopvp/oprs/OPVPWrapper_0_2.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -MT pdftoopvp-OPVPWrapper_0_2.o -MD -MP -MF $(DEPDIR)/pdftoopvp-OPVPWrapper_0_2.Tpo -c -o pdftoopvp-OPVPWrapper_0_2.o `test -f 'filter/pdftoopvp/oprs/OPVPWrapper_0_2.cxx' || echo '$(srcdir)/'`filter/pdftoopvp/oprs/OPVPWrapper_0_2.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoopvp-OPVPWrapper_0_2.Tpo $(DEPDIR)/pdftoopvp-OPVPWrapper_0_2.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoopvp/oprs/OPVPWrapper_0_2.cxx' object='pdftoopvp-OPVPWrapper_0_2.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -c -o pdftoopvp-OPVPWrapper_0_2.o `test -f 'filter/pdftoopvp/oprs/OPVPWrapper_0_2.cxx' || echo '$(srcdir)/'`filter/pdftoopvp/oprs/OPVPWrapper_0_2.cxx
+
+pdftoopvp-OPVPWrapper_0_2.obj: filter/pdftoopvp/oprs/OPVPWrapper_0_2.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -MT pdftoopvp-OPVPWrapper_0_2.obj -MD -MP -MF $(DEPDIR)/pdftoopvp-OPVPWrapper_0_2.Tpo -c -o pdftoopvp-OPVPWrapper_0_2.obj `if test -f 'filter/pdftoopvp/oprs/OPVPWrapper_0_2.cxx'; then $(CYGPATH_W) 'filter/pdftoopvp/oprs/OPVPWrapper_0_2.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoopvp/oprs/OPVPWrapper_0_2.cxx'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoopvp-OPVPWrapper_0_2.Tpo $(DEPDIR)/pdftoopvp-OPVPWrapper_0_2.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoopvp/oprs/OPVPWrapper_0_2.cxx' object='pdftoopvp-OPVPWrapper_0_2.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -c -o pdftoopvp-OPVPWrapper_0_2.obj `if test -f 'filter/pdftoopvp/oprs/OPVPWrapper_0_2.cxx'; then $(CYGPATH_W) 'filter/pdftoopvp/oprs/OPVPWrapper_0_2.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoopvp/oprs/OPVPWrapper_0_2.cxx'; fi`
+
+pdftoopvp-OPVPOutputDev.o: filter/pdftoopvp/OPVPOutputDev.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -MT pdftoopvp-OPVPOutputDev.o -MD -MP -MF $(DEPDIR)/pdftoopvp-OPVPOutputDev.Tpo -c -o pdftoopvp-OPVPOutputDev.o `test -f 'filter/pdftoopvp/OPVPOutputDev.cxx' || echo '$(srcdir)/'`filter/pdftoopvp/OPVPOutputDev.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoopvp-OPVPOutputDev.Tpo $(DEPDIR)/pdftoopvp-OPVPOutputDev.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoopvp/OPVPOutputDev.cxx' object='pdftoopvp-OPVPOutputDev.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -c -o pdftoopvp-OPVPOutputDev.o `test -f 'filter/pdftoopvp/OPVPOutputDev.cxx' || echo '$(srcdir)/'`filter/pdftoopvp/OPVPOutputDev.cxx
+
+pdftoopvp-OPVPOutputDev.obj: filter/pdftoopvp/OPVPOutputDev.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -MT pdftoopvp-OPVPOutputDev.obj -MD -MP -MF $(DEPDIR)/pdftoopvp-OPVPOutputDev.Tpo -c -o pdftoopvp-OPVPOutputDev.obj `if test -f 'filter/pdftoopvp/OPVPOutputDev.cxx'; then $(CYGPATH_W) 'filter/pdftoopvp/OPVPOutputDev.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoopvp/OPVPOutputDev.cxx'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoopvp-OPVPOutputDev.Tpo $(DEPDIR)/pdftoopvp-OPVPOutputDev.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoopvp/OPVPOutputDev.cxx' object='pdftoopvp-OPVPOutputDev.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -c -o pdftoopvp-OPVPOutputDev.obj `if test -f 'filter/pdftoopvp/OPVPOutputDev.cxx'; then $(CYGPATH_W) 'filter/pdftoopvp/OPVPOutputDev.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoopvp/OPVPOutputDev.cxx'; fi`
+
+pdftoopvp-pdftoopvp.o: filter/pdftoopvp/pdftoopvp.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -MT pdftoopvp-pdftoopvp.o -MD -MP -MF $(DEPDIR)/pdftoopvp-pdftoopvp.Tpo -c -o pdftoopvp-pdftoopvp.o `test -f 'filter/pdftoopvp/pdftoopvp.cxx' || echo '$(srcdir)/'`filter/pdftoopvp/pdftoopvp.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoopvp-pdftoopvp.Tpo $(DEPDIR)/pdftoopvp-pdftoopvp.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoopvp/pdftoopvp.cxx' object='pdftoopvp-pdftoopvp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -c -o pdftoopvp-pdftoopvp.o `test -f 'filter/pdftoopvp/pdftoopvp.cxx' || echo '$(srcdir)/'`filter/pdftoopvp/pdftoopvp.cxx
+
+pdftoopvp-pdftoopvp.obj: filter/pdftoopvp/pdftoopvp.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -MT pdftoopvp-pdftoopvp.obj -MD -MP -MF $(DEPDIR)/pdftoopvp-pdftoopvp.Tpo -c -o pdftoopvp-pdftoopvp.obj `if test -f 'filter/pdftoopvp/pdftoopvp.cxx'; then $(CYGPATH_W) 'filter/pdftoopvp/pdftoopvp.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoopvp/pdftoopvp.cxx'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoopvp-pdftoopvp.Tpo $(DEPDIR)/pdftoopvp-pdftoopvp.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoopvp/pdftoopvp.cxx' object='pdftoopvp-pdftoopvp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoopvp_CXXFLAGS) $(CXXFLAGS) -c -o pdftoopvp-pdftoopvp.obj `if test -f 'filter/pdftoopvp/pdftoopvp.cxx'; then $(CYGPATH_W) 'filter/pdftoopvp/pdftoopvp.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoopvp/pdftoopvp.cxx'; fi`
+
+pdftopdf-pdftopdf.o: filter/pdftopdf/pdftopdf.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-pdftopdf.o -MD -MP -MF $(DEPDIR)/pdftopdf-pdftopdf.Tpo -c -o pdftopdf-pdftopdf.o `test -f 'filter/pdftopdf/pdftopdf.cc' || echo '$(srcdir)/'`filter/pdftopdf/pdftopdf.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-pdftopdf.Tpo $(DEPDIR)/pdftopdf-pdftopdf.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/pdftopdf.cc' object='pdftopdf-pdftopdf.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-pdftopdf.o `test -f 'filter/pdftopdf/pdftopdf.cc' || echo '$(srcdir)/'`filter/pdftopdf/pdftopdf.cc
+
+pdftopdf-pdftopdf.obj: filter/pdftopdf/pdftopdf.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-pdftopdf.obj -MD -MP -MF $(DEPDIR)/pdftopdf-pdftopdf.Tpo -c -o pdftopdf-pdftopdf.obj `if test -f 'filter/pdftopdf/pdftopdf.cc'; then $(CYGPATH_W) 'filter/pdftopdf/pdftopdf.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/pdftopdf.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-pdftopdf.Tpo $(DEPDIR)/pdftopdf-pdftopdf.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/pdftopdf.cc' object='pdftopdf-pdftopdf.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-pdftopdf.obj `if test -f 'filter/pdftopdf/pdftopdf.cc'; then $(CYGPATH_W) 'filter/pdftopdf/pdftopdf.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/pdftopdf.cc'; fi`
+
+pdftopdf-pdftopdf_jcl.o: filter/pdftopdf/pdftopdf_jcl.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-pdftopdf_jcl.o -MD -MP -MF $(DEPDIR)/pdftopdf-pdftopdf_jcl.Tpo -c -o pdftopdf-pdftopdf_jcl.o `test -f 'filter/pdftopdf/pdftopdf_jcl.cc' || echo '$(srcdir)/'`filter/pdftopdf/pdftopdf_jcl.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-pdftopdf_jcl.Tpo $(DEPDIR)/pdftopdf-pdftopdf_jcl.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/pdftopdf_jcl.cc' object='pdftopdf-pdftopdf_jcl.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-pdftopdf_jcl.o `test -f 'filter/pdftopdf/pdftopdf_jcl.cc' || echo '$(srcdir)/'`filter/pdftopdf/pdftopdf_jcl.cc
+
+pdftopdf-pdftopdf_jcl.obj: filter/pdftopdf/pdftopdf_jcl.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-pdftopdf_jcl.obj -MD -MP -MF $(DEPDIR)/pdftopdf-pdftopdf_jcl.Tpo -c -o pdftopdf-pdftopdf_jcl.obj `if test -f 'filter/pdftopdf/pdftopdf_jcl.cc'; then $(CYGPATH_W) 'filter/pdftopdf/pdftopdf_jcl.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/pdftopdf_jcl.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-pdftopdf_jcl.Tpo $(DEPDIR)/pdftopdf-pdftopdf_jcl.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/pdftopdf_jcl.cc' object='pdftopdf-pdftopdf_jcl.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-pdftopdf_jcl.obj `if test -f 'filter/pdftopdf/pdftopdf_jcl.cc'; then $(CYGPATH_W) 'filter/pdftopdf/pdftopdf_jcl.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/pdftopdf_jcl.cc'; fi`
+
+pdftopdf-pdftopdf_processor.o: filter/pdftopdf/pdftopdf_processor.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-pdftopdf_processor.o -MD -MP -MF $(DEPDIR)/pdftopdf-pdftopdf_processor.Tpo -c -o pdftopdf-pdftopdf_processor.o `test -f 'filter/pdftopdf/pdftopdf_processor.cc' || echo '$(srcdir)/'`filter/pdftopdf/pdftopdf_processor.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-pdftopdf_processor.Tpo $(DEPDIR)/pdftopdf-pdftopdf_processor.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/pdftopdf_processor.cc' object='pdftopdf-pdftopdf_processor.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-pdftopdf_processor.o `test -f 'filter/pdftopdf/pdftopdf_processor.cc' || echo '$(srcdir)/'`filter/pdftopdf/pdftopdf_processor.cc
+
+pdftopdf-pdftopdf_processor.obj: filter/pdftopdf/pdftopdf_processor.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-pdftopdf_processor.obj -MD -MP -MF $(DEPDIR)/pdftopdf-pdftopdf_processor.Tpo -c -o pdftopdf-pdftopdf_processor.obj `if test -f 'filter/pdftopdf/pdftopdf_processor.cc'; then $(CYGPATH_W) 'filter/pdftopdf/pdftopdf_processor.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/pdftopdf_processor.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-pdftopdf_processor.Tpo $(DEPDIR)/pdftopdf-pdftopdf_processor.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/pdftopdf_processor.cc' object='pdftopdf-pdftopdf_processor.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-pdftopdf_processor.obj `if test -f 'filter/pdftopdf/pdftopdf_processor.cc'; then $(CYGPATH_W) 'filter/pdftopdf/pdftopdf_processor.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/pdftopdf_processor.cc'; fi`
+
+pdftopdf-qpdf_pdftopdf_processor.o: filter/pdftopdf/qpdf_pdftopdf_processor.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-qpdf_pdftopdf_processor.o -MD -MP -MF $(DEPDIR)/pdftopdf-qpdf_pdftopdf_processor.Tpo -c -o pdftopdf-qpdf_pdftopdf_processor.o `test -f 'filter/pdftopdf/qpdf_pdftopdf_processor.cc' || echo '$(srcdir)/'`filter/pdftopdf/qpdf_pdftopdf_processor.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-qpdf_pdftopdf_processor.Tpo $(DEPDIR)/pdftopdf-qpdf_pdftopdf_processor.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/qpdf_pdftopdf_processor.cc' object='pdftopdf-qpdf_pdftopdf_processor.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-qpdf_pdftopdf_processor.o `test -f 'filter/pdftopdf/qpdf_pdftopdf_processor.cc' || echo '$(srcdir)/'`filter/pdftopdf/qpdf_pdftopdf_processor.cc
+
+pdftopdf-qpdf_pdftopdf_processor.obj: filter/pdftopdf/qpdf_pdftopdf_processor.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-qpdf_pdftopdf_processor.obj -MD -MP -MF $(DEPDIR)/pdftopdf-qpdf_pdftopdf_processor.Tpo -c -o pdftopdf-qpdf_pdftopdf_processor.obj `if test -f 'filter/pdftopdf/qpdf_pdftopdf_processor.cc'; then $(CYGPATH_W) 'filter/pdftopdf/qpdf_pdftopdf_processor.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/qpdf_pdftopdf_processor.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-qpdf_pdftopdf_processor.Tpo $(DEPDIR)/pdftopdf-qpdf_pdftopdf_processor.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/qpdf_pdftopdf_processor.cc' object='pdftopdf-qpdf_pdftopdf_processor.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-qpdf_pdftopdf_processor.obj `if test -f 'filter/pdftopdf/qpdf_pdftopdf_processor.cc'; then $(CYGPATH_W) 'filter/pdftopdf/qpdf_pdftopdf_processor.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/qpdf_pdftopdf_processor.cc'; fi`
+
+pdftopdf-pptypes.o: filter/pdftopdf/pptypes.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-pptypes.o -MD -MP -MF $(DEPDIR)/pdftopdf-pptypes.Tpo -c -o pdftopdf-pptypes.o `test -f 'filter/pdftopdf/pptypes.cc' || echo '$(srcdir)/'`filter/pdftopdf/pptypes.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-pptypes.Tpo $(DEPDIR)/pdftopdf-pptypes.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/pptypes.cc' object='pdftopdf-pptypes.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-pptypes.o `test -f 'filter/pdftopdf/pptypes.cc' || echo '$(srcdir)/'`filter/pdftopdf/pptypes.cc
+
+pdftopdf-pptypes.obj: filter/pdftopdf/pptypes.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-pptypes.obj -MD -MP -MF $(DEPDIR)/pdftopdf-pptypes.Tpo -c -o pdftopdf-pptypes.obj `if test -f 'filter/pdftopdf/pptypes.cc'; then $(CYGPATH_W) 'filter/pdftopdf/pptypes.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/pptypes.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-pptypes.Tpo $(DEPDIR)/pdftopdf-pptypes.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/pptypes.cc' object='pdftopdf-pptypes.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-pptypes.obj `if test -f 'filter/pdftopdf/pptypes.cc'; then $(CYGPATH_W) 'filter/pdftopdf/pptypes.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/pptypes.cc'; fi`
+
+pdftopdf-nup.o: filter/pdftopdf/nup.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-nup.o -MD -MP -MF $(DEPDIR)/pdftopdf-nup.Tpo -c -o pdftopdf-nup.o `test -f 'filter/pdftopdf/nup.cc' || echo '$(srcdir)/'`filter/pdftopdf/nup.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-nup.Tpo $(DEPDIR)/pdftopdf-nup.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/nup.cc' object='pdftopdf-nup.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-nup.o `test -f 'filter/pdftopdf/nup.cc' || echo '$(srcdir)/'`filter/pdftopdf/nup.cc
+
+pdftopdf-nup.obj: filter/pdftopdf/nup.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-nup.obj -MD -MP -MF $(DEPDIR)/pdftopdf-nup.Tpo -c -o pdftopdf-nup.obj `if test -f 'filter/pdftopdf/nup.cc'; then $(CYGPATH_W) 'filter/pdftopdf/nup.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/nup.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-nup.Tpo $(DEPDIR)/pdftopdf-nup.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/nup.cc' object='pdftopdf-nup.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-nup.obj `if test -f 'filter/pdftopdf/nup.cc'; then $(CYGPATH_W) 'filter/pdftopdf/nup.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/nup.cc'; fi`
+
+pdftopdf-intervalset.o: filter/pdftopdf/intervalset.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-intervalset.o -MD -MP -MF $(DEPDIR)/pdftopdf-intervalset.Tpo -c -o pdftopdf-intervalset.o `test -f 'filter/pdftopdf/intervalset.cc' || echo '$(srcdir)/'`filter/pdftopdf/intervalset.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-intervalset.Tpo $(DEPDIR)/pdftopdf-intervalset.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/intervalset.cc' object='pdftopdf-intervalset.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-intervalset.o `test -f 'filter/pdftopdf/intervalset.cc' || echo '$(srcdir)/'`filter/pdftopdf/intervalset.cc
+
+pdftopdf-intervalset.obj: filter/pdftopdf/intervalset.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-intervalset.obj -MD -MP -MF $(DEPDIR)/pdftopdf-intervalset.Tpo -c -o pdftopdf-intervalset.obj `if test -f 'filter/pdftopdf/intervalset.cc'; then $(CYGPATH_W) 'filter/pdftopdf/intervalset.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/intervalset.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-intervalset.Tpo $(DEPDIR)/pdftopdf-intervalset.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/intervalset.cc' object='pdftopdf-intervalset.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-intervalset.obj `if test -f 'filter/pdftopdf/intervalset.cc'; then $(CYGPATH_W) 'filter/pdftopdf/intervalset.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/intervalset.cc'; fi`
+
+pdftopdf-qpdf_tools.o: filter/pdftopdf/qpdf_tools.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-qpdf_tools.o -MD -MP -MF $(DEPDIR)/pdftopdf-qpdf_tools.Tpo -c -o pdftopdf-qpdf_tools.o `test -f 'filter/pdftopdf/qpdf_tools.cc' || echo '$(srcdir)/'`filter/pdftopdf/qpdf_tools.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-qpdf_tools.Tpo $(DEPDIR)/pdftopdf-qpdf_tools.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/qpdf_tools.cc' object='pdftopdf-qpdf_tools.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-qpdf_tools.o `test -f 'filter/pdftopdf/qpdf_tools.cc' || echo '$(srcdir)/'`filter/pdftopdf/qpdf_tools.cc
+
+pdftopdf-qpdf_tools.obj: filter/pdftopdf/qpdf_tools.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-qpdf_tools.obj -MD -MP -MF $(DEPDIR)/pdftopdf-qpdf_tools.Tpo -c -o pdftopdf-qpdf_tools.obj `if test -f 'filter/pdftopdf/qpdf_tools.cc'; then $(CYGPATH_W) 'filter/pdftopdf/qpdf_tools.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/qpdf_tools.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-qpdf_tools.Tpo $(DEPDIR)/pdftopdf-qpdf_tools.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/qpdf_tools.cc' object='pdftopdf-qpdf_tools.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-qpdf_tools.obj `if test -f 'filter/pdftopdf/qpdf_tools.cc'; then $(CYGPATH_W) 'filter/pdftopdf/qpdf_tools.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/qpdf_tools.cc'; fi`
+
+pdftopdf-qpdf_xobject.o: filter/pdftopdf/qpdf_xobject.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-qpdf_xobject.o -MD -MP -MF $(DEPDIR)/pdftopdf-qpdf_xobject.Tpo -c -o pdftopdf-qpdf_xobject.o `test -f 'filter/pdftopdf/qpdf_xobject.cc' || echo '$(srcdir)/'`filter/pdftopdf/qpdf_xobject.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-qpdf_xobject.Tpo $(DEPDIR)/pdftopdf-qpdf_xobject.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/qpdf_xobject.cc' object='pdftopdf-qpdf_xobject.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-qpdf_xobject.o `test -f 'filter/pdftopdf/qpdf_xobject.cc' || echo '$(srcdir)/'`filter/pdftopdf/qpdf_xobject.cc
+
+pdftopdf-qpdf_xobject.obj: filter/pdftopdf/qpdf_xobject.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-qpdf_xobject.obj -MD -MP -MF $(DEPDIR)/pdftopdf-qpdf_xobject.Tpo -c -o pdftopdf-qpdf_xobject.obj `if test -f 'filter/pdftopdf/qpdf_xobject.cc'; then $(CYGPATH_W) 'filter/pdftopdf/qpdf_xobject.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/qpdf_xobject.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-qpdf_xobject.Tpo $(DEPDIR)/pdftopdf-qpdf_xobject.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/qpdf_xobject.cc' object='pdftopdf-qpdf_xobject.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-qpdf_xobject.obj `if test -f 'filter/pdftopdf/qpdf_xobject.cc'; then $(CYGPATH_W) 'filter/pdftopdf/qpdf_xobject.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/qpdf_xobject.cc'; fi`
+
+pdftopdf-qpdf_pdftopdf.o: filter/pdftopdf/qpdf_pdftopdf.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-qpdf_pdftopdf.o -MD -MP -MF $(DEPDIR)/pdftopdf-qpdf_pdftopdf.Tpo -c -o pdftopdf-qpdf_pdftopdf.o `test -f 'filter/pdftopdf/qpdf_pdftopdf.cc' || echo '$(srcdir)/'`filter/pdftopdf/qpdf_pdftopdf.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-qpdf_pdftopdf.Tpo $(DEPDIR)/pdftopdf-qpdf_pdftopdf.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/qpdf_pdftopdf.cc' object='pdftopdf-qpdf_pdftopdf.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-qpdf_pdftopdf.o `test -f 'filter/pdftopdf/qpdf_pdftopdf.cc' || echo '$(srcdir)/'`filter/pdftopdf/qpdf_pdftopdf.cc
+
+pdftopdf-qpdf_pdftopdf.obj: filter/pdftopdf/qpdf_pdftopdf.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-qpdf_pdftopdf.obj -MD -MP -MF $(DEPDIR)/pdftopdf-qpdf_pdftopdf.Tpo -c -o pdftopdf-qpdf_pdftopdf.obj `if test -f 'filter/pdftopdf/qpdf_pdftopdf.cc'; then $(CYGPATH_W) 'filter/pdftopdf/qpdf_pdftopdf.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/qpdf_pdftopdf.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-qpdf_pdftopdf.Tpo $(DEPDIR)/pdftopdf-qpdf_pdftopdf.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/qpdf_pdftopdf.cc' object='pdftopdf-qpdf_pdftopdf.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-qpdf_pdftopdf.obj `if test -f 'filter/pdftopdf/qpdf_pdftopdf.cc'; then $(CYGPATH_W) 'filter/pdftopdf/qpdf_pdftopdf.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/qpdf_pdftopdf.cc'; fi`
+
+pdftopdf-qpdf_cm.o: filter/pdftopdf/qpdf_cm.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-qpdf_cm.o -MD -MP -MF $(DEPDIR)/pdftopdf-qpdf_cm.Tpo -c -o pdftopdf-qpdf_cm.o `test -f 'filter/pdftopdf/qpdf_cm.cc' || echo '$(srcdir)/'`filter/pdftopdf/qpdf_cm.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-qpdf_cm.Tpo $(DEPDIR)/pdftopdf-qpdf_cm.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/qpdf_cm.cc' object='pdftopdf-qpdf_cm.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-qpdf_cm.o `test -f 'filter/pdftopdf/qpdf_cm.cc' || echo '$(srcdir)/'`filter/pdftopdf/qpdf_cm.cc
+
+pdftopdf-qpdf_cm.obj: filter/pdftopdf/qpdf_cm.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -MT pdftopdf-qpdf_cm.obj -MD -MP -MF $(DEPDIR)/pdftopdf-qpdf_cm.Tpo -c -o pdftopdf-qpdf_cm.obj `if test -f 'filter/pdftopdf/qpdf_cm.cc'; then $(CYGPATH_W) 'filter/pdftopdf/qpdf_cm.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/qpdf_cm.cc'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftopdf-qpdf_cm.Tpo $(DEPDIR)/pdftopdf-qpdf_cm.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftopdf/qpdf_cm.cc' object='pdftopdf-qpdf_cm.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftopdf_CXXFLAGS) $(CXXFLAGS) -c -o pdftopdf-qpdf_cm.obj `if test -f 'filter/pdftopdf/qpdf_cm.cc'; then $(CYGPATH_W) 'filter/pdftopdf/qpdf_cm.cc'; else $(CYGPATH_W) '$(srcdir)/filter/pdftopdf/qpdf_cm.cc'; fi`
+
+pdftoraster-pdftoraster.o: filter/pdftoraster.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoraster_CXXFLAGS) $(CXXFLAGS) -MT pdftoraster-pdftoraster.o -MD -MP -MF $(DEPDIR)/pdftoraster-pdftoraster.Tpo -c -o pdftoraster-pdftoraster.o `test -f 'filter/pdftoraster.cxx' || echo '$(srcdir)/'`filter/pdftoraster.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoraster-pdftoraster.Tpo $(DEPDIR)/pdftoraster-pdftoraster.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoraster.cxx' object='pdftoraster-pdftoraster.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoraster_CXXFLAGS) $(CXXFLAGS) -c -o pdftoraster-pdftoraster.o `test -f 'filter/pdftoraster.cxx' || echo '$(srcdir)/'`filter/pdftoraster.cxx
+
+pdftoraster-pdftoraster.obj: filter/pdftoraster.cxx
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoraster_CXXFLAGS) $(CXXFLAGS) -MT pdftoraster-pdftoraster.obj -MD -MP -MF $(DEPDIR)/pdftoraster-pdftoraster.Tpo -c -o pdftoraster-pdftoraster.obj `if test -f 'filter/pdftoraster.cxx'; then $(CYGPATH_W) 'filter/pdftoraster.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoraster.cxx'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pdftoraster-pdftoraster.Tpo $(DEPDIR)/pdftoraster-pdftoraster.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/pdftoraster.cxx' object='pdftoraster-pdftoraster.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdftoraster_CXXFLAGS) $(CXXFLAGS) -c -o pdftoraster-pdftoraster.obj `if test -f 'filter/pdftoraster.cxx'; then $(CYGPATH_W) 'filter/pdftoraster.cxx'; else $(CYGPATH_W) '$(srcdir)/filter/pdftoraster.cxx'; fi`
+
+rastertopdf-rastertopdf.o: filter/rastertopdf.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rastertopdf_CXXFLAGS) $(CXXFLAGS) -MT rastertopdf-rastertopdf.o -MD -MP -MF $(DEPDIR)/rastertopdf-rastertopdf.Tpo -c -o rastertopdf-rastertopdf.o `test -f 'filter/rastertopdf.cpp' || echo '$(srcdir)/'`filter/rastertopdf.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rastertopdf-rastertopdf.Tpo $(DEPDIR)/rastertopdf-rastertopdf.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/rastertopdf.cpp' object='rastertopdf-rastertopdf.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rastertopdf_CXXFLAGS) $(CXXFLAGS) -c -o rastertopdf-rastertopdf.o `test -f 'filter/rastertopdf.cpp' || echo '$(srcdir)/'`filter/rastertopdf.cpp
+
+rastertopdf-rastertopdf.obj: filter/rastertopdf.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rastertopdf_CXXFLAGS) $(CXXFLAGS) -MT rastertopdf-rastertopdf.obj -MD -MP -MF $(DEPDIR)/rastertopdf-rastertopdf.Tpo -c -o rastertopdf-rastertopdf.obj `if test -f 'filter/rastertopdf.cpp'; then $(CYGPATH_W) 'filter/rastertopdf.cpp'; else $(CYGPATH_W) '$(srcdir)/filter/rastertopdf.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rastertopdf-rastertopdf.Tpo $(DEPDIR)/rastertopdf-rastertopdf.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/rastertopdf.cpp' object='rastertopdf-rastertopdf.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rastertopdf_CXXFLAGS) $(CXXFLAGS) -c -o rastertopdf-rastertopdf.obj `if test -f 'filter/rastertopdf.cpp'; then $(CYGPATH_W) 'filter/rastertopdf.cpp'; else $(CYGPATH_W) '$(srcdir)/filter/rastertopdf.cpp'; fi`
+
+urftopdf-urftopdf.o: filter/urftopdf.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(urftopdf_CXXFLAGS) $(CXXFLAGS) -MT urftopdf-urftopdf.o -MD -MP -MF $(DEPDIR)/urftopdf-urftopdf.Tpo -c -o urftopdf-urftopdf.o `test -f 'filter/urftopdf.cpp' || echo '$(srcdir)/'`filter/urftopdf.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/urftopdf-urftopdf.Tpo $(DEPDIR)/urftopdf-urftopdf.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/urftopdf.cpp' object='urftopdf-urftopdf.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(urftopdf_CXXFLAGS) $(CXXFLAGS) -c -o urftopdf-urftopdf.o `test -f 'filter/urftopdf.cpp' || echo '$(srcdir)/'`filter/urftopdf.cpp
+
+urftopdf-urftopdf.obj: filter/urftopdf.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(urftopdf_CXXFLAGS) $(CXXFLAGS) -MT urftopdf-urftopdf.obj -MD -MP -MF $(DEPDIR)/urftopdf-urftopdf.Tpo -c -o urftopdf-urftopdf.obj `if test -f 'filter/urftopdf.cpp'; then $(CYGPATH_W) 'filter/urftopdf.cpp'; else $(CYGPATH_W) '$(srcdir)/filter/urftopdf.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/urftopdf-urftopdf.Tpo $(DEPDIR)/urftopdf-urftopdf.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filter/urftopdf.cpp' object='urftopdf-urftopdf.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(urftopdf_CXXFLAGS) $(CXXFLAGS) -c -o urftopdf-urftopdf.obj `if test -f 'filter/urftopdf.cpp'; then $(CYGPATH_W) 'filter/urftopdf.cpp'; else $(CYGPATH_W) '$(srcdir)/filter/urftopdf.cpp'; fi`
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+.cxx.o:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cxx.obj:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cxx.lo:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool config.lt
+install-man1: $(man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(man_MANS)'; \
+ test -n "$(man1dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.1[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man1:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man1dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.1[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
+install-man5: $(man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(man_MANS)'; \
+ test -n "$(man5dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.5[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man5:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man5dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.5[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir)
+install-man8: $(man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+install-docDATA: $(doc_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \
+ done
+
+uninstall-docDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir)
+install-nodist_pkgppdcDATA: $(nodist_pkgppdc_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(nodist_pkgppdc_DATA)'; test -n "$(pkgppdcdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgppdcdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgppdcdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgppdcdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgppdcdir)" || exit $$?; \
+ done
+
+uninstall-nodist_pkgppdcDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(nodist_pkgppdc_DATA)'; test -n "$(pkgppdcdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(pkgppdcdir)'; $(am__uninstall_files_from_dir)
+install-pkgbannerDATA: $(pkgbanner_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgbanner_DATA)'; test -n "$(pkgbannerdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgbannerdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgbannerdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgbannerdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgbannerdir)" || exit $$?; \
+ done
+
+uninstall-pkgbannerDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgbanner_DATA)'; test -n "$(pkgbannerdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(pkgbannerdir)'; $(am__uninstall_files_from_dir)
+install-pkgcharsetDATA: $(pkgcharset_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgcharset_DATA)'; test -n "$(pkgcharsetdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgcharsetdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgcharsetdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgcharsetdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgcharsetdir)" || exit $$?; \
+ done
+
+uninstall-pkgcharsetDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgcharset_DATA)'; test -n "$(pkgcharsetdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(pkgcharsetdir)'; $(am__uninstall_files_from_dir)
+install-pkgconfDATA: $(pkgconf_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgconf_DATA)'; test -n "$(pkgconfdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgconfdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfdir)" || exit $$?; \
+ done
+
+uninstall-pkgconfDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgconf_DATA)'; test -n "$(pkgconfdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(pkgconfdir)'; $(am__uninstall_files_from_dir)
+install-pkgcupsdataDATA: $(pkgcupsdata_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgcupsdata_DATA)'; test -n "$(pkgcupsdatadir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgcupsdatadir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgcupsdatadir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgcupsdatadir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgcupsdatadir)" || exit $$?; \
+ done
+
+uninstall-pkgcupsdataDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgcupsdata_DATA)'; test -n "$(pkgcupsdatadir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(pkgcupsdatadir)'; $(am__uninstall_files_from_dir)
+install-pkgcupsserverrootDATA: $(pkgcupsserverroot_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgcupsserverroot_DATA)'; test -n "$(pkgcupsserverrootdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgcupsserverrootdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgcupsserverrootdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgcupsserverrootdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgcupsserverrootdir)" || exit $$?; \
+ done
+
+uninstall-pkgcupsserverrootDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgcupsserverroot_DATA)'; test -n "$(pkgcupsserverrootdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(pkgcupsserverrootdir)'; $(am__uninstall_files_from_dir)
+install-pkgdriverDATA: $(pkgdriver_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgdriver_DATA)'; test -n "$(pkgdriverdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgdriverdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgdriverdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdriverdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdriverdir)" || exit $$?; \
+ done
+
+uninstall-pkgdriverDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgdriver_DATA)'; test -n "$(pkgdriverdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(pkgdriverdir)'; $(am__uninstall_files_from_dir)
+install-pkgfiltersincludeDATA: $(pkgfiltersinclude_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgfiltersinclude_DATA)'; test -n "$(pkgfiltersincludedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgfiltersincludedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgfiltersincludedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgfiltersincludedir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgfiltersincludedir)" || exit $$?; \
+ done
+
+uninstall-pkgfiltersincludeDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgfiltersinclude_DATA)'; test -n "$(pkgfiltersincludedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(pkgfiltersincludedir)'; $(am__uninstall_files_from_dir)
+install-pkgfontconfigDATA: $(pkgfontconfig_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgfontconfig_DATA)'; test -n "$(pkgfontconfigdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgfontconfigdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgfontconfigdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgfontconfigdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgfontconfigdir)" || exit $$?; \
+ done
+
+uninstall-pkgfontconfigDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgfontconfig_DATA)'; test -n "$(pkgfontconfigdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(pkgfontconfigdir)'; $(am__uninstall_files_from_dir)
+install-pkgfontembedincludeDATA: $(pkgfontembedinclude_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgfontembedinclude_DATA)'; test -n "$(pkgfontembedincludedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgfontembedincludedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgfontembedincludedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgfontembedincludedir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgfontembedincludedir)" || exit $$?; \
+ done
+
+uninstall-pkgfontembedincludeDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgfontembedinclude_DATA)'; test -n "$(pkgfontembedincludedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(pkgfontembedincludedir)'; $(am__uninstall_files_from_dir)
+install-pkgmimeDATA: $(pkgmime_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgmime_DATA)'; test -n "$(pkgmimedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgmimedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgmimedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgmimedir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgmimedir)" || exit $$?; \
+ done
+
+uninstall-pkgmimeDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgmime_DATA)'; test -n "$(pkgmimedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(pkgmimedir)'; $(am__uninstall_files_from_dir)
+install-pkgppdcDATA: $(pkgppdc_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgppdc_DATA)'; test -n "$(pkgppdcdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgppdcdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgppdcdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgppdcdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgppdcdir)" || exit $$?; \
+ done
+
+uninstall-pkgppdcDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgppdc_DATA)'; test -n "$(pkgppdcdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(pkgppdcdir)'; $(am__uninstall_files_from_dir)
+install-ppdDATA: $(ppd_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(ppd_DATA)'; test -n "$(ppddir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(ppddir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(ppddir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(ppddir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(ppddir)" || exit $$?; \
+ done
+
+uninstall-ppdDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(ppd_DATA)'; test -n "$(ppddir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(ppddir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscope: cscope.files
+ test ! -s cscope.files \
+ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+ -rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+ -rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS:
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+testdither.log: testdither$(EXEEXT)
+ @p='testdither$(EXEEXT)'; \
+ b='testdither'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+test_analyze.log: test_analyze$(EXEEXT)
+ @p='test_analyze$(EXEEXT)'; \
+ b='test_analyze'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+test_pdf.log: test_pdf$(EXEEXT)
+ @p='test_pdf$(EXEEXT)'; \
+ b='test_pdf'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+test_ps.log: test_ps$(EXEEXT)
+ @p='test_ps$(EXEEXT)'; \
+ b='test_ps'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+test_pdf1.log: test_pdf1$(EXEEXT)
+ @p='test_pdf1$(EXEEXT)'; \
+ b='test_pdf1'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+test_pdf2.log: test_pdf2$(EXEEXT)
+ @p='test_pdf2$(EXEEXT)'; \
+ b='test_pdf2'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ test -d "$(distdir)" || mkdir "$(distdir)"
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ -test -n "$(am__skip_mode_fix)" \
+ || find "$(distdir)" -type d ! -perm -755 \
+ -exec chmod u+rwx,go+rx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__post_remove_distdir)
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+ $(am__post_remove_distdir)
+
+dist-lzip: distdir
+ tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+ $(am__post_remove_distdir)
+dist-xz: distdir
+ tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+ $(am__post_remove_distdir)
+
+dist-tarZ: distdir
+ @echo WARNING: "Support for distribution archives compressed with" \
+ "legacy program 'compress' is deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__post_remove_distdir)
+
+dist-shar: distdir
+ @echo WARNING: "Support for shar distribution archives is" \
+ "deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__post_remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__post_remove_distdir)
+
+dist dist-all:
+ $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+ $(am__post_remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lz*) \
+ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir)
+ chmod u+w $(distdir)
+ mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
+ chmod a-w $(distdir)
+ test -d $(distdir)/_build || exit 0; \
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && am__cwd=`pwd` \
+ && $(am__cd) $(distdir)/_build/sub \
+ && ../../configure \
+ $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ --srcdir=../.. --prefix="$$dc_install_base" \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+ && cd "$$am__cwd" \
+ || exit 1
+ $(am__post_remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+ @test -n '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: trying to run $@ with an empty' \
+ '$$(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ $(am__cd) '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(MANS) $(DATA) \
+ config.h
+install-binPROGRAMS: install-libLTLIBRARIES
+
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(phpextensiondir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgbackenddir)" "$(DESTDIR)$(pkgfilterdir)" "$(DESTDIR)$(pkgppdgendir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(initrcdir)" "$(DESTDIR)$(pkgbrailledir)" "$(DESTDIR)$(pkgfilterdir)" "$(DESTDIR)$(pkgfilterdir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(pkgppdcdir)" "$(DESTDIR)$(pkgbannerdir)" "$(DESTDIR)$(pkgcharsetdir)" "$(DESTDIR)$(pkgconfdir)" "$(DESTDIR)$(pkgcupsdatadir)" "$(DESTDIR)$(pkgcupsserverrootdir)" "$(DESTDIR)$(pkgdriverdir)" "$(DESTDIR)$(pkgfiltersincludedir)" "$(DESTDIR)$(pkgfontconfigdir)" "$(DESTDIR)$(pkgfontembedincludedir)" "$(DESTDIR)$(pkgmimedir)" "$(DESTDIR)$(pkgppdcdir)" "$(DESTDIR)$(ppddir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
+ clean-libLTLIBRARIES clean-libtool \
+ clean-phpextensionLTLIBRARIES clean-pkgbackendPROGRAMS \
+ clean-pkgfilterPROGRAMS clean-pkgppdgenPROGRAMS \
+ clean-sbinPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-hdr distclean-libtool distclean-local distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-docDATA install-initrcSCRIPTS install-man \
+ install-nodist_pkgbrailleSCRIPTS \
+ install-nodist_pkgfilterSCRIPTS install-nodist_pkgppdcDATA \
+ install-phpextensionLTLIBRARIES install-pkgbackendPROGRAMS \
+ install-pkgbannerDATA install-pkgcharsetDATA \
+ install-pkgconfDATA install-pkgcupsdataDATA \
+ install-pkgcupsserverrootDATA install-pkgdriverDATA \
+ install-pkgfilterPROGRAMS install-pkgfilterSCRIPTS \
+ install-pkgfiltersincludeDATA install-pkgfontconfigDATA \
+ install-pkgfontembedincludeDATA install-pkgmimeDATA \
+ install-pkgppdcDATA install-pkgppdgenPROGRAMS install-ppdDATA
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS install-libLTLIBRARIES \
+ install-sbinPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man1 install-man5 install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-docDATA \
+ uninstall-initrcSCRIPTS uninstall-libLTLIBRARIES uninstall-man \
+ uninstall-nodist_pkgbrailleSCRIPTS \
+ uninstall-nodist_pkgfilterSCRIPTS uninstall-nodist_pkgppdcDATA \
+ uninstall-phpextensionLTLIBRARIES uninstall-pkgbackendPROGRAMS \
+ uninstall-pkgbannerDATA uninstall-pkgcharsetDATA \
+ uninstall-pkgconfDATA uninstall-pkgcupsdataDATA \
+ uninstall-pkgcupsserverrootDATA uninstall-pkgdriverDATA \
+ uninstall-pkgfilterPROGRAMS uninstall-pkgfilterSCRIPTS \
+ uninstall-pkgfiltersincludeDATA uninstall-pkgfontconfigDATA \
+ uninstall-pkgfontembedincludeDATA uninstall-pkgmimeDATA \
+ uninstall-pkgppdcDATA uninstall-pkgppdgenPROGRAMS \
+ uninstall-ppdDATA uninstall-sbinPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-hook
+uninstall-man: uninstall-man1 uninstall-man5 uninstall-man8
+
+.MAKE: all check check-am install install-am install-data-am \
+ install-exec-am install-strip uninstall-am
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-TESTS \
+ check-am clean clean-binPROGRAMS clean-checkPROGRAMS \
+ clean-cscope clean-generic clean-libLTLIBRARIES clean-libtool \
+ clean-phpextensionLTLIBRARIES clean-pkgbackendPROGRAMS \
+ clean-pkgfilterPROGRAMS clean-pkgppdgenPROGRAMS \
+ clean-sbinPROGRAMS cscope cscopelist-am ctags ctags-am dist \
+ dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
+ dist-xz dist-zip distcheck distclean distclean-compile \
+ distclean-generic distclean-hdr distclean-libtool \
+ distclean-local distclean-tags distcleancheck distdir \
+ distuninstallcheck dvi dvi-am html html-am info info-am \
+ install install-am install-binPROGRAMS install-data \
+ install-data-am install-data-hook install-docDATA install-dvi \
+ install-dvi-am install-exec install-exec-am install-exec-hook \
+ install-html install-html-am install-info install-info-am \
+ install-initrcSCRIPTS install-libLTLIBRARIES install-man \
+ install-man1 install-man5 install-man8 \
+ install-nodist_pkgbrailleSCRIPTS \
+ install-nodist_pkgfilterSCRIPTS install-nodist_pkgppdcDATA \
+ install-pdf install-pdf-am install-phpextensionLTLIBRARIES \
+ install-pkgbackendPROGRAMS install-pkgbannerDATA \
+ install-pkgcharsetDATA install-pkgconfDATA \
+ install-pkgcupsdataDATA install-pkgcupsserverrootDATA \
+ install-pkgdriverDATA install-pkgfilterPROGRAMS \
+ install-pkgfilterSCRIPTS install-pkgfiltersincludeDATA \
+ install-pkgfontconfigDATA install-pkgfontembedincludeDATA \
+ install-pkgmimeDATA install-pkgppdcDATA \
+ install-pkgppdgenPROGRAMS install-ppdDATA install-ps \
+ install-ps-am install-sbinPROGRAMS install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am \
+ uninstall-binPROGRAMS uninstall-docDATA uninstall-hook \
+ uninstall-initrcSCRIPTS uninstall-libLTLIBRARIES uninstall-man \
+ uninstall-man1 uninstall-man5 uninstall-man8 \
+ uninstall-nodist_pkgbrailleSCRIPTS \
+ uninstall-nodist_pkgfilterSCRIPTS uninstall-nodist_pkgppdcDATA \
+ uninstall-phpextensionLTLIBRARIES uninstall-pkgbackendPROGRAMS \
+ uninstall-pkgbannerDATA uninstall-pkgcharsetDATA \
+ uninstall-pkgconfDATA uninstall-pkgcupsdataDATA \
+ uninstall-pkgcupsserverrootDATA uninstall-pkgdriverDATA \
+ uninstall-pkgfilterPROGRAMS uninstall-pkgfilterSCRIPTS \
+ uninstall-pkgfiltersincludeDATA uninstall-pkgfontconfigDATA \
+ uninstall-pkgfontembedincludeDATA uninstall-pkgmimeDATA \
+ uninstall-pkgppdcDATA uninstall-pkgppdgenPROGRAMS \
+ uninstall-ppdDATA uninstall-sbinPROGRAMS
+
+.PRECIOUS: Makefile
+
+
+@ENABLE_BRAILLE_TRUE@filter/braille/filters/liblouis1.defs: filter/braille/filters/liblouis1.defs.gen
+@ENABLE_BRAILLE_TRUE@ $< > $@
+
+@ENABLE_BRAILLE_TRUE@$(GENERATED_LIBLOUIS): filter/braille/filters/liblouis%.defs: filter/braille/filters/liblouis1.defs
+@ENABLE_BRAILLE_TRUE@ sed -e "s/Braille transcription/Additional Braille transcription ($*)/" \
+@ENABLE_BRAILLE_TRUE@ -e "s/^ \\*Choice / Choice /" \
+@ENABLE_BRAILLE_TRUE@ -e "s/^ Choice \"None\// *Choice \"None\//" \
+@ENABLE_BRAILLE_TRUE@ -e s/LibLouis/LibLouis$*/ \
+@ENABLE_BRAILLE_TRUE@ < $< > $@
+
+$(cups_notifier_sources): utils/org.cups.cupsd.Notifier.xml
+ gdbus-codegen \
+ --interface-prefix org.cups.cupsd \
+ --c-namespace Cups \
+ --generate-c-code cups-notifier \
+ utils/org.cups.cupsd.Notifier.xml
+
+distclean-local:
+ rm -rf *.cache *~
+
+install-exec-hook:
+ $(INSTALL) -d -m 755 $(DESTDIR)$(bindir)
+ $(INSTALL) -d -m 755 $(DESTDIR)$(pkgfilterdir)
+ $(INSTALL) -d -m 755 $(DESTDIR)$(pkgbackenddir)
+@ENABLE_FOOMATIC_TRUE@ $(LN_S) -r -f $(DESTDIR)$(pkgfilterdir)/foomatic-rip $(DESTDIR)$(bindir)
+@ENABLE_DRIVERLESS_TRUE@ $(LN_S) -r -f $(DESTDIR)$(pkgppdgendir)/driverless $(DESTDIR)$(bindir)
+@ENABLE_DRIVERLESS_TRUE@ $(LN_S) -r -f $(DESTDIR)$(pkgppdgendir)/driverless $(DESTDIR)$(pkgbackenddir)
+@ENABLE_BRAILLE_TRUE@ $(LN_S) -f imagetobrf $(DESTDIR)$(pkgfilterdir)/imagetoubrl
+@ENABLE_BRAILLE_TRUE@ $(LN_S) -f vectortopdf $(DESTDIR)$(pkgfilterdir)/svgtopdf
+@ENABLE_BRAILLE_TRUE@ $(LN_S) -f vectortopdf $(DESTDIR)$(pkgfilterdir)/xfigtopdf
+@ENABLE_BRAILLE_TRUE@ $(LN_S) -f vectortopdf $(DESTDIR)$(pkgfilterdir)/wmftopdf
+@ENABLE_BRAILLE_TRUE@ $(LN_S) -f vectortopdf $(DESTDIR)$(pkgfilterdir)/emftopdf
+@ENABLE_BRAILLE_TRUE@ $(LN_S) -f vectortopdf $(DESTDIR)$(pkgfilterdir)/cgmtopdf
+@ENABLE_BRAILLE_TRUE@ $(LN_S) -f vectortopdf $(DESTDIR)$(pkgfilterdir)/cmxtopdf
+@ENABLE_BRAILLE_TRUE@ $(LN_S) -f vectortobrf $(DESTDIR)$(pkgfilterdir)/vectortoubrl
+@ENABLE_BRAILLE_TRUE@ $(LN_S) -f textbrftoindexv3 $(DESTDIR)$(pkgfilterdir)/textbrftoindexv4
+
+install-data-hook:
+@RCLINKS_TRUE@ for level in $(RCLEVELS); do \
+@RCLINKS_TRUE@ $(INSTALL) -d -m 755 $(DESTDIR)$(INITDIR)/rc$${level}.d; \
+@RCLINKS_TRUE@ $(LN_S) -f ../init.d/cups-browsed $(DESTDIR)$(INITDIR)/rc$${level}.d/S$(RCSTART)cups-browsed; \
+@RCLINKS_TRUE@ $(LN_S) -f ../init.d/cups-browsed $(DESTDIR)$(INITDIR)/rc$${level}.d/K$(RCSTOP)cups-browsed; \
+@RCLINKS_TRUE@ done; \
+@RCLINKS_TRUE@ $(INSTALL) -d -m 755 $(DESTDIR)$(INITDIR)/rc0.d; \
+@RCLINKS_TRUE@ $(LN_S) -f ../init.d/cups-browsed $(DESTDIR)$(INITDIR)/rc0.d/K$(RCSTOP)cups-browsed;
+ $(LN_S) -f pdf.utf-8.simple \
+ $(DESTDIR)$(pkgcharsetdir)/pdf.utf-8
+@ENABLE_BRAILLE_TRUE@ chmod g-rwx,o-rwx $(DESTDIR)/$(pkgbackenddir)/cups-brf
+
+uninstall-hook:
+@RCLINKS_TRUE@ if test "x$(INITDIR)" != x; then \
+@RCLINKS_TRUE@ $(RM) $(DESTDIR)$(BUILDROOT)$(INITDIR)/rc?.d/[SK]??cups-browsed || :; \
+@RCLINKS_TRUE@ rmdir $(DESTDIR)$(BUILDROOT)$(INITDIR)/rc?.d || :;\
+@RCLINKS_TRUE@ fi
+ $(RM) $(DESTDIR)$(pkgcharsetdir)/pdf.utf-8
+@ENABLE_FOOMATIC_TRUE@ $(RM) $(DESTDIR)$(bindir)/foomatic-rip
+@ENABLE_DRIVERLESS_TRUE@ $(RM) $(DESTDIR)$(bindir)/driverless
+@ENABLE_DRIVERLESS_TRUE@ $(RM) $(DESTDIR)$(pkgbackenddir)/driverless
+@ENABLE_BRAILLE_TRUE@ $(RM) $(DESTDIR)$(pkgfilterdir)/imagetoubrl
+@ENABLE_BRAILLE_TRUE@ $(RM) $(DESTDIR)$(pkgfilterdir)/svgtopdf
+@ENABLE_BRAILLE_TRUE@ $(RM) $(DESTDIR)$(pkgfilterdir)/xfigtopdf
+@ENABLE_BRAILLE_TRUE@ $(RM) $(DESTDIR)$(pkgfilterdir)/wmftopdf
+@ENABLE_BRAILLE_TRUE@ $(RM) $(DESTDIR)$(pkgfilterdir)/emftopdf
+@ENABLE_BRAILLE_TRUE@ $(RM) $(DESTDIR)$(pkgfilterdir)/cgmtopdf
+@ENABLE_BRAILLE_TRUE@ $(RM) $(DESTDIR)$(pkgfilterdir)/cmxtopdf
+@ENABLE_BRAILLE_TRUE@ $(RM) $(DESTDIR)$(pkgfilterdir)/vectortoubrl
+@ENABLE_BRAILLE_TRUE@ $(RM) $(DESTDIR)$(pkgfilterdir)/textbrftoindexv4
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/NEWS b/NEWS
new file mode 100644
index 000000000..e3824f434
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,2306 @@
+NEWS - OpenPrinting CUPS Filters v1.17.9 - 2017-10-05
+-----------------------------------------------------
+
+CHANGES IN V1.17.9
+
+ - cups-browsed: Applying option defaults from the
+ DefaultOptions directive in cups-browsed.conf got
+ lost. Re-introduced it (Bug #1414).
+ - cups-browsed: Get printer-location field from remote
+ printers. Thanks to Marek Kasik for the patch (Bug #1413).
+
+CHANGES IN V1.17.8
+
+ - foomatic-rip: Change execution of renderer thread to fail
+ whenever any of its individual sub-comands fails. Thanks to
+ LUUM (luum at chromium dot org) for the patch (Bug #1412).
+ - foomatic-rip: Parent process now ignores SIGPIPE calls from
+ upstream/downstream CUPS filters, per
+ https://www.cups.org/doc/api-filter.html, while correctly
+ noting child process failures and exiting
+ accordingly. Thanks to LUUM (luum at chromium dot org) for
+ the patch (Bug #1412).
+ - Build system: Fixed typo which broke the
+ "--enable-gs-ps2write" ./configure command line option (Bug
+ #1410).
+
+CHANGES IN V1.17.7
+
+ - braille: Add a mirror option for graphical output. Thanks to
+ Samuel Thibault for this patch.
+ - braille: Rename the internal cups name of the Resize option
+ to the standard well-known and well-documented fitplot
+ option. Thanks to Samuel Thibault for this patch.
+ - braille: Add support for margins in graphical mode,
+ defaulting them to 15 points (a bit more than 5mm). Thanks
+ to Samuel Thibault for this patch.
+ - braille: Updated French translation. Thanks to Samuel
+ Thibault for this patch.
+ - braille: Add a PPD which generates UBRL output, i.e. Braille
+ expressed in Unicode. This is not useful for actual
+ embossers, but very convenient to check output to be
+ embossed without wasting paper. Thanks to Samuel Thibault
+ for this patch.
+ - braille: Add virtual BRF backend for generating
+ ready-to-emboss BRF files with CUPS, similarly to the
+ cups-pdf backend. Thanks to Samuel Thibault for this patch.
+ - braille: Some tools seem to emit true/false instead of
+ True/False, so let us cope with it. Thanks to Samuel
+ Thibault for this patch.
+ - braille: "make uninstall" did not remove all the
+ links. Thanks to Samuel Thibault for this patch.
+ - braille: Add support for embossing MusicXML files, through
+ the FreeDots transcriptor. Thanks to Samuel Thibault for
+ this patch.
+ - braille: Add proper support for hardware margins on braille
+ embossers. Thanks to Samuel Thibault for this patch.
+ - braille: Fix the disabling of the text margins in Index
+ graphics mode. Thanks to Samuel Thibault for this patch.
+ - braille: Support for direct, structured embossing of XML and
+ XML-based file formats (like odt, docx, ...). Thanks to
+ Samuel Thibault for this patch.
+
+CHANGES IN V1.17.6
+
+ - braille: Embossers can only emboss integer numbers of 2x4
+ cells. Thanks to Samuel Thibault for this patch.
+ - braille: In Index graphical mode we need to disable the text
+ margins, since they come in earlier on the way to
+ there. Thanks to Samuel Thibault for this patch.
+ - braille: Also, we should always add a 1.6mm margin for
+ taking into account the width of dots. Thanks to Samuel
+ Thibault for this patch.
+
+CHANGES IN V1.17.5
+
+ - libcupsfilters: In the PPD generator for driverless printing
+ renamed the "print-quality" option back to
+ "cupsPrintQuality" as the support for this option got fixed
+ in CUPS (CUPS issue #5090).
+ - braille: Improvements on the braille support for bitmap
+ images: Moves the graphical dot distance option to the image
+ conversion group, add an option to avoid image resize, and
+ make the rotation option easier by proposing to just fit
+ paper instead of fitting portrait or landscape. Thanks to
+ Samuel Thibault for this patch.
+ - braille: Support for embossing vector images as braille.
+ Thanks to Samuel Thibault for this patch.
+ - braille: Fix liblouis1.defs installation. Thanks to Samuel
+ Thibault for this fix.
+
+CHANGES IN V1.17.4
+
+ - pdftopdf: If the input PDF file contains an interactive
+ form, flatten it to static PDF so that further manipulation,
+ like scaling, number-up, ... do not let the filled for
+ content getting lost. This is implemented by using the
+ pdftocairo utility of Poppler and if this fails Ghostscript
+ (9.22 or later recommended). This will probably replaced by
+ a QPDF-based solution later. Thanks to Tobias Hoffmann for
+ the QPDF-based detection of PDF forms (Bug #1315, Ubuntu bug
+ #1564249).
+
+CHANGES IN V1.17.3
+
+ - bannertopdf: Make it working also with Poppler 0.58.0 and
+ newer (Bug #1408).
+ - gstoraster, pdftops, foomatic-rip: Added "-dShowAcroForm" to
+ all Ghostscript command lines where the input data format
+ can be PDF. With this and the fix of Ghostscript bug
+ #698461 most filled PDF forms should be rendered correctly
+ by Ghostscript now.
+ - libcupsfilters: Do not check maximum resolutions of
+ raster-based PDLs, as implementation was incorrect and
+ reliability of PDLs is more important than maximum
+ resolution.
+
+CHANGES IN V1.17.2
+
+ - rastertopdf: Fixed outstanding bug in PCLm with JPEG (DCT)
+ compression. Now PCLm support is completely working.
+
+CHANGES IN V1.17.1
+
+ - libcupsfilters: Added direct PNG printing to the PPD
+ generator, the one of CUPS has it, too.
+ - libcupsfilters: In the PPD file generator renamed the option
+ "cupsPrintQuality" into the IPP name "print-quality" as CUPS
+ does not update the "print-quality=4" entry in the filter
+ command line based on the setting of "cupsPrintQuality"
+ (CUPS issue #5090).
+ - libcupsfilters: Completely redone the way how to determine
+ the resolutions to use for the default resolution and print
+ quality option in the PPDs generated for IPP
+ printers. Resolution lists from IPP attributes are now read
+ into sorted, duplicate-free lists with wrong resolutions
+ removed or fixed. Resolutions actually used are the common
+ ones between the supported PDLs, PDls with inferior maximum
+ resolution or with broken resolution list are skipped
+ (Debian bug #868360, Ubuntu bug #1712019, CUPS issue #5088,
+ CUPS issue #5091).
+ - rastertopdf: Prefer RLE compression instead of Flate as
+ there are HP printers where Flate is buggy.
+ - Build system: Fixed help mesage for "--enable-driverless"
+ configure option (Bug #1405).
+
+CHANGES IN V1.17.0
+
+ - rastertopdf, rastertopclm, driverless, cups-browsed,
+ libcupsfilters: Added support for the PCLm output format for
+ driverless printing on Mopria and Wi-Fi Direct
+ printers. This is the Google Summer of Code 2017 project of
+ Sahil Arora (sahilarora dot 535 at gmail dot com). Thank you
+ very much for your great work! The PCLm support requires
+ QPDF 7.0.0 or later.
+
+CHANGES IN V1.16.4
+
+ - Build system: Switched over to C11 standard with GNU
+ extensions (-std=gnu11).
+ - Build system: Removed -pedantic flag as it is only needed
+ for compatibility with commercial compilers like the ones of
+ Windows (and we use GNU extensions anyway).
+ - libfontembed, texttopdf: reverted removal of anonymous
+ union.
+
+CHANGES IN V1.16.3
+
+ - libfontembed: Reverted unneeded soname change.
+
+CHANGES IN V1.16.2
+
+ - README: Minimum CUPS requirement of cups-filters is CUPS
+ 1.4.x. It does not build with earlier CUPS versions (Bug
+ #993).
+ - driverless, foomatic-rip: Create relative symbolic links.
+ - All C/C++ files: Silenced all compiler warnings, at least
+ the ones appearing when building on Ubuntu Linux 17.10 with
+ GCC 7.1.0.
+ - README: Updated the introduction section to reflect the
+ current functionality of cups-filters, and the build
+ requirements for the Poppler-based filters (C++11: Bug
+ #1404, Build configuration of Poppler: Bug #1257). Thanks to
+ Roland Hieber (r dot hieber at pengutronix dot de) to find
+ out about this.
+ - pdftoopvp, bannertopdf, pdftoraster: Build with C++11
+ standard as some features of this standard are needed by
+ these filters (or by Poppler). Thanks to Roland Hieber (r
+ dot hieber at pengutronix dot de) for the patch (Bug #1404).
+
+CHANGES IN V1.16.1
+
+ - cups-browsed: Make timeouts for HTTP access to the local
+ CUPS daemon and remote IPP printers configurable. Thanks to
+ Cedric Dufour (cedric dot dufour at idiap dot ch) for the
+ patch (Bug #1387, Debian bug #852436).
+ - texttopdf: Allow bold and underline formatting to be used
+ together when using "prettyprint". Thanks to Michael Moran
+ (vampm at comcast dot net) for the patch.
+ - texttopdf: Allow to alter margins, and chars/lines per Inch
+ when using "prettyprint". Thanks to Michael Moran (vampm at
+ comcast dot net) for the patch.
+ - texttopdf: When "prettyprint" is used, do not drop out of
+ C/shell comment mode too early. Thanks to Michael Moran
+ (vampm at comcast dot net) for the patch.
+ - cups-browsed: Additional NULL checks for description and
+ location.
+ - cups-browsed: Fixed crash which happens when using
+ BrowsePoll (Debian bug #723835).
+
+CHANGES IN V1.16.0
+
+ - cups-browsed: Let elements in arrays get stacked up in the
+ order they are added, before, they were in the order how
+ they are positioned in memory. This especially led to a
+ random order of printer cluster definitions and of
+ command-line-supplied configuration options.
+ - cups-browsed: On shutdown not all locally created queues got
+ deleted.
+ - cups-browsed: Added support for manual definition of
+ load-balancing printer clusters via the "Cluster" directive
+ in cups-browsed.conf.
+
+CHANGES IN V1.15.0
+
+ - cups-browsed: Removed the function to compare printer entries
+ for sorting the printer entry list. This led to corruption
+ of the list and so to crashes.
+ - cups-browsed: Fixed crashes when many printers (especially
+ all printers of a load-balanced cluster) are removed at once.
+ - cups-browsed: Log the full list of handled remote printers
+ whenever one is added or removed.
+ - cups-browsed: Renamed the handle_cups_queues() function to
+ update_cups_queues() to better reflect what it is doing.
+ - cups-browsed: When clustering remote CUPS printers together
+ do not call them duplicates but slaves asigned to a master.
+ - cups-browsed: Log the error if the network interface name of
+ a DNS-SD event could not be determined.
+ - cups-browsed: Simplified printer entry removal procedure.
+ - cups-browsed: Log memeber printer list of a printer cluster
+ (implicit class) when a member printer is added or removed.
+ - cups-browsed: Removed superfluous (and not correctly
+ working) duplicate counter from the remote printer entry
+ data structure.
+ - cups-browsed: Add "AutoClustering" directive to
+ cups-browsed.conf to turn on and off automatically
+ clustering equally named local print queues which point to
+ remote CUPS printers. When automatic clustering is turned
+ off, queue name clashes are prevented by adding "@<server
+ name>" to local queue names based on the remote queue name
+ or on make and model.
+ - cups-browsed: Skip callback functions and the CUPS queue
+ creation/update/removal loop when cups-browsed is terminated
+ by a SIGTERM signal. This avoids hanging on shutdown. Thanks
+ to Edgar Fuss (ef at math dot uni-bonn dot de, Bug #1402).
+ - libcupsfilters: Added some fallbacks for incorrect
+ resolution IPP attributes on IPP network printers (Debian
+ bug #868360).
+ - pdftoopvp: Added missing "#include <math.h>" needed for
+ cross-compiling for arm-v7a-linux-gnueabi (Bug #1232).
+ - cups-browsed: Prevent the creation of two remote printer
+ entries for two IPP network printers or an IPP network
+ printer and a remote CUPS printer with the same local queue
+ name. This could easily happen with make/model-based naming.
+ - cups-browsed: Added the possibility to optionally not
+ create local queues for remote printers for which CUPS
+ (from 2.2.x on) auto-creates queues by itself (DNS-SD
+ advertised driverless printers).
+ - cups-browsed: Removed repeated code for clean-up when
+ generate_local_queue() function fails.
+ - cups-browsed: Take care of CUPS' temporary queues. Do not
+ consider them when checking whether a queue with the same
+ name as the one we are creating already exists and make
+ temporary queues permanent (or remove them) before
+ overwriting them with our local queue.
+ - cups-browsed: Make the naming scheme for locally created
+ print queue configurable, especially allow for naming based
+ on the DNS-SD service name (now default) as this is the same
+ scheme as CUPS uses for its temporary queues. This way we
+ prevent CUPS creating temporary queues when cups-browsed is
+ already creating a queue.
+ - cups-browsed: Do not add "APRemoteQueueID" keyword to the
+ local queue's PPD file if the queue is for an IPP network
+ printer.
+ - cups-browsed: Skip multiple browse entries for the same
+ printer with interface alias addresses. Thanks to Edgar
+ Fuss (ef at math dot uni-bonn dot de, Bug #1399).
+ - cups-browsed: Improved support for Description (Info) and
+ Location fields of remote CUPS queues. Thanks to Edgar Fuss
+ (ef at math dot uni-bonn dot de, Bug #1398).
+ - cups-browsed: Renamed variable names for better code
+ readability. Thanks to Edgar Fuss (ef at math dot uni-bonn
+ dot de, Bug #1398).
+ - cups-browsed: Additional NULL checks in the
+ create_local_queue() function. Thanks to Edgar Fuss (ef at
+ math dot uni-bonn dot de, Bug #1398).
+
+CHANGES IN V1.14.1
+
+ - cups-browsed: Do correct removal of printer entry handling
+ duplicates correctly also when a legacy CUPS-broadcasted
+ printer disappears or a printer remaining from the last
+ session does not appear again.
+ - cups-browsed: Use getline() instead of fgets() to read saved
+ option settings. This is less crash-prone (Ubuntu bug
+ #1658833).
+ - cups-browsed: Improved error logging when saving option
+ settings.
+ - cups-browsed: Added NULL checks for generate_local_queue()
+ and create_local_queue() functions.
+ - cups-browsed: When accessing local CUPS queues use always
+ the correct port of the CUPS daemon we are attached to.
+ - cups-browsed: Check whether a connection to the local CUPS
+ daemon actually happened before using it (Ubuntu bug
+ #1644049).
+ - cups-browsed: Set unused fields of printer record to NULL
+ when tranfering data from the record of a duplicate printer
+ to the record of a disappeared one.
+ - cups-browsed: Simplify removal of all queues on shutdown or
+ stop of Avahi.
+ - cups-browsed: When creating a record for a discovered
+ printer set it all zero before filling it in, to assure
+ that no field is in an undefined state.
+ - cups-browsed: All functions which are called via Glib
+ functions or otherwise event-triggered log now in which
+ thread they are running. This way one can see whether
+ problems can be caused by concurrent access to global
+ resources.
+ - cups-browsed: Do not check whether the DNS-SD event is from
+ the local machine in the browse_callback() function. We
+ cannot check the port here.
+ - cups-browsed: Added more NULL checks to Avahi callback
+ functions.
+ - cups-browsed: Added NULL check to avoid crashes in the Avahi
+ resolver callback (Ubuntu bug #1696967).
+ - libcupsfilters: Let PPD generator do case-insensitive
+ comparisons for PWG Raster color spaces, as some printers
+ (Epson) do not use the standard-conforming all-lowercase
+ form for them (CUPS Issue #4998).
+
+CHANGES IN V1.14.0
+
+ - cups-browsed: When a printer is discovered via DNS-SD on the
+ "lo" (loopback) interface the printer is not reliably
+ accessible through the reported host name (which is the
+ network host name of the local machine). Until this problem
+ is fixed in Avahi, we create queues for such printers with a
+ URI based on the IP address. This is a workaround until
+ Avahi fully supports the "lo" interface.
+ - cups-browsed: Added new setting "LocalOnly" for the
+ CreateIPPPrinterQueues in cups-browsed.conf. With this new
+ setting (which is the default from now on) only for local
+ printers made available as IPP printers (like IPP-over-USB
+ printers with ippusbxd) queues are auto-created. With this
+ we can follow the common standard of distributions where USB
+ printers are automatically set up and network printers not.
+ - cups-browsed: Fixes and improvements in comments and debug
+ messages: 1. Bonjour -> DNS-SD; 2. When a remote CUPS class
+ is discovered, tell that it is a class; 3. Show network
+ interface and IPv4/IPv6 when a DNS-Sd service appears or
+ disappears.
+ - cups-browsed: Added ./configure script option
+ "--enable-auto-setup-driverless" to let cups-browsed
+ automatically set up IPP network printers by default.
+
+CHANGES IN V1.13.5
+
+ - foomatic-rip: When called via the utility cupsfilter from
+ CUPS, foomatic-rip was not able to read the PPD file with
+ the file name supplied as environment variable PPD (Bug
+ #1388).
+ - driverless: Improved error message output.
+ - libcupsfilters: Fixed error handling of the PPD file
+ generator for driverless printing, so that callers get
+ decent error messages.
+ - libcupsfilters: Do not generate a PPD file where the only
+ output data format is JPEG, as JPEG does not support
+ multi-page documents.
+ - libcupsfilters: Let PPD generator skip broken page size
+ records and add warnings for debugging to the PPD.
+ - libcupsfilters: Updated PPD generator to match with the
+ current GIT state of the one of CUPS.
+ - braille: Automatically select a table according to the
+ current locale.
+ - braille: Update for liblouis table list.
+ - braille: Added support for text margins.
+ - cups-browsed: When creating a local queue for a remote CUPS
+ printer, add the line '*APRemoteQueueID: ""' to the PPD file
+ so that CUPS sets the CUPS_PRINTER_REMOTE bit for the
+ printer type of the local queue (Bug #1386).
+
+CHANGES IN V1.13.4
+
+ - libcupsfilters: Let PPD generator for driverless printing
+ not error out when there is no urf-supported or
+ pwg-raster-document-resolution-supported IPP attribute,
+ simply accept the default resolution also from the
+ printer-resolution-default attribute or set a default value
+ of 300 dpi to get a working PPD file.
+ - cups-browsed: Do not use deprecated names for IPP status
+ constants
+ - cups-browsed: Corrected determination whether an IPP status
+ is an error, to avoid "Unable to create/modify CUPS queue
+ (Success)" and infinite repetition of a succeeded operation
+ (Debian bug #852436).
+
+CHANGES IN V1.13.3
+
+ - libcupsfilters: When auto-generating PPD files added support
+ for passing through JPEG input to printers which understand
+ JPEG. This is also done in CUPS-generated PPDs (Debian bug
+ #851499).
+ - libcupsfilters: Added the "output-bin" option support from
+ CUPS' PPD generator to our PPD generator (CUPS Issue #4938).
+ - cups-browsed: Make support for printers with IPv6 IP address
+ work. Both link-local and regular addresses work.
+
+CHANGES IN V1.13.2
+
+ - cupsfilters.drv: Corrected cupsFilter entry for the "Generic
+ IPP Everywhere Printer".
+ - driverless: Fixes on the man page (Debian bug #849075).
+ - driverless: Do not error-exit (non-zero status) when run by
+ CUPS as backend or PPD generator when no driverless printer
+ is found or Avahi not running. When run from thr command
+ line, exit status is the same as of ippfind.
+ - imagetoraster: Removed (incomplete) PWG Raster support. For
+ PWG Raster output we let the rastertopwg filter from CUPS do
+ the finalization (mainly adding white pixels at the borders
+ to get a full-page bitmap).
+ - imagetoraster: Fixed several bugs in the calculation of the
+ page geometry (Debian bug #849380).
+ - libcupsfilters: If the IPP-polled printer has the
+ "sides-supported" attribute, determine the need of a
+ "Duplex" option solely whether the attribute has a
+ "two-sided-long-edge" choice and ignore the "duplex"
+ parameter of the ppdCreateFromIPP() function call. This lets
+ the more precise information coming from the IPP query
+ always be preferred against information from the Bonjour
+ record.
+ - driverless: When listing printers let the device ID contain
+ "AppleRaster" (for Apple Raster printers) and "PWGRaster"
+ (for IPP Everywhere printers) in the "CMD" field.
+ - driverless: Added "-T 3" to the ippfind command line. This
+ makes ippfind search the Bonjour broadcasts for up to 3
+ seconds when searching for IPP printers, raising the
+ reliability in finding all of them (Debian bug #848712).
+
+CHANGES IN V1.13.1
+
+ - cups-browsed: Avoid erroring out when restarting after a
+ crash (with generated queues not deleted due to the crash)
+ and the configuration option
+ CreateRemoteCUPSPrinterQueues=No being set.
+ - cups-browsed: If CUPS is stopped while cups-browsed is
+ running and there are queue for IPP network printers (not
+ remote CUPS queues) on restart of CUPS the still existing
+ local CUPS queue is not correctly re-connected with
+ cups-browsed and therefore gets removed after a
+ timeout. This should be fixed after a clean-up of
+ re-connecting with remaining queues from a previous session
+ (Debian bug #848223).
+ - cups-browsed: Generated queues did not get removed on
+ shutdown (Debian bug #848167).
+ - libcupsfilters: Let PPD generator for driverless printing
+ suppress page sizes which the printer reports more than
+ once (CUPS Issue #4933).
+ - driverless, libcupsfilters: Make "driverless list" output
+ and output of driverless as CUPS backend in discovery mode
+ add the word "driverless" to its output, to make it easier
+ to set up driverless printers with printer setup tools.
+ Made the NickName of the generated PPDs also match with the
+ "driverless list" output.
+
+CHANGES IN V1.13.0
+
+ - cups-browsed: Use the httpGetAddr() only with CUPS 2.0.x or
+ newer, as older CUPS versions do not provide it (Bug #1381).
+ - cups-browsed: Minor corrections in the handling of the data
+ records of the discovered printers.
+ - rastertopdf, urftopdf: As with libcupsimage from CUPS 2.2.2
+ on rastertopdf also understands Apple Raster and much better
+ than urftopdf does, use rastertopdf for Apple Raster
+ (image/urf) input files then. Also allow for manually
+ choosing by the ./configure command line.
+ - driverless: Added a CUPS backend mode to the driverless
+ utility. Running as a CUPS backend in discovery mode it
+ lists the IPP URIs of the suitable printers in printer setup
+ tools and in "lpinfo -v", as conneting via IPP is required
+ for driverless printing.
+
+CHANGES IN V1.12.0
+
+ - cups-browsed: Added new "CreateRemoteCUPSPrinterQueues"
+ directive to cups-browsed.conf, which allows to decide
+ whether to auto-create local print queues for shared CUPS
+ queues on remote machines. This way one can also set up
+ servers which only create queues for IPP network printers.
+ - driverless: Added new /usr/lib/cups/driver/driverless
+ utility to make CUPS auto-generate PPD files for printers
+ designed for driverless use (IPP Everywhere, Apple Raster)
+ when they are set up with a printer setup tool. This gives
+ transparency to set up these printers with legacy printer
+ setup tools. This utility is also linked to /ustr/bin to
+ manually generate PPDs via command line.
+ - libcupsfilters, cups-browsed: Moved the PPD generator for
+ IPP network printers from cups-browsed to libcupsfilters, so
+ that it can also be used by other utilities.
+ - cups-browsed: When auto-generating a PPD set the cost values
+ in the filter lines to give the highest priority to PDF,
+ then PWG Raster, Apple Raster, PCL-XL, PostScript, PCL 5c/e.
+ - cups-browsed: Synced the PPD generator with the one of CUPS,
+ giving the best possible support for IPP Everywhere and
+ AirPrint printers. Especially support for more media types
+ and for finishing units got added. Also support for more
+ different ways to represent the printer capabilities via
+ IPP attributes got added.
+ - cups-browsed: Added support for auto setup of IPP printers
+ understanding the Apple Raster input data format (.urf, on
+ AirPrint printers), only if CUPS 2.2.2 is used, which can
+ generate this format via its rastertopwg filter.
+ - cups-browsed: Added new "NewIPPPrinterQueuesShared"
+ directive to cups-browsed.conf, which allows to decide
+ whether the auto-created local print queue for a newly
+ discovered IPP network printer will be shared or not. For
+ printers discovered earlier, cups-browsed remembers the
+ previous setting.
+ - cups-browsed: If a user changes the printer-is-shared bit of
+ an auto-created print queue for an IPP network printer (not
+ for a remote CUPS queue), record this fact and recover the
+ change when creating this queue in the next session.
+ - cups-browsed: For automatic creation of print queues for IPP
+ network printers also allow only creating queues for IPP
+ Everywhere printers, only for Apple Raster printers, or for
+ both printer types designed for driverless printing and not
+ only for all suitable printers, configurable via the
+ CreateIPPPrinterQueues directive in cups-browsed.conf.
+
+CHANGES IN V1.11.6
+
+ - pdftops: Do not default to simply "pdftops" when calling the
+ Poppler pdftops utility, as the $PATH of CUPS when running
+ filters/backends starts with /usr/lib/cups/filter/ and then
+ pdftops would call itself (Bug #1380).
+
+CHANGES IN V1.11.5
+
+ - cups-browsed: Fixed several typos in the documentation (Bug
+ #1378).
+ - gstoraster, mupdftoraster, pdftops, sys5ippprinter: Use
+ execvp() and execvpe() to call programs so that the $PATH
+ environment variable gets used to find the programs (Bug
+ #1378).
+ - build system: Several fixes, especially to make it work when
+ cross-compiling or using a build server (Bug #1378).
+ - cups-browsed: Silenced a warning.
+ - cups-browsed: For remote CUPS queues with a dot in their
+ name no local queue got created (Bug #1379).
+ - pdftopdf: Do the page logging also for IPP Everywhere
+ printers which use the PWG Raster data format as the
+ ...toraster filters being the last filter then do not log.
+ - gstoraster, pdftoraster: Let filters generate PWG Raster if
+ the environment variable FINAL_CONTENT_TYPE is set to
+ image/pwg-raster, make sure full-page bitmaps are generated
+ in PWG_raster mode, and added mime conversion rules for
+ direct PWG Raster output.
+ - cups-browsed: Corrected checking of the PDLs of an IPP network
+ printer. Now PCL 5c/e printers (not HP inkjets) should get
+ recognized correctly.
+ - texttopdf: Added missing NULL check to avoid a segfault when
+ texttopdf does not find a suitable (monospace TTF) font.
+ - foomatic-rip: Replace old manpage macro calls from
+ foomatic-filters 3.0.2-20050114.
+ - cups-browsed: Allow changing BrowseInterval and
+ BrowseTimeout via cups-browsed.conf, as it was formerly with
+ CUPS (Debian bug #794655).
+ - pdftopdf: Count the actual output pages also if the
+ number-up option is not used, to correctly find out whether
+ we have an even or odd number of pages, even if the
+ page-ranges option is used. This is needed to correctly
+ decide whether for duplex printing a blank page has to be
+ added (Bug #1377).
+
+CHANGES IN V1.11.4
+
+ - gstoraster: Allow Ghostscript to use the center-of-pixel
+ method instead of the PostScript-standard any-part-of-pixel
+ method when rendering filled paths. This improves the
+ graphics output quality of low-resolution printers like
+ label printers, for example to assure readability of bar
+ codes (Bug #1373).
+ - cups-browsed: Fixes to avoid unneeded calls of
+ handle_cups_queues() and even infinite loops (Possible fix
+ for bug #1376). Also make sure that queues left over from
+ the previous cups-browsed session are integrated correctly.
+
+CHANGES IN V1.11.3
+
+ - cups-browsed: If a queue is not only discovered via Bonjour
+ but also via legacy CUPS or LDAP, prefer the Bonjour record
+ as it provides more information and there is also a defined
+ cancellation broadcast.
+ - cups-browsed: Let PPD options saved in the last session also
+ get applied to generated PPDs for IPP network printers.
+ - cups-browsed: Make sure that saved PPD options do not get
+ lost if for some reason the PPD file cannot be loaded in a
+ new cups-browsed session (or the loaded PPD file is
+ different). This is done by holding a copy of the settings
+ in the remote printer data structure.
+ - cups-browsed: When saving option settings, remove
+ backslashes added when the settings are read out via IPP
+ request. Otherwise the backslashes would double with each
+ session of cups-browsed.
+ - implicitclass: Do not let the job get immediately retried on
+ failure to send it out to the remote CUPS printer. By
+ repeating to send the job to an unavailable server so
+ quickly, cups-browsed gets bombed with requests and hangs on
+ shutdown.
+ - cups-browsed: Shortened timeouts of HTTP connections and IPP
+ requests to 3 seconds amd of IPP requests to remote CUPS
+ servers to 2 seconds. For local IPP requests always use the
+ connection once created via http_connect_local(). Also call
+ g_main_context_wakeup(NULL) after each
+ g_main_loop_quit(gmainloop) call. These measures should
+ reduce long hangs of cups-browsed on shutdown when a CUPS
+ server got unavailable.
+ - cups-browsed: Do not mark remote printers discovered via
+ legacy CUPS broadcasts as disappeared right from the
+ beginning to implement the browse timeout. Instead manage
+ their expiring by introducing a flag which marks them as
+ CUPS legacy printers. Printers with disappeared status are
+ considered invalid in some situations, especially when
+ clusterin equally-named remote printers (Bug #1374).
+ - cups-browsed: When we have remote CUPS printers, we use the
+ implicitclass backend and a local copy of the remote PPD
+ file already if we have only a single remote printer with
+ this queue name. This simplifies the management of remote
+ CUPS printers and also we do not hassle with using a remote
+ PPD file. Now one can change PPD option defaults with
+ printer setup tools or the lpadmin command and they get
+ preserved in the next cups-browsed sessions.
+ - if we are using the implicitclass backend CUPS does not make
+ the server's PPD file available on the client any more. To
+ fix this, we download the PPD file when creating an
+ implictclass:... queue and apply it to the queue. This way
+ the options of the printer(s) are always available for
+ enumeration, especially in print dialogs (Bug #1372). We
+ modify the local copy setting any options saved from the
+ previous session and inhibiting local execution of filters
+ (as the driver for the remote printer is not necessarily
+ available locally).
+ - cups-browsed: Added flag to inhibit auto-backup of option
+ settings by the on_printer_modified() notification handler
+ during print queue setup and removal.
+ - cups-browsed: Let the printer_record() function always
+ return the master record for the printer name and not an
+ arbitrary duplicate.
+ - cups-browsed: Fixes in the functionality for saving option
+ settings: Make sure to not save the same option twice with
+ different values, do not save the "printer-is-shared" option
+ (errors out when re-applying option in the next session).
+ - cups-browsed: Treat discovered printers correctly also if
+ they use a non-standard port, even if several CUPS daemons
+ are running on the same server but on different ports. This
+ also improves the support of a sandboxed printing stack.
+ - cups-browsed: Close http connections opened for polling
+ properties of IPP network printers, to fix a possible memory
+ leak.
+ - cups-browsed: Cleaned up HTTP access to local and remote
+ CUPS servers and IPP printers, to assure that the local CUPS
+ daemon is always accessed the same (user-defined) way
+ (domain socket/localhost:port). This especially prevents
+ cups-browwsed hanging on shutdown (Debian bug #832637).
+ - cups-browsed: Fixed clustering equally-named queues of
+ different remote servers, to assure to have one master
+ referencing to all duplicates and not a daisy chain of
+ duplicate references.
+
+CHANGES IN V1.11.2
+
+ - cups-browsed: Allow turning off the use of CUPS' domain
+ socket via cups-browsed.conf.
+ - foomatic-rip: When run as regular CUPS filter use preferably
+ /etc/cups/foomatic-rip.conf (or whereever the CUPS
+ configuration files reside, according to the CUPS_SERVERROOT
+ environment variable) as configuration file. This way we can
+ more easily run the printing stack in a sandbox.
+ - foomatic-rip: When run as regular CUPS filter, read the PPD
+ through CUPS and get the print queue name by environment
+ variable.
+ - bannertopdf, foomatic-rip, gstoraster, mupdftoraster,
+ pdftoopvp, pdftoraster: Do not use build-time hard-coded
+ paths, but always the paths from the environment variables
+ which CUPS sets when calling its filters. This is needed to
+ run the printing stack in a sandbox.
+
+CHANGES IN V1.11.1
+
+ - mupdftoraster: Lowered the priority (raised the cost value)
+ in the cupsfilters-mupdf.convs file so that in a full
+ cups-filters installation MuPDF is not prioritized.
+
+CHANGES IN V1.11.0
+
+ - pdftops: Added support for MuPDF as PDF renderer. MuPDF can
+ be selected by the "pdftops-renderer=mupdf" option.
+ - rastertops: Removed unneeded page logging.
+ - rastertops: Fixed DSC comments, some were only preceded by
+ a single '%' instead of a double "%%".
+ - gstoraster, pdftops, foomatic-rip: Use -dNOMEDIAATTRS when
+ calling Ghostscript. This way Ghostscript does not try to
+ match media sizes with internal lists.
+ - Build system: Allow building cups-filters without Poppler
+ (--disable-poppler in ./configure command line) This skips
+ the build of pdftoraster, bannertopdf, pdftoijs, and
+ pdftoopvp and the installation of these filters and their
+ auxiliary files. With this cups-filters can be easily
+ installed on mobile/appliance systems with MuPDF as the only
+ PDF interpreter.
+ - mupdftoraster: Added filter to support MuPDF as PDF
+ interpreter. MuPDF is a lightweight PDF interpreter
+ especially interesting for mobile systems and
+ appliances. Thanks to Pranjal Bhor for contributing this as
+ part of his Google Summer of Code project.
+ - gstoraster: Fix setting of width and height of the page in
+ pixels when there is no Resolution option in the PPD.
+ - cups-browsed, implicitclass: Avoid the use of files for the
+ communication between cups-browsed and the load-balancing
+ backend implicitclass. Instead of in a file, cups-brwsed
+ stores the destination server name in an option (which CUPS
+ saves in printers.conf) which the implicitclass backend
+ reads via IPP. This not only makes it easier to run
+ cups-filters in a sandbox, but it is also better in terms of
+ system security.
+ - cups-browsed: Allow configuring where the files produced by
+ cups-browsed will get stored. This makes it easier to run
+ cups-filters in a sandbox.
+ - beh: Fixed printing multiple copies with beh (Ubuntu bug
+ #1605514).
+ - cups-browsed: Fixed several memory leaks, especially when
+ using IPP requests and DNS-SD TXT record look-ups. Thanks to
+ Ivo Straka for finding them with Valgrind and supplying
+ patches to fix them (Bug #1365, Bug #1368, Ubuntu bug
+ #1203276).
+ - libcupsfilters: Added missing "#include <cups/ppd.h>" to
+ make sure that the package builds on all systems (Bug
+ #1366).
+
+CHANGES IN V1.10.0
+
+ - texttotext: Added new filter for text-only printers written
+ in C, to use the CUPS library to access the print queue's
+ PPD file, with a lot of options to fit practically all
+ printer models amd paper sizes, support for CUPS' page
+ management options, and support for configuring the print
+ queue and controlling the options by the PPD file. The PPD
+ is now generated on-the-fly by cupsfilters.drv.
+ - textonly: Removed the old script-based filter and its PPD
+ for text-only printers.
+ - rastertops: Added new filter to turn PWG Raster into
+ PostScript, in preparation for MuPDF support. Thanks to
+ Pranjal Bhor for contributing this as part of his Google
+ Summer of Code project.
+ - gstoraster, gstopxl, gstopdf, pstopdf: Integrated
+ functionality of script-based filters pstopdf and gstopxl
+ into gstoraster filter as script-based filters cannot access
+ the print queue's PPD file with current CUPS due to change
+ of PPD file permissions. To make gstoraster always produce
+ the correct output format (CUPS/PWG Raster, PDF, PCL-XL) it
+ is called via new wrapper scripts (gstopdf, gstopxl) which
+ set an environment variable telling the format. The old
+ filter scripts got removed.
+ - imagetops, texttops: Do not use $0 in the wrapper scripts,
+ when CUPS calls filters, it passes the queue name as $0, not
+ path and name of the called filter.
+ - cups-browsed: When creating local queues for discovered IPP
+ network printers always create PPD files and if the
+ information supplied by the printer via IPP is insufficient
+ use information from the DNS-SD entry or default values
+ suitable for most printers. Use System V interface scripts
+ only on explicit request in cups-browsed.conf. This change
+ is to address the fact that System V interface script
+ support is removed from CUPS 2.2.x and later for security
+ reasons.
+ - pstopdf: Make the filter only get installed if Ghostscript is
+ present and also moved its conversion rules into the
+ cupsfilters-ghostscript.convs file.
+ - cups-browsed: Fixed crash when trying to get debugg logging
+ both to the terminal and into a file.
+ - libcupsfilters: Fixed crash of pdftoraster when the color
+ space is an RGB space (3 colors) with 1 bit color
+ depth. Here we need to add one bit to the pixels (to get 4
+ bits per pixel) to align the pixels with the bytes.
+ - cups-browsed: From cups-browsed.service removed the unneeded
+ "Wants=cups.service" as we have "Requires=cups.service"
+ (Debian bug #827455, #827457).
+ - foomatic-rip: Updated man page for removed page logging
+ facility.
+ - pdftops: Also added Dell to the list of manufacturers whose
+ printers need Poppler's PostScript to work around their
+ PostScript interpreter bugs (Debian bug #827040).
+
+CHANGES IN V1.9.0
+
+ - foomatic-rip: Removed page logging via insertion of PostScript code.
+ This works only with Ghostscript and PostScript input and even
+ then it can break things or simply not work. We do the page logging
+ for foomatic-rip in pdftopdf now, which is more universal and more
+ reliable.
+ - sys5ippprinter: Added page logging (to /var/log/cups/page_log)
+ functionality.
+ - pdftopdf: Added functionality for logging pages in the
+ /var/log/cups/page_log file. Logging can also be forced or
+ surpressed via command line (page-logging=on/off/auto) and
+ page logging is also done for filters which should do but
+ actually do not do: foomatic-rip, gstopxl, hpps (CUPS issue #4798,
+ Ubuntu bug #1585380).
+ - pdftopdf: Whitespace and indentation clean-up.
+ - README: Removed the documentation of the old Poppler-based pdftopdf
+ filter which is not included any more.
+ - cups-browsed: Do not schedule failed operations for later repetition
+ during shutdown.
+ - cups-browsed: Added support for debug logging into a file (usually
+ /var/log/cups/cups-browsed_log, to be activated via "-l" or
+ "--logfile" option or via "DebugLogging file" option in
+ cups-browsed.conf.
+ - cups-browesd: Consistent use of debug_printf() in the LDAP support.
+ - cups-browsed: Added "Requires=cups-service" to the
+ cups-browsed.service file, so that systemd keeps CUPS running while
+ shutting down cups-browsed on system shutdown (Ubuntu bug #1579905).
+ - README: Extended pdftopdf's documentation.
+ - README: Added documentation for the pdfAutorotate option in
+ pdftopdf.
+ - gstoraster: Treat status output of the waitpid() function properly,
+ to avoid gstoraster exiting with zero status when Ghostscript
+ exited with non-zero status or got terminated by a signal
+ (Bug #1354).
+ - README: Fixed typos. Thanks to Pranjal Bhor (bhor dot pranjal at
+ gmail dot com) for the patch.
+ - braille: Recognize application/vnd.cups-pdf-banner MIME type and
+ read standard input directly instead of using /dev/stdin.
+ - braille: Drop output of the "type" command when checking the
+ presence of helper utilities.
+ - braille: Do not send EOF twice to the braille embosser.
+ - cups-browsed/sys5ippprinter: Fixed documentation about the allowed
+ input formats for auto-created network printer queues using
+ sys5ippprinter, also improved NEWS entry about renaming of
+ sys5ippprinter (Debian bug #819665).
+
+CHANGES IN V1.8.3
+
+ - cups-browsed: When creating or modifying a local print queue
+ set the printer-is-shared bit to false in a separate IPP
+ request as this operation errors on queues directly pointing
+ to remote CUPS queues with the IPP backend. This way we can
+ ignore the error and assure that all other settings are
+ applied (Ubuntu bug #1560099).
+ - Fixed pkg-config support so that $PKG_CONFIG gets used and
+ cross compilation works (Bug #1347).
+ - gstoraster: Put conversion rules for this filter into a
+ separate file, so that they do not get installed when we
+ build without Ghostscript support (Bug #1346).
+ - Allow disabling dependencies on IJS (Bug #1345).
+ - pdftops: Switch to Poppler as PDF renderer also for the
+ Apple LaserWriter 12/640, to work around a bug in the
+ printer's PostScript interpreter (Bug #1344).
+
+CHANGES IN V1.8.2
+
+ - Allow disabling dependencies on Ghostscript and Foomatic
+ (Bug #1342).
+ - cups-browsed: Optionally generate also local queues pointing
+ to remote raw queues. Usually only queues pointing to remote
+ queues with PPD/driver are created (Debian bug #814020,
+ Debian bug #756724).
+
+CHANGES IN V1.8.1
+
+ - cups-browsed: Do not disable queues which still have jobs (and
+ therefore cannot be removed) when avahi-daemon goes away, the
+ print server is most probably still available and printing can
+ be continued. Especially important on mobile devices where
+ avahi-daemon is shut down when the print dialog is closed (and
+ the job(s) still printing).
+
+CHANGES IN V1.8.0
+
+ - COPYING: Replaced the COPYING file by a file in Debian format,
+ derived from Debian's file but updated and corrected.
+ - braille: Added info about additional packages needed for Braille
+ printing to the README file.
+ - braille: Let the Braille filters use lou_translate of
+ liblouis if the more sophisticated file2brl of liblouisutdml
+ is not installed. This is decided on at run time, so later
+ installation of liblouisutdml will let the filters
+ automatically switch to file2brl.
+ - braille: Allow to build with Braille support also if
+ liblouis is not installed at build time.
+ - braille: Added checks for the presence of helper tools, to
+ get clear messages in the CUPS error_log if something is
+ missing.
+ - Fixed copyright headers of files inherited from CUPS or
+ derived from CUPS, pointing to COPYING as license info file,
+ removing Apple exceptions, removing hints that a missing
+ license info file can be found at www.cups.org, and removing
+ "$Id" SVN file ID placeholders.
+ - Updated COPYING file for missing implicitclass and beh
+ backends.
+
+CHANGES IN V1.7.0
+
+ - cups-browsed: Added possibility to trigger the auto shutdown
+ by the queues of cups-browsed being without jobs. Before
+ auto shutdown was only possible when all queues have gone
+ away. This allows auto shutdown on mobile devices where
+ avahi-daemon is also used for other things than printing.
+
+CHANGES IN V1.6.0
+
+ - cups-browsed: Fixed use of CUPS domain socket, both
+ detection during build process and permission check at
+ runtime.
+ - foomatic-rip: Fixed buffer overflow when reading environment
+ variables CUPS_FONTPATH, CUPS_DATADIR, and GS_LIB (Bug
+ #1336).
+ - beh: Introduced beh, the Backend Error Handler, a wrapper
+ backend to make handling of backend errors more
+ configurable. This backend is a C re-write of the beh
+ backend written in Perl which was part of the former
+ foomatic-filters package. Several people asked for beh
+ getting moved to cups-filters.
+ - braille: Make image printing working also if ImageMagick
+ generates formatted images without header.
+ - braille: If the user does not select a Braille translation,
+ let the embosser do the translation.
+ - cups-browsed: Added version info to help screen and start-up
+ in debug mode, call help screen also via "--version" option.
+ - cups-browsed: Minor improvements in help screen and man
+ page.
+
+CHANGES IN V1.5.0
+
+ - cups-browsed: Allow use of an alternative configuration file
+ via the "-c" command line option.
+ - cups-browsed: Allow supplying configuration settings via the
+ command line using the "-o" command line option.
+ - cups-browsed: Command line help via the "-h" or "--help"
+ command line option.
+
+CHANGES IN V1.4.0
+
+ - foomatic-rip: SECURITY FIX: Also consider the semicolon
+ (';') as an illegal shell escape character. Thanks to Adam
+ Chester (adam dot chester at pentest dot co dot uk) for the
+ hint (CVE-2015-8560).
+ - brftoembosser, imagetobrf, imagetoubrl, imageubrltoindexv3,
+ imageubrltoindexv4, textbrftoindexv3, textbrftoindexv4,
+ texttobrf, braille.convs, braille.types, generic-brf.drv,
+ indexv3.drv, indexv4.drv: Added support for Braille
+ embossing via CUPS. Text and even images can now be sent to
+ a Braille embosser like to a printer. Thanks to Samuel
+ Thibault (samuel dot thibault at ens-lyon dot org) for this
+ contribution.
+
+CHANGES IN V1.3.0
+
+ - cups-browsed: Added new BrowseFilter directive in
+ cups-browsed.conf. This directive allows filtering of the
+ remote printers to be accepted on most properties/metadata
+ supplied with the DNS-SD broadcasts. This allows, in
+ addition to BrowseAllow/BrowseDeny/BrowseOrder, to reduce
+ the amount of printers listed in print dialogs to a more
+ useful amount.
+ - cups-browsed: Added support for BrowseDeny and BrowseOrder
+ directives in cups-browsed.conf.
+ - cups-browsed: Let the BrowseAllow lines in cups-browsed.conf
+ also apply to remote printers discovered via DNS-SD.
+ - cups-browsed: Auto-create queues for PCL-5c/e printers but
+ not for HP inkjet printers (which also advertise themselves
+ as PCL printers).
+ - cups-browsed, sys5ippprinter: Recognize PCL-5c/e printers
+ not only by the application/vnd.hp-pcl MIME type but also by
+ application/pcl and application/x-pcl.
+
+CHANGES IN V1.2.0
+
+ - cups-browsed: When using IP-address-based device URIs via
+ the "IPBasedDeviceURIs" directive in cups-browsed.conf, add
+ two additional settings to restrict the used IP addresses to
+ either only IPv4 addresses or only IPv6 addresses.
+ - foomatic-rip: SECURITY FIX: Also consider the back tick
+ ('`') as an illegal shell escape character. Thanks to Michal
+ Kowalczyk from the Google Security Team for the hint
+ (CVE-2015-8327).
+
+CHANGES IN V1.1.0
+
+ - Version numbering scheme changed: Releases with feature
+ addition/change have the minor number increased now, pure
+ bug fix releases get the revision number increased, to make
+ use of the minor number which stayed zero all the time.
+ - cups-browsed: Added "DefaultOptions" directive to
+ cups-browsed.conf to allow defining default option settings
+ for local queues to be generated for newly appearing remote
+ printers.
+ - cups-browsed: Removed assert() calls which remained from
+ copy and paste in the very beginning of the development of
+ cups-browsed. assert() is only for use during debugging and
+ should not be used in production code.
+ - cups-browsed: Let option settings of a generated print queue
+ be saved before taking the queue down so that when the remote
+ printer appears again all user changes get restored, making
+ user changes permanent on generated queues.
+ - foomatic-rip: Fixed string length for shell path constant, to
+ work also with systems having longer paths (Bug #1325)
+ - cups-browsed: Added a mode in which IP-based device URIs
+ for the generation of local print queues are used, for
+ cases with problems in local host name resolution.
+ - foomatic-rip: Use -dFirstPage=... and -dLastPage=... only
+ if really needed (Bug #1324).
+ - cups-browsed, implicitclass: Make the load-balancing
+ configurable so that one can select whether the jobs get
+ queued up locally like in a CUPS class or whether they get
+ immediately distributed to the remote servers letting them
+ queue up there.
+
+CHANGES IN V1.0.76
+
+ - cups-browsed: Make build also working with BSD make (Bug
+ #1310).
+ - cups-browsed, implicitclass: Let the load-balancing queue up
+ the jobs in the local (generated) queue until a free (idle,
+ enabled, and accepting jobs) remote queue is found (check
+ every 5 sec if no free queue available). This gives a more
+ even distribution of the work amongst the servers and
+ protects against the case that a bunch of jobs gets
+ inaccessible or lost if one of the servers fails.
+ - cups-browsed: Let the load-balancing also check whether the
+ destination queue is actually accepting jobs.
+ - cups-browsed: If a generated queue is not removed on
+ shutdown of cups-browsed due to remaining jobs in it,
+ re-enable it in the next cups-browsed session even if it was
+ disabled by something other than cups-browsed.
+ - implicitclass: Clean up debug and error messages.
+ - implicitclass: Fix exit codes for immediate retry of jobs.
+ - cups-browsed: Make absence of CUPS notifications via D-Bus
+ non-fatal and fall back to the old behavior of cups-browsed
+ (fail-over instead of load balancing for equally-named
+ remote queues, do not remove generated queue if it is
+ default instead of default printer management). This solves
+ problems of CUPS and/or cups-browsed built without D-Bus
+ support or absence of D-Bus on the system (Bug #1316).
+ - cups-browsed: Do not use g_warning() function, sneaked in by
+ copy and paste of CUPS subscription functions.
+
+CHANGES IN V1.0.75
+
+ - texttopdf: Really support BoldItalic (original texttops just maps
+ BoldItalic to Bold).
+ - texttopdf: Fixed segfault when outputting BoldItalic (Bug #1314).
+
+CHANGES IN V1.0.74
+
+ - cups-browsed: Added NULL check when getting the notification of
+ a printer starting to process a job and checking whether this
+ printer is created by cups-browsed with the implicitclass:
+ backend (Ubuntu bug #1488524).
+ - backends: Include unistd.h and fcntl.h in backend-private.h for
+ all platforms, not only Linux, so that the backends build also
+ on non-Linux platforms (Bug #1308).
+ - cups-browsed: Do not schedule printers for update when they are
+ already marked as disappeared.
+ - cups-browsed: Added sanity checks when saving the default printer
+ selection in a file.
+ - cups-browsed, implicitclass: If remote queues disappear or
+ cups-browsed shuts down and a cups-browsed-generated queue still
+ has jobs and needs to be kept therefore, disable it and re-enable
+ it when cups-browsed starts again and/or the remote queue(s) re-
+ appear(s). This avoids repeated retries of the jobs while the
+ remote server is not available, causing unneeded system load and
+ battery consumption.
+ - cups-browsed: After polling info from remote CUPS servers to find
+ the best destination job, set the default CUPS server back to local.
+
+CHANGES IN V1.0.73
+
+ - cups-browsed: Added missing
+ utils/org.cups.cupsd.Notifier.xml file.
+
+CHANGES IN V1.0.72
+
+ - cups-browsed, implicitclass: Added load balancing
+ functionality. If there are several remote CUPS printers
+ with the same name, they for locally a cluster represented
+ by a print queue with this name. This printer prints through
+ a special backend (implicitclass) which makes cups-browsed
+ find the best destination remote queue (fewest jobs,
+ enabled) for this job.
+ - cups-browsed: Added protection against accidental deletion of
+ print queues generated by cups-browsed. These queues now get
+ automatically re-created.
+ - cups-browsed: Added LDAP support. Appropriately configured via
+ cups-browsed.conf remote printers made available via LDAP will be
+ looked up and local queues pointing to them created. Thanks to
+ Raphael Geissert (atomo64 at gmail dot com) for contributing this
+ patch (Debian bug #795185).
+ - cups-browsed: Introduced new handling for the default
+ printer using cache files. So we do not need to keep an auto-generated
+ queue because it is set as default printer. If the auto-generated
+ queue disappears, the old local printer is set as default again and
+ when it re-appears it returns to be the default printer.
+ - cups-browsed: Added infrastructure for subscribing to CUPS
+ notifications for things like improved default printer handling,
+ load balancing, ...
+ - foomatic-rip: Prevent crash when supplying "media" option with empty
+ value ("media=", Ubuntu bug #1479871).
+ - pdftoopvp: Adaptations to API changes on Poppler 0.34.0, note that
+ this patch disables color management in this filter. Thanks to
+ Vincent le Garrec and Andreas K. Huettel for the patch (Bug #1301,
+ Gentoo bug #554782).
+ - libcupsfilters, bannertopdf, foomatic-rip, gstoraster, pdftoijs,
+ sys5ippprinter, pdftoopvp, pdftops, pdftoraster, rastertoescpx,
+ urftopdf, texttopdf: Miscellaneous fixes for build compatibility with
+ different platforms, like config.h as very first include and so on.
+ Thanks to Richard Palo for the patch (Bug #1264).
+ - texttopdf: Request the generic 'monospace' font alias from fontconfig
+ instead of the hard-coded FreeMono. Thanks to Fabian Greffrath
+ (fabian at debian dot org) for the patch (Debian bug #788048).
+
+CHANGES IN V1.0.71
+
+ - texttopdf: The Page allocation is moved into textcommon.c, where it
+ does all the necessary checking: lower-bounds for CVE-2015-3258 and
+ upper-bounds for CVE-2015-3279 due to integer overflows for the
+ calloc() call initialising Page[0] and the memset() call in
+ texttopdf.c's WritePage() function zeroing the entire array. Thanks
+ to Tim Waugh from Red Hat for the patch.
+ - texttopdf: Upper-bounds checking (CVE-2015-3279).
+
+CHANGES IN V1.0.70
+
+ - texttopdf: Fixed buffer overflow on size allocation of texttopdf
+ when working with extremely small line sizes, which causes the size
+ calculation to result in 0 (CVE-2015-3258, thanks to Stefan
+ Cornelius fro Red Hat for the patch).
+ - cups-browsed: leak fixes
+ - cups-browsed: Further BrowseAllow fixing
+ - cups-browsed: BrowsePoll is an array of pointers, not structures,
+ so allocate room for the pointers
+ - cups-browsed: Prevent NULL dereference when handling BrowseAllow
+ without value
+ - cups-browsed: Use memory deallocation function corresponding to
+ allocation function used
+ - cups-browsed: Fixes for glib source handling (Red Hat bug #1228555)
+ - foomatic-rip: Allow using another shell than /bin/bash using the
+ "--with-shell=..." option for "./configure". Thanks to Leonardo
+ Taccari for the patch (Bug #1288).
+
+CHANGES IN V1.0.69
+
+ - cups-browsed: When generating a PPD for an auto-discovered IPP
+ network printer, create a "ColorModel" option only if valid
+ choices are reported for it by the IPP printer.
+ - cups-browsed: Updated PPD file generator for auto-generated queues
+ for IPP network printers from the CUPS 2.1.x upstream code, so that
+ floating-point numbers are written in a locale-neutral way
+ (CUPS STR #4579).
+ - cups-browsed: When checking whether a queue name already exists
+ as a locally defined queue, do case-insensitive comparing as for
+ CUPS printer names are case-insensitive. This assures that
+ already existing queues do never get overwritten.
+ - cups-browsed: Added "IPPPrinterQueueType Auto/PPD/NoPPD" directive
+ to cups-browsed.conf to allow controlling how cups-browsed
+ creates queues fr native IPP network printers: with PPD, with
+ System V interface script, or selecting automatically.
+ - pdftopdf: Center Landscape-oriented jobs correctly on the page
+ if the "fitplot" or "number-up" options are used (Bug #1284).
+ - pstopdf: Removed "-dUseCIEColor" from the Ghostscript command line.
+ In modern Ghostscript versions (9.11 and newer) it is recommended to
+ not use it with the pdfwrite and ps2write output devices any more.
+ - imagetopdf: Corrections in PDF output: Let evince display the PDF
+ with the correct size including margins and let ghostscript not
+ complain about an invalid xref entry.
+ - cups-browsed: Do not add options to the System V interface script
+ which calls sys5ippprinter but set the options as defaults for the
+ CUPS queue in printers.conf.
+ - cups-browsed: When auto-generating a PPD-less print queue for an
+ IPP network printer, determine default page size, unprintable margins,
+ and color space from the printer via an IPP request.
+ - imagetopdf: Debug logging should be only controlled by the LogLevel
+ of CUPS, not by an awkward build time switch.
+ - cups-browsed: Determine from the TXT records of the Bonjour broadcast
+ of an IPP network printer whether it has color and duplex
+ capabilities and if yes, let auto-generated PPD-less print queues
+ use appropriate command line options to make use of these
+ capabilities.
+ - imagetopdf: Make this filter also work with auto-generated PPD-less
+ print queues for IPP network printers.
+ - sys5ippprinter: Renamed from pdftoippprinter to reflect that
+ it is a System 5 interface script and does not accept only
+ PDF as input.
+ - pdftoippprinter: Support also PWG Raster and JPEG as input formats
+ so that an auto-generated, PPD-less queue for an IPP printer emulates
+ an IPP Everywhere printer.
+
+CHANGES IN V1.0.68
+
+ - cups-browsed: Numeric IDs for GSources of the glib event
+ loop must be positive integers greater than zero according
+ to the documentation of the g_source_get_id() function.
+ Taken care of this at all places.
+ - cups-browsed: Added conditionals so that it also builds with
+ CUPS 1.5.x (but then withou support for automatically creating
+ queues for IPP network printers). Thanks to Johannes Meixner from
+ SUSE for the patch (Bug #1268).
+ - Ricoh-PDF_Printer-PDF.ppd: Added PPD file for Ricoh's PDF printers
+ (experimental). Thanks to Ulrich Wehner from Ricoh for the file.
+
+CHANGES IN V1.0.67
+
+ - cups-browsed: Use g_source_remove() instead of g_source_destroy()
+ for killing auto shutdown timers (Ubuntu bug #1427344).
+
+CHANGES IN V1.0.66
+
+ - cups-browsed: SECURITY FIX: Fixed a bug in the remove_bad_chars()
+ failing to reliably filter out illegal characters if there are two
+ or more subsequent illegal characters, allowing execution of
+ arbitrary commands with the rights of the "lp" user, using forged
+ print service announcements on DNS-SD servers (Bug #1265).
+ - pdftoopvp: Added conditionals to also build with Poppler 0.31.0
+ and newer. Thanks to Armin K. (krejzi at email dot com) for the
+ patch (Bug #1254).
+
+CHANGES IN V1.0.65
+
+ - cups-browsed: Listen for NetworkManager changes (Red Hat bug #975933).
+ - cups-browsed: Fix for memory leak introduced in BZR rev 7059.
+ - cups-browsed: Memory leak/uninit fixes.
+ - cups-browsed: Cache prepared browse data to send.
+ - cups-browsed: Only get local notifications once per BrowsePoll run.
+ - cups-browsed: Fix BrowsePoll now notifications work properly. Need
+ to maintain a list of printers to keep alive for the case of there
+ being no notifications of changes.
+ - cups-browsed: Use local browsepolling for getting initial printer
+ list.
+ - cups-browsed: Ignore browse packets for deleted printers.
+ - cups-browsed: Cache connection to local cupsd.
+ - cups-browsed: Use notifications to track local printers.
+ This avoids expensive calls to cupsGetDests().
+ - cups-browsed: Manage subscriptions for local browsepolling.
+ - cups-browsed: Track notify-sequence-number for notifications.
+
+CHANGES IN V1.0.64
+
+ - cups-browsed: Added PPD file generator for IPP Everywhere
+ printers. If auto-setup of discovered IPP printers is
+ activated ("CreateIPPPrinterQueues Yes" in
+ cups-browsed.conf), the printer provides suitable capability
+ information via a Get-Printer-Attributes IPP call, and
+ prints PWG or PostScript input, a PPD is auto-generated
+ based on the Get-Printer-Attributes IPP response. Otherwise
+ a System-V interface script is used as befreo. Advantage of
+ the PPD file is that current print dialogs aloow access to
+ the options, no IPP request done by the dialog is
+ required. The PPD generator code is borrowed from the CUPS
+ 2.1.x development code repository. It will perhaps be
+ removed in the future when CUPS provides proper API function
+ for its PPD generator.
+
+CHANGES IN V1.0.63
+
+ - foomatic-rip: Added hint to man page that direct, spooler-less mode
+ is mainly for testing and debugging (Bug #1253).
+ - foomatic-rip: Added a symlink of the filter to the binary executable
+ directory (usually /usr/bin), so that LSB compliance test scripts
+ work (Bug #1255).
+ - cups-browsed: Fixed CUPS Browsing timeouts. Thanks to Tim
+ Waugh from Red Hat for the patch (Bug #1252, Red Hat bug
+ #1189254).
+
+CHANGES IN V1.0.62
+
+ - cups-browsed: Allow underscore characters in print queue names.
+ Thanks to Tim Waugh from Red Hat for the bug report (Bug
+ #1241).
+ - pdftops: Apply workarounds for Kyocera also to Utax printers
+ as Utax uses hard- and software from Kyocera. Thanks to Edward
+ Huang from Kyocera.
+ - cups-browsed: Added support for "BrowseAllow All" in the
+ cups-browsed.conf file.
+ - cups-browsed: Reorder inclusion of headers for compatibility
+ with NetBSD (Bug #1235).
+ - imagetopdf, pdftopdf: Correct handling of hardware copies in
+ PJL/JCL and/or when the PPD file has a "Copies" option.
+
+CHANGES IN V1.0.61
+
+ - cups-browsed: Fixed memory leak when a
+ cups-browsed-generated print queue is the default
+ printer. Thanks to Tim Waugh from Red Hat for the patch (Red
+ Hat bug: #1119290).
+ - cupsfilters.drv, *-PDF.ppd, textonly.ppd: Added
+ "*cupsFilter2: ..." lines to the PPD files to support
+ data-format-specific behavior of backends, especially of the
+ IPP backend.
+
+CHANGES IN V1.0.60
+
+ - cups-browsed, pdftoippprinter: Do not confuse the PDL "PCLm"
+ with "PCL". The former is a proprietary, PDF-based raster
+ format and has nothing to do with PCL.
+ - cupsfilters.drv: Corrected the CMD: field of the device ID,
+ it must read "PWGRaster" there to conform to the PWG standard.
+
+CHANGES IN V1.0.59
+
+ - cupsfilters.drv: Added PPD file for a Generic IPP Everywhere
+ Printer, generating PWG Raster output.
+ - gstoraster, pdftoraster, imagetoraster: Allow PWG Raster
+ output with print queues using a PPD file, using the new
+ "PWGRaster" PPD attribute.
+ - pdftoraster: Removed "cm_disabled" flag in selectConvFunc()
+ - libcupsfilters: Allowed color management to continue while
+ invalid input
+ - rastertopdf: Streamlined PDF conversion code
+ - rastertopdf: Invert all CUPS_CSPACE_K documents by default
+ - foomatic-rip: Clean trailing white space from PPD file lines to
+ avoid a segfault caused by it (Bug #1227).
+
+CHANGES IN V1.0.58
+
+ - pdftoraster: Changed ICC profile get function to accept a
+ PPD fallback profile.
+ - pdftoraster: Fixed handling of cupsColorSpaces 18,19,20.
+ - rastertopdf: Added test feature to force color management if
+ "profile=" option is specified.
+ - rastertopdf: Grayscale color conversion now properly inverts
+ bits.
+ - rastertopdf: Code cleanup for prepare_pdf_page().
+ - rastertopdf: Implemented basic 8bit->8bit color space
+ conversions.
+ - rastertopdf: Added black point compensation.
+ - rastertopdf: Added handling of color rendering intent.
+ - gstoraster, imagetoraster, pdftoraster, rastertopclx,
+ rastertopdf, foomatic-rip: Use color management functions in
+ libcupsfilters.
+ - libcupsfilters: Modified code formatting and documentation in
+ the color management functions.
+ - libcupsfilters: Fixed string handling and added debug log
+ messages in the color management functions.
+ - libcupsfilters: Fixed Adobe RGB matrix for proper rendering
+ (transpose)
+ - libcupsfilters: Moved color management functions from the
+ individual filters to the libcupsfilters library.
+
+CHANGES IN V1.0.57
+
+ - rastertopclx: Fixed implicit declaration of
+ colord_get_inhibit_for_device_id.
+ - Build system: Explicitly link to libm as -lm was dropped
+ from cups-config --libs.
+ - libcupsfilters, foomaticrip, gstoraster, imagetoraster,
+ pdftoraster, rastertopclx, rastertopdf: Handle absence of
+ colord or D-Bus gracefully (Ubuntu bug #1356405).
+
+CHANGES IN V1.0.56
+
+ - rastertopdf: Some code polishing and removal of now unneeded
+ functions
+ - rastertopdf: Reduced color space handling to only
+ PWG-supported color spaces
+ - rastertopdf: Added colorspace calibration function; included
+ optional "/Alternate" PDF key for ICC profile embedding
+ - rastertopdf: Colorspace sRGB now embeds srgb icc profile;
+ implemented ICC Profile embedding (PDF 1.3 spec)
+ - rastertopdf: Added basic color calibration
+ - rastertopdf: Implemented ICC Profile creation code for IPP
+ Everywhere (from PWG raster)
+ - pdftoraster: Added colord handling of ICC profiles
+ - kmdevices.cpp/.h: Added interface for Kolor Manager
+ - cups-browsed: Do not consider a remote CUPS queue as raw if
+ the TXT record is NULL as for queues broadcasted by the
+ legacy CUPS method the TXT record does not exist. Now
+ consider a queue with NULL TXT record only as raw if the
+ domain entry is not empty (which tells that the queue is
+ Bonjour-broadcasted (Bug #1223).
+ - cups-browsed: Do also not mark a discovered printer as
+ already provided by another server when the other server's
+ queue has "unconfirmed" status. Mark the other queue with
+ "disappeared" or "unconfirmed" status as duplicate of the
+ discovered printer so that the new queue for the discovered
+ printer does not get removed when the entry for the other
+ queue times out.
+
+CHANGES IN V1.0.55
+
+ - pdftopdf: Fixed manual duplex by adding a blank page to evn
+ pages if the total number of pages of the document is
+ odd. Otherwise the last page of the document would stay in
+ the input tray. This fixes also a side effect as the set of
+ even pages reducing to a zero page job if the job consists
+ of only one page, making Poppler's pdftops error out (Ubuntu
+ bug #1340435).
+ - cups-browsed: Do not mark a discovered printer as already
+ provided by another server when the other server's queue has
+ "disappeared" status. This queue can be from the same server
+ before it changed its name.
+ - cups-browsed: Do not create a local queue pointing to a
+ remote raw queue (Ubuntu bug #1335211).
+ - foomatic-rip, imagetoraster, pdftoraster, rastertopclx,
+ rastertopdf: Added colord "device_inhibit" support for
+ color-managed filters.
+ - foomatic-rip: Let it also build correctly on systems which
+ already provide the strlcat() and strlcpy() functions, like
+ Mac OS X. Thanks to Matt Broughton for reporting this
+ (bug #1215).
+ - bannertopdf: Added support for PPD-less printing, especially
+ one gets a useful test page with PPD-less queues now.
+ - bannertopdf: Fixed "Printer Location" and "Driver Version"
+ entries on the test page/the banners.
+ - bannertopdf: Added new PDF template files which contain the
+ text strings appropriate to the banners, before the banners
+ were all equal, without text. Thanks to Johannes Meixner
+ from SUSE/Novell for this fix (Bug #1209).
+ - bannertopdf: Fixed Makefile to mark it dependent on
+ libfontembed.la. Thanks to Tim Waugh from Red Hat for the
+ patch (Red Hat bug #1106101).
+ - pstopdf: Use "grep -E" instead of "grep -P" as the latter
+ generates executable code and executes it, requiring
+ "execmem" privileges which could be not available in some
+ security policies. Thanks to Tim Waugh from Red Hat for the
+ patch (Red Hat bug #1079534).
+ - foomatic-rip: NetBSD does not provide a mkstemps() function,
+ use appropriate workaround then (Bug #1211).
+ - cups-browsed: Reorder inclusion of headers for compatibility
+ with NetBSD (Bug #1212).
+ - pdftoraster: Fixed segfault caused by introduction of
+ "no-color-management" option (Bug #1214).
+ - libcupsfilters: Let cupsRasterParseIPPOptions() also accept
+ "pwg-raster-document-type" settings with hyphen between
+ color space name and color depth.
+
+CHANGES IN V1.0.54
+
+ - pdftoraster: Support for output in the color spaces 18
+ (CUPS_CSPACE_SW, sGray), 19 (CUPS_CSPACE_SRGB, sRGB), and 20
+ (CUPS_CSPACE_ADOBERGB, Adobe RGB). No color management
+ appropriate to these color spaces is added yet.
+ - foomatic-rip, gstoraster, imagetoraster, pdftoraster,
+ rastertopclx: added boolean option "no-color-management" to
+ suppress all forms of color correction when
+ color-calibrating the printer.
+ - pdftops: Default to "hybrid" setting for the PDF->PostScript
+ renderer.
+ - pdftoraster: Produce correct (compressed) PWG Raster output
+ when requested by using the correct mode in
+ cupsRasterOpen().
+ - rastertopdf: Added new filter to convert PWG Raster input
+ into a PDF file (using QPDF). This filter makes CUPS
+ supporting the PWG Raster input format which is required to
+ be supported by IPP Everywhere printers, making a shared
+ CUPS queue emulating an IPP Everywhere printer. This is a
+ first implementation which supports the black, RGB, CMYK,
+ sGray, sRGB, and Adobe RGB color spaces (all mapped to
+ DeviceGray, DeviceRGB, and DeviceCMYK resp. in the PDF
+ output) with 1, 8, and 16 bits per component color
+ depth. sGray, sRGB, and Adobe RGB are currently also mapped
+ to DeviceGray and DeviceRGB and do not have the correct
+ color management yet, so color output is not absolutely
+ correct. Note that mime.types of CUPS up to 1.7.2 has a bug
+ which prevents PWG Raster to be recognized, the
+ "priority(100)" of the rule needs to be changed to
+ "priority(150)".
+ - foomatic-rip: Corrected declaration of print_pdf() function in
+ pdf.h file (Debian bug #748028).
+ - foomatic-rip: Let it also build with uclibc which does not
+ provide the mkstemps() function. Thanks to Andreas K.
+ Huettel for the patch (Gentoo bug #509884).
+ - cups-browsed: Create local queues also to access classes on
+ remote CUPS servers (Ubuntu bug #1313741).
+ - cups-browsed: Let a newly discovered printer not only
+ overtaking an existing printer entry if it is from the same
+ host (usually IPP -> IPPS) or without host entry
+ (unconfirmed local queue from previous cups-browsed session)
+ but also if it is marked disappeared. So printer entries get
+ correctly migrated when things like a host name change of
+ the remote server happen.
+ - cups-browsed: Always do case-insensitive comparing of
+ strings, as CUPS queue names and URIs are case-insensitive
+ (CUPS STR #4411).
+
+CHANGES IN V1.0.53
+
+ - foomatic-rip: Fixed segfault when creating log file (Bug
+ #1206).
+ - cups-browsed: SECURITY FIX: Fix on usage of the
+ "BrowseAllow" directive in cups-browsed.conf. Before, if the
+ argument of a "BrowseAllow" directive is not understood it
+ is treated as the directive not having been there, allowing
+ any host if this was the only "BrowseAllow" directive. Now
+ we treat this as a directive which no host can fulfill, not
+ allowing any host if it was the only one. No "BrowseAllow"
+ directive means access for all, as before (Bug #1204).
+ - cups-browsed: SECURITY FIX: Further improvement on the fix
+ in 1.0.51 as it was insufficient. In addition, some fixes
+ against OOB access are done. Thanks to Sebastian Krahmer for
+ the patch (SUSE/Novell bug #871327).
+
+CHANGES IN V1.0.52
+
+ - texttopdf: Make sure that margin changes for prettyprint
+ get applied.
+ - texttopdf, imagetopdf, imagetoraster: Range-check paper
+ dimensions and margins taken from the PPD file and correct
+ them if needed (Bug #1195).
+
+CHANGES IN V1.0.51
+
+ - cups-browsed: SECURITY FIX to prevent arbitrary code
+ injection into the System V interface scripts generated for
+ queues for discovered native IPP printers by a malicious IPP
+ print service with forged make/model and/or PDL string.
+
+CHANGES IN V1.0.50
+
+ - pdftops: Let old HP LaserJet printers (model number without
+ letter, like "LaserJet 3" or "LaserJet 4000") use Poppler
+ instead of Ghostscript (Debian bug #742765).
+ - pdftops: Improved workaround for Toshiba printers. Instead
+ of using Poppler do not emit TrueType fonts with Ghostscript
+ (Ubuntu bug #998087).
+ - cups-browsed: Build the device URIs for all local queues we create
+ with the CUPS library function httpAssembleURIf() for proper
+ percent escaping of characters which are not allowed in URIs
+ (Bug #1187).
+
+CHANGES IN V1.0.49
+
+ - pdftops: Use Poppler also for Toshiba printers (Ubuntu bug
+ #998087).
+ - pdftops: Fixed typo which always made PostScript level 2 being
+ generated when using Poppler's pdftops (Ubuntu bug #1294370).
+
+CHANGES IN V1.0.48
+
+ - cups-browsed: Fix for a crash which happens on Bonjour reports of
+ printers without "product", "usb_MDL", and "ty" fields in the
+ text record (Ubuntu bug #1284834).
+ - cups-browsed: In README and in the sample startup scripts/configs
+ for System V Init and Upstart taken into account the fact that it
+ is not required any more to start avahi-daemon before starting
+ cups-browsed.
+
+CHANGES IN V1.0.47
+
+ - pdftoopvp: SECURITY FIX for CVE-2013-6474, CVE-2013-6475,
+ and CVE-2013-6476: Introductionof gmallocn and gmallocn3
+ to protect against arbitrary code execution with the
+ privileges of the "lp" user via malicious PDF files. Also
+ restrict the directory from where OPVP drivers can get
+ loaded.
+ - urftopdf: SECURITY FIX for CVE-2013-6473: Two heap-based
+ buffer overflow flaws in urftopdf. If a malicious URF file
+ were processed it could lead to arbitrary code execution
+ with the privileges of the "lp" user.
+ - pdftopdf: Fixed typo in initialization which sets the default
+ value page border to an undefined value. Thanks to Helge
+ Blischke for the patch.
+ - cups-browsed: Check for changes of the URI of a queue which
+ we have created and correct the URI if needed, especially if
+ a queue was not removed on shutdown of cups-browsed (default
+ printer or still having jobs) and before restart of
+ cups-browsed the server's DNS-SD-provided has changed.
+ - bannertopdf: Support PDF forms as banner template. This allows
+ especially internationalized banner pages. Forms can contain
+ fields for any CUPS/IPP value and get automatically filled
+ Thanks to Andrew V. Stepanov from ALT Linux (Bug #1170,
+ also first step to fix Ubuntu bug #1196986).
+
+CHANGES IN V1.0.46
+
+ - gstoraster: Ignore SIGCHLD, rely on waitpid instead. Thanks
+ to Lauri Tirkkonen (Bug #1184).
+ - gstoraster: Fix two instances of insufficient EINTR handling.
+ Thanks to Lauri Tirkkonen (Bug #1184).
+
+CHANGES IN V1.0.45
+
+ - cups-browsed: Under Upstart load the AppArmor profile
+ (Ubuntu bug #1276630).
+ - cups-browsed: Added auto-shutdown feature for on-demand use
+ of cups-browsed (for example on mobile devices). With auto
+ shutdown active, cups-browsed terminates after a certain
+ time interval (30 sec by default) without having any remote
+ printer to make available locally. The mode can be turned
+ on, turned off (default) or set to automatically be off
+ while avahi-daemon is running an on otherwise (controlled by
+ avahi-daemon running on-demand). The mode and the timeout
+ interval can be selected by command line options, the
+ configuration file, and sending signals to cups-browsed
+ (on/off only).
+ - cups-browsed: To make Bonjour-discovered printers locally
+ available avahi-daemon does not need to be started before
+ cups-browsed and does not need to stay continuously running
+ while cups-browsed is running. Bonjour-discovered printers
+ are now added whenever avahi-daemon starts and removed
+ whenever avahi-daemon stops and cups-browsed keeps
+ running. This makes it easier to use cups-browsed in
+ different system-configurations and also on systems with
+ daemons running on-demand (like mobile systems).
+ - foomatic-rip: Fixed pid_t/int function prototype mismatch
+ (Bug #1182).
+ - Fixed --with-pdftops-path and --with-pdftocairo-path options
+ in ./configure (Bug #1181).
+ - foomatic-rip: Do not use PATH_MAX for the length of static
+ strings which are supposed to hold a command line. Use our
+ own CMDLINE_MAX constant to set them to a length of 65535
+ bytes (Ubuntu bug #1019662, Debian bug #738440).
+ - pdftops: Log command lines of renderer (Ghostscript, pdftops,
+ pdftocairo, acroread) and of pstops in CUPS' error_log (in
+ debug mode).
+
+CHANGES IN V1.0.44
+
+ - README: Documented the "hybrid" choice for the PDF renderer
+ in the pdftops filter.
+ - pdftoippprinter: Handle missing Ghostscript/Poppler for all
+ output formats.
+ - cups-browsed: Minor corrections in the error messages.
+ - gstopxl: Support for PPD-less printing. Resolution,
+ InputSlot, Duplex, and ColorModel are set also without PPD
+ file now.
+ - Added another sample PPD file for a native PDF printer,
+ Fuji_Xerox-DocuPrint_CM305_df-PDF.ppd. Thanks to Adrian
+ Johnson for contributing this PPD file.
+
+CHANGES IN V1.0.43
+
+ - cups-browsed: When automatically setting up a PPD-less print
+ queue for an IPP network printer add make/model info as an
+ additional "make-and-model" command line option to the call
+ of the pdftoippprinter filter, this way filters can do
+ make/model-specific exceptions (quirk rules).
+ - pdftopdf: Take page size from the command line if not
+ already given by the PPD file, this way
+ "fitplot"/"fit-to-page" also works with PPD-less printing.
+ - libcupsfilters: cupsRasterParseIPPOptions() did not set
+ sRGB color space.
+ - libcupsfilters: cupsRasterParseIPPOptions() did not set
+ Tumble with "Duplex=DuplexTumble".
+ - pdftopdf: Fixed software copy generation logic for printers
+ with hardware copy generation, but without collate support
+ (Ubuntu bug #1259240).
+ - pdftops: Let Ghostscript output PostScript level 3 also for
+ PPD-less printing, but not for HP lasers or when make/model
+ info is not supplied.
+ - cups-browsed: removed duplicate definition of ippSetVersion.
+ - foomatic-rip: Take PATH_MAX constant from limits.h if
+ available instead defining it's own version conflicting with
+ kfreebsd. Thanks to Peter Green for the patch (Debian bug
+ #731658).
+ - pdftops: Ignore "landscape", "orientation-requested",
+ "fit-to-page", and any page geometry options. The first two
+ do not make sense on PDF input and therefore should only be
+ used in ...topdf filters used before pdftopdf, the others
+ are already taken care of by pdftopdf so that pdftops gets
+ pages with print-ready page geometry.
+ - pdftops: Added "-nocenter" to the call of "pdftops
+ -origpagesizes" (Poppler/freedesktop.org bug #72312,
+ comments #6 and #7).
+ - pdftopdf: If there is no PPD file or no
+ "*LandscapeOrientation:" keyword in the PPD file, rotate
+ counterclockwise, not clockwise to fit a landscape-oriented
+ page on a portrait-oriented sheet (See
+ Poppler/freedesktop.org bug #72312, comment #6).
+ - pstopdf: Support for the "landscape" and
+ "orientation-requested" options (Ubuntu bug #1243484).
+ - pdftops: Support for PPD-less printing on PostScript
+ printers: duplex, resolution, input tray, color mode, and
+ make/model (for quirk rules) can now be supplied by the
+ command line, pdftopdf takes care of the page geometry.
+ - libcupsfilters: cupsRasterParseIPPOptions() allows
+ specifying resolutions without unit now, assuming dpi then
+ (example: "600x600").
+ - Fixed "--with-cups-rundir" and "--with-cups-domainsocket"
+ options in configure (Bug #1174).
+ - pdftops: After fixing the output of rotated PDF pages
+ (usually landscape-oriented pages rotated by pdftopdf) in
+ Poppler (Poppler/freedesktop.org bug #72312) corrected the
+ use of "pdftops -origpagesizes" in pdftops appropriately
+ (Red Hat bug #768811).
+
+CHANGES IN V1.0.42
+
+ - pdftoippprinter: Check also the presence of Ghostscript and
+ use pdftoraster if Ghostscript is missing.
+ - gstoraster: At build time use the path for Ghostscript which
+ our build system already finds for pdftops.
+ - pdftoraster: Take into account rotate field in PDF header,
+ when pdftopdf rotates a page to fit the paper it sets the
+ rotate field and does not swap the width and height entries.
+ - pdftoippprinter: Made PCL 5c/e printing working correctly,
+ by first adding support for unprintable margins and
+ defaulting to 12pt margins if no margin info is supplied,
+ and second, by doing color printing always in RGB color
+ space.
+ - rastertopclx: Improved support for PPD-less printing,
+ allowing color printing with (s)RGB color space. Output is
+ in sRGB then.
+ - rastertopclx: Determine page size and select correct PCL
+ command for the page size more reliably, especially for
+ landscape-oriented pages.
+ - gstoraster, pdftoraster: Do correct PWG Raster output, allow
+ switching to PWG Raster via "media-class=PwgRaster" option
+ and CUPS Raster via "media-class=". Default for PPD-less
+ printing is PWG Raster.
+ - gstoraster, pdftoraster: Support applying unprintable
+ margins for PPD-less mode with CUPS Raster output.
+ - libcupsfilters: Added support for "media-left-margin",
+ "media-right-margin", "media-bottom-margin", and
+ "media-top-margin" IPP options to specify unprintable
+ margins in 1/100th of a mm, to allow PPD-less printing with
+ unprintable margins (esp. PCL 5c/e with rastertopclx).
+ - libcupsfilters: Do not set "MediaClass" to "PwgRaster" when
+ we request a CUPS Raster header and not a PWG Raster header.
+ - libcupsfilters: Fixed typo in a debug message in the colord
+ support part.
+ - cupsfilters.convs: Corrected cost factor of
+ vnd.cups-postscript -> vnd.cups-raster conversion with
+ gstoraster, so that input data of the type
+ application/vnd.adobe-reader-postscript is converted
+ correctly (not via pstotiff). Thanks to Tim Waugh from Red
+ Hat for this patch
+ - cups-browsed: Fixed several memory leaks by adding missing
+ free() calls and removing an unneeded strdup(). Thanks to
+ Jaromir Koncicky from Red Hat for the patch (Red Hat bug
+ #1027317).
+ - Backends parallel and serial: Fixed logical expressions for
+ error handling (Bug #1172).
+ - libcupsfilters: Moved filter/colord.[ch] into the library as
+ this code is now used by both gstoraster and foomatic-rip.
+ - libcupsfilters: Made the names of the flags to tell that the
+ header is already included unique in all API header files.
+ - foomatic-rip: Moved foomatic-rip's upstream home from the
+ foomatic-filters package to cups-filters, to make it easier
+ for distributions to ship and maintain a complete printing
+ stack and also to make upstream maintenance and development
+ easier.
+ - foomatic-rip: Removed support for all the non-CUPS printing
+ environments as they are discontinued upstream. Now
+ foomatic-rip only works as a CUPS filter and in a spooler-less
+ direct mode, where the latter is mainly for testing and
+ debugging. Thanks to Anshul Kushwaha (anshulkushwaha1 at gmail
+ dot com) for doing this as a Google Summer of Code 2013 project.
+ - foomatic-rip: Eliminated compiler warnings.
+ - foomatic-rip: fixed "endswith()" string utility function.
+ - foomatic-rip: Removed unneeded HAVE_DBUS conditionals.
+ - gstoraster: Fixed build system for gstoraster use D-Bus for
+ colord support.
+ - libcupsfilters: Recognize more Adobe-generated CMYK JPEGs to
+ take into account their inverted colors (Bug #1169).
+ - pdftopdf: When checking whether double-sided printing is
+ chosen, do not only check for the choice names "DuplexNoTumble"
+ and "DuplexTumble" but also for "LongEdge", "ShortEdge",
+ "Top", and "Bottom", as CUPS does (Bug #1167).
+
+CHANGES IN V1.0.41
+
+ - cups-browsed: Added support for automatic PPD-less setup of
+ print queues for IPP printers discovered on the network via
+ Bonjour. Supported are printers with known languages (PWG
+ Raster, PDF, PostScript, PCL XL, PCL 5c/e), especially also
+ IPP Everywhere printers. This functionality is especially
+ ment for mobile devices to be able to print without printer
+ setup tool and without printer driver/PPD collection.
+ - cups-browsed: Fixed a Valgrind-reported issue.
+ - pdftoippprinter: New filter for PPD-less printing. The filter
+ will be configured as System-V interface script for a print
+ queue for a discovered IPP network printer generated by
+ cups-browsed.
+ - rastertopclx: Added support for PPD-less printing. Without
+ PPD the filter generates PCL 5e.
+ - cups-browsed: Fixed socket leaks in recent IPP subscriptions
+ changes. Thanks to Tim Waugh from Red Hat for the patch (Red
+ Hat bug #1021512).
+
+CHANGES IN V1.0.40
+
+ - pdftops: Introduced new "hybrid" renderer: Here usually
+ Ghostscript is used, but if the printer is a Brother,
+ Minolta, or Konica Minolta Poppler's pdftops gets used. This
+ is a quirk rule to work around bugs in the PS interpreters
+ of the printers.
+ - Fixed format string issues and added __attribute__ wording
+ to printf-like functions to catch any regressions. Thanks to
+ Tim Waugh from Red Hat for the patch.
+
+CHANGES IN V1.0.39
+
+ - pdftops: Fix for landscape PDF handling. Do not use the
+ command line options "-origpagesizes" and
+ "-choosePaperByPDFPageSize" of Poppler's pdftops utility on
+ already processed PDF data. Thanks to Tim Waugh from Red Hat
+ for the patch.
+ - cups-browsed: Improve the efficiency of BrowsePoll by using
+ IPP notifications when possible. It falls back to the
+ previous behaviour if it is not possible to use this
+ optimization. Thanks to Tim Waugh from Red Hat for the patch.
+
+CHANGES IN V1.0.38
+
+ - pdftops: Added "-dNOINTERPOLATE" to the Ghostscript command line
+ for quicker processing of embedded bitmaps.
+ - pstopdf: Added "-dUseCIEColor" to the Ghostscript command line
+ to assure compatibility with newer Ghostscript versions (9.08
+ and newer).
+
+CHANGES IN V1.0.37
+
+ - Added example configuration files for systemd and Upstart. Thanks
+ to Tomáš Chvátal for the systemd file.
+ - Build system: Make sure that gstoraster gets linked against the
+ libcupsfilters of the currently built package and not of the
+ system. Thanks to Tomáš Chvátal.
+ - cupsfilters.convs: Reworked the cost factors of the filters to
+ avoid bogus filter chains like pstotiff|imagetopdf instead of
+ pstopdf|pdftopdf for PostScript->PDF. Thanks to Tim Waugh from
+ Red Hat for the report.
+ - pdftopdf: Accept additional command line options for PPD-less
+ printing.
+ - cups-browsed: Fixed building with CUPS 1.5.x and older,
+ ippSetVersion() was missing under the accessor function definitions
+ for backward compatibility.
+
+CHANGES IN V1.0.36
+
+ - Fixed libdl detection in configure. Thanks to Andreas Huettel and
+ Yuta Satoh (Gentoo bug #478642).
+ - cups-browsed: Allow BrowsePoll operation also access print queues
+ on older CUPS servers. Thanks to David Mohr for the patch.
+ - cups-browsed: Assure that it always applies to the local CUPS
+ daemon and never to a remote one specified via client.conf
+ (Ubuntu bug #1207203).
+ - pdftoopvp, pdftoijs, pdftoraster, bannertopdf: Made code working
+ with Poppler 0.24.x (Bug #1144).
+ - gstoraster: Silenced compiler warnings.
+ - gstoraster, pdftoraster: Added support for PPD-less printing
+ controlled by IPP attributes (CUPS 1.7.x+ only).
+ - gstoraster, gstopxl: Moved these filters from Ghostscript to
+ cups-filters as upstream home.
+ - libcupsfilters: Added new cupsRasterParseIPPOptions() API
+ function for PPD-less printing controlled by IPP attributes
+ (raster.h, CUPS 1.7.x+ only).
+ - pdftopdf: Added support for page labels. "page-label" option and
+ "CLASSIFICATION" environment variable. Thanks to Tim Waugh from
+ Red Hat for the patch.
+ - pdftops: If one or more of the PDF-to-PS renderers (Ghostscript,
+ Poppler pdftops, Poppler pdftocairo, acroread) is not installed
+ at build time, pre-fill the appropriate executable's path with the
+ executable name to allow the use of this renderer when it gets
+ installed later (Debian bug #716842).
+ - cups-browsed: Do not resolve host names of remote printers discovered
+ via CUPS broadcasts (Bug #1141).
+ - Added man pages for cups-browsed and cups-browsed.conf. Thanks to
+ Brian Potkin for the contribution (Debian bug #714460).
+ - Install also escp.h, it is useful for .drv files.
+
+CHANGES IN V1.0.35
+
+ - pdftoraster: Silenced compiler warning (Bug #1092).
+ - bannertopdf: Fixed typo which prevented the host name to be shown
+ (Bug #1115).
+ - README: Fixed info about the PPD keyword cupsManualCopies (Bug
+ #1086).
+ - Modified the cost factors of the filters to avoid unneeded PDF
+ conversion detours when the input data is PostScript. Instead of
+ pstopdf->pdftopdf->pdftops and pstopdf->pdftopdf->gstoraster we
+ get pstops and pstops->gstoraster now (Bug #1138).
+ - pdftops: Added experimental support for pdftocairo as PDF renderer.
+ Note that PostScript level 1 output and PDF input with color
+ spaces other than DeviceRGB, DeviceGray, sRGB or sGray is not
+ supported. PDFs generated by Cairo (for example when printing from
+ evince) uses only supported color spaces. Thanks to James Cloos
+ for the patch (Bug #1139).
+ - cups-browsed: Changed default of browsing protocols fron none to
+ both DNS-SD and CUPS.
+ - pdftops: Let Poppler generally generate PostScript level 3 if the
+ PPD identifies the printer as PS3 printer, make an exception of
+ sending PostScript Level 2 only for HP's laser printers, to not
+ compromise print quality and performance on all PS3 printers only
+ due to some buggy HP models (Debian bug #712949, see also Ubuntu bug
+ #277404).
+ - Install pcl.h, it is needed by cupsfilters.drv. Thanks to Jiri
+ Popelka from Red Hat for the patch (Bug #1133).
+ - Make cups-filters building with automake 1.13. Thanks to Andreas K.
+ Huettel (dilfridge) on IRC.
+ - libcupsfilters, libfontembed, pdftopdf, texttopdf, cups-browsed:
+ Fixed several resource leaks and other problems. Thanks to Jiri
+ Popelka from Red Hat for the patches (Bug #1116).
+
+CHANGES IN V1.0.34
+
+ - cups-browsed: Fixed build with OpenBSD (Bug #1103).
+ - pdftopdf: Enabled hardware copy generation, if available.
+ - pdftopdf: Fixed evenDuplex logic.
+ - cups-browsed: If a queue left over from the last session
+ gets confirmed, fill in the data structure with the Bonjour
+ parameters, also update the Bonjour parameters if a local
+ queue is upgraded from IPP to IPPS.
+
+CHANGES IN V1.0.33
+
+ - cups-browsed: Added NULL check (Bug #1106).
+
+CHANGES IN V1.0.32
+
+ - cups-browsed: Shared algorithm to generate local queues based on
+ browsed remote queue data between Bonjour and CUPS browsing, as the
+ simpler method used for CUPS browsing could overwrite local print
+ queues and had de-duplication problems, for example if the server
+ appears on two IPs in the network (connected by both ethernet and
+ WLAN).
+ - cups-browsed: CUPS broadcasting also broadcasted non-shared,
+ especially cups-browsed-generated printers. Switched to detection
+ of non-shared printers by the appropriate bit in the printer-type
+ bit field IPP attribute.
+ - cups-browsed: Made CUPS broadcasting work also without BrowseAllow
+ lines in cups-browsed.conf. In this case we accept all remote
+ printers (Ubuntu bug #1163764).
+ - README: Updated documentation for cups-browsed.
+ - Added more comments and examples to /etc/cups/cups-browsed.conf.
+ - cups-browsed: Added support for "...:<port>" extensions of
+ BrowsePoll addresses. Thanks to Tim Waugh from Red Hat (Ubuntu
+ bug 1159213).
+
+CHANGES IN V1.0.31
+
+ - cups-browsed: cups-browsed removed valid local queues pointing to
+ remote queues when cups-browsed did not shut down cleanly after
+ the previous session, leaving the user with missing local accessor
+ queues for some of the remote CUPS queues (Ubuntu bug #1131149).
+ - Fixed build system to allow parallel or multilib builds. Thanks to
+ Timo Gurr for the patch (Bug #1104).
+ - pdftopdf: Improved error output.
+ - pdftopdf: getRotation now handles unusual cases more graceful
+ (probably fixes Ubuntu Bug #1154318).
+ - Fixed build system to allow building without Avahi. In this case
+ a cups-browsed with only CUPS broadcasting/browsing will get
+ built. Thanks to Tim Waugh from Red Hat (Bug #1101, Bug #1102).
+
+CHANGES IN V1.0.30
+
+ - cups-browsed: Do not remove a generated local print queue when
+ it was made the system default printer (Ubuntu bug #1146407).
+ - texttopdf: Fixed corrupted pdf when a utf-8 title is given and
+ corresponding crash with 'prettyprint' (Ubuntu Bug #1137438).
+ - cups-browsed: Added CUPS Broadcasting for sharing local printers
+ to remote CUPS clients with CUPS 1.5.x and older. Thanks to Tim
+ Waugh from Red Hat.
+ - cups-browsed: Added sample config-file and build-time default
+ setting options. Thanks to Tim Waugh from Red Hat.
+ - cups-browsed: Added CUPS browsing and BrowsePoll functionality, to
+ be backwards compatible to CUPS 1.5.x and older servers. Thanks
+ to Tim Waugh from Red Hat.
+ - pdftopdf: Fixed incorrect evenDuplex page insertion (Bug #1088).
+ - pdftoopvp: Let it build with Poppler 0.22.x. Thanks to Koji Otani
+ from BBR Inc. (Bug #1089).
+
+CHANGES IN V1.0.29
+
+ - Fixed ./configure option "--with-rcdir=no". Thanks to Jiri
+ Popelka from Red Hat (Bug #1091).
+
+CHANGES IN V1.0.28
+
+ - cups-browsed: Do not create CUPS queues for shared local CUPS
+ printers.
+
+CHANGES IN V1.0.27
+
+ - cups-browsed: The daemon crashed if there is no local CUPS queue
+ at all. Fixed.
+
+CHANGES IN V1.0.26
+
+ - Some fixes in README and INSTALL.
+ - cups-browsed: Added daemon to browse the Bonjour broadcasts of
+ shared remote CUPS printers and automatically add local raw queues
+ pointing to them, to resemble the behavior of the former CUPS
+ broadcasting/browsing which was dropped in CUPS 1.6. Now remote
+ printers appear as local print queues as before, but with the
+ standardized Bonjour broadcasting.
+ - "make dist" got broken in 1.0.25. Fixed.
+
+CHANGES IN V1.0.25
+
+ - urftopdf: Newly added filter to convert the URF format which (at
+ least some) iOS apps send when printing via AirPrint (Bug #1076).
+ - pdftopdf: pdfautorotate functionality has been patched directly
+ into pdftopdf (Bug #1080).
+ - pdftopdf: "mirror" produced only empty pages (XObjects not there).
+ - pdftopdf: Fixed segfault on "page-ranges=1-2147483647" (from cups).
+ - pdftopdf: Fixed collate filler insertion.
+ - texttopdf: Fixed deficient string escaping (Bug #1071).
+ - pdftoopvp: Get correct byte order definition when building under
+ OpenBSD (Bug #1070).
+ - serial backend: Added check for sys/ioctl.h to configure.ac (Bug
+ #1069).
+ - pdftopdf: Made code building under OpenBSD (Bug #1068).
+ - pdftopdf: Don't expect too much C++11 support for now (Bug #1067).
+
+CHANGES IN V1.0.24
+
+ - pdftopdf now generates the necessary pdf comments to disable
+ duplicate number-up when pdftops is also applied (Bug #1063).
+ - pdftops: Added support for using Adobe Reader (acroread) in command
+ line mode for turning PDF to PostScript (Bug #1065).
+ - pdftopdf: Fix build on OpenBSD (Bug #1062).
+ - pdftops: Fix stripping of page management options from the pstops
+ command line which got already applied by pdftopdf. If the name
+ of the option to be removed is contained in the name of a option
+ in the command line (like "number-up" in "number-up-layout" or
+ "scaling" in "Natural-scaling"), this option gets stripped instead
+ of the correct option (Bug #1064).
+
+CHANGES IN V1.0.23
+
+ - Removed filter/pdftopdf.old
+ - Fixed the requires.private for cupsfilters lib
+
+CHANGES IN V1.0.22
+
+ - Added missing *.h files of filter/pdftopdf/ to source file list so
+ that "make dist" builds correct upstream tarballs.
+
+CHANGES IN V1.0.21
+
+ - bannertopdf: Page duplication routine fixed.
+ - bannertopdf: Fixed invalid output of a direct stream object.
+ - pdftopdf filter replaced by new QPDF-based filter from Tobias
+ Hoffmann's Google Summer of Code project. The former Poppler-based
+ pdftopdf duplicated a lot of Poppler's code. The old filter is
+ still in the package as pdftopdf.old with source code in
+ filter/pdftopdf.old. It will be removed in a later release.
+ - Added most recent contributors to AUTHORS and COPYING files.
+
+CHANGES IN V1.0.20
+
+ - pdftops: Added another workaround for Kyocera printers: Some
+ models get very slow on images which request interpolation,
+ so now we remove the image interpolation requests by additional
+ PostScript code only inserted for Kyocera printers (Ubuntu bug
+ #1026974).
+ - pdftops: The build system only configured the default renderer
+ (Ghostscript OR Poppler), not the other renderer, but as we support
+ switching on runtime both need to get configured.
+ - Improved portability of the package to non-Linux systems (Bug #1056).
+ - Made the Poppler-based filters pdftopdf and pdftoopvp build with
+ both Poppler 0.18.x and 0.20.x (Bug #1055).
+ - Let build system check for dlopen.
+
+CHANGES IN V1.0.19
+
+ - Fixes according to Coverity scan results (Bug #1054).
+ - Added distribution packaging instructions to INSTALL.
+ - Switched build system to autotools. This especially fixes several
+ build problems in Gentoo. Also build-tested with CUPS 1.6.0b1.
+ - Fixes for compatibility with clang/gcc-4.7.
+ - textonly: Filter did not work as a pipe with copies=1 (Bug #1032).
+ - texttopdf: Avoid trimming the results of FcFontSort(), as this may
+ miss some reasonable candidates under certain circumstances. BTW,
+ fix passing a non-pointer as a pointer to "result" (Debian bug
+ #670055),
+ - Corrected documentation. The option for the maximum image rendering
+ resolution in pdftops is "pdftops-max-image-resolution", not
+ "pdftops-max-image-resolution-default".
+
+CHANGES IN V1.0.18
+
+ - Modified "./configure" options related to the pdftops filter to
+ allow changing the defaults for the renderer being used by default
+ (Ghostscript or Poppler) and the maximum image rendering resolution
+ and to supply paths for both Ghostscript's gs and Poppler's pdftops.
+ - pdftops: Allow selection whether Ghostscript or Poppler is used
+ at runtime, setting the "pdftops-renderer" option to "gs" or
+ "pdftops".
+ - pdftops: Allow setting an upper limit for the image rendering
+ resolution, also at runtime, setting the option
+ "pdftops-max-image-resolution" to the desired limit in dpi.
+ "0" means no limit.
+ - pdftops: Fixed crash by wrong usage of sizeof() function when adding
+ "Collate" to the fifth command line argument for the "pstops" CUPS
+ filter call (Ubuntu bug #982675).
+ - pdftops: Removed newline from copies value when reading it from
+ the "%%PDFTOPDFNumCopies" entry of the incoming PDF file.
+ - pdftops: Silenced compiler warning about ignoring the return
+ value of the write() function.
+ - pdftops: Added a crash guard.
+ - pdftops: Start determining the printing resolution with
+ cupsRasterInterpretPPD(), this is the most reliable as often
+ the choice names of the "Resolution" option are marketing names
+ with higher numerical values than the actual resolution. Also
+ ignore error exit values of cupsRasterInterpretPPD() as the
+ function can error out after having found the resolution.
+ - pdftops: If printing resolution is determined by
+ cupsRasterInterpretPPD() do not stick on 100 dpi if the
+ resolution cannot be determined (Ubuntu bug #984082).
+
+CHANGES IN V1.0.17
+
+ - pdftopdf: Fixed segmentation fault when printing selected pages
+ ("page-ranges" option, Ubuntu bug #980673).
+
+CHANGES IN V1.0.16
+
+ - pdftopdf: Fixed segmentation faults when using N-up with certain PDF
+ files (Ubuntu bug #980673) and when calling pdftopdf manually without
+ specifyting a PPD file.
+
+CHANGES IN V1.0.15
+
+ - pdftops: Suppress image compression only for Brother printers as they
+ really need this measure to print at all. This accelerates printer-
+ internal job processing on most other printers (tested on HP and
+ Kyocera). Also suppress page compression on Kyocera printers, this
+ works around a bug in Kyocera's PostScript interpreters which makes
+ printing pages with images very slow (Ubuntu bug #977912).
+
+CHANGES IN V1.0.14
+
+ - pdftops: Determine printing resolution from the PPD file and supply
+ it on the Ghostscript or pdftops (Poppler) command line, so that
+ the renderer does the image rendering with a resolution matching the
+ printer's resolution. This avoids too slow processing of the jobs
+ by the printer's built-in PostScript interpreter. In addition
+ a default resolution of 300 dpi is used for PPDs without any hint
+ of the printer's resolution, as most PostScript lasers use multiples
+ of 300 dpi as resolution (Ubuntu bug #977912).
+
+CHANGES IN V1.0.13
+
+ - bannertopdf: Fix display of the job dates on the test page and on
+ banner pages (Ubuntu bug #975064).
+
+CHANGES IN V1.0.12
+
+ - Fixed crash of imagetopdf filter when it is called manually
+ without supplying a valid PPD file (Ubuntu bug #973564).
+
+CHANGES IN V1.0.11
+
+ - Actually install the Generic PDF printer PPD file.
+ - Really introduce a Generic PDF printer PPD file.
+
+CHANGES IN V1.0.10
+
+ - Added Generic PPD file for native PDF printers.
+ - Updated all code copied from Poppler to the current state of Poppler.
+ - Made Poppler-based PDF filters building with various versions of
+ Poppler.
+
+CHANGES IN V1.0.9
+
+ - Deactivated NIME conversion rules which are not used by the PDF-
+ based printing workflow.
+ - Cleaned up sample PPD file HP-Color_LaserJet_CM3530_MFP-PDF.ppd.
+ - imagetopdf: Added support for native PDF printers.
+ - imagetopdf, imagetoraster: Let image input "scale to fit"
+ by default. This makes photo printing via AirPrint work,
+ as the iOS devices send JPEG but do not allow setting options.
+
+CHANGES IN V1.0.8
+
+ - pdftops: Generally do not compress fonts and images, and
+ also do not do CCITT compression for bitmap glyphs to make
+ the PostScript output more compatible with buggy PostScript
+ interpreters. The output gets 30-50% longer but will work on
+ many more different printer models. Problems were also
+ discovered on HP and not only on Brother (Ubuntu bug
+ #960666).
+
+CHANGES IN V1.0.7
+
+ - pdftops: Added PostScript debug mode. For jobs sent with "-o psdebug"
+ the PostScript output by Ghostscript does not have compression of
+ pages and fonts, so that one can analyse the PostScript code,
+ especially in cases of incompatibilities and bugs of the built-in
+ PostScript interpreters of printers. Thanks to the Ghostscript
+ upstream developers for this hint.
+
+CHANGES IN V1.0.6
+
+ - texttopdf: Fixed minor miscalculation of /AvgWidth.
+ - texttopdf: Added support for direct file references in pdf.utf-8.
+ - pdftops: Added another workaround for a bug in Brother's PostScript
+ interpreter: Suppress CCITT compression for bitmap glyphs and
+ images on Brother printers (Ubuntu bug #955553).
+ - texttopdf: Fixed typo in pdf font descriptor dictionary keys.
+ - Fixed ColorDevice definition in cupsfilters.drv for HP DesignJet
+ printers.
+ - Put ModelNumber entries in cupsfilters.drv at the right place to
+ get correct "*cupsModelNumber:" entries in the PPDs for the HP
+ DesignJet printers.
+ - rastertopclx: Code of JCL options did not get inserted into the JCL
+ header.
+ - parallel backend: Use the same way as CUPS does to prevent an
+ infinite loop on side channel errors (CUPS STR #4044).
+ - pdftopdf: Added support for native PDF printers, add JCL (PJL)
+ options and send page_log entries only if the PDF has the
+ "*JCLToPDFInterpreter:" keyword.
+ - Updated README.txt for the new native PDF printer support.
+ - Added a sample PPD file for a native PDF printer,
+ HP-Color_LaserJet_CM3530_MFP-PDF.ppd.
+ - texttopdf: A lot of internal rework; also split up into more files
+ - texttopdf: Fixed many bugs on the way
+ - texttopdf: Added support for CFF-flavoured OTFs; for these
+ subsetting is not yet implemented, full embedding is done instead
+ - texttopdf: Adapted and improved fontconfig font selection
+ - Make sure that "make clean" and "make distclean" also work if
+ Makedefs does not exist (Debian bug #663564).
+
+CHANGES IN V1.0.5
+
+ - pdftops: Added insertion of workaround PostScript code for printers
+ with bugs in their PS interpreters (Ubuntu bugs #950713, #951627).
+ - parallel backend: Break infinite loop (Ubuntu bug #936647).
+ - texttopdf: Complete the implementation of fontconfig-based font
+ selection (Debian bug #663070).
+
+CHANGES IN V1.0.4
+
+ - texttopdf: Fall back to altermative fonts via fontconfig if the
+ FreeMono TrueType fonts are not installed (Debian bugs #495598
+ and #662660).
+ - bannertopdf: Fix off-by-one error in page duplication
+ - bannertopdf: Put indirect references to streams into the page's
+ contents
+ - bannertopdf: Let byte offsets for the Xref table of the PDF output
+ being determined correctly also when the output goes to stdout
+ (Ubuntu bug #939735).
+ - bannertopdf: Output multiple copies of the test page if duplex
+ and/or N-up is chosen, to let the test page appear on all possible
+ positions of the sheet (Ubuntu bug #939530).
+
+CHANGES IN V1.0.3
+
+ - bannertopdf: Draw the frame to mark the non-printable borders 1pt
+ smaller all around to assure that it is always visible, like it was
+ done in bannertops.
+ - bannertopdf: Scale the page to fit onto the desired output page.
+ - bannertopdf: Get and output the correct media limits.
+
+CHANGES IN V1.0.2
+
+ - bannertopdf: Fixed crash caused by wrong Poppler API use.
+ - bannertopdf: Info text on test page came out in gray and not in
+ black.
+
+CHANGES IN V1.0.1
+
+ - Added the textonly filter and its PPD file, a driver for text-only
+ printers.
+ - Install the pdftoijs sample PPD file
+ HP-PhotoSmart_Pro_B8300-hpijs-pdftoijs.ppd
+ - Added cupsfilters.drv, centralized ppdc-based PPD generator for the
+ printer driver filters in this package. Current printers supported
+ are several HP DesignJet large format inkjet printers.
+ - Fixed "make uninstall". Now everything of this package gets removed.
+ - Added wrapper scripts texttops and imagetops for backward
+ compatibility to third-party PPD files or custom configurations
+ which refer to these filters explicitly (Debian bug #658258).
+
+CHANGES IN V1.0
+
+ - Built the pdftops filter based on Ghostscript by default, as
+ Ghostscript is better optimized for print output (Ubuntu bug
+ #926068).
+ - If the pdftops filter is built for using Poppler, let Poppler not
+ emit PostScript level 3, as this causes problems with some HP
+ printers (Ubuntu bug #277404, Freedesktop (Poppler) bug #19640).
+ - bannertopdf needs to be linked with C++ (bug #995)
+ - Added test.sh script for testing texttopdf
+ - Added original documentation of the PDF filters to README.txt
+ - Install C header files and the static library
+ - General clean-up of "make install" targets in Makefiles
+ - Raised MIME conversion cost factor of pdftoraster from 66 to 100 to
+ give priority to the gstoraster filter from Ghostscript, as this
+ filter supports ICC-profile-based color management.
+ - Documentation updated because libijs, liblcms, freetype, and
+ fontconfig are needed to build this package
+
+CHANGES IN V1.0b1
+
+ - Removed the bannertops, imagetops, and texttops filters, they are
+ not needed any more in the PDF-based printing workflow
+ - Added support for liblcms2
+ - Named the package "OpenPrinting CUPS Filters"
+ - Renamed libcupslegacy to libcupsfilters
+ - Joined pdftops and cpdftocps filters into one C program
+ - Added new bannertopdf filter from Lars Uebernickel:
+ https://launchpad.net/bannertopdf
+ - Added the filters for the PDF-based printing workflow, from
+ OpenPrinting: http://sourceforge.jp/projects/opfc/ and
+ http://www.openprinting.org/download/printing/pdf-printing/
+ - Initial packaging of files that are no longer included in CUPS 1.6
+ from CUPS upstream (http://www.cups.org/)
diff --git a/README b/README
new file mode 100644
index 000000000..25cb9f4dd
--- /dev/null
+++ b/README
@@ -0,0 +1,1805 @@
+README - OpenPrinting CUPS Filters v1.17.9 - 2017-10-05
+-------------------------------------------------------
+
+Looking for compile instructions? Read the file "INSTALL.txt"
+instead...
+
+
+INTRODUCTION
+
+ CUPS is a standards-based, open source printing system developed
+ by Apple Inc. for Mac OS® X and other UNIX®-like operating
+ systems. CUPS uses the Internet Printing Protocol ("IPP") and
+ provides System V and Berkeley command-line interfaces, a web
+ interface, and a C API to manage printers and print jobs.
+
+ This package contains backends, filters, and other software that
+ was once part of the core CUPS distribution but is no longer
+ maintained by Apple Inc. In addition it contains additional
+ filters and software developed independently of Apple, especially
+ filters for the PDF-centric printing workflow introduced by
+ OpenPrinting and a daemon to browse broadcasts of remote CUPS
+ printers and IPP printers to make them available locally.
+
+ From CUPS 1.6.0 on, this package is required for using printer
+ drivers (und also driverless printing) with CUPS under Linux. With
+ CUPS 1.5.x and 1.4.x this package can be used optionally to switch
+ over to PDF-based printing. In that case some filters are provided
+ by both CUPS and this package. Then the filters of this package
+ should be used.
+
+ For compiling and using this package CUPS, libqpdf, libjpeg,
+ libpng, libtiff, freetype, fontconfig, liblcms (liblcms2
+ recommended), libavahi-common, libavahi-client, libdbus, and glib
+ are needed. It is highly recommended, especially if non-PDF
+ printers are used, to have at least one of Ghostscript, Poppler,
+ or MuPDF. To print banner pages Poppler is needed.
+
+ The Poppler-based filters need a C++ compiler which supports C++11
+ and Poppler being built with the "./configure" options
+ "--enable-splash --disable-fixedpoint --disable-single-precision"
+ (if in the actually used Poppler version such options are
+ available). This is the case for most modern Linux distributions.
+
+ For PCLm output (used by Mopria and Wi-Fi Direct printers) QPDF of
+ at least version 7.0.0 is required.
+
+ For Apple Raster output (used by AirPrint printers) at least CUPS
+ 2.2.2 is required.
+
+ For Braille embosser support (see below) you will also need at
+ least liblouis, ImageMagick, and poppler-utils. Recommended is to
+ also have liblouisutdml, antiword, docx2txt for more sophisticated
+ Braille generation representing also the formatting of the input
+ text. None of these is needed for compiling cups-filters.
+
+ CUPS, this package, and Ghostscript contain some rudimentary
+ printer drivers and especially the filters needed for driverless
+ printing (currently PWG Raster, Apple Raster, PCLm, and PDF output
+ formats, for IPP Everywhere, AirPrint, Mopria, and Wi-Fi Direct
+ printers), see http://www.openprinting.org/drivers/ for a more
+ comprehensive set of printer drivers for Linux.
+
+ See
+
+ https://wiki.linuxfoundation.org/openprinting/pdf_as_standard_print_job_format
+
+ for information about the PDF-based printing workflow.
+
+ Report bugs to
+
+ https://bugs.linuxfoundation.org/
+
+ Choose "OpenPrinting" as the product and "cups-filters" as the component.
+
+ See the "COPYING" files for legal information.
+
+IMAGE PRINTING DEFAULT CHANGED TO "SCALE TO FIT"
+
+ Compared to the PostScript-based original CUPS filters there is a
+ change of defaults: The imagetopdf and imagetoraster filters print
+ in "scale-to-fit" mode (image is scaled to fill one page but
+ nothing of the image being cut off) by default.
+
+ This is done to support photo printing via AirPrint. The photo
+ apps on Apple's iOS devices send print jobs as JPEG images and do
+ not allow to set any options like "scaling" or the page size. With
+ "scale-to-fit" mode set by default, the iOS photos come out on one
+ page, as expected.
+
+ To get back to the old behavior, supply one of the options
+ "nofitplot" "filplot=Off", "nofit-to-page", or "fit-to-page=Off".
+
+GHOSTSCRIPT RENDERING OF FILLED PATHS
+
+ When Ghostscript is rendering PostScript or PDF files into a
+ raster format the filled paths are ususally rendered with the
+ any-part-of-pixel method as it is PostScript standard. On
+ low-resolution printers, like label printers with 203 dpi,
+ graphics output can get inaccurate and so for example bar codes do
+ not work any more. This problem can be solved by letting
+ Ghostscript use the center-of-pixel method.
+
+ This can be done by either supplying the option "-o
+ center-of-pixel" or "-o CenterOfPixel" on the command line when
+ printing or by adding a "CenterOfPixel" option to the PPD file and
+ set it to "true", for example by adding the following lines to the
+ PPD file of the print queue (usually in /etc/cups/ppd/):
+
+ *OpenUI *CenterOfPixel/Center Of Pixel: PickOne
+ *OrderDependency: 20 AnySetup *CenterOfPixel
+ *DefaultCenterOfPixel: true
+ *CenterOfPixel true/true: ""
+ *CenterOfPixel false/false: ""
+ *CloseUI: *CenterOfPixel
+
+ This option can be used when the print queue uses the gstoraster
+ filter.
+
+POSTSCRIPT PRINTING RENDERER AND RESOLUTION SELECTION
+
+ If you use CUPS with this package and a PostScript printer then
+ the included pdftops filter converts the print job data which is
+ in PDF format into PostScript. By default, the PostScript is
+ generated with Ghostscript's "ps2write" output device, which
+ generates a DSC-conforming PostScript with compressed embedded
+ fonts and compressed page content. This is resource-saving and
+ leads to fast wire transfer of print jobs to the printer.
+
+ Unfortunately, Ghostscript's PostScript output is not compatible
+ with some printers due to interpreter bugs in the printer and in
+ addition, processing (by Ghostscript or by the printer's
+ interpreter) can get very slow with high printing resolutions when
+ parts of the incoming PDF file are converted to bitmaps if they
+ contain graphical structures which are not supported by
+ PostScript. The bitmap problem especially occurs on input files
+ with transparency, especially also the ones produced by Cairo
+ (evince and many other GNOME/GTK applications) which unnecessarily
+ introduces transparency even if the input PDF has no transparency.
+
+ Therefore there are two possibilities to configure pdftops at
+ runtime:
+
+ 1. Selection of the renderer: Ghostscript, Poppler, pdftocairo,
+ Adobe Reader, or MuPDF
+
+ Ghostscript has better color management and is generally optimized
+ more for printing. Poppler produces a PostScript which is
+ compatible with more buggy built-in PostScript interpreters of
+ printers and it leads to a somewhat quicker workflow when
+ graphical structures of the input PDF has to be turned into
+ bitmaps. Adobe Reader is the PDF renderer from Adobe, the ones who
+ created PDF and PostScript. pdftocairo is a good choice for the
+ PDF output of Cairo (for example when printing from evince). It
+ is less resource-consuming when rasterizing graphical elements
+ which cannot be represented in PostScript (like
+ transparency). Note that pdftocairo only supports PDF input using
+ DeviceRGB, DeviceGray, RGB or sGray and is not capable of
+ generating PostScript level 1. So its support is only experimental
+ and distributions should not choose it as default.
+
+ The selection is done by the "pdftops-renderer" option, setting it
+ to "gs", "pdftops", "pdftocairo", "acroread", "mupdf", or "hybrid":
+
+ Per-job: lpr -o pdftops-renderer=pdftops ...
+ Per-queue default: lpadmin -p printer -o pdftops-renderer-default=gs
+ Remove default: lpadmin -p printer -R pdftops-renderer-default
+
+ By default, pdftops uses Ghostscript if this does not get changed
+ at compile time, for example by the Linux distribution vendor.
+
+ Hybrid means Ghostscript for most printers, but Poppler's pdftops
+ for Brother, Minolta, and Konica Minolta. Printer make and model
+ information comes from the PPD or via the "make-and-model" option.
+
+ 2. Limitation of the image rendering resolution
+
+ If graphical structures of the incoming PDF file have to be
+ converted to bitmaps due to limitations of PostScript, the
+ conversion of the file by pdftops or the rendering by the printer
+ can get too slow if the bitmap resolution is too high or the
+ printout quality can degrade if the bitmap resolution is too low.
+
+ By default, pdftops tries to find out the actual printing
+ resolution and sets the resolution for bitmap generation to the
+ same value. If it cannot find the printing resolution, it uses 300
+ dpi. It never goes higher than a limit of 1440 dpi. Note that this
+ default limit can get changed at compile time, for example by the
+ Linux distribution vendor.
+
+ The resolution limit for bitmaps can be changed to a lower or
+ higher value, or be set to unlimited. This is done by the option
+ "pdftops-max-image-resolution", setting it to the desired value
+ (in dpi) or to zero for unlimited. It can be used per-job or as
+ per-queue default as the "pdftops-renderer" option described
+ above.
+
+ The "pdftops-max-image-resolution" option is ignored when Adobe
+ Reader is selected as PDF renderer.
+
+POSTSCRIPT PRINTING DEBUG MODE
+
+ Sometimes a PostScript printer's interpreter errors, crashes, or
+ somehow else misbehaves on Ghostscript's output. To find
+ workarounds (currently we have already workarounds for Brother and
+ Kyocera) it is much easier to work with uncompressed PostScript.
+ To get uncompressed PostScript as output, send a job with the
+ "psdebug" option, with commands like the following:
+
+ lpr -P <printer> -o psdebug <file>
+ lp -d <printer> -o psdebug <file>
+
+ If you want to send your job out of a desktop application, run
+
+ lpoptions -p <printer> -o psdebug
+
+ to make "psdebug" a personal default setting for you.
+
+ To extract the PostScript output for a developer to analyse it,
+ clone your print queue to a one which prints into a file:
+
+ cupsctl FileDevice=yes
+ lpadmin -p test -E -v file:/tmp/printout \
+ -P /etc/cups/ppd/<name of original queue>.ppd
+
+ and print into this queue as described above. The PostScript
+ output is in /tmp/printout after the job has completed.
+
+ This option does not change anything if Poppler's pdftops is used
+ as renderer.
+
+HELPER DAEMON FOR BROWSING REMOTE CUPS PRINTERS AND IPP NETWORK PRINTERS
+
+ From version 1.6.0 on in CUPS the CUPS broadcasting/browsing
+ facility was dropped, in favour of Bonjour-based broadcasting of
+ shared printers. This is done as Bonjour broadcasting of shared
+ printers is a standard, established by the PWG (Printing Working
+ Group, http://www.pwg.org/), and most other network services
+ (shared file systems, shared media files/streams, remote desktop
+ services, ...) are also broadcasted via Bonjour.
+
+ Problem is that CUPS only broadcasts its shared printers but does
+ not browse broadcasts of other CUPS servers to make the shared
+ remote printers available locally without any configuration
+ efforts. This is a regression compared to the old CUPS
+ broadcasting/browsing. The intention of CUPS upstream is that the
+ application's print dialogs browse the Bonjour broadcasts as an
+ AirPrint-capable iPhone does, but it will take its time until all
+ toolkit developers add the needed functionality, and programs
+ using old toolkits or no toolkits at all, or the command line stay
+ uncovered.
+
+ The solution is cups-browsed, a helper daemon running in parallel
+ to the CUPS daemon which listens to Bonjour broadcasts of shared
+ CUPS printers on remote machines in the local network via Avahi,
+ and can also listen for (and send) CUPS Browsing broadcasts. For
+ each reported remote printer it creates a local raw queue pointing
+ to the remote printer so that the printer appears in local print
+ dialogs and is also available for printing via the command
+ line. As with the former CUPS broadcasting/browsing with this
+ queue the driver on the server is used and the local print dialogs
+ give access to all options of the server-side printer driver.
+
+ Note that CUPS broadcasting/browsing is available for legacy
+ support, to let the local CUPS daemon work seamlessly together
+ with remote CUPS daemons of version 1.5.x and older which only
+ support CUPS broadcasting/browsing. In networks with only CUPS
+ 1.6.x servers (or Ubuntu or Fedora/Red Hat servers with CUPS
+ 1.5.x) please use the native Bonjour broadcasting of your servers
+ and cups-browsed, configured for Bonjour browsing only on the
+ clients.
+
+ Also high availability with redundant print servers and load
+ balancing is supported. If there is more than one server providing
+ a shared print queue with the same name, cups-browsed forms a
+ cluster locally with this name as queue name and printing through
+ the "implicitclass" backend. Each job triggers cups-browsed to
+ check which remote queue is suitable for the job, meaning that it
+ is enabled, accepts jobs, and is not currently printing. If none
+ of the remote queues fulfills these criteria, we check again in 5
+ seconds, until a printer gets free to accommodate the job. When we
+ search for a free printer, we do not start at the first in the
+ list, but always on the one after the last one used (as CUPS also
+ does with classes), so that all printer get used, even if the
+ frequency of jobs is low. This is also what CUPS formerly did with
+ implicit classes. Optionally, jobs can be sent immediately into
+ the remote queue with the lowest number of waiting jobs, so that
+ no local queue of waiting jobs is built up.
+
+ For maximum security cups-browsed uses IPPS (encrypted IPP)
+ whenever possible.
+
+ In addition, cups-browsed is also capable of discovering IPP
+ network printers (native printers, not CUPS queues) with known
+ page description languages (PWG Raster, Apple Raster, PDF,
+ PostScript, PCL XL, PCL 5c/e) in the local network and auto-create
+ print queues with auto-created PPD file or PPD-less for them (for
+ the latter using a System V interface script to control the filter
+ chain, only available for CUPS 2.1.0 and older, clients have to
+ IPP-poll the capabilities of the printer and send option settings
+ as standard IPP attributes then). This functionality is primarily
+ for mobile devices running CUPS to not need a printer setup tool
+ nor a collection of printer drivers and PPDs.
+
+ cups-browsed can also be started on-demand, for example to save
+ resources on mobile devices. For this, cups-browsed can be set
+ into an auto shutdown mode so that it stops automatically when it
+ has no remote printers to take care of any more, especially if an
+ on-demand running avahi-daemon stops. Note that CUPS must stay
+ running for cups-browsed removing its queues and so being able to
+ shut down. Ideal is if CUPS stays running another 30 seconds after
+ finishing its last job so that cups-browsed can take down the
+ queue. For how to set up and control this mode via command line,
+ configuration directives, or sending signals see the man pages
+ cups-browsed(8) and cups-browsed.conf(5).
+
+ The configuration file for cups-browsed is
+ /etc/cups/cups-browsed.conf. This file can include limited forms
+ of the original CUPS BrowseRemoteProtocols, BrowseLocalProtocols,
+ BrowsePoll, and BrowseAllow directives. It also can contain the
+ new CreateIPPPrinterQueues to activate discovering of IPP network
+ printers and creating PPD-less queues for them.
+
+ Note that cups-browsed does not work with remote CUPS servers
+ specified by a client.conf file. It always connects to the local
+ CUPS daemon by setting the CUPS_SERVER environment variable and so
+ overriding client.conf. If your local CUPS daemon uses a
+ non-standard domain socket as only way of access, you need to
+ specify it via the DomainSocket directive in
+ /etc/cups/cups-browsed.conf.
+
+ The "make install" process installs init scripts which make the
+ daemon automatically started during boot. You can also manually
+ start it with (as root):
+
+ /usr/sbin/cups-browsed &
+
+ or in debug mode with
+
+ /usr/sbin/cups-browsed --debug
+
+ Shut it down by sending signal 2 (SIGINT) or 15 (SIGTERM) to
+ it. The queues which it has created get removed then (except a
+ queue set as system default, to not loose its system default
+ state).
+
+ On systems using systemd use a
+ /usr/lib/systemd/system/cups-browsed.service file like this:
+
+ [Unit]
+ Description=Make remote CUPS printers available locally
+ After=cups.service avahi-daemon.service
+ Wants=cups.service avahi-daemon.service
+
+ [Service]
+ ExecStart=/usr/sbin/cups-browsed
+
+ [Install]
+ WantedBy=multi-user.target
+
+ On systems using Upstart use an /etc/init/cups-browsed.conf file like this:
+
+ start on (filesystem
+ and (started cups or runlevel [2345]))
+ stop on runlevel [016]
+
+ respawn
+ respawn limit 3 240
+
+ pre-start script
+ [ -x /usr/sbin/cups-browsed ]
+ end script
+
+ exec /usr/sbin/cups-browsed
+
+ These files are included in the source distribution as
+ utils/cups-browsed.service and utils/cups-browsed-upstart.conf.
+
+ In the examples we start cups-browsed after starting
+ avahi-daemon. This is not required. If cups-browsed starts first,
+ then Bonjour/DNS-SD browsing kicks in as soon as avahi-daemon comes
+ up. cups-browsed is also robust against any shutdown and restart
+ of avahi-daemon.
+
+ Here is some info on how cups-browsed works internally (first concept of a
+ daemon which does only Bonjour browsing):
+
+ - Daemon start
+ o Wait for CUPS daemon if it is not running
+ o Read out all CUPS queues created by this daemon (in former sessions)
+ o Mark them unconfirmed and set timeout 10 sec from now
+ - Main loop (use avahi_simple_poll_iterate() to do queue list maintenance
+ regularly)
+ o Event: New printer shows up
+ + Queue for printer is already created by this daemon -> Mark list
+ entry confirmed, if discovered printer is ipps but existing queue ipp,
+ upgrade existing queue by setting URI to ipps. Set status to
+ to-be-created and timeout to now-1 sec to make the CUPS queue be
+ updated.
+ + Queue does not yet exist -> Mark as to-be-created and set
+ timeout to now-1 sec.
+ o Event: A printer disappears
+ + If we have listed a queue for it, mark the entry as disappeared, set
+ timeout to now-1 sec
+ o On any of the above events and every 2 sec
+ + Check through list of our listed queues
+ - If queue is unconfirmed and timeout has passed, mark it as
+ disappeared, set timeout to now-1 sec
+ - If queue is marked disappered and timeout has passed, check whether
+ there are still jobs in it, if yes, set timeout to 10 sec from now,
+ if no, remove the CUPS queue and the queue entry in our list. If
+ removal fails, set timeout to 10 sec.
+ - If queue is to-be-created, create it, if succeeded set to
+ confirmed, if not, set timeout to 10 sec fron now. printer-is-shared
+ must be set to false.
+ - Daemon shutdown
+ o Remove all CUPS queues in our list, as long as they do not have jobs.
+
+ Do not overwrite existing queues which are not created by us If
+ the simple <remote_printer> name is already taken, try to create a
+ <remote_printer>@<server> name, if this is also taken, ignore the
+ remote printer. Do not retry, to avoid polling CUPS all the time.
+
+ Do not remove queues which are not created by us. We do this by
+ listing only our queues and remove only listed queues.
+
+ Queue names: Use the name of the remote queue. If a queue with the
+ same name from another server already exists, mark the new queue
+ as duplicate and when a queue disappears, check whether it has
+ duplicates and change the URI of the disappeared queue to the URI
+ of the first duplicate, mark the queue as to-be-created with
+ timeout now-1 sec (to update the URI of the CUPS queue) and mark
+ the duplicate disappeared with timeout now-1 sec. In terms of
+ high availability we replace the old load balancing of the
+ implicit class by a failover solution. Alternatively (not
+ implemented), if queue with same name but from other server
+ appears, create new queue as <original name>@<server name without
+ .local>. When queue with simple name is removed, replace the first
+ of the others by one with simple name (mark old queue disappeared
+ with timeout now-1 sec and create new queue with simple name).
+
+ Fill description of the created CUPS queue with the Bonjour
+ service name (= original description) and location with the server
+ name without .local.
+
+ stderr messages only in debug mode (command line options:
+ "--debug" or "-d" or "-v").
+
+ Queue identified as from this daemon by doing the equivalent of
+ "lpadmin -p printer -o cups-browsed-default", this generates a
+ "cups-browsed" attribute in printers.conf with value "true".
+
+CUPS FILTERS FOR PDF AS STANDARD PRINT JOB FORMAT
+
+ Here is documentation from the former CUPS add-on tarball with the filters
+ for the PDF-based printing workflow: imagetopdf, texttopdf,
+ pdftopdf, pdftoraster, pdftoopvp, and pdftoijs
+
+ The original filters are from http://sourceforge.jp/projects/opfc/
+
+ NOTE: the texttops and imagetops filters shipping with this package
+ are simple wrapper scripts for backward compatibility with third-party
+ PPD files and custom configurations. There are not referred to in the
+ cupsfilters.convs file and therefore not used by the default
+ configuration. Direct conversion of text or images to PostScript is
+ deprecated in the PDF-based printing workflow. So do not use these
+ filters when creating new PPDs or custom configurations. The parameters
+ for these filters are the same as for texttopdf and imagetopdf (see
+ below) as the ...tops filter calls the ....topdf filter plus
+ Ghostscript's pdf2ps.
+
+
+IMAGETOPDF
+==========
+
+1. INTRODUCTION
+
+This program is "imagetopdf". "imagetopdf" is a CUPS filter which reads
+a single image file, converts it into a PDF file and outputs it to stdout.
+
+This program accepts the following image file format;
+
+ gif, png, jpeg, tiff, photocd, portable-anymap, portable-bitmap,
+ portable-graymap, portable-pixmap, sgi-rgb, sun-raster, xbitmap,
+ xpixmap, xwindowdump
+
+xbitmap, xpixmap and xwindowdump images are converted into png images by
+the "convert" command. Other kinds of image file format can be supported
+if the "convert" command support them.
+
+Output PDF file format conforms to PDF version 1.3 specification, and
+input image is converted and contained in the output PDF file as a binary
+format non-compression image.
+
+"imagetopdf" may outputs multiple pages if the input image exceeds page
+printable area.
+
+2. LICENSE
+
+"imagetopdf.c" is under the CUPS license. See the "COPYING" file.
+For other files, see the copyright notice and license of each file.
+
+3. COMMAND LINE
+
+"imagetopdf" is a CUPS filter, and the command line arguments, environment
+variables and configuration files are in accordance with the CUPS filter
+interface.
+
+imagetopdf <job> <user> <title> <num-copies> <options> [<filename>]
+
+"imagetopdf" ignores <job> and <user>.
+<title> is appended into the PDF dictionary as /Title.
+<num-copies> specifies the number of document copies.
+<options> is a CUPS option list.
+<filename> is an input image file name.
+
+When omit the <filename>, "imagetopdf" reads an image file from stdin.
+
+4. ENVIRONMENT VARIABLES
+
+This program refers the following environment variable;
+
+ PPD: PPD file name of the printer.
+
+5. COMMAND OPTIONS
+
+"imagetopdf" accepts the following CUPS standard options;
+
+fitplot
+mirror
+PageSize
+page-left, page-right, page-bottom, page-top
+OutputOrder
+Collate
+sides
+cupsEvenDuplex
+position
+scaling
+ppi
+natural-scaling
+landscape
+orientation-requested
+
+See the CUPS documents for details of these options.
+
+6. KNOWN PROBLEMS
+
+Problem:
+ PBM and SUN raster images can not be printed.
+Solution:
+ Due to the CUPS libcupsimage library's bug. Update the CUPS on your system.
+
+7. INFORMATION FOR DEVELOPERS
+
+Following information is for developers, not for driver users.
+
+7.1 Options handled by a printer or "imagetopdf"
+
+Following options are handled by a printer or "imagetopdf".
+ Collate, Copies, Duplex, OutputOrder
+
+Which handles these options depends on following options and attributes.
+ Collate, Copies, Duplex, OutputOrder, cupsEvenDuplex, cupsManualCopies
+
+"imagetopdf" judges whether a printer can handle these options according to
+the followings option settings in a PPD file.
+
+Collate:
+ If Collate is defined, "imagetopdf" judges the printer supports Collate.
+Copies:
+ If cupsManualCopies is defined as True, "imagetopdf" judges the printer
+ does not support Copies feature.
+ 
+Duplex:
+ If Duplex is defined, "imagetopdf" judges the printer supports Duplex.
+ If cupsEvenDuplex is True, Number of pages must be even.
+OutputOrder:
+ If OutputOrder is defined, "imagetopdf" judges the printer supports
+ OutputOrder.
+
+If the printer cannot handle these options, "imagetopdf" handles it.
+
+Following pseudo program describes how "imagetopdf" judges to handle
+these options.
+
+Variables
+
+Copies : specified Copies
+Duplex : specified Duplex
+Collate : specified Collate
+OutputOrder : specified OutputOrder
+EvenDuplex : specified cupsEvenDuplex
+pages : number of pages
+number_up : specified number-up
+
+device_copies : Copies passed to the printer
+device_duplex : Duplex passed to the printer
+device_collate : Collate passed to the printer
+device_outputorder : OutputOrder passed to the printer
+
+soft_copies : copies by imagetopdf
+
+
+device_copies = 1;
+device_duplex = False;
+device_collate = False;
+device_outputorder = False;
+
+if (Copies == 1) {
+ /* Collate is not needed. */
+ Collate = False;
+}
+
+if (!Duplex) {
+ /* EvenDuplex is not needed */
+ EvenDuplex = False;
+}
+
+
+if (Copies > 1 && the printer can handle Copies) device_copies = Copies;
+if (Duplex && the printer can handle Duplex) {
+ device_duplex = True;
+} else {
+ /* imagetopdf cannot handle Duplex */
+}
+if (Collate && the printer can handle Collate) device_collate = True;
+if (OutputOrder == Reverse && the printer can handle OutputOrder)
+ device_outputorder = True;
+
+if (Collate && !device_collate) {
+ /* The printer cannot handle Collate.
+ So imagetopdf handle Copies */
+ device_copies = 1;
+}
+
+if (device_copies != Copies /* imagetopdf handle Copies */ && Duplex)
+ /* Make imagetopdf handle Collate, otherwise both paper side may have
+ same page */
+ Collate = True;
+ device_collate = False;
+}
+
+if (Duplex && Collate && !device_collate) {
+ /* Handle EvenDuplex, otherwise the last page has
+ the next copy's first page in the other side of the paper. */
+ EvenDuplex = True;
+}
+
+if (Duplex && OutputOrder == Reverse && !device_outputorder) {
+ /* Handle EvenDuplex, otherwise the first page's other side of paper
+ is empty. */
+ EvenDuplex = True;
+}
+
+soft_copies = device_copies > 1 ? 1 : Copies;
+
+7.2 JCL
+
+When you print PDF files to a PostScript(PS) printer, you can specify
+device options in PS. In this case, you can write PS commands in a PPD file
+like as follows.
+
+*OpenUI *Resolution/Resolution : PickOne
+*DefaultResolution: 600
+*Resolution 300/300 dpi: "<</HWResolution[300 300]>>setpagedevice"
+*Resolution 600/600 dpi: "<</HWResolution[600 600]>>setpagedevice"
+*CloseUI: *Resolution
+
+However, if options cannot be described in PS file, you can write JCLs
+as follows;
+
+*JCLOpenUI *JCLFrameBufferSize/Frame Buffer Size: PickOne
+*DefaultJCLFrameBufferSize: Letter
+*OrderDependency: 20 JCLSetup *JCLFrameBufferSize
+*JCLFrameBufferSize Off: '@PJL SET PAGEPROTECT = OFF<0A>'
+*JCLFrameBufferSize Letter: '@PJL SET PAGEPROTECT = LTR<0A>'
+*JCLFrameBufferSize Legal: '@PJL SET PAGEPROTECT = LGL<0A>'
+*JCLCloseUI: *JCLFrameBufferSize
+
+Because PDF cannot specify device options in a PDF file, you have to define
+all the device options as JCLs.
+
+When a printer does not support PS or PDF, you can use Ghostscript (GS).
+In this case, you can specify device options like a PS printer.
+If you want to use the same printer and same PPD file for both PDF and PS
+printing, when you print a PS file, you can specify that GS handles it,
+and when you print a PDF file, you can also specify that PDF filters handle
+it in the same PPD file. However in this case, previous methods is not
+appropriate to specify device options.
+
+So, "imagetopdf" handles this case as follows;
+(In following pseudo program, JCL option is an option specified with JCLOpenUI)
+
+if (Both JCLBegin and JCLToPSInterpreter are specified in the PPD file) {
+ output JCLs that marked JCL options.
+}
+
+if (pdftopdfJCLBegin attribute is specified in the PPD file) {
+ output it's value
+}
+
+if (Copies option is specified in the PPD file) {
+ mark Number of copies specified
+} else if (pdftopdfJCLCopies is specified in the PPD file) {
+ output JCL specified with JCLCopies
+}
+
+for (each marked options) {
+ if (pdftopdfJCL<marked option's name> is specified in the PPD file) {
+ output it's value as a JCL
+ } else if (pdftopdfJCLBegin attributes is specified in the PPD file) {
+ output "<option's name>=<marked choice>;" as a JCL
+ }
+}
+output NEWLINE
+
+Thus, if you want to use both PDF filters and GS by single PPD file,
+what you should do is to add the following line in the PPD file;
+
+*pdftopdfJCLBegin: "pdftoopvp jobInfo:"
+
+Note:
+ If you specify JCLBegin, you have to specify JCLToPSInterpreter as well.
+
+Note:
+ When you need to specify the value which is different from the choosen
+ value based on the PPD into the jobInfo, you have to specify the values
+ with the key started by "pdftopdfJCL" string.
+
+ For example, if the page size is defined in a PPD file as following;
+
+ *OpenUI *PageSize/Page Size: PickOne
+ *DefaultPageSize: A4
+ *PageSize A4/A4:
+ *PageSize Letter/US Letter:
+ *CloseUI: *PageSize
+
+ if you choose the page size "Letter", the string "PageSize=Letter;" is
+ added to jobInfo. On the other hand, if the driver requires the different
+ value for the "Letter" size, for instance driver requires "PS=LT;"
+ instead of "PageSize=Letter;" as the jobInfo value, the PPD file has to
+ be defined as following;
+
+ *OpenUI *PageSize/Page Size: PickOne
+ *DefaultPageSize: A4
+ *PageSize A4/A4:
+ *pdftopdfJCLPageSize A4/A4: "PS=A4;"
+ *PageSize Letter/US Letter:
+ *pdftopdfJCLPageSize Letter/US Letter: "PS=LT;"
+ *CloseUI: *PageSize
+
+7.3 Temporally files location
+
+"imagetopdf" creates temporally files if needed. Temporary files are created
+in the location specified by TMPDIR environment variable. Default location
+is "/tmp".
+
+
+PDFTOPDF
+========
+
+The pdftopdf filter depends on libqpdf to read and write PDF files.
+
+It replaces and imitates the pstops filter in the PDF-based workflow.
+A similar filter (which can serve as behavior reference)
+is called "cgpdftopdf" in OS X (not open source).
+
+Command line
+------------
+
+pdftopdf follows the usual CUPS filter calling conventions, i.e.
+
+ pdftopdf <job> <user> <title> <num-copies> <options> [<filename>]
+
+together with the environment variables "PPD" and "CLASSIFICATION".
+
+When omitting <filename>, "pdftopdf" reads a PDF file from stdin.
+Internally this will write the data to a temporary file, because
+the PDF format cannot be processed in a streaming fashion.
+
+<options> are delimited by space; boolean type CUPS options can be set
+by only adding the option key, other types are provided as
+pairs of key and value, <key>=<value>.
+
+pdftopdf processes the following standard command-line and/or PPD options:
+
+Copies # ppd will only override, when commandline parameter was 1
+fitplot / fit-to-page / ipp-attribute-fidelity
+landscape / orientation-requested
+PageSize / page-size / MediaSize / media-size
+page-left / page-right / page-bottom / page-top
+media-top-margin / media-left-margin / media-right-margin / media-bottom-margin
+Duplex / JCLDuplex / EFDuplex / JD03Duplex / sides
+number-up / number-up-layout
+page-border
+OutputOrder / OutputBin / DefaultOutputOrder / page-delivery
+page-label
+page-set
+page-ranges
+MirrorPrint / mirror
+emit-jcl
+position
+Collate / multiple-document-handling / sheet-collate
+cupsEvenDuplex
+cupsManualCopies # via ppd
+
+Additional (non-standard) options
+---------------------------------
+
+1) Booklet printing
+
+ booklet=Off/On/Shuffle-Only
+
+"On" also tries to set DuplexTumble (two-sided-short-edge) and forces number-up=2
+
+ booklet-signature=(multiple of 4, or default: -1 to use "all pages")
+
+2) Page autorotate
+
+pdftopdf automatically rotates pages to the same orientation,
+instead of (e.g. fitplot) scaling them down unrotated.
+This behavier can be controlled by
+
+ pdfAutorotate / nopdfAutorotate
+
+Specifically, if a PDF file contains pages with page width greater than
+page height (a landscape page), such pages are automatically rotated
+anticlockwise by 90 degrees, unless the PPD file specifies
+"*LandscapeOrientation: Minus90". In this case, clockwise rotation is used.
+To turn off the feature on a job-by-job basis use
+
+ lp -d <print_queue_name> -o nopdfAutorotate <document>
+
+On a per-queue basis use
+
+ -o nopdfAutorotate-default
+
+as an option to lpadmin.
+
+When the 'landscape' or 'orientation-requested=4' (or =5) option of CUPS is
+given, the pdfAutorotate processing will adjust and accordingly rotate the
+non-landscape pages are rotated instead.
+
+Note: Some pages might end up 180 degree rotated (instead of 0 degree).
+Those should probably be rotated manually before binding the pages together.
+
+Native PDF Printer / JCL Support
+--------------------------------
+
+pdftopdf will emit JCL when provided with a PPD file that includes the
+"*JCLToPDFInterpreter:" keyword.
+
+This enables for hardware copy generation and device collate; e.g. with PJL:
+
+*JCLBegin: "<1B>%-12345X@PJL JOB<0A>"
+*JCLToPDFInterpreter: "@PJL ENTER LANGUAGE = PDF <0A>"
+*JCLEnd: "<1B>%-12345X@PJL EOJ <0A><1B>%-12345X"
+
+For each marked option, the prefixed "pdftopdfJCL<option name>" keywords
+can also be used to send raw JCL strings for that option.
+These keywords also include *pdftopdfJCLBegin and *pdftopdfJCLCopies,
+This allows the use of the same PPD for PDF- and PS-based workflows,
+as pdftopdfJCL... will not be read in the PS case.
+
+When the PPD contains the "Copies" keyword, pdftopdf will detect the use
+of PJL and has special code which adds "@PJL SET COPIES=...",
+or "@PJL SET QTY=...", respectively.
+
+Other JCL code can be injected via "*JCLOpenUI: ..." ... "*JCLCloseUI: ...".
+
+Special PDF comments
+--------------------
+
+pdftopdf adds comments to the pdf preamble that might esp. be of use
+to subsequent filters, e.g.
+
+ % This file was generated by pdftopdf
+ %%PDFTOPDFNumCopies : 1
+ %%PDFTOPDFCollate : false
+
+The "NumCopies" and "Collate" values refer to the expected device/hardware
+copies, i.e. when pdftopdf's soft-copy generation did not handle this options.
+
+Limitations
+-----------
+
+pdftopdf does not support functions that are not related to printing
+features, including interactive features and document interchange features.
+Many of these operators and sections are just ignored.
+Some of these may be output, but those functions are not assured.
+
+Most notable is the use of AcroForms; their content will not be printed
+if any non-trivial processing by pdftopdf is involved (e.g. "fitplot").
+This only occurs when a file is printed directly, e.g. by "lpr".
+
+Usual PDF viewer applications (xpdf, evince, acroread, ghostscript, ...)
+will hardcopy the form content into printable pdf operations,
+when choosing to print such a document.
+
+Known issues
+------------
+
+- Borders, esp. in the "number-up=1 fitplot=false"-case might be drawn
+ at incorrect locations.
+
+- JCL documentation is sparse.
+ The imagetopdf or old pdftopdf documentation contains a tad more information.
+
+- Missing AcroForm-content might surprise users printing PDF files directly /
+ from the command-line (see the Limitations section, above).
+
+License
+-------
+
+pdftopdf is released under the MIT license.
+
+The required libqpdf is available under version 2 of the Artistic License,
+e.g. here: https://github.com/qpdf/qpdf
+
+
+TEXTTOPDF
+=========
+
+This implements a texttopdf filter, and is derived from cups' texttops.
+
+To configure:
+-------------
+
+- texttopdf uses CUPS_DATADIR/charset/pdf.utf-8 for font configuration
+ (when utf-8 was requested as charset). The font names given there are
+ used as fontconfig selectors; the best matching font, that is both
+ monospaced and in a supported format (TTC, TTF or OTF) will then be used.
+
+- As a special exception, all fontnames that start with a '.' or '/' are
+ considered filenames, and fontconfig is skipped; the name is used directly
+ for loading the font file.
+
+- Implementation note: TrueType Collections (.TTC) are internally handled
+ by appending '/' and the index of the font inside the collection to
+ the filename (e.g. to use the second font of uming.ttc, the filename
+ uming.ttc/1 must be given to the fontembed-library).
+ By appending the index-field returned from fontconfig, this is completely
+ transparent to the user (but currently not widely tested).
+
+- You may look at the two examples: pdf.utf-8.simple and pdf.utf-8.heavy.
+
+To use:
+-------
+
+The filter is called just like any other cups filter. Have a
+look at test.sh for example.
+
+Known Issues
+------------
+
+ - Text extraction does not work (at least for pdftotext from xpdf)
+ for the resulting pdfs.
+
+ - OTF(CFF) embedding currently does not subset the fonts.
+
+ - Text wrapping in pretty-printing mode does not respect double-wide
+ characters (CJK), and thus produce wrong results (wrap too late)
+ for lines where they occur. The fix is not trivial, since all the
+ pretty-printing processing is done without knowledge of / prior to
+ the font configuration (which is where single or double width
+ code-ranges are specified).
+
+ - The hebrew example in test5.pdf shows one of our limitations:
+ Compose glyphs are not composed with the primary glyph but printed
+ as separate glyphs.
+
+Further Infos
+-------------
+
+Font embedding is handled by libfontembed in the filter/fontembed
+subdirectory.
+
+Please report all bugs to https://bugs.linuxfoundation.org/, product
+"OpenPrinting", component "cups-filters".
+
+
+PDFTORASTER
+===========
+
+1. INTRODUCTION
+
+"pdftoraster" is a filter for CUPS. It reads PDF files, convert it and
+output CUPS raster.
+
+"pdftoraster" does not support functions that are not related to printing
+features, including interactive features and document interchange features.
+Many of these operators and sections are just ignored.
+Some of these may be output, but those functions are not assured.
+Encryption feature is not supported.
+
+2. LICENSE
+
+Almost source files are under MIT like license. However, "pdftoraster" links
+some "poppler" libraries, and these files are under GNU public license.
+See copyright notice of each file for details.
+
+3. COMMAND LINE
+
+"pdftoraster" is a CUPS filter, and the command line arguments, environment
+variables and configuration files are in accordance with the CUPS filter
+interface.
+
+pdftoraster <job> <user> <title> <num-copies> <options> [<filename>]
+
+"pdftoraster" ignores <job> and <user>.
+<title> is appended into the PDF dictionary as /Title.
+<num-copies> specifies the number of document copies.
+<options> is a CUPS option list.
+<filename> is an input PDF file name.
+
+When omit the <filename>, "pdftoraster" reads a PDF file from the stdin,
+and save it as a temporary file.
+
+4. ENVIRONMENT VARIABLES
+
+This program refers the following environment variable;
+ PPD: PPD file name of the printer.
+
+5. COMMAND OPTIONS
+
+See CUPS documents for details.
+
+6. INFORMATION FOR DEVELOPERS
+
+Following information is for developers, not for driver users.
+
+6.1 Options handled by a printer or "pdftoraster"
+
+"pdftopdf" outputs the following special comments from the 4th line in the
+created PDF data.
+
+%%PDFTOPDFNumCopies : <copies> --- <copies> specified Number of Copies
+%%PDFTOPDFCollate : <collate> --- <collate> is true or false
+
+"pdftoraster" overrides the command line options by above two option's values.
+
+6.2 Temporally files location
+
+"pdftoraster" creates temporally files if needed. Temporary files are created
+in the location specified by TMPDIR environment variable. Default location
+is "/tmp".
+
+
+PDFTOIJS
+========
+
+1. INTRODUCTION
+
+"pdftoijs" is a filter for CUPS. It reads PDF files, converts it
+and sends it to an IJS server.
+
+2. LICENSE
+
+Almost source files are under MIT like license. However, "pdftoijs" links
+some "poppler" libraries, and these files are under GNU public license.
+See copyright notice of each file for details.
+
+3. COMMAND LINE
+
+"pdftoijs" is a CUPS filter, and the command line arguments, environment
+variables and configuration files are in accordance with the CUPS filter
+interface.
+
+pdftoijs <job> <user> <title> <num-copies> <options> [<filename>]
+
+"pdftoijs" ignores <job> and <user>.
+<title> is appended into the PDF dictionary as /Title.
+<num-copies> specifies the number of document copies.
+<options> is a CUPS option list.
+<filename> is an input PDF file name.
+
+When omit the <filename>, "pdftoijs" reads a PDF file from the stdin,
+and save it as a temporary file.
+
+4. ENVIRONMENT VARIABLES
+
+This program refers the following environment variable;
+ PPD: PPD file name of the printer.
+
+5. NEW PPD KEYWORDS
+
+*ijsServer : the ijsserver executable
+*ijsManufacturer, *ijsModel : as used by the ijs server
+*ijsColorspace : the desired output colorspace, one of
+ 'rgb'
+ 'cmyk' (availability depending on poppler compile-options)
+ 'white1', 'black1': 1-bit normal/inverted
+ 'white8', 'black8': 8-bit greyscale normal/inverted
+*ijsResolution [option]=[choice]: the desired output resolution e.g. "600 600"
+*ijsParams [option]=[choice]: custom ijs parameters, separated by ','
+ (to escape: use \,)
+
+6. COMMAND OPTIONS
+
+(See CUPS documents for details.)
+
+ijsOutputFile : the destination file, stdout otherwise
+
+7. INFORMATION FOR DEVELOPERS
+
+Following information is for developers, not for driver users.
+
+7.1 Temporally files location
+
+"pdftoijs" creates temporary files if needed. Temporary files are created
+in the location specified by TMPDIR environment variable. Default location
+is "/tmp".
+
+
+PDFTOOPVP
+=========
+
+1. INTRODUCTION
+
+"pdftoopvp" is a CUPS filter which reads PDF file, renders pages and
+outputs PDL to a printer driver which is compliant with the OpenPrinting
+Vector Printer Driver Interface "opvp".
+
+2. CONFIGURATION
+
+"pdftoopvp" refers the poppler configuration file. Be aware that poppler
+uses "fontconfig" for its font configuration.
+
+3. JCL
+
+When "pdftoopvp" reads a PDF file from stdin, "pdftoopvp" handles the data
+prior to PDF header (%PDF ...) as JCL options. JCL options for "pdftoopvp"
+must begin with "pdftoopvp jobInfo:". "pdftoopvp" passes the option string
+just after ":" to the driver as the jobInfo option.
+
+4. COMMAND LINE
+
+"pdftoopvp" is a CUPS filter, and the command line arguments,
+environment variables and configuration files are in accordance with
+the CUPS filter interface.
+
+pdftoopvp <job> <user> <title> <num-copies> <options> [<filename>]
+
+"pdftoopvp" ignores <job>, <user>, <title> and <num-copies>.
+<options> is a CUPS option list.
+
+When omit the <filename>, "pdftoopvp" reads a PDF file from stdin,
+and save it as a temporary file.
+
+CUPS options defined in <options> are delimited by space. Boolean
+type CUPS option is defined only by the option key, and other type
+CUPS option are defined by pairs of key and value, <key>=<value>.
+
+5. COMMAND OPTIONS
+
+"pdftoopvp" accepts the following CUPS standard options;
+
+Resolution=<int>
+ Specifies a printer resolution in dpi.
+ When this option is omitted, the resolution is treated as 300dpi.
+ Horizontal and vertical resolution are treated as the same resolution.
+
+PageSize=<string>
+ Specifies a paper size by name defined in the PPD file.
+ This option is ignored when no PPD file is assigned for the printer
+ queue.
+
+"pdftoopvp" accepts the following original options;
+
+opvpDriver=<string>
+ Specifies a driver library name.
+
+opvpModel=<string>
+ Specifies a printer model name.
+
+opvpJobInfo=<string>
+ Specifies "jobInfo" printing options that are passed to the driver.
+ Printing options are overridden by JCL options.
+
+opvpDocInfo=<string>
+ Specifies "docInfo" document options that are passed to the driver.
+
+opvpPageInfo=<string>
+ Specifies "pageInfo" page options that are passed to the driver.
+
+pdftoopvpClipPathNotSaved (Boolean option)
+ Specifies that the driver cannot save clipping path operators in PDF.
+
+nopdftoopvpShearImage (Boolean option)
+ Specifies that the driver cannot rotate/shear images by CTM.
+
+nopdftoopvpMiterLimit (Boolean option)
+ Specifies that the driver does not support miter limit.
+ If the driver does not prepare the opvpSetMiterLimit function entry,
+ this option setting is ignored, and also miter limit is ignored.
+
+pdftoopvpIgnoreMiterLimit (Boolean option)
+ When nopdftoopvpMiterLimit option is set, pdftoopvp automatically
+ replace paths to multiple lines or drawing images. This option
+ specifies to avoid the path replacement even when nopdftoopvpMiterLimit
+ option is set.
+
+pdftoopvpMaxClipPathLength=<int>
+ Specifies the maximum number of clipping path points that the driver
+ supports. Default value is 2000 points.
+
+pdftoopvpMaxFillPathLength=<int>
+ Specifies the maximum number of fill path points that the driver supports.
+ Default value is 4000 points.
+
+nopdftoopvpLineStyle (Boolean option)
+ Specifies that the driver ignores the line style settings in PDF.
+ If the driver does not prepare the SetLineStyle , SetLineDash or
+ SetLineDashOffset function entry, this option setting is ignored, and
+ also line style, line dash and line dash offset are ignored.
+
+nopdftoopvpClipPath (Boolean option)
+ Specifies that the driver does not support clipping path.
+ If the driver does not prepare the opvpSetClipPath function entry, this
+ option is ignored, and also clip path setting is ignored.
+
+nopdftoopvpBitmapChar (Boolean option)
+ Specifies that the driver does not output characters as images.
+ Default setting is that "pdftoopvp" outputs small characters as images.
+
+pdftoopvpBitmapCharThreshold=<int>
+ Specifies the threshold value that "pdftoopvp" outputs characters as
+ images. Threshold value is defined as W x H where character's width
+ is given by W pixels and height is given by H pixels.
+ Default threshold value is 2000 points.
+
+nopdftoopvpImageMask (Boolean option)
+ Specifies that the driver does not support image mask.
+ If this option is set, "pdftoopvp" treats as the nopdftoopvpBitmapChar
+ option is given.
+
+6. PPD OPTIONS
+
+Following options can be defined in a PPD.
+
+Resolution=<int>
+PageSize=<string>
+opvpDriver=<string>
+opvpModel=<string>
+opvpJobInfo=<string>
+opvpDocInfo=<string>
+opvpPageInfo=<string>
+pdftoopvpClipPathNotSaved=True
+pdftoopvpShearImage=False
+pdftoopvpMiterLimit=False
+pdftoopvpIgnoreMiterLimit=True
+pdftoopvpMaxClipPathLength=<int>
+pdftoopvpMaxFillPathLength=<int>
+pdftoopvpLineStyle=False
+pdftoopvpClipPath=False
+pdftoopvpBitmapChar=False
+pdftoopvpBitmapCharThreshold=<int>
+pdftoopvpImageMask=False
+
+7. OPTIONS OVERRIDING RULE
+
+"jobInfo" printing options in a PPD is used as a initial "jobInfo" printing
+options. If opvpJobInfo option is given in the command line, precedent
+"jobInfo" printing options are overridden by the opvpJobInfo options.
+
+After the "jobInfo" printing options are overridden by the opvpJobInfo
+options, if JCL options are given, precedent "jobInfo" printing options are
+overridden by the options given by JCL options.
+
+8. INFORMATION FOR CUPS 1.1
+
+To use this program under CUPS 1.1, following lines must be defined
+in the CUPS's "mime.types" file.
+
+application/vnd.cups-pdf
+
+9. KNOWN PROBLEMS
+
+Problem:
+ When a page is rotated and a character is small, character might not be
+ rotated correctly. This problem is caused by free type library.
+Solution:
+ Define the nopdftoopvpBitmapChar to inhibit characters output as images.
+
+
+URFTOPDF
+========
+
+"urftopdf" is a filter to convert Apple's proprietary URF raster
+format into PDF. URF raster is generated by some iOS applications when
+printing via Airprint, so this filter provides a more complete support
+for AirPrint clients. Note that it is not clear whether nowadays all
+iOS applications send PDF and not URF any more. Also the filter does
+not support all variants of URF format so the URF support is most
+probably incomplete.
+
+Apple does not provide any official documentation of the format but there is
+already some reverse engineering done. A description of the format as far as it
+got found out and two sample files can be found here:
+
+https://github.com/AlanQuatermain/unirast
+
+An actual implementation of an urftopdf filter is here:
+
+https://github.com/superna9999/urftopdf
+
+This original version uses libharu and to avoid an extra dependency
+the filter coming with this package is converted to use libqpdf
+instead (the same library as pdftopdf uses).
+
+License: GNU General Public License version 3 or any newer version
+
+
+TEXTTOTEXT
+==========
+
+This is a special filter for text-only printers (e. g. line printers,
+daisy-wheel printers, POS printers, ...) or for using printers in
+their text mode (e. g. dot-matrix printers or otherwise unsupported
+printers). It takes plain text (UTF-8-encoded as this is standard with
+CUPS) and not PDF as input.
+
+The texttotext filter replaces the former textonly filter.
+
+It is for the following use cases:
+
+- Using text-only printers, like line printers or daisy-wheel
+ printers. Note that only text can get printed in the way the printer
+ is designed. No support for graphics printing tricks like ASCII art
+ or printing pixels with the period character.
+
+- Fast and less resource-consuming text printing with dot-matrix
+ printers using the printer's text mode instead of converting the
+ text to PDF and printing the PDF in the printer's graphics mode,
+ which is slow, loud, and consumes much more ink.
+
+- POS printing. POS printers often print only text on roll paper. This
+ filter has a non-paginated mode which prints continuously, ignoring
+ page height definitions.
+
+The filter has the following features:
+
+- Conversion of UTF-8 to most printer's encodings.
+
+- To each page size a number of lines and columns is assigned, after that
+ you only need to select the size of the paper in use.
+
+- At end of page you can optionally send a Form Feed or let the filter fill
+ up the rest of the page with blank lines.
+
+- New lines can be initiated by Line Feed, Carriage Return, or both.
+
+- Adjustable margins.
+
+- Adjustable width for tab stops.
+
+- Pagination can be turned off for roll paper or continuous printing in
+ general.
+
+- Wrapping or truncation of long lines
+
+- Support for most of CUPS' page management options (only with
+ pagination turned on): page-ranges, page-set, output-order, collate,
+ multiple copies.
+
+Setting up the printer
+
+In the printer setup tool select the "Generic Text-Only Printer" (with
+lpadmin use "-m drv:///cupsfilters.drv/textonly.ppd"), then under the
+"Installable Options" adjust the following:
+
+- Which page sizes to use and how many lines and columns the printer
+ is capable to print on them. The default setting for lines and
+ columns assume 6 lines per inch and 10 columns per inch.
+
+- Whether to send a Form Feed character after each page. Sending a
+ Form Feed is highly recommended to get the content of each page
+ exactly onto the desired sheet. If the printer does not support Form
+ Feed characters, turn them off and make sure that you have adjusted
+ the correct number of lines for each page size, as the printer is
+ advancing pages by filling up the rest of the paper with blank
+ lines.
+
+- How the printer advancs to a new line. Most printers require both
+ Crriage Return and Line Feed (the DOS/Windows standard), but some
+ would also work with either Carriage Return or Line Feed.
+
+- The printer's encoding: Most text and dot-matrix printers (usually
+ older devices) do not understand CUPS' standard encoding UTF-8 but
+ instead, the use a simpler encoding (where each character is
+ represented by one byte). ASCII should always work, but does not
+ support letters with accents. So check the printer's manual what is
+ supported. You cannot only use the encodings suggested by the PPD
+ file, but any one-byte-per-character encoding which the "iconv"
+ utility supports (see "iconv --list" for a list of encodings).
+
+Also note that text-only and dot-matrix printers often have a DIP
+switch block which allows for some hardware configuration, like
+newline characters, length of page, input encoding, ...
+
+Options of the texttotext filter:
+
+To be usually used when sending a job:
+
+PageSize: Paper format to be used. Make sure that the number of lines
+and columns printable on each paper size are correctly adjusted with
+the appropriate setup option. The page height is ignore when
+pagination is turned off. Possible values: Letter, Legal, Tabloid,
+Ledger, A4, A3, FanFoldGerman, FanFoldGermanLegal, 11x14Rotated,
+LegalRotated, Custom1, Custom2, Custom3
+
+OverLongLines: What to do with lines longer that the width of the
+page: Truncate: Simply drop the extra characters; WrapAtWidth
+(default): Continue the line in the next line on the paper; WordWrap:
+As WrapAtWidth, but do not cut in the middle of a word.
+
+TabWidth: Width of a tab stop. Can be any positive number.
+
+Pagination: On: Text is divided in pages depending on the page size
+selection, with each page having the user-selected margins,
+recommended for sheet paper; Off: Text is printed continuously,
+ignoring page breaks and the height and upper and lower margins of the
+destination page size, recommended for roll paper, POS, long lists on
+continuous paper, ... Note that with pagination turned off, multiple
+copies, collate, page-ranges, page-set, and output-order are not
+supported and therefore ignored.
+
+page-left, page-right, page-top, page-bottom: Width of the margins
+left blank, counted in lines or columns. Top and bottom margins are
+ignored when pagination is turned off. Can be any positive number or
+zero for no margin.
+
+To be usually used when setting up the printer:
+
+PrinterEncoding: The printer's character encoding (code page). Any
+encoding which the iconv utility can generate (see "iconv --list") and
+which uses only one byte per character can be used. This should
+support practically any printer which is capable of printing
+text. ASCII is the default setting. See the printer's manual for the
+correct encoding to use.
+
+NewlineCharacters: The characters sent on the end of a line, LineFeed
+(LF), Crriage Return (CR), or both Carriage Return and Line Feed
+(CRLF). Default is CRLF as most printers require this.
+
+SendFF: On: Send a Form Feed after each page, so that printer changes
+to the next sheet. Off: Do not send Form Feeds. To advance to the next
+page blank lines are printed to fill up the page (requires the number
+of limes for the selected page size correctly being set). When
+pagination is off, Form Feeds are never sent.
+
+LetterAvailable, LegalAvailable, TabloidAvailable, LedgerAvailable,
+A4Available, A3Available, FanFoldGermanAvailable,
+FanFoldGermanLegalAvailable, 11x14RotatedAvailable,
+LegalRotatedAvailable, Custom1Available, Custom2Available,
+Custom3Available: On: Paper of this size is available; Off: This paper
+size is not available.
+
+LetterNumLines, LegalNumLines, TabloidNumLines, LedgerNumLines,
+A4NumLines, A3NumLines, FanFoldGermanNumLines,
+FanFoldGermanLegalNumLines, 11x14RotatedNumLines,
+LegalRotatedNumLines, Custom1NumLines, Custom2NumLines,
+Custom3NumLines: Maximum number of text lines fitting on the paper
+size. Default value is selected assuming 6 lines per inch. Can be any
+positive number.
+
+LetterNumColumns, LegalNumColumns, TabloidNumColumns,
+LedgerNumColumns, A4NumColumns, A3NumColumns, FanFoldGermanNumColumns,
+FanFoldGermanLegalNumColumns, 11x14RotatedNumColumns,
+LegalRotatedNumColumns, Custom1NumColumns, Custom2NumColumns,
+Custom3NumColumns: Maximum number of columns (characters) fitting on
+the paper size. Default value is selected assuming 10 characters per
+inch. Can be any positive number.
+
+Standard CUPS options supported:
+
+page-ranges, page set, output-order, collate
+
+Note that these options and multiple copies are ignored when
+pagination is turned off.
+
+
+BEH - Backend Error Handler wrapper backend
+===========================================
+
+A wrapper for CUPS backends to make error handling more configurable
+
+Usually, if a CUPS backend exits with an error status other than zero
+(for example if a printer is not turned on or not reachable on the
+network), CUPS disables the print queue and one can only print again
+if a system administrator re-enables the queue manually. Even
+restarting CUPS (or rebooting) does not re-enable disabled queues.
+
+For system administrators this can get annoying, for newbie users who
+are not aware of this problem it looks like that CUPS is severely
+broken. They remove and re-install print queues, getting on the nerves
+of distro install support, people, or even switch back to a
+proprietary operating system.
+
+Nowadays CUPS allows some configurability to avoid this, setting the
+Error Policy to "retry-job", but this does not allow to retry for
+infinitely many times and generally does not allow to change the
+number of repetitions. It is also not possible to simply drop the job
+without disabling the queue when CUPS gives up repeating the job.
+
+This script makes the handling of such backend errors more
+configurable, so that the problem can easily be worked around. The new
+possibilities are:
+
+ - Let queues simply not being disabled. Simple approach, but job gets
+ lost.
+
+ - Repeat a given number of times.
+
+ - Repeat infinitely often, until the job gets finally through. This
+ is the standard of LPRng, and it eliminates loss of the job.
+
+ - The interval between two attempts to run the backend can also be
+ configured.
+
+ - Configuration is done independently for each print queue. So local
+ printers and network printers can be treated differently.
+
+
+Usage:
+
+Activate "beh" for your print queue(s) with command(s) like this:
+
+lpadmin -p <queue name> -E -v beh:/<dd>/<att>/<delay>/<originaluri>
+
+with
+ <queue name>: The name of your print queue
+ <dd>: Don't Disable, if "1", beh always exits with zero
+ status, so the queue gets never disabled when the
+ original backend exits with an error. "0" carries
+ the error status of the last call of the backend
+ (after <att> retries) on to CUPS, so the queue
+ usually gets disabled.
+ <att>: Attempts, number of attempts to recall the backend
+ in case of an error. "0" means infinite retries. In
+ this case <dd> gets meaningless.
+ <delay>: Delay between two attempts to call the beckend, to
+ be given in seconds and as an integer number.
+ Meaningless if <att> is one.
+ <originaluri>: The original URI, which your queue had before. Can
+ be determined with "lpstat -v".
+
+All parameters, especially, <dd>, <att>, and <delay> have always to be
+specified, even if one of them is meaningless due to the setting of
+the others.
+
+beh works with every backend except the "hp" backend of HPLIP, as the
+"hp" backend repeats failed jobs by itself.
+
+Example URIs:
+
+beh:/1/3/5/socket://printer:9100
+
+ On the network printer with host name "printer" it is tried to
+ access 3 times with 5 second delays between the attempts. If the job
+ still fails, the queue is not disabled (and the job discarded).
+
+beh:/0/10/60/socket://printer:9100
+
+ Retry 10 times in one minute intervals, disable the queue when still
+ not succeeding.
+
+beh:/1/0/60/usb://Brother/HL-5040%20series
+
+ On a Brother HL-5040 on the USB try infinitely often until the
+ printer comes back, in intervals of one minute. This way the job
+ does not get lost when the printer is turned off and one can
+ intendedly delay printing by simply switching off the printer. The
+ ideal configuration for desktop printers and/or home users.
+
+Originally this backend was written in Perl and part of the
+foomatic-filters package. It was not overtaken into cups-filters
+together with foomatic-rip to avoid the introduction of a dependency
+on Perl. Now it has been re-written in C and so it can be part of
+cups-filters without introducing new dependencies.
+
+
+BRAILLE EMBOSSING
+=================
+
+cups-filters also provides filters and drivers for braille
+embossers. It supports:
+
+- Text on all kinds of embossers with generic support
+- Text and graphics on the Index V3 embossers and above.
+
+This is configured in CUPS just like any printer. Options can then be configured
+in the standard printer panel, or passed as -o options to the lp command.
+
+
+------------
+Text support
+------------
+
+Text can be embossed either with no translation on the computer side (the
+embosser will translate), or with translation on the computer side (thanks to
+liblouis). It is a matter of running
+
+lp file.txt
+
+or even
+
+lp file.html
+lp file.odt
+lp file.doc
+lp file.rtf
+lp file.docx
+lp file.pdf
+
+Important: it is really preferrable to directly print the document files
+themselves, and not a pdf output, or printing from the application (which
+would first convert to pdf). That way, the braille conversion will have the
+proper document structure (paragraphs, titles, footnotes, etc.) to produce good
+quality.
+
+
+--------------------
+Vector Image support
+--------------------
+
+Vector images can be embossed by converting them to braille dots.
+
+This needs the inkscape package installed. Various input formats are then
+supported: .svg, .fig, .wmf, .emf, .cgm, .cmx
+
+The conversion assumes that the input is black-on-white. If it is
+white-on-black, the -o Negate option can be used.
+
+This image support is preferred over the generic image support described below,
+which has to reconstruct lines to be embossed.
+
+
+-------------
+Image support
+-------------
+
+Images can be embossed by converting them to braille dots.
+
+The orientation of the image can be controlled. By default it will be rotate to
+fit the image orientation, i.e. it will be rotate by 90 degree if it is wider
+than high and the paper is higher than wide, or if vice-versa. Other rotation
+modes are provided.
+
+By default, the image will be resized to fit the size of the paper. Disabling
+the resize (fitplot set to No) will crop the image to the paper size. This is
+useful for instance when a carefully-drawn image was designed especially for
+embossing, and thus its pixels should exactly match with braille dots. In such
+case, edge detection should very probably be disabled too.
+
+The image can be processed for edge detection. When no processing is done (edge
+detection is configured to "None"), the dark pixels are embossed if the Negate
+option is off, or the light pixels are embossed if the Negate option is on. When
+edge processing is done, only the edges of the images will be embossed. The
+Basic and the Canny algorithms bring differing results. The Basic algorithm
+can be tuned thanks to the edge factor only. The Canny algorithm can also be
+tuned: increasing the Upper value will reduce the amount of detected edges (and
+vice-versa), increasing the Lower value will reduce the lengths of the detected
+edges (and vice-versa). The Radius and Sigma parameter control the blurring
+performed before edge detection, to improve the result; the Radius parameter
+controls how large blurring should be performed, setting it to zero requests
+autodetection; the Sigma parameter determines how strongly blurring should be
+performed.
+
+A lot of images formats are support, so one can just run
+
+lp file.png
+lp file.gif
+lp file.jpg
+...
+
+Here are complete examples for controlling the processing (all options can be
+omitted, the default values are shown here):
+
+Emboss the image without edge detection, as black on white or white on black:
+
+lp -o "Edge=None" file.png
+lp -o "Edge=None Negate" file.png
+
+Emboss the image with edge detection, the default tuning parameters are set
+here:
+
+lp -o "Edge=Edge EdgeFactor=1" file.png
+lp -o "Edge=Canny CannyRadius=0 CannySigma=1 CannyLower=10 CannyUpper=30" file.png
+
+Emboss the image as it is, without any resize or edge detection, as black on
+white or white on black:
+
+lp -o "nofitplot Edge=None" file.png
+lp -o "nofitplot Edge=None Negate" file.png
+
+------------------------
+Generic embosser support
+------------------------
+
+It should be possible to make all embossers use the generic driver. For this to
+work, one has to:
+
+- configure the embosser itself so that it uses an MIT/NABCC/BRF braille table
+- add in CUPS a printer with the "Generic" manufacturer and "Braille embosser"
+ model
+- configure CUPS options according to the embosser settings, so that CUPS knows
+ the page size, braille spacing, etc.
+
+The generic driver can emboss text, as well as images, but images will probably
+be distorted by the Braille interline spacing.
+
+
+-----------------------
+Index embossers support
+-----------------------
+
+Supported models:
+
+Basic-S V3/4
+Basic-D V3/4
+Everest-D V3/4
+4-Waves PRO V3
+4X4 PRO V3
+Braille Box V4
+
+Index V3 embosser support has been well tested. It supports both text and
+graphics mode. Embossers with firmware 10.30 and above can be easily configured
+from CUPS (paper dimension, braille spacing, etc.).
+
+Index V4 embosser support has not been tested, but is very close to V3 support,
+so it is probably working fine already. Feedback would be very welcome.
+
+To connect an Index embosser through Ethernet, gather its IP adress, select the
+"AppSocket/HP JetDirect" network printer protocol, and set
+socket://the.embosser.IP.address:9100 as Connection URL.
+
+The density of dots for images can easily be chosen from the command line, for
+instance:
+
+lp -o "GraphicDotDistance=160" file.png
+
+to select 1.6mm dots spacing
+
+Troubleshooting: if your embosser starts every document with spurious
+"TM0,BM0,IM0,OM0" or "TM0,BI0", your embosser is most probably still using an
+old 10.20 firmware. Please either reflash the embosser with a firmware version
+10.30 or above, or select the 10.20 firmware version in the "index" panel of the
+cups printer options.
+
+----------------------
+Braille output options
+----------------------
+
+The output can be finely tuned from the standard printing panel, or from the
+command-line, the following example selects translation tables for French and
+Greek, with 2.5mm dot spacing and 5mm line spacing. All options can be omitted,
+the default values are shown here.
+
+lp -o "LibLouis=fr-fr-g1 LibLouis2=gr-gr-g1 TextDotDistance=250 LineSpacing=500" file.txt
+
+
+---------------
+BRF file output
+---------------
+
+One can generate BRF files by adding a virtual BRF printer.
+
+When creating it in the cups interface, choose the CUPS-BRF local printer,
+select the Generic maker, and choose the Generic Braille embosser model.
+
+Printing to the resulting printer will generate a .brf file in a BRF
+subdirectory of the home directory.
+
+
+----------------
+UBRL file output
+----------------
+
+One can generate Unicode braille files, not useful for embossing, but which can
+be easily looked at by sighted people to check for the output.
+
+In the cups interface, create a printer with the CUPS-BRF local printer,
+the Generic maker, and choose the Generic UBRL generator model.
+
+Printing to the resulting printer will generate a .brf file in a BRF
+subdirectory of the home directory.
+
+
+----------------------------
+Remark about the source code
+----------------------------
+
+The file filter/braille/drivers/index/ubrlto4dot.c is used to generate
+the translation table in
+filter/braille/drivers/index/imageubrltoindexv[34]. It is included as
+"source code" for these two files, even if actually running the
+generation in the Makefile is more tedious than really useful.
+
+
+----
+TODO
+----
+
+- Test whether one wants to negate, e.g. to emboss as few dots as possible
+- textubrltoindex when liblouis tools will be able to emit 8dot braille
+
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 000000000..bc857a953
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,1472 @@
+# generated automatically by aclocal 1.15 -*- Autoconf -*-
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically 'autoreconf'.])])
+
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_require_defined.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_REQUIRE_DEFINED(MACRO)
+#
+# DESCRIPTION
+#
+# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have
+# been defined and thus are available for use. This avoids random issues
+# where a macro isn't expanded. Instead the configure script emits a
+# non-fatal:
+#
+# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found
+#
+# It's like AC_REQUIRE except it doesn't expand the required macro.
+#
+# Here's an example:
+#
+# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
+#
+# LICENSE
+#
+# Copyright (c) 2014 Mike Frysinger <vapier@gentoo.org>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 2
+
+AC_DEFUN([AX_REQUIRE_DEFINED], [dnl
+ m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])
+])dnl AX_REQUIRE_DEFINED
+
+dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
+dnl serial 11 (pkg-config-0.29.1)
+dnl
+dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
+dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+dnl 02111-1307, USA.
+dnl
+dnl As a special exception to the GNU General Public License, if you
+dnl distribute this file as part of a program that contains a
+dnl configuration script generated by Autoconf, you may include it under
+dnl the same distribution terms that you use for the rest of that
+dnl program.
+
+dnl PKG_PREREQ(MIN-VERSION)
+dnl -----------------------
+dnl Since: 0.29
+dnl
+dnl Verify that the version of the pkg-config macros are at least
+dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
+dnl installed version of pkg-config, this checks the developer's version
+dnl of pkg.m4 when generating configure.
+dnl
+dnl To ensure that this macro is defined, also add:
+dnl m4_ifndef([PKG_PREREQ],
+dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
+dnl
+dnl See the "Since" comment for each macro you use to see what version
+dnl of the macros you require.
+m4_defun([PKG_PREREQ],
+[m4_define([PKG_MACROS_VERSION], [0.29.1])
+m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
+ [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
+])dnl PKG_PREREQ
+
+dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
+dnl ----------------------------------
+dnl Since: 0.16
+dnl
+dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
+dnl first found in the path. Checks that the version of pkg-config found
+dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
+dnl used since that's the first version where most current features of
+dnl pkg-config existed.
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
+m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
+AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
+AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=m4_default([$1], [0.9.0])
+ AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ PKG_CONFIG=""
+ fi
+fi[]dnl
+])dnl PKG_PROG_PKG_CONFIG
+
+dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl -------------------------------------------------------------------
+dnl Since: 0.18
+dnl
+dnl Check to see whether a particular set of modules exists. Similar to
+dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
+dnl
+dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+dnl only at the first occurence in configure.ac, so if the first place
+dnl it's called might be skipped (such as if it is within an "if", you
+dnl have to call PKG_CHECK_EXISTS manually
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+ m4_default([$2], [:])
+m4_ifvaln([$3], [else
+ $3])dnl
+fi])
+
+dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+dnl ---------------------------------------------
+dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
+dnl pkg_failed based on the result.
+m4_define([_PKG_CONFIG],
+[if test -n "$$1"; then
+ pkg_cv_[]$1="$$1"
+ elif test -n "$PKG_CONFIG"; then
+ PKG_CHECK_EXISTS([$3],
+ [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes ],
+ [pkg_failed=yes])
+ else
+ pkg_failed=untried
+fi[]dnl
+])dnl _PKG_CONFIG
+
+dnl _PKG_SHORT_ERRORS_SUPPORTED
+dnl ---------------------------
+dnl Internal check to see if pkg-config supports short errors.
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi[]dnl
+])dnl _PKG_SHORT_ERRORS_SUPPORTED
+
+
+dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+dnl [ACTION-IF-NOT-FOUND])
+dnl --------------------------------------------------------------
+dnl Since: 0.4.0
+dnl
+dnl Note that if there is a possibility the first call to
+dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
+dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+ AC_MSG_RESULT([no])
+ _PKG_SHORT_ERRORS_SUPPORTED
+ if test $_pkg_short_errors_supported = yes; then
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
+ else
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+ m4_default([$4], [AC_MSG_ERROR(
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT])[]dnl
+ ])
+elif test $pkg_failed = untried; then
+ AC_MSG_RESULT([no])
+ m4_default([$4], [AC_MSG_FAILURE(
+[The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
+ ])
+else
+ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+ $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+ AC_MSG_RESULT([yes])
+ $3
+fi[]dnl
+])dnl PKG_CHECK_MODULES
+
+
+dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+dnl [ACTION-IF-NOT-FOUND])
+dnl ---------------------------------------------------------------------
+dnl Since: 0.29
+dnl
+dnl Checks for existence of MODULES and gathers its build flags with
+dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
+dnl and VARIABLE-PREFIX_LIBS from --libs.
+dnl
+dnl Note that if there is a possibility the first call to
+dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
+dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
+dnl configure.ac.
+AC_DEFUN([PKG_CHECK_MODULES_STATIC],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+_save_PKG_CONFIG=$PKG_CONFIG
+PKG_CONFIG="$PKG_CONFIG --static"
+PKG_CHECK_MODULES($@)
+PKG_CONFIG=$_save_PKG_CONFIG[]dnl
+])dnl PKG_CHECK_MODULES_STATIC
+
+
+dnl PKG_INSTALLDIR([DIRECTORY])
+dnl -------------------------
+dnl Since: 0.27
+dnl
+dnl Substitutes the variable pkgconfigdir as the location where a module
+dnl should install pkg-config .pc files. By default the directory is
+dnl $libdir/pkgconfig, but the default can be changed by passing
+dnl DIRECTORY. The user can override through the --with-pkgconfigdir
+dnl parameter.
+AC_DEFUN([PKG_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([pkgconfigdir],
+ [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
+ [with_pkgconfigdir=]pkg_default)
+AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+])dnl PKG_INSTALLDIR
+
+
+dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
+dnl --------------------------------
+dnl Since: 0.27
+dnl
+dnl Substitutes the variable noarch_pkgconfigdir as the location where a
+dnl module should install arch-independent pkg-config .pc files. By
+dnl default the directory is $datadir/pkgconfig, but the default can be
+dnl changed by passing DIRECTORY. The user can override through the
+dnl --with-noarch-pkgconfigdir parameter.
+AC_DEFUN([PKG_NOARCH_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([noarch-pkgconfigdir],
+ [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
+ [with_noarch_pkgconfigdir=]pkg_default)
+AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+])dnl PKG_NOARCH_INSTALLDIR
+
+
+dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
+dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl -------------------------------------------
+dnl Since: 0.28
+dnl
+dnl Retrieves the value of the pkg-config variable for the given module.
+AC_DEFUN([PKG_CHECK_VAR],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
+
+_PKG_CONFIG([$1], [variable="][$3]["], [$2])
+AS_VAR_COPY([$1], [pkg_cv_][$1])
+
+AS_VAR_IF([$1], [""], [$5], [$4])dnl
+])dnl PKG_CHECK_VAR
+
+# Copyright (C) 2002-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.15'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.15], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.15])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to
+# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is '.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+m4_if([$1], [CC], [depcc="$CC" am_compiler_list=],
+ [$1], [CXX], [depcc="$CXX" am_compiler_list=],
+ [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
+ [$1], [UPC], [depcc="$UPC" am_compiler_list=],
+ [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ am__universal=false
+ m4_case([$1], [CC],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac],
+ [CXX],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac])
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE([dependency-tracking], [dnl
+AS_HELP_STRING(
+ [--enable-dependency-tracking],
+ [do not reject slow dependency extractors])
+AS_HELP_STRING(
+ [--disable-dependency-tracking],
+ [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+ # Older Autoconf quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named 'Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running 'make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "$am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each '.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.65])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[AC_DIAGNOSE([obsolete],
+ [$0: two- and three-arguments forms are deprecated.])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(
+ m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+ [ok:ok],,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
+AM_MISSING_PROG([AUTOCONF], [autoconf])
+AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
+AM_MISSING_PROG([AUTOHEADER], [autoheader])
+AM_MISSING_PROG([MAKEINFO], [makeinfo])
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES([CC])],
+ [m4_define([AC_PROG_CC],
+ m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES([CXX])],
+ [m4_define([AC_PROG_CXX],
+ m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES([OBJC])],
+ [m4_define([AC_PROG_OBJC],
+ m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+ [_AM_DEPENDENCIES([OBJCXX])],
+ [m4_define([AC_PROG_OBJCXX],
+ m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
+])
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+ fi
+fi
+dnl The trailing newline in this macro's definition is deliberate, for
+dnl backward compatibility and to allow trailing 'dnl'-style comments
+dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
+])
+
+dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST([install_sh])])
+
+# Copyright (C) 2003-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
+else
+ am_missing_run=
+ AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# --------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+ [whether $CC understands -c and -o together],
+ [am_cv_prog_cc_c_o],
+ [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+ ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ (exit $ac_status); }])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+ alias in your environment])
+ fi
+ if test "$[2]" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT([yes])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+ [AC_MSG_CHECKING([that generated files are newer than configure])
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+ [--enable-silent-rules],
+ [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+ [--disable-silent-rules],
+ [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+ [am_cv_make_support_nested_variables],
+ [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+ dnl Using '$V' instead of '$(V)' breaks IRIX make.
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor 'install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in "make install-strip", and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# --------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of 'v7', 'ustar', or 'pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+#
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+m4_if([$1], [v7],
+ [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+ [m4_case([$1],
+ [ustar],
+ [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+ # There is notably a 21 bits limit for the UID and the GID. In fact,
+ # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+ # and bug#13588).
+ am_max_uid=2097151 # 2^21 - 1
+ am_max_gid=$am_max_uid
+ # The $UID and $GID variables are not portable, so we need to resort
+ # to the POSIX-mandated id(1) utility. Errors in the 'id' calls
+ # below are definitely unexpected, so allow the users to see them
+ # (that is, avoid stderr redirection).
+ am_uid=`id -u || echo unknown`
+ am_gid=`id -g || echo unknown`
+ AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+ if test $am_uid -le $am_max_uid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi
+ AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+ if test $am_gid -le $am_max_gid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi],
+
+ [pax],
+ [],
+
+ [m4_fatal([Unknown tar format])])
+
+ AC_MSG_CHECKING([how to create a $1 tar archive])
+
+ # Go ahead even if we have the value already cached. We do so because we
+ # need to set the values for the 'am__tar' and 'am__untar' variables.
+ _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+ for _am_tool in $_am_tools; do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar; do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works.
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ AM_RUN_LOG([cat conftest.dir/file])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+ done
+ rm -rf conftest.dir
+
+ AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+ AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([m4/ax_cxx_compile_stdcxx.m4])
+m4_include([m4/libtool.m4])
+m4_include([m4/ltoptions.m4])
+m4_include([m4/ltsugar.m4])
+m4_include([m4/ltversion.m4])
+m4_include([m4/lt~obsolete.m4])
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 000000000..5462a3234
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+TESTLIBTOOLIZE="glibtoolize libtoolize"
+
+LIBTOOLIZEFOUND="0"
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+olddir=`pwd`
+cd $srcdir
+
+aclocal --version > /dev/null 2> /dev/null || {
+ echo "error: aclocal not found"
+ exit 1
+}
+automake --version > /dev/null 2> /dev/null || {
+ echo "error: automake not found"
+ exit 1
+}
+
+for i in $TESTLIBTOOLIZE; do
+ if which $i > /dev/null 2>&1; then
+ LIBTOOLIZE=$i
+ LIBTOOLIZEFOUND="1"
+ break
+ fi
+done
+
+if [ "$LIBTOOLIZEFOUND" = "0" ]; then
+ echo "$0: need libtoolize tool to build cups-filters" >&2
+ exit 1
+fi
+
+amcheck=`automake --version | grep 'automake (GNU automake) 1.5'`
+if test "x$amcheck" = "xautomake (GNU automake) 1.5"; then
+ echo "warning: you appear to be using automake 1.5"
+ echo " this version has a bug - GNUmakefile.am dependencies are not generated"
+fi
+
+rm -rf autom4te*.cache
+
+$LIBTOOLIZE --force --copy || {
+ echo "error: libtoolize failed"
+ exit 1
+}
+aclocal $ACLOCAL_FLAGS || {
+ echo "error: aclocal $ACLOCAL_FLAGS failed"
+ exit 1
+}
+autoheader || {
+ echo "error: autoheader failed"
+ exit 1
+}
+automake -a -c --gnu --add-missing || {
+ echo "warning: automake failed"
+}
+autoconf || {
+ echo "error: autoconf failed"
+ exit 1
+}
diff --git a/backend/backend-private.h b/backend/backend-private.h
new file mode 100644
index 000000000..aa9f9dd6b
--- /dev/null
+++ b/backend/backend-private.h
@@ -0,0 +1,81 @@
+/*
+ * Backend support definitions for OpenPrinting CUPS Filters.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ */
+
+#ifndef _CUPSFILTERS_BACKEND_PRIVATE_H_
+# define _CUPSFILTERS_BACKEND_PRIVATE_H_
+
+
+/*
+ * Include necessary headers.
+ */
+
+# include <config.h>
+# include <cups/cups.h>
+# include <cups/ppd.h>
+# include <cups/backend.h>
+# include <cups/sidechannel.h>
+# include <string.h>
+# include <stdlib.h>
+# include <errno.h>
+# include <signal.h>
+# include <unistd.h>
+# include <fcntl.h>
+
+# ifdef __linux
+# include <sys/ioctl.h>
+# include <linux/lp.h>
+# define IOCNR_GET_DEVICE_ID 1
+# define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len)
+# include <linux/parport.h>
+# include <linux/ppdev.h>
+# endif /* __linux */
+
+# ifdef __sun
+# ifdef __sparc
+# include <sys/ecppio.h>
+# else
+# include <sys/ioccom.h>
+# include <sys/ecppsys.h>
+# endif /* __sparc */
+# endif /* __sun */
+
+
+/*
+ * C++ magic...
+ */
+
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+
+
+/*
+ * Prototypes...
+ */
+
+extern int backendDrainOutput(int print_fd, int device_fd);
+extern int backendGetDeviceID(int fd, char *device_id,
+ int device_id_size,
+ char *make_model,
+ int make_model_size,
+ const char *scheme, char *uri,
+ int uri_size);
+extern int backendGetMakeModel(const char *device_id,
+ char *make_model,
+ int make_model_size);
+
+
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+#endif /* !_CUPSFILTERS_BACKEND_PRIVATE_H_ */
+
diff --git a/backend/beh.c b/backend/beh.c
new file mode 100644
index 000000000..9ba6613cc
--- /dev/null
+++ b/backend/beh.c
@@ -0,0 +1,285 @@
+/*
+ * beh ("Backend Error Handler") wrapper backend to extend the possibilities
+ * of handling errors of backends.
+ *
+ * Copyright 2015 by Till Kamppeter
+ *
+ * This is based on dnssd.c of CUPS
+ * dnssd.c copyright notice is follows:
+ *
+ * Copyright 2008-2015 by Apple Inc.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "backend-private.h"
+#include <cups/array.h>
+#include <ctype.h>
+
+/*
+ * Local globals...
+ */
+
+static int job_canceled = 0; /* Set to 1 on SIGTERM */
+
+/*
+ * Local functions...
+ */
+
+static int call_backend(char *uri, int argc, char **argv,
+ char *tempfile);
+static void sigterm_handler(int sig);
+
+
+/*
+ * 'main()' - Browse for printers.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line args */
+ char *argv[]) { /* I - Command-line arguments */
+ char *uri, *ptr, *filename;
+ char tmpfilename[1024], buf[8192];
+ int dd, att, delay, retval;
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+ /*
+ * Don't buffer stderr, and catch SIGTERM...
+ */
+
+ setbuf(stderr, NULL);
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, sigterm_handler);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = sigterm_handler;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, sigterm_handler);
+#endif /* HAVE_SIGSET */
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc == 1) {
+ if ((ptr = strrchr(argv[0], '/')) != NULL)
+ ptr ++;
+ else
+ ptr = argv[0];
+ printf("network %s \"Unknown\" \"Backend Error Handler\"\n",
+ ptr);
+ return (CUPS_BACKEND_OK);
+ } else if (argc < 6) {
+ fprintf(stderr,
+ "Usage: %s job-id user title copies options [file]\n",
+ argv[0]);
+ return (CUPS_BACKEND_FAILED);
+ }
+
+ /*
+ * Read out the parameters
+ */
+
+ uri = getenv("DEVICE_URI");
+ if (!uri) {
+ fprintf(stderr,
+ "ERROR: No device URI supplied!");
+ return (CUPS_BACKEND_FAILED);
+ }
+
+ ptr = strstr(uri, ":/");
+ if (!ptr) goto bad_uri;
+ ptr += 2;
+ if (*ptr == '0')
+ dd = 0;
+ else if (*ptr == '1')
+ dd = 1;
+ else
+ goto bad_uri;
+ ptr ++;
+ if (*ptr != '/') goto bad_uri;
+ ptr ++;
+ att = 0;
+ while (isdigit(*ptr)) {
+ att = att * 10 + (int)(*ptr) - 48;
+ ptr ++;
+ }
+ if (*ptr != '/') goto bad_uri;
+ ptr ++;
+ delay = 0;
+ while (isdigit(*ptr)) {
+ delay = delay * 10 + (int)(*ptr) - 48;
+ ptr ++;
+ }
+ if (*ptr != '/') goto bad_uri;
+ ptr ++;
+ fprintf(stderr,
+ "DEBUG: beh: Don't disable: %d; Attempts: %d; Delay: %d; Destination URI: %s\n",
+ dd, att, delay, ptr);
+
+ /*
+ * If reading from stdin, write everything into a temporary file
+ */
+
+ if (argc == 6) {
+ char *tmpdir;
+ int fd;
+ FILE *tmpfile;
+ size_t bytes;
+
+ tmpdir = getenv("TMPDIR");
+ if (!tmpdir)
+ tmpdir = "/tmp";
+ snprintf(tmpfilename, sizeof(tmpfilename), "%s/beh-XXXXXX", tmpdir);
+ fd = mkstemp(tmpfilename);
+ if (fd < 0) {
+ fprintf(stderr,
+ "ERROR: beh: Could not create temporary file: %s\n",
+ strerror(errno));
+ return (CUPS_BACKEND_FAILED);
+ }
+ tmpfile = fdopen(fd, "r+");
+ while ((bytes = fread(buf, 1, sizeof(buf), stdin)))
+ fwrite(buf, 1, bytes, tmpfile);
+ fclose(tmpfile);
+
+ filename = tmpfilename;
+ } else {
+ tmpfilename[0] = '\0';
+ filename = argv[6];
+ }
+
+ /*
+ * Do it!
+ */
+
+ while ((retval = call_backend(ptr, argc, argv, filename)) !=
+ CUPS_BACKEND_OK &&
+ !job_canceled) {
+ if (att > 0) {
+ att --;
+ if (att == 0)
+ break;
+ }
+ if (delay > 0)
+ sleep (delay);
+ }
+
+ if (strlen(tmpfilename) > 0)
+ unlink(tmpfilename);
+
+ /*
+ * Return the exit value of the backend only if requested
+ */
+
+ if (!dd)
+ return (retval);
+ else
+ return (CUPS_BACKEND_OK);
+
+ /*
+ * Error handling
+ */
+
+ bad_uri:
+
+ fprintf(stderr,
+ "ERROR: URI must be \"beh:/<dd>/<att>/<delay>/<original uri>\"!\n");
+ return (CUPS_BACKEND_FAILED);
+}
+
+
+/*
+ * 'call_backend()' - Execute the command line of the destination backend
+ */
+
+static int
+call_backend(char *uri, /* I - URI of final destination */
+ int argc, /* I - Number of command line
+ arguments */
+ char **argv, /* I - Command-line arguments */
+ char *filename) { /* I - File name of input data */
+ const char *cups_serverbin; /* Location of programs */
+ char scheme[1024], /* Scheme from URI */
+ *ptr, /* Pointer into scheme */
+ cmdline[65536]; /* Backend command line */
+ int retval;
+
+ /*
+ * Build the backend command line...
+ */
+
+ strncpy(scheme, uri, sizeof(scheme));
+ if ((ptr = strchr(scheme, ':')) != NULL)
+ *ptr = '\0';
+
+ if ((cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL)
+ cups_serverbin = CUPS_SERVERBIN;
+
+ if (!strncasecmp(uri, "file:", 5) || uri[0] == '/') {
+ fprintf(stderr,
+ "ERROR: beh: Direct output into a file not supported.\n");
+ exit (CUPS_BACKEND_FAILED);
+ } else
+ snprintf(cmdline, sizeof(cmdline),
+ "%s/backend/%s '%s' '%s' '%s' '%s' '%s' %s",
+ cups_serverbin, scheme, argv[1], argv[2], argv[3],
+ /* Apply number of copies only if beh was called with a
+ file name and not with the print data in stdin, as
+ backends should handle copies only if they are called
+ with a file name */
+ (argc == 6 ? "1" : argv[4]),
+ argv[5], filename);
+
+ /*
+ * Overwrite the device URI and run the actual backend...
+ */
+
+ setenv("DEVICE_URI", uri, 1);
+
+ fprintf(stderr,
+ "DEBUG: beh: Executing backend command line \"%s\"...\n",
+ cmdline);
+ fprintf(stderr,
+ "DEBUG: beh: Using device URI: %s\n",
+ uri);
+
+ retval = system(cmdline) >> 8;
+
+ if (retval == -1)
+ fprintf(stderr, "ERROR: Unable to execute backend command line: %s\n",
+ strerror(errno));
+
+ return (retval);
+}
+
+
+/*
+ * 'sigterm_handler()' - Handle termination signals.
+ */
+
+static void
+sigterm_handler(int sig) { /* I - Signal number (unused) */
+ (void)sig;
+
+ fprintf(stderr,
+ "DEBUG: beh: Job canceled.\n");
+
+ if (job_canceled)
+ _exit(CUPS_BACKEND_OK);
+ else
+ job_canceled = 1;
+}
diff --git a/backend/cups-brf.c b/backend/cups-brf.c
new file mode 100644
index 000000000..ae7b096c2
--- /dev/null
+++ b/backend/cups-brf.c
@@ -0,0 +1,162 @@
+/*
+ * BRF (Braille-Ready Format) virtual backend
+ *
+ * Copyright (c) 2017 by Samuel Thibault <samuel.thibault@ens-lyon.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "backend-private.h"
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <pwd.h>
+
+int main(int argc, char *argv[]) {
+ char *user;
+ char *dir;
+ char *title;
+ char *outfile;
+ char *c;
+ char buffer[4096];
+ ssize_t sizein, sizeout, done;
+ struct passwd *pw;
+ int ret;
+ int fd;
+
+ if (setuid(0)) {
+ /* We need to be root to be able to turn into another user. */
+ fprintf(stderr,"ERROR: cups-brf must be called as root\n");
+ return CUPS_BACKEND_FAILED;
+ }
+
+ if (argc == 1) {
+ /* This is just discovery. */
+ printf("file cups-brf:/ \"Virtual Braille BRF Printer\" \"CUPS-BRF\" \"MFG:Generic;MDL:CUPS-BRF Printer;DES:Generic CUPS-BRF Printer;CLS:PRINTER;CMD:BRF;\"\n");
+ return CUPS_BACKEND_OK;
+ }
+
+ if (argc < 6) {
+ /* Invalid number of parameters. */
+ fprintf(stderr, "ERROR: cups-brf jobid user name nb options [filename]\n");
+ return CUPS_BACKEND_FAILED;
+ }
+
+ if (argc == 7) {
+ /* Explicit file name, open it. */
+ char *filename = argv[6];
+ fd = open(filename, O_RDONLY);
+ if (dup2(fd, STDIN_FILENO) < 0) {
+ fprintf(stderr, "ERROR: opening file \"%s\"\n", filename);
+ return CUPS_BACKEND_FAILED;
+ }
+ }
+
+ /* Now we have everything, turn into the user */
+ user = argv[2];
+ pw = getpwnam(user);
+ if (pw == NULL) {
+ fprintf(stderr, "ERROR: getting user \"%s\" information\n", user);
+ return CUPS_BACKEND_FAILED;
+ }
+ if (setgid(pw->pw_gid)) {
+ fprintf(stderr, "ERROR: turning gid into %u\n", pw->pw_gid);
+ return CUPS_BACKEND_FAILED;
+ }
+ if (setuid(pw->pw_uid)) {
+ fprintf(stderr, "ERROR: turning uid into %u\n", pw->pw_uid);
+ return CUPS_BACKEND_FAILED;
+ }
+
+ /* Now we act as user */
+ umask(0077);
+
+ /* Create BRF directory in $HOME */
+ if (asprintf(&dir, "%s/BRF", pw->pw_dir) < 0) {
+ fprintf(stderr, "ERROR: could not allocate memory\n");
+ return CUPS_BACKEND_FAILED;
+ }
+ fprintf(stderr, "DEBUG: creating directory \"%s\n", dir);
+ ret = mkdir(dir, 0700);
+ if (ret == -1 && errno != EEXIST) {
+ fprintf(stderr, "ERROR: could not create directory \"%s\": %s\n", dir, strerror(errno));
+ return CUPS_BACKEND_FAILED;
+ }
+
+ /* Avoid escaping from the directory */
+ title = argv[3];
+ for (c = title; *c; c++) {
+ if (*c == '/')
+ *c = '_';
+ }
+ /* Avoid hiding the file */
+ while (*title == '.')
+ title++;
+
+ /* Avoid empty title */
+ if (!*title)
+ title = "unknown";
+
+ /* generate mask */
+ if (asprintf(&outfile, "%s/%s.XXXXXX.brf", dir, title) < 0) {
+ fprintf(stderr, "ERROR: could not allocate memory\n");
+ return CUPS_BACKEND_FAILED;
+ }
+
+ /* Create file */
+ fprintf(stderr, "DEBUG: creating file \"%s\n", outfile);
+ fd = mkstemps(outfile, 4);
+ if (fd < 0) {
+ fprintf(stderr, "ERROR: could not create file \"%s\": %s\n", outfile, strerror(errno));
+ return CUPS_BACKEND_FAILED;
+ }
+
+ /* We are all set, copy data. */
+ while (1) {
+ /* Read some. */
+ sizein = read(STDIN_FILENO, buffer, sizeof(buffer));
+ if (sizein < 0) {
+ fprintf(stderr, "ERROR: while reading input: %s\n", strerror(errno));
+ return CUPS_BACKEND_FAILED;
+ }
+ if (sizein == 0)
+ /* We are done! */
+ break;
+
+ /* Write it. */
+ for (done = 0; done < sizein; done += sizeout) {
+ sizeout = write(fd, buffer + done, sizein - done);
+ if (sizeout < 0) {
+ fprintf(stderr, "ERROR: while writing to \"%s\": %s\n", outfile, strerror(errno));
+ return CUPS_BACKEND_FAILED;
+ }
+ }
+ }
+ if (close(fd) < 0) {
+ fprintf(stderr, "ERROR: while closing \"%s\": %s\n", outfile, strerror(errno));
+ return CUPS_BACKEND_FAILED;
+ }
+
+ return CUPS_BACKEND_OK;
+}
diff --git a/backend/ieee1284.c b/backend/ieee1284.c
new file mode 100644
index 000000000..34a1bbc3b
--- /dev/null
+++ b/backend/ieee1284.c
@@ -0,0 +1,781 @@
+/*
+ * IEEE-1284 support functions for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * backendGetDeviceID() - Get the IEEE-1284 device ID string and
+ * corresponding URI.
+ * backendGetMakeModel() - Get the make and model string from the device
+ * ID.
+ * get_1284_values() - Get 1284 device ID keys and values.
+ * normalize_make_and_model() - Normalize a product/make-and-model string.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "backend-private.h"
+#include <cups/cups.h>
+#include <string.h>
+#include <ctype.h>
+#define DEBUG_printf(x)
+#define DEBUG_puts(x)
+#define _cups_isspace(x) isspace((x) & 255)
+#define _cups_strcasecmp strcasecmp
+#define _cups_strncasecmp strncasecmp
+
+
+/*
+ * Local functions...
+ */
+
+static int get_1284_values(const char *device_id, cups_option_t **values);
+static char *normalize_make_and_model(const char *make_and_model,
+ char *buffer, size_t bufsize);
+
+
+/*
+ * 'backendGetDeviceID()' - Get the IEEE-1284 device ID string and
+ * corresponding URI.
+ */
+
+int /* O - 0 on success, -1 on failure */
+backendGetDeviceID(
+ int fd, /* I - File descriptor */
+ char *device_id, /* O - 1284 device ID */
+ int device_id_size, /* I - Size of buffer */
+ char *make_model, /* O - Make/model */
+ int make_model_size, /* I - Size of buffer */
+ const char *scheme, /* I - URI scheme */
+ char *uri, /* O - Device URI */
+ int uri_size) /* I - Size of buffer */
+{
+#ifdef __APPLE__ /* This function is a no-op */
+ (void)fd;
+ (void)device_id;
+ (void)device_id_size;
+ (void)make_model;
+ (void)make_model_size;
+ (void)scheme;
+ (void)uri;
+ (void)uri_size;
+
+ return (-1);
+
+#else /* Get the device ID from the specified file descriptor... */
+# ifdef __linux
+ int length; /* Length of device ID info */
+ int got_id = 0;
+# endif /* __linux */
+# if defined(__sun) && defined(ECPPIOC_GETDEVID)
+ struct ecpp_device_id did; /* Device ID buffer */
+# endif /* __sun && ECPPIOC_GETDEVID */
+ char *ptr; /* Pointer into device ID */
+
+
+ DEBUG_printf(("backendGetDeviceID(fd=%d, device_id=%p, device_id_size=%d, "
+ "make_model=%p, make_model_size=%d, scheme=\"%s\", "
+ "uri=%p, uri_size=%d)\n", fd, device_id, device_id_size,
+ make_model, make_model_size, scheme ? scheme : "(null)",
+ uri, uri_size));
+
+ /*
+ * Range check input...
+ */
+
+ if (!device_id || device_id_size < 32)
+ {
+ DEBUG_puts("backendGetDeviceID: Bad args!");
+ return (-1);
+ }
+
+ if (make_model)
+ *make_model = '\0';
+
+ if (fd >= 0)
+ {
+ /*
+ * Get the device ID string...
+ */
+
+ *device_id = '\0';
+
+# ifdef __linux
+ if (ioctl(fd, LPIOC_GET_DEVICE_ID(device_id_size), device_id))
+ {
+ /*
+ * Linux has to implement things differently for every device it seems.
+ * Since the standard parallel port driver does not provide a simple
+ * ioctl() to get the 1284 device ID, we have to open the "raw" parallel
+ * device corresponding to this port and do some negotiation trickery
+ * to get the current device ID.
+ */
+
+ if (uri && !strncmp(uri, "parallel:/dev/", 14))
+ {
+ char devparport[16]; /* /dev/parportN */
+ int devparportfd, /* File descriptor for raw device */
+ mode; /* Port mode */
+
+
+ /*
+ * Since the Linux parallel backend only supports 4 parallel port
+ * devices, just grab the trailing digit and use it to construct a
+ * /dev/parportN filename...
+ */
+
+ snprintf(devparport, sizeof(devparport), "/dev/parport%s",
+ uri + strlen(uri) - 1);
+
+ if ((devparportfd = open(devparport, O_RDWR | O_NOCTTY)) != -1)
+ {
+ /*
+ * Claim the device...
+ */
+
+ if (!ioctl(devparportfd, PPCLAIM))
+ {
+ fcntl(devparportfd, F_SETFL, fcntl(devparportfd, F_GETFL) | O_NONBLOCK);
+
+ mode = IEEE1284_MODE_COMPAT;
+
+ if (!ioctl(devparportfd, PPNEGOT, &mode))
+ {
+ /*
+ * Put the device into Device ID mode...
+ */
+
+ mode = IEEE1284_MODE_NIBBLE | IEEE1284_DEVICEID;
+
+ if (!ioctl(devparportfd, PPNEGOT, &mode))
+ {
+ /*
+ * Read the 1284 device ID...
+ */
+
+ if ((length = read(devparportfd, device_id,
+ device_id_size - 1)) >= 2)
+ {
+ device_id[length] = '\0';
+ got_id = 1;
+ }
+ }
+ }
+
+ /*
+ * Release the device...
+ */
+
+ ioctl(devparportfd, PPRELEASE);
+ }
+
+ close(devparportfd);
+ }
+ }
+ }
+ else
+ got_id = 1;
+
+ if (got_id)
+ {
+ /*
+ * Extract the length of the device ID string from the first two
+ * bytes. The 1284 spec says the length is stored MSB first...
+ */
+
+ length = (((unsigned)device_id[0] & 255) << 8) +
+ ((unsigned)device_id[1] & 255);
+
+ /*
+ * Check to see if the length is larger than our buffer; first
+ * assume that the vendor incorrectly implemented the 1284 spec,
+ * and then limit the length to the size of our buffer...
+ */
+
+ if (length > device_id_size || length < 14)
+ length = (((unsigned)device_id[1] & 255) << 8) +
+ ((unsigned)device_id[0] & 255);
+
+ if (length > device_id_size)
+ length = device_id_size;
+
+ /*
+ * The length field counts the number of bytes in the string
+ * including the length field itself (2 bytes). The minimum
+ * length for a valid/usable device ID is 14 bytes:
+ *
+ * <LENGTH> MFG: <MFG> ;MDL: <MDL> ;
+ * 2 + 4 + 1 + 5 + 1 + 1
+ */
+
+ if (length < 14)
+ {
+ /*
+ * Can't use this device ID, so don't try to copy it...
+ */
+
+ device_id[0] = '\0';
+ got_id = 0;
+ }
+ else
+ {
+ /*
+ * Copy the device ID text to the beginning of the buffer and
+ * nul-terminate.
+ */
+
+ length -= 2;
+
+ memmove(device_id, device_id + 2, length);
+ device_id[length] = '\0';
+ }
+ }
+ else
+ {
+ DEBUG_printf(("backendGetDeviceID: ioctl failed - %s\n",
+ strerror(errno)));
+ *device_id = '\0';
+ }
+# endif /* __linux */
+
+# if defined(__sun) && defined(ECPPIOC_GETDEVID)
+ did.mode = ECPP_CENTRONICS;
+ did.len = device_id_size - 1;
+ did.rlen = 0;
+ did.addr = device_id;
+
+ if (!ioctl(fd, ECPPIOC_GETDEVID, &did))
+ {
+ /*
+ * Nul-terminate the device ID text.
+ */
+
+ if (did.rlen < (device_id_size - 1))
+ device_id[did.rlen] = '\0';
+ else
+ device_id[device_id_size - 1] = '\0';
+ }
+# ifdef DEBUG
+ else
+ DEBUG_printf(("backendGetDeviceID: ioctl failed - %s\n",
+ strerror(errno)));
+# endif /* DEBUG */
+# endif /* __sun && ECPPIOC_GETDEVID */
+ }
+
+ /*
+ * Check whether device ID is valid. Turn line breaks and tabs to spaces and
+ * reject device IDs with non-printable characters.
+ */
+
+ for (ptr = device_id; *ptr; ptr ++)
+ if (_cups_isspace(*ptr))
+ *ptr = ' ';
+ else if ((*ptr & 255) < ' ' || *ptr == 127)
+ {
+ DEBUG_printf(("backendGetDeviceID: Bad device_id character %d.",
+ *ptr & 255));
+ *device_id = '\0';
+ break;
+ }
+
+ DEBUG_printf(("backendGetDeviceID: device_id=\"%s\"\n", device_id));
+
+ if (scheme && uri)
+ *uri = '\0';
+
+ if (!*device_id)
+ return (-1);
+
+ /*
+ * Get the make and model...
+ */
+
+ if (make_model)
+ backendGetMakeModel(device_id, make_model, make_model_size);
+
+ /*
+ * Then generate a device URI...
+ */
+
+ if (scheme && uri && uri_size > 32)
+ {
+ int num_values; /* Number of keys and values */
+ cups_option_t *values; /* Keys and values in device ID */
+ const char *mfg, /* Manufacturer */
+ *mdl, /* Model */
+ *sern; /* Serial number */
+ char temp[256], /* Temporary manufacturer string */
+ *tempptr; /* Pointer into temp string */
+
+
+ /*
+ * Get the make, model, and serial numbers...
+ */
+
+ num_values = get_1284_values(device_id, &values);
+
+ if ((sern = cupsGetOption("SERIALNUMBER", num_values, values)) == NULL)
+ if ((sern = cupsGetOption("SERN", num_values, values)) == NULL)
+ sern = cupsGetOption("SN", num_values, values);
+
+ if ((mfg = cupsGetOption("MANUFACTURER", num_values, values)) == NULL)
+ mfg = cupsGetOption("MFG", num_values, values);
+
+ if ((mdl = cupsGetOption("MODEL", num_values, values)) == NULL)
+ mdl = cupsGetOption("MDL", num_values, values);
+
+ if (mfg)
+ {
+ if (!_cups_strcasecmp(mfg, "Hewlett-Packard"))
+ mfg = "HP";
+ else if (!_cups_strcasecmp(mfg, "Lexmark International"))
+ mfg = "Lexmark";
+ }
+ else
+ {
+ strncpy(temp, make_model, sizeof(temp) - 1);
+ temp[sizeof(temp) - 1] = '\0';
+
+ if ((tempptr = strchr(temp, ' ')) != NULL)
+ *tempptr = '\0';
+
+ mfg = temp;
+ }
+
+ if (!mdl)
+ mdl = "";
+
+ if (!_cups_strncasecmp(mdl, mfg, strlen(mfg)))
+ {
+ mdl += strlen(mfg);
+
+ while (isspace(*mdl & 255))
+ mdl ++;
+ }
+
+ /*
+ * Generate the device URI from the manufacturer, make_model, and
+ * serial number strings.
+ */
+
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, uri_size, scheme, NULL, mfg, 0,
+ "/%s%s%s", mdl, sern ? "?serial=" : "", sern ? sern : "");
+
+ cupsFreeOptions(num_values, values);
+ }
+
+ return (0);
+#endif /* __APPLE__ */
+}
+
+
+/*
+ * 'backendGetMakeModel()' - Get the make and model string from the device ID.
+ */
+
+int /* O - 0 on success, -1 on failure */
+backendGetMakeModel(
+ const char *device_id, /* O - 1284 device ID */
+ char *make_model, /* O - Make/model */
+ int make_model_size) /* I - Size of buffer */
+{
+ int num_values; /* Number of keys and values */
+ cups_option_t *values; /* Keys and values */
+ const char *mfg, /* Manufacturer string */
+ *mdl, /* Model string */
+ *des; /* Description string */
+
+
+ DEBUG_printf(("backendGetMakeModel(device_id=\"%s\", "
+ "make_model=%p, make_model_size=%d)\n", device_id,
+ make_model, make_model_size));
+
+ /*
+ * Range check input...
+ */
+
+ if (!device_id || !*device_id || !make_model || make_model_size < 32)
+ {
+ DEBUG_puts("backendGetMakeModel: Bad args!");
+ return (-1);
+ }
+
+ *make_model = '\0';
+
+ /*
+ * Look for the description field...
+ */
+
+ num_values = get_1284_values(device_id, &values);
+
+ if ((mdl = cupsGetOption("MODEL", num_values, values)) == NULL)
+ mdl = cupsGetOption("MDL", num_values, values);
+
+ if (mdl)
+ {
+ /*
+ * Build a make-model string from the manufacturer and model attributes...
+ */
+
+ if ((mfg = cupsGetOption("MANUFACTURER", num_values, values)) == NULL)
+ mfg = cupsGetOption("MFG", num_values, values);
+
+ if (!mfg || !_cups_strncasecmp(mdl, mfg, strlen(mfg)))
+ {
+ /*
+ * Just copy the model string, since it has the manufacturer...
+ */
+
+ normalize_make_and_model(mdl, make_model, make_model_size);
+ }
+ else
+ {
+ /*
+ * Concatenate the make and model...
+ */
+
+ char temp[1024]; /* Temporary make and model */
+
+ snprintf(temp, sizeof(temp), "%s %s", mfg, mdl);
+
+ normalize_make_and_model(temp, make_model, make_model_size);
+ }
+ }
+ else if ((des = cupsGetOption("DESCRIPTION", num_values, values)) != NULL ||
+ (des = cupsGetOption("DES", num_values, values)) != NULL)
+ {
+ /*
+ * Make sure the description contains something useful, since some
+ * printer manufacturers (HP) apparently don't follow the standards
+ * they helped to define...
+ *
+ * Here we require the description to be 8 or more characters in length,
+ * containing at least one space and one letter.
+ */
+
+ if (strlen(des) >= 8)
+ {
+ const char *ptr; /* Pointer into description */
+ int letters, /* Number of letters seen */
+ spaces; /* Number of spaces seen */
+
+
+ for (ptr = des, letters = 0, spaces = 0; *ptr; ptr ++)
+ {
+ if (isspace(*ptr & 255))
+ spaces ++;
+ else if (isalpha(*ptr & 255))
+ letters ++;
+
+ if (spaces && letters)
+ break;
+ }
+
+ if (spaces && letters)
+ normalize_make_and_model(des, make_model, make_model_size);
+ }
+ }
+
+ if (!make_model[0])
+ {
+ /*
+ * Use "Unknown" as the printer make and model...
+ */
+
+ strncpy(make_model, "Unknown", make_model_size - 1);
+ make_model[make_model_size - 1] = '\0';
+ }
+
+ cupsFreeOptions(num_values, values);
+
+ return (0);
+}
+
+
+/*
+ * 'get_1284_values()' - Get 1284 device ID keys and values.
+ *
+ * The returned dictionary is a CUPS option array that can be queried with
+ * cupsGetOption and freed with cupsFreeOptions.
+ */
+
+static int /* O - Number of key/value pairs */
+get_1284_values(
+ const char *device_id, /* I - IEEE-1284 device ID string */
+ cups_option_t **values) /* O - Array of key/value pairs */
+{
+ int num_values; /* Number of values */
+ char key[256], /* Key string */
+ value[256], /* Value string */
+ *ptr; /* Pointer into key/value */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (values)
+ *values = NULL;
+
+ if (!device_id || !values)
+ return (0);
+
+ /*
+ * Parse the 1284 device ID value into keys and values. The format is
+ * repeating sequences of:
+ *
+ * [whitespace]key:value[whitespace];
+ */
+
+ num_values = 0;
+ while (*device_id)
+ {
+ while (_cups_isspace(*device_id))
+ device_id ++;
+
+ if (!*device_id)
+ break;
+
+ for (ptr = key; *device_id && *device_id != ':'; device_id ++)
+ if (ptr < (key + sizeof(key) - 1))
+ *ptr++ = *device_id;
+
+ if (!*device_id)
+ break;
+
+ while (ptr > key && _cups_isspace(ptr[-1]))
+ ptr --;
+
+ *ptr = '\0';
+ device_id ++;
+
+ while (_cups_isspace(*device_id))
+ device_id ++;
+
+ if (!*device_id)
+ break;
+
+ for (ptr = value; *device_id && *device_id != ';'; device_id ++)
+ if (ptr < (value + sizeof(value) - 1))
+ *ptr++ = *device_id;
+
+ if (!*device_id)
+ break;
+
+ while (ptr > value && _cups_isspace(ptr[-1]))
+ ptr --;
+
+ *ptr = '\0';
+ device_id ++;
+
+ num_values = cupsAddOption(key, value, num_values, values);
+ }
+
+ return (num_values);
+}
+
+
+/*
+ * 'normalize_make_and_model()' - Normalize a product/make-and-model string.
+ *
+ * This function tries to undo the mistakes made by many printer manufacturers
+ * to produce a clean make-and-model string we can use.
+ */
+
+static char * /* O - Normalized make-and-model string or NULL on error */
+normalize_make_and_model(
+ const char *make_and_model, /* I - Original make-and-model string */
+ char *buffer, /* I - String buffer */
+ size_t bufsize) /* I - Size of string buffer */
+{
+ char *bufptr; /* Pointer into buffer */
+
+
+ if (!make_and_model || !buffer || bufsize < 1)
+ {
+ if (buffer)
+ *buffer = '\0';
+
+ return (NULL);
+ }
+
+ /*
+ * Skip leading whitespace...
+ */
+
+ while (_cups_isspace(*make_and_model))
+ make_and_model ++;
+
+ /*
+ * Remove parenthesis and add manufacturers as needed...
+ */
+
+ if (make_and_model[0] == '(')
+ {
+ strncpy(buffer, make_and_model + 1, bufsize - 1);
+ buffer[bufsize - 1] = '\0';
+
+ if ((bufptr = strrchr(buffer, ')')) != NULL)
+ *bufptr = '\0';
+ }
+ else if (!_cups_strncasecmp(make_and_model, "XPrint", 6))
+ {
+ /*
+ * Xerox XPrint...
+ */
+
+ snprintf(buffer, bufsize, "Xerox %s", make_and_model);
+ }
+ else if (!_cups_strncasecmp(make_and_model, "Eastman", 7))
+ {
+ /*
+ * Kodak...
+ */
+
+ snprintf(buffer, bufsize, "Kodak %s", make_and_model + 7);
+ }
+ else if (!_cups_strncasecmp(make_and_model, "laserwriter", 11))
+ {
+ /*
+ * Apple LaserWriter...
+ */
+
+ snprintf(buffer, bufsize, "Apple LaserWriter%s", make_and_model + 11);
+ }
+ else if (!_cups_strncasecmp(make_and_model, "colorpoint", 10))
+ {
+ /*
+ * Seiko...
+ */
+
+ snprintf(buffer, bufsize, "Seiko %s", make_and_model);
+ }
+ else if (!_cups_strncasecmp(make_and_model, "fiery", 5))
+ {
+ /*
+ * EFI...
+ */
+
+ snprintf(buffer, bufsize, "EFI %s", make_and_model);
+ }
+ else if (!_cups_strncasecmp(make_and_model, "ps ", 3) ||
+ !_cups_strncasecmp(make_and_model, "colorpass", 9))
+ {
+ /*
+ * Canon...
+ */
+
+ snprintf(buffer, bufsize, "Canon %s", make_and_model);
+ }
+ else if (!_cups_strncasecmp(make_and_model, "primera", 7))
+ {
+ /*
+ * Fargo...
+ */
+
+ snprintf(buffer, bufsize, "Fargo %s", make_and_model);
+ }
+ else if (!_cups_strncasecmp(make_and_model, "designjet", 9) ||
+ !_cups_strncasecmp(make_and_model, "deskjet", 7))
+ {
+ /*
+ * HP...
+ */
+
+ snprintf(buffer, bufsize, "HP %s", make_and_model);
+ }
+ else
+ {
+ strncpy(buffer, make_and_model, bufsize - 1);
+ buffer[bufsize - 1] = '\0';
+ }
+
+ /*
+ * Clean up the make...
+ */
+
+ if (!_cups_strncasecmp(buffer, "agfa", 4))
+ {
+ /*
+ * Replace with AGFA (all uppercase)...
+ */
+
+ buffer[0] = 'A';
+ buffer[1] = 'G';
+ buffer[2] = 'F';
+ buffer[3] = 'A';
+ }
+ else if (!_cups_strncasecmp(buffer, "Hewlett-Packard hp ", 19))
+ {
+ /*
+ * Just put "HP" on the front...
+ */
+
+ buffer[0] = 'H';
+ buffer[1] = 'P';
+ memmove(buffer + 2, buffer + 18, strlen(buffer + 18) + 1);
+ }
+ else if (!_cups_strncasecmp(buffer, "Hewlett-Packard ", 16))
+ {
+ /*
+ * Just put "HP" on the front...
+ */
+
+ buffer[0] = 'H';
+ buffer[1] = 'P';
+ memmove(buffer + 2, buffer + 15, strlen(buffer + 15) + 1);
+ }
+ else if (!_cups_strncasecmp(buffer, "Lexmark International", 21))
+ {
+ /*
+ * Strip "International"...
+ */
+
+ memmove(buffer + 8, buffer + 21, strlen(buffer + 21) + 1);
+ }
+ else if (!_cups_strncasecmp(buffer, "herk", 4))
+ {
+ /*
+ * Replace with LHAG...
+ */
+
+ buffer[0] = 'L';
+ buffer[1] = 'H';
+ buffer[2] = 'A';
+ buffer[3] = 'G';
+ }
+ else if (!_cups_strncasecmp(buffer, "linotype", 8))
+ {
+ /*
+ * Replace with LHAG...
+ */
+
+ buffer[0] = 'L';
+ buffer[1] = 'H';
+ buffer[2] = 'A';
+ buffer[3] = 'G';
+ memmove(buffer + 4, buffer + 8, strlen(buffer + 8) + 1);
+ }
+
+ /*
+ * Remove trailing whitespace and return...
+ */
+
+ for (bufptr = buffer + strlen(buffer) - 1;
+ bufptr >= buffer && _cups_isspace(*bufptr);
+ bufptr --);
+
+ bufptr[1] = '\0';
+
+ return (buffer[0] ? buffer : NULL);
+}
diff --git a/backend/implicitclass.c b/backend/implicitclass.c
new file mode 100644
index 000000000..3ce4d1098
--- /dev/null
+++ b/backend/implicitclass.c
@@ -0,0 +1,320 @@
+/*
+ * implicitclass backend for implementing an implicit-class-like behavior
+ * of redundant print servers managed by cups-browsed.
+ *
+ * Copyright 2015 by Till Kamppeter
+ *
+ * This is based on dnssd.c of CUPS
+ * dnssd.c copyright notice is follows:
+ *
+ * Copyright 2008-2015 by Apple Inc.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "backend-private.h"
+#include <cups/array.h>
+#include <ctype.h>
+
+/*
+ * Local globals...
+ */
+
+/* IPP Attribute which cups-browsed uses to tell us the destination queue for
+ the current job */
+#define CUPS_BROWSED_DEST_PRINTER "cups-browsed-dest-printer"
+
+static int job_canceled = 0;
+ /* Set to 1 on SIGTERM */
+
+/*
+ * Local functions... */
+
+static void sigterm_handler(int sig);
+
+
+/*
+ * 'main()' - Browse for printers.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line args */
+ char *argv[]) /* I - Command-line arguments */
+{
+ const char *device_uri; /* URI with which we were called */
+ char queue_name[1024];
+ const char *ptr1;
+ char *ptr2;
+ const char *job_id;
+ int i;
+ char dest_host[1024]; /* Destination host */
+ ipp_t *request, *response;
+ ipp_attribute_t *attr;
+ char uri[HTTP_MAX_URI];
+ static const char *pattrs[] =
+ {
+ "printer-defaults"
+ };
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+ /*
+ * Don't buffer stderr, and catch SIGTERM...
+ */
+
+ setbuf(stderr, NULL);
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, sigterm_handler);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = sigterm_handler;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, sigterm_handler);
+#endif /* HAVE_SIGSET */
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc >= 6)
+ {
+ if ((device_uri = getenv("DEVICE_URI")) == NULL)
+ {
+ if (!argv || !argv[0] || !strchr(argv[0], ':'))
+ return (-1);
+
+ device_uri = argv[0];
+ }
+ if ((ptr1 = strchr(device_uri, ':')) == NULL) {
+ fprintf(stderr, "ERROR: Incorrect device URI syntax: %s\n",
+ device_uri);
+ return (CUPS_BACKEND_STOP);
+ }
+ ptr1 ++;
+ strncpy(queue_name, ptr1, sizeof(queue_name));
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", ippPort(), "/printers/%s", queue_name);
+ job_id = argv[1];
+ for (i = 0; i < 40; i++) {
+ /* Wait up to 20 sec for cups-browsed to supply the destination host */
+ /* Try reading the option in which cups-browsed has deposited the
+ destination host */
+ request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
+ uri);
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes",
+ sizeof(pattrs) / sizeof(pattrs[0]),
+ NULL, pattrs);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name",
+ NULL, cupsUser());
+ if ((response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")) ==
+ NULL)
+ goto failed;
+ for (attr = ippFirstAttribute(response); attr != NULL;
+ attr = ippNextAttribute(response)) {
+ while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_PRINTER)
+ attr = ippNextAttribute(response);
+ if (attr == NULL)
+ break;
+ ptr1 = NULL;
+ while (attr != NULL && ippGetGroupTag(attr) ==
+ IPP_TAG_PRINTER) {
+ if (!strcmp(ippGetName(attr),
+ CUPS_BROWSED_DEST_PRINTER "-default"))
+ ptr1 = ippGetString(attr, 0, NULL);
+ if (ptr1 != NULL)
+ break;
+ attr = ippNextAttribute(response);
+ }
+ if (ptr1 != NULL)
+ break;
+ }
+ fprintf(stderr, "DEBUG: Read " CUPS_BROWSED_DEST_PRINTER " option: %s\n", ptr1);
+ if (ptr1 == NULL)
+ goto failed;
+ /* Destination host is between double quotes, as double quotes are
+ illegal in host names one easily recognizes whether the option is
+ complete and avoids accepting a partially written host name */
+ if (*ptr1 != '"')
+ goto failed;
+ ptr1 ++;
+ /* Check whether option was set for this job, if not, keep waiting */
+ if (strncmp(ptr1, job_id, strlen(job_id)) != 0)
+ goto failed;
+ ptr1 += strlen(job_id);
+ if (*ptr1 != ' ')
+ goto failed;
+ ptr1 ++;
+ /* Read destination host name (or message) and check whether it is
+ complete (second double quote) */
+ strncpy(dest_host, ptr1, sizeof(dest_host));
+ ptr1 = dest_host;
+ if ((ptr2 = strchr(ptr1, '"')) != NULL) {
+ *ptr2 = '\0';
+ ippDelete(response);
+ break;
+ }
+ failed:
+ ippDelete(response);
+ /* Pause half a second before next attempt */
+ usleep(500000);
+ }
+
+ if (i >= 40) {
+ /* Timeout, no useful data from cups-browsed received */
+ fprintf(stderr, "ERROR: No destination host name supplied by cups-browsed for printer \"%s\", is cups-browsed running?\n",
+ queue_name);
+ return (CUPS_BACKEND_STOP);
+ }
+
+ if (!strcmp(dest_host, "NO_DEST_FOUND")) {
+ /* All remote queues are either disabled or not accepting jobs, let
+ CUPS retry after the usual interval */
+ fprintf(stderr, "ERROR: No suitable destination host found by cups-browsed.\n");
+ return (CUPS_BACKEND_RETRY);
+ } else if (!strcmp(dest_host, "ALL_DESTS_BUSY")) {
+ /* We queue on the client and all remote queues are busy, so we wait
+ 5 sec and check again then */
+ fprintf(stderr, "DEBUG: No free destination host found by cups-browsed, retrying in 5 sec.\n");
+ sleep(5);
+ return (CUPS_BACKEND_RETRY_CURRENT);
+ } else {
+ /* We have the destination host name now, do the job */
+ char server_str[1024];
+ const char *title;
+ int num_options = 0;
+ cups_option_t *options = NULL;
+ int fd, job_id;
+ char buffer[8192];
+
+ ptr2 = strrchr(dest_host, '/');
+ if (ptr2) {
+ *ptr2 = '\0';
+ ptr2 ++;
+ } else
+ ptr2 = queue_name;
+
+ fprintf(stderr, "DEBUG: Received destination host name from cups-browsed: %s\n",
+ dest_host);
+ fprintf(stderr, "DEBUG: Received destination queue name from cups-browsed: %s\n",
+ ptr2);
+
+ /* Instead of feeding the job into the IPP backend, we re-print it into
+ the server's CUPS queue. This way the job gets spooled on the server
+ and we are not blocked until the job is printed. So a subsequent job
+ will be immediately processed and sent out to another server */
+ /* Set destination server */
+ snprintf(server_str, sizeof(server_str), "%s", dest_host);
+ cupsSetServer(server_str);
+ /* Parse the command line option and prepare them for the new print
+ job */
+ cupsSetUser(argv[2]);
+ title = argv[3];
+ if (title == NULL)
+ {
+ if (argc == 7) {
+ if ((title = strrchr(argv[6], '/')) != NULL)
+ title ++;
+ else
+ title = argv[6];
+ } else
+ title = "(stdin)";
+ }
+ num_options = cupsAddOption("copies", argv[4], num_options, &options);
+ num_options = cupsParseOptions(argv[5], num_options, &options);
+ if (argc == 7)
+ fd = open(argv[6], O_RDONLY);
+ else
+ fd = 0; /* stdin */
+
+ /* Queue the job directly on the server */
+ if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, ptr2,
+ title ? title : "(stdin)",
+ num_options, options)) > 0) {
+ http_status_t status; /* Write status */
+ const char *format; /* Document format */
+ ssize_t bytes; /* Bytes read */
+
+ if (cupsGetOption("raw", num_options, options))
+ format = CUPS_FORMAT_RAW;
+ else if ((format = cupsGetOption("document-format", num_options,
+ options)) == NULL)
+ format = CUPS_FORMAT_AUTO;
+
+ status = cupsStartDocument(CUPS_HTTP_DEFAULT, ptr2, job_id, NULL,
+ format, 1);
+
+ while (status == HTTP_CONTINUE &&
+ (bytes = read(fd, buffer, sizeof(buffer))) > 0)
+ status = cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, (size_t)bytes);
+
+ if (status != HTTP_CONTINUE) {
+ fprintf(stderr, "ERROR: %s: Unable to queue the print data - %s. Retrying.",
+ argv[0], httpStatus(status));
+ cupsFinishDocument(CUPS_HTTP_DEFAULT, ptr2);
+ cupsCancelJob2(CUPS_HTTP_DEFAULT, ptr2, job_id, 0);
+ return (CUPS_BACKEND_RETRY);
+ }
+
+ if (cupsFinishDocument(CUPS_HTTP_DEFAULT, ptr2) != IPP_OK) {
+ fprintf(stderr, "ERROR: %s: Unable to complete the job - %s. Retrying.",
+ argv[0], cupsLastErrorString());
+ cupsCancelJob2(CUPS_HTTP_DEFAULT, ptr2, job_id, 0);
+ return (CUPS_BACKEND_RETRY);
+ }
+ }
+
+ if (job_id < 1) {
+ fprintf(stderr, "ERROR: %s: Unable to create job - %s. Retrying.",
+ argv[0], cupsLastErrorString());
+ return (CUPS_BACKEND_RETRY);
+ }
+
+ return (CUPS_BACKEND_OK);
+ }
+ }
+ else if (argc != 1)
+ {
+ fprintf(stderr,
+ "Usage: %s job-id user title copies options [file]",
+ argv[0]);
+ return (CUPS_BACKEND_FAILED);
+ }
+
+ /*
+ * No discovery mode at all for this backend
+ */
+
+ return (CUPS_BACKEND_OK);
+}
+
+
+/*
+ * 'sigterm_handler()' - Handle termination signals.
+ */
+
+static void
+sigterm_handler(int sig) /* I - Signal number (unused) */
+{
+ (void)sig;
+
+ if (job_canceled)
+ _exit(CUPS_BACKEND_OK);
+ else
+ job_canceled = 1;
+}
+
diff --git a/backend/parallel.c b/backend/parallel.c
new file mode 100644
index 000000000..c3fe9e81e
--- /dev/null
+++ b/backend/parallel.c
@@ -0,0 +1,861 @@
+/*
+ * Parallel port backend for OpenPrinting CUPS Filters.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * main() - Send a file to the specified parallel port.
+ * drain_output() - Drain pending print data to the device.
+ * list_devices() - List all parallel devices.
+ * run_loop() - Read and write print and back-channel data.
+ * side_cb() - Handle side-channel requests...
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "backend-private.h"
+#include <unistd.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <sys/socket.h>
+
+
+/*
+ * Local functions...
+ */
+
+static int drain_output(int print_fd, int device_fd);
+static void list_devices(void);
+static ssize_t run_loop(int print_fd, int device_fd, int use_bc,
+ int update_state);
+static int side_cb(int print_fd, int device_fd, int use_bc);
+
+
+/*
+ * 'main()' - Send a file to the specified parallel port.
+ *
+ * Usage:
+ *
+ * printer-uri job-id user title copies options [file]
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments (6 or 7) */
+ char *argv[]) /* I - Command-line arguments */
+{
+ char method[255], /* Method in URI */
+ hostname[1024], /* Hostname */
+ username[255], /* Username info (not used) */
+ resource[1024], /* Resource info (device and options) */
+ *options; /* Pointer to options */
+ int port; /* Port number (not used) */
+ int print_fd, /* Print file */
+ device_fd, /* Parallel device */
+ use_bc; /* Read back-channel data? */
+ int copies; /* Number of copies to print */
+ ssize_t tbytes; /* Total number of bytes written */
+ struct termios opts; /* Parallel port options */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Ignore SIGPIPE signals...
+ */
+
+#ifdef HAVE_SIGSET
+ sigset(SIGPIPE, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &action, NULL);
+#else
+ signal(SIGPIPE, SIG_IGN);
+#endif /* HAVE_SIGSET */
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc == 1)
+ {
+ list_devices();
+ return (CUPS_BACKEND_OK);
+ }
+ else if (argc < 6 || argc > 7)
+ {
+ fprintf(stderr, "Usage: %s job-id user title copies options [file]",
+ argv[0]);
+ return (CUPS_BACKEND_FAILED);
+ }
+
+ /*
+ * If we have 7 arguments, print the file named on the command-line.
+ * Otherwise, send stdin instead...
+ */
+
+ if (argc == 6)
+ {
+ print_fd = 0;
+ copies = 1;
+ }
+ else
+ {
+ /*
+ * Try to open the print file...
+ */
+
+ if ((print_fd = open(argv[6], O_RDONLY)) < 0)
+ {
+ perror("ERROR: Unable to open print file");
+ return (CUPS_BACKEND_FAILED);
+ }
+
+ copies = atoi(argv[4]);
+ }
+
+ /*
+ * Extract the device name and options from the URI...
+ */
+
+ httpSeparateURI(HTTP_URI_CODING_ALL, cupsBackendDeviceURI(argv),
+ method, sizeof(method), username, sizeof(username),
+ hostname, sizeof(hostname), &port,
+ resource, sizeof(resource));
+
+ /*
+ * See if there are any options...
+ */
+
+ if ((options = strchr(resource, '?')) != NULL)
+ {
+ /*
+ * Yup, terminate the device name string and move to the first
+ * character of the options...
+ */
+
+ *options++ = '\0';
+ }
+
+ /*
+ * Open the parallel port device...
+ */
+
+ fputs("STATE: +connecting-to-device\n", stderr);
+
+ do
+ {
+#if defined(__linux) || defined(__FreeBSD__)
+ /*
+ * The Linux and FreeBSD parallel port drivers currently are broken WRT
+ * select() and bidirection I/O...
+ */
+
+ device_fd = open(resource, O_WRONLY | O_EXCL);
+ use_bc = 0;
+
+#else
+ if ((device_fd = open(resource, O_RDWR | O_EXCL)) < 0)
+ {
+ device_fd = open(resource, O_WRONLY | O_EXCL);
+ use_bc = 0;
+ }
+ else
+ use_bc = 1;
+#endif /* __linux || __FreeBSD__ */
+
+ if (device_fd == -1)
+ {
+ if (getenv("CLASS") != NULL)
+ {
+ /*
+ * If the CLASS environment variable is set, the job was submitted
+ * to a class and not to a specific queue. In this case, we want
+ * to abort immediately so that the job can be requeued on the next
+ * available printer in the class.
+ */
+
+ fputs("INFO: Unable to contact printer, queuing on next printer in "
+ "class.\n", stderr);
+
+ /*
+ * Sleep 5 seconds to keep the job from requeuing too rapidly...
+ */
+
+ sleep(5);
+
+ return (CUPS_BACKEND_FAILED);
+ }
+
+ if (errno == EBUSY)
+ {
+ fputs("INFO: Printer busy; will retry in 30 seconds.\n", stderr);
+ sleep(30);
+ }
+ else if (errno == ENXIO || errno == EIO || errno == ENOENT)
+ {
+ fputs("INFO: Printer not connected; will retry in 30 seconds.\n",
+ stderr);
+ sleep(30);
+ }
+ else
+ {
+ perror("ERROR: Unable to open parallel port");
+ return (CUPS_BACKEND_FAILED);
+ }
+ }
+ }
+ while (device_fd < 0);
+
+ fputs("STATE: -connecting-to-device\n", stderr);
+
+ /*
+ * Set any options provided...
+ */
+
+ tcgetattr(device_fd, &opts);
+
+ opts.c_lflag &= ~(ICANON | ECHO | ISIG); /* Raw mode */
+
+ /**** No options supported yet ****/
+
+ tcsetattr(device_fd, TCSANOW, &opts);
+
+ /*
+ * Finally, send the print file...
+ */
+
+ tbytes = 0;
+
+ while (copies > 0 && tbytes >= 0)
+ {
+ copies --;
+
+ if (print_fd != 0)
+ {
+ fputs("PAGE: 1 1\n", stderr);
+ lseek(print_fd, 0, SEEK_SET);
+ }
+
+ tbytes = run_loop(print_fd, device_fd, use_bc, 1);
+
+ if (print_fd != 0 && tbytes >= 0)
+ fputs("INFO: Print file sent.\n", stderr);
+ }
+
+ /*
+ * Close the socket connection and input file and return...
+ */
+
+ close(device_fd);
+
+ if (print_fd != 0)
+ close(print_fd);
+
+ return (CUPS_BACKEND_OK);
+}
+
+
+/*
+ * 'drain_output()' - Drain pending print data to the device.
+ */
+
+static int /* O - 0 on success, -1 on error */
+drain_output(int print_fd, /* I - Print file descriptor */
+ int device_fd) /* I - Device file descriptor */
+{
+ int nfds; /* Maximum file descriptor value + 1 */
+ fd_set input; /* Input set for reading */
+ ssize_t print_bytes, /* Print bytes read */
+ bytes; /* Bytes written */
+ char print_buffer[8192], /* Print data buffer */
+ *print_ptr; /* Pointer into print data buffer */
+ struct timeval timeout; /* Timeout for read... */
+
+
+ /*
+ * Figure out the maximum file descriptor value to use with select()...
+ */
+
+ nfds = (print_fd > device_fd ? print_fd : device_fd) + 1;
+
+ /*
+ * Now loop until we are out of data from print_fd...
+ */
+
+ for (;;)
+ {
+ /*
+ * Use select() to determine whether we have data to copy around...
+ */
+
+ FD_ZERO(&input);
+ FD_SET(print_fd, &input);
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+
+ if (select(nfds, &input, NULL, NULL, &timeout) < 0)
+ return (-1);
+
+ if (!FD_ISSET(print_fd, &input))
+ return (0);
+
+ if ((print_bytes = read(print_fd, print_buffer,
+ sizeof(print_buffer))) < 0)
+ {
+ /*
+ * Read error - bail if we don't see EAGAIN or EINTR...
+ */
+
+ if (errno != EAGAIN && errno != EINTR)
+ {
+ perror("ERROR: Unable to read print data");
+ return (-1);
+ }
+
+ print_bytes = 0;
+ }
+ else if (print_bytes == 0)
+ {
+ /*
+ * End of file, return...
+ */
+
+ return (0);
+ }
+
+ fprintf(stderr, "DEBUG: Read %d bytes of print data.\n",
+ (int)print_bytes);
+
+ for (print_ptr = print_buffer; print_bytes > 0;)
+ {
+ if ((bytes = write(device_fd, print_ptr, print_bytes)) < 0)
+ {
+ /*
+ * Write error - bail if we don't see an error we can retry...
+ */
+
+ if (errno != ENOSPC && errno != ENXIO && errno != EAGAIN &&
+ errno != EINTR && errno != ENOTTY)
+ {
+ perror("ERROR: Unable to write print data");
+ return (-1);
+ }
+ }
+ else
+ {
+ fprintf(stderr, "DEBUG: Wrote %d bytes of print data.\n", (int)bytes);
+
+ print_bytes -= bytes;
+ print_ptr += bytes;
+ }
+ }
+ }
+}
+
+
+/*
+ * 'list_devices()' - List all parallel devices.
+ */
+
+static void
+list_devices(void)
+{
+#ifdef __sun
+ static char *funky_hex = "0123456789abcdefghijklmnopqrstuvwxyz";
+ /* Funky hex numbering used for some devices */
+#endif /* __sun */
+
+#ifdef __linux
+ int i; /* Looping var */
+ int fd; /* File descriptor */
+ char device[255], /* Device filename */
+ basedevice[255], /* Base device filename for ports */
+ device_id[1024], /* Device ID string */
+ make_model[1024], /* Make and model */
+ info[1024], /* Info string */
+ uri[1024]; /* Device URI */
+
+
+ if (!access("/dev/parallel/", 0))
+ strcpy(basedevice, "/dev/parallel/");
+ else if (!access("/dev/printers/", 0))
+ strcpy(basedevice, "/dev/printers/");
+ else
+ strcpy(basedevice, "/dev/lp");
+
+ for (i = 0; i < 4; i ++)
+ {
+ /*
+ * Open the port, if available...
+ */
+
+ sprintf(device, "%s%d", basedevice, i);
+ if ((fd = open(device, O_RDWR | O_EXCL)) < 0)
+ fd = open(device, O_WRONLY);
+
+ if (fd >= 0)
+ {
+ /*
+ * Now grab the IEEE 1284 device ID string...
+ */
+
+ snprintf(uri, sizeof(uri), "parallel:%s", device);
+
+ if (!backendGetDeviceID(fd, device_id, sizeof(device_id),
+ make_model, sizeof(make_model),
+ NULL, uri, sizeof(uri)))
+ {
+ snprintf(info, sizeof(info), "%s LPT #%d", make_model, i + 1);
+ cupsBackendReport("direct", uri, make_model, info, device_id, NULL);
+ }
+ else
+ {
+ snprintf(info, sizeof(info), "LPT #%d", i + 1);
+ cupsBackendReport("direct", uri, NULL, info, NULL, NULL);
+ }
+
+ close(fd);
+ }
+ }
+#elif defined(__sun)
+ int i, j, n; /* Looping vars */
+ char device[255]; /* Device filename */
+
+
+ /*
+ * Standard parallel ports...
+ */
+
+ for (i = 0; i < 10; i ++)
+ {
+ sprintf(device, "/dev/ecpp%d", i);
+ if (access(device, 0) == 0)
+ printf("direct parallel:%s \"Unknown\" \"Sun IEEE-1284 Parallel Port #%d\"\n",
+ device, i + 1);
+ }
+
+ for (i = 0; i < 10; i ++)
+ {
+ sprintf(device, "/dev/bpp%d", i);
+ if (access(device, 0) == 0)
+ printf("direct parallel:%s \"Unknown\" \"Sun Standard Parallel Port #%d\"\n",
+ device, i + 1);
+ }
+
+ for (i = 0; i < 3; i ++)
+ {
+ sprintf(device, "/dev/lp%d", i);
+
+ if (access(device, 0) == 0)
+ printf("direct parallel:%s \"Unknown\" \"PC Parallel Port #%d\"\n",
+ device, i + 1);
+ }
+
+ /*
+ * MAGMA parallel ports...
+ */
+
+ for (i = 0; i < 40; i ++)
+ {
+ sprintf(device, "/dev/pm%02d", i);
+ if (access(device, 0) == 0)
+ printf("direct parallel:%s \"Unknown\" \"MAGMA Parallel Board #%d Port #%d\"\n",
+ device, (i / 10) + 1, (i % 10) + 1);
+ }
+
+ /*
+ * Central Data parallel ports...
+ */
+
+ for (i = 0; i < 9; i ++)
+ for (j = 0; j < 8; j ++)
+ for (n = 0; n < 32; n ++)
+ {
+ if (i == 8) /* EtherLite */
+ sprintf(device, "/dev/sts/lpN%d%c", j, funky_hex[n]);
+ else
+ sprintf(device, "/dev/sts/lp%c%d%c", i + 'C', j,
+ funky_hex[n]);
+
+ if (access(device, 0) == 0)
+ {
+ if (i == 8)
+ printf("direct parallel:%s \"Unknown\" \"Central Data EtherLite Parallel Port, ID %d, port %d\"\n",
+ device, j, n);
+ else
+ printf("direct parallel:%s \"Unknown\" \"Central Data SCSI Parallel Port, logical bus %d, ID %d, port %d\"\n",
+ device, i, j, n);
+ }
+ }
+#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
+ int i; /* Looping var */
+ int fd; /* File descriptor */
+ char device[255]; /* Device filename */
+
+
+ for (i = 0; i < 3; i ++)
+ {
+ sprintf(device, "/dev/lpt%d", i);
+ if ((fd = open(device, O_WRONLY)) >= 0)
+ {
+ close(fd);
+ printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d (interrupt-driven)\"\n", device, i + 1);
+ }
+
+ sprintf(device, "/dev/lpa%d", i);
+ if ((fd = open(device, O_WRONLY)) >= 0)
+ {
+ close(fd);
+ printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d (polled)\"\n", device, i + 1);
+ }
+ }
+#endif
+}
+
+
+/*
+ * 'run_loop()' - Read and write print and back-channel data.
+ */
+
+static ssize_t /* O - Total bytes on success, -1 on error */
+run_loop(int print_fd, /* I - Print file descriptor */
+ int device_fd, /* I - Device file descriptor */
+ int use_bc, /* I - Use back-channel? */
+ int update_state) /* I - Update printer-state-reasons? */
+{
+ int nfds; /* Maximum file descriptor value + 1 */
+ fd_set input, /* Input set for reading */
+ output; /* Output set for writing */
+ ssize_t print_bytes, /* Print bytes read */
+ bc_bytes, /* Backchannel bytes read */
+ total_bytes, /* Total bytes written */
+ bytes; /* Bytes written */
+ int paperout; /* "Paper out" status */
+ int offline; /* "Off-line" status */
+ char print_buffer[8192], /* Print data buffer */
+ *print_ptr, /* Pointer into print data buffer */
+ bc_buffer[1024]; /* Back-channel data buffer */
+ struct timeval timeout; /* Timeout for select() */
+ int sc_ok; /* Flag a side channel error and
+ stop using the side channel
+ in such a case. */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ /*
+ * If we are printing data from a print driver on stdin, ignore SIGTERM
+ * so that the driver can finish out any page data, e.g. to eject the
+ * current page. We only do this for stdin printing as otherwise there
+ * is no way to cancel a raw print job...
+ */
+
+ if (!print_fd)
+ {
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, SIG_IGN);
+#endif /* HAVE_SIGSET */
+ }
+ else if (print_fd < 0)
+ {
+ /*
+ * Copy print data from stdin, but don't mess with the signal handlers...
+ */
+
+ print_fd = 0;
+ }
+
+ /*
+ * Figure out the maximum file descriptor value to use with select()...
+ */
+
+ nfds = (print_fd > device_fd ? print_fd : device_fd) + 1;
+
+
+ /*
+ * Side channel is OK...
+ */
+
+ sc_ok = 1;
+
+ /*
+ * Now loop until we are out of data from print_fd...
+ */
+
+ for (print_bytes = 0, print_ptr = print_buffer, offline = -1,
+ paperout = -1, total_bytes = 0;;)
+ {
+ /*
+ * Use select() to determine whether we have data to copy around...
+ */
+
+ FD_ZERO(&input);
+ if (!print_bytes)
+ FD_SET(print_fd, &input);
+ if (use_bc)
+ FD_SET(device_fd, &input);
+ if (!print_bytes && sc_ok)
+ FD_SET(CUPS_SC_FD, &input);
+
+ FD_ZERO(&output);
+ if (print_bytes)
+ FD_SET(device_fd, &output);
+
+ timeout.tv_sec = 5;
+ timeout.tv_usec = 0;
+
+ if (select(nfds, &input, &output, NULL, &timeout) < 0)
+ {
+ /*
+ * Pause printing to clear any pending errors...
+ */
+
+ if (errno == ENXIO && offline != 1 && update_state)
+ {
+ fputs("STATE: +offline-report\n", stderr);
+ offline = 1;
+ }
+ else if (errno == EINTR && total_bytes == 0)
+ {
+ fputs("DEBUG: Received an interrupt before any bytes were "
+ "written, aborting.\n", stderr);
+ return (0);
+ }
+
+ sleep(1);
+ continue;
+ }
+
+ /*
+ * Check if we have a side-channel request ready...
+ */
+
+ if (sc_ok && FD_ISSET(CUPS_SC_FD, &input))
+ {
+ /*
+ * Do the side-channel request, then start back over in the select
+ * loop since it may have read from print_fd...
+ *
+ * If the side channel processing errors, go straight on to avoid
+ * blocking of the backend by side channel problems, deactivate the side
+ * channel.
+ */
+
+ if (side_cb(print_fd, device_fd, use_bc))
+ sc_ok = 0;
+ continue;
+ }
+
+ /*
+ * Check if we have back-channel data ready...
+ */
+
+ if (FD_ISSET(device_fd, &input))
+ {
+ if ((bc_bytes = read(device_fd, bc_buffer, sizeof(bc_buffer))) > 0)
+ {
+ fprintf(stderr, "DEBUG: Received %d bytes of back-channel data.\n",
+ (int)bc_bytes);
+ cupsBackChannelWrite(bc_buffer, bc_bytes, 1.0);
+ }
+ else if (bc_bytes < 0 && errno != EAGAIN && errno != EINTR)
+ {
+ perror("DEBUG: Error reading back-channel data");
+ use_bc = 0;
+ }
+ else if (bc_bytes == 0)
+ use_bc = 0;
+ }
+
+ /*
+ * Check if we have print data ready...
+ */
+
+ if (FD_ISSET(print_fd, &input))
+ {
+ if ((print_bytes = read(print_fd, print_buffer,
+ sizeof(print_buffer))) < 0)
+ {
+ /*
+ * Read error - bail if we don't see EAGAIN or EINTR...
+ */
+
+ if (errno != EAGAIN && errno != EINTR)
+ {
+ perror("ERROR: Unable to read print data");
+ return (-1);
+ }
+
+ print_bytes = 0;
+ }
+ else if (print_bytes == 0)
+ {
+ /*
+ * End of file, break out of the loop...
+ */
+
+ break;
+ }
+
+ print_ptr = print_buffer;
+
+ fprintf(stderr, "DEBUG: Read %d bytes of print data.\n",
+ (int)print_bytes);
+ }
+
+ /*
+ * Check if the device is ready to receive data and we have data to
+ * send...
+ */
+
+ if (print_bytes && FD_ISSET(device_fd, &output))
+ {
+ if ((bytes = write(device_fd, print_ptr, print_bytes)) < 0)
+ {
+ /*
+ * Write error - bail if we don't see an error we can retry...
+ */
+
+ if (errno == ENOSPC)
+ {
+ if (paperout != 1 && update_state)
+ {
+ fputs("STATE: +media-empty-warning\n", stderr);
+ paperout = 1;
+ }
+ }
+ else if (errno == ENXIO)
+ {
+ if (offline != 1 && update_state)
+ {
+ fputs("STATE: +offline-report\n", stderr);
+ offline = 1;
+ }
+ }
+ else if (errno != EAGAIN && errno != EINTR && errno != ENOTTY)
+ {
+ perror("ERROR: Unable to write print data");
+ return (-1);
+ }
+ }
+ else
+ {
+ if (paperout && update_state)
+ {
+ fputs("STATE: -media-empty-warning\n", stderr);
+ paperout = 0;
+ }
+
+ if (offline && update_state)
+ {
+ fputs("STATE: -offline-report\n", stderr);
+ offline = 0;
+ }
+
+ fprintf(stderr, "DEBUG: Wrote %d bytes of print data...\n", (int)bytes);
+
+ print_bytes -= bytes;
+ print_ptr += bytes;
+ total_bytes += bytes;
+ }
+ }
+ }
+
+ /*
+ * Return with success...
+ */
+
+ return (total_bytes);
+}
+
+
+/*
+ * 'side_cb()' - Handle side-channel requests...
+ */
+
+static int /* O - 0 on success, -1 on error */
+side_cb(int print_fd, /* I - Print file */
+ int device_fd, /* I - Device file */
+ int use_bc) /* I - Using back-channel? */
+{
+ cups_sc_command_t command; /* Request command */
+ cups_sc_status_t status; /* Request/response status */
+ char data[2048]; /* Request/response data */
+ int datalen; /* Request/response data size */
+
+
+ datalen = sizeof(data);
+
+ if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0))
+ return (-1);
+
+ switch (command)
+ {
+ case CUPS_SC_CMD_DRAIN_OUTPUT :
+ if (drain_output(print_fd, device_fd))
+ status = CUPS_SC_STATUS_IO_ERROR;
+ else if (tcdrain(device_fd))
+ status = CUPS_SC_STATUS_IO_ERROR;
+ else
+ status = CUPS_SC_STATUS_OK;
+
+ datalen = 0;
+ break;
+
+ case CUPS_SC_CMD_GET_BIDI :
+ status = CUPS_SC_STATUS_OK;
+ data[0] = use_bc;
+ datalen = 1;
+ break;
+
+ case CUPS_SC_CMD_GET_DEVICE_ID :
+ memset(data, 0, sizeof(data));
+
+ if (backendGetDeviceID(device_fd, data, sizeof(data) - 1,
+ NULL, 0, NULL, NULL, 0))
+ {
+ status = CUPS_SC_STATUS_NOT_IMPLEMENTED;
+ datalen = 0;
+ }
+ else
+ {
+ status = CUPS_SC_STATUS_OK;
+ datalen = strlen(data);
+ }
+ break;
+
+ default :
+ status = CUPS_SC_STATUS_NOT_IMPLEMENTED;
+ datalen = 0;
+ break;
+ }
+
+ return (cupsSideChannelWrite(command, status, data, datalen, 1.0));
+}
diff --git a/backend/serial.c b/backend/serial.c
new file mode 100644
index 000000000..e38de0e7b
--- /dev/null
+++ b/backend/serial.c
@@ -0,0 +1,1228 @@
+/*
+ * Serial port backend for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * main() - Send a file to the printer or server.
+ * list_devices() - List all serial devices.
+ * side_cb() - Handle side-channel requests...
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "backend-private.h"
+#include <stdio.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <sys/select.h>
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif /* HAVE_SYS_IOCTL_H */
+
+#ifndef CRTSCTS
+# ifdef CNEW_RTSCTS
+# define CRTSCTS CNEW_RTSCTS
+# else
+# define CRTSCTS 0
+# endif /* CNEW_RTSCTS */
+#endif /* !CRTSCTS */
+
+#if defined(__APPLE__)
+# include <CoreFoundation/CoreFoundation.h>
+# include <IOKit/IOKitLib.h>
+# include <IOKit/serial/IOSerialKeys.h>
+# include <IOKit/IOBSD.h>
+#endif /* __APPLE__ */
+
+#if defined(__linux) && defined(TIOCGSERIAL)
+# include <linux/serial.h>
+# include <linux/ioctl.h>
+#endif /* __linux && TIOCGSERIAL */
+
+
+/*
+ * Local functions...
+ */
+
+static int drain_output(int print_fd, int device_fd);
+static void list_devices(void);
+static int side_cb(int print_fd, int device_fd, int use_bc);
+
+
+/*
+ * 'main()' - Send a file to the printer or server.
+ *
+ * Usage:
+ *
+ * printer-uri job-id user title copies options [file]
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments (6 or 7) */
+ char *argv[]) /* I - Command-line arguments */
+{
+ char method[255], /* Method in URI */
+ hostname[1024], /* Hostname */
+ username[255], /* Username info (not used) */
+ resource[1024], /* Resource info (device and options) */
+ *options, /* Pointer to options */
+ *name, /* Name of option */
+ *value, /* Value of option */
+ sep; /* Option separator */
+ int port; /* Port number (not used) */
+ int copies; /* Number of copies to print */
+ int side_eof = 0, /* Saw EOF on side-channel? */
+ print_fd, /* Print file */
+ device_fd; /* Serial device */
+ int nfds; /* Maximum file descriptor value + 1 */
+ fd_set input, /* Input set for reading */
+ output; /* Output set for writing */
+ ssize_t print_bytes, /* Print bytes read */
+ bc_bytes, /* Backchannel bytes read */
+ total_bytes, /* Total bytes written */
+ bytes; /* Bytes written */
+ int dtrdsr; /* Do dtr/dsr flow control? */
+ int print_size; /* Size of output buffer for writes */
+ char print_buffer[8192], /* Print data buffer */
+ *print_ptr, /* Pointer into print data buffer */
+ bc_buffer[1024]; /* Back-channel data buffer */
+ struct termios opts; /* Serial port options */
+ struct termios origopts; /* Original port options */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Ignore SIGPIPE signals...
+ */
+
+#ifdef HAVE_SIGSET
+ sigset(SIGPIPE, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &action, NULL);
+#else
+ signal(SIGPIPE, SIG_IGN);
+#endif /* HAVE_SIGSET */
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc == 1)
+ {
+ list_devices();
+ return (CUPS_BACKEND_OK);
+ }
+ else if (argc < 6 || argc > 7)
+ {
+ fprintf(stderr, "Usage: %s job-id user title copies options [file]\n",
+ argv[0]);
+ return (CUPS_BACKEND_FAILED);
+ }
+
+ /*
+ * If we have 7 arguments, print the file named on the command-line.
+ * Otherwise, send stdin instead...
+ */
+
+ if (argc == 6)
+ {
+ print_fd = 0;
+ copies = 1;
+ }
+ else
+ {
+ /*
+ * Try to open the print file...
+ */
+
+ if ((print_fd = open(argv[6], O_RDONLY)) < 0)
+ {
+ perror("ERROR: Unable to open print file");
+ return (CUPS_BACKEND_FAILED);
+ }
+
+ copies = atoi(argv[4]);
+ }
+
+ /*
+ * Extract the device name and options from the URI...
+ */
+
+ httpSeparateURI(HTTP_URI_CODING_ALL, cupsBackendDeviceURI(argv),
+ method, sizeof(method), username, sizeof(username),
+ hostname, sizeof(hostname), &port,
+ resource, sizeof(resource));
+
+ /*
+ * See if there are any options...
+ */
+
+ if ((options = strchr(resource, '?')) != NULL)
+ {
+ /*
+ * Yup, terminate the device name string and move to the first
+ * character of the options...
+ */
+
+ *options++ = '\0';
+ }
+
+ /*
+ * Open the serial port device...
+ */
+
+ fputs("STATE: +connecting-to-device\n", stderr);
+
+ do
+ {
+ if ((device_fd = open(resource, O_RDWR | O_NOCTTY | O_EXCL |
+ O_NDELAY)) == -1)
+ {
+ if (getenv("CLASS") != NULL)
+ {
+ /*
+ * If the CLASS environment variable is set, the job was submitted
+ * to a class and not to a specific queue. In this case, we want
+ * to abort immediately so that the job can be requeued on the next
+ * available printer in the class.
+ */
+
+ fputs("INFO: Unable to contact printer, queuing on next printer in "
+ "class.\n", stderr);
+
+ /*
+ * Sleep 5 seconds to keep the job from requeuing too rapidly...
+ */
+
+ sleep(5);
+
+ return (CUPS_BACKEND_FAILED);
+ }
+
+ if (errno == EBUSY)
+ {
+ fputs("INFO: Printer busy; will retry in 30 seconds.\n", stderr);
+ sleep(30);
+ }
+ else
+ {
+ perror("ERROR: Unable to open serial port");
+ return (CUPS_BACKEND_FAILED);
+ }
+ }
+ }
+ while (device_fd < 0);
+
+ fputs("STATE: -connecting-to-device\n", stderr);
+
+ /*
+ * Set any options provided...
+ */
+
+ tcgetattr(device_fd, &origopts);
+ tcgetattr(device_fd, &opts);
+
+ opts.c_lflag &= ~(ICANON | ECHO | ISIG);
+ /* Raw mode */
+ opts.c_oflag &= ~OPOST; /* Don't post-process */
+
+ print_size = 96; /* 9600 baud / 10 bits/char / 10Hz */
+ dtrdsr = 0; /* No dtr/dsr flow control */
+
+ if (options)
+ {
+ while (*options)
+ {
+ /*
+ * Get the name...
+ */
+
+ name = options;
+
+ while (*options && *options != '=' && *options != '+' && *options != '&')
+ options ++;
+
+ if ((sep = *options) != '\0')
+ *options++ = '\0';
+
+ if (sep == '=')
+ {
+ /*
+ * Get the value...
+ */
+
+ value = options;
+
+ while (*options && *options != '+' && *options != '&')
+ options ++;
+
+ if (*options)
+ *options++ = '\0';
+ }
+ else
+ value = (char *)"";
+
+ /*
+ * Process the option...
+ */
+
+ if (!strcasecmp(name, "baud"))
+ {
+ /*
+ * Set the baud rate...
+ */
+
+ print_size = atoi(value) / 100;
+
+#if B19200 == 19200
+ cfsetispeed(&opts, atoi(value));
+ cfsetospeed(&opts, atoi(value));
+#else
+ switch (atoi(value))
+ {
+ case 1200 :
+ cfsetispeed(&opts, B1200);
+ cfsetospeed(&opts, B1200);
+ break;
+ case 2400 :
+ cfsetispeed(&opts, B2400);
+ cfsetospeed(&opts, B2400);
+ break;
+ case 4800 :
+ cfsetispeed(&opts, B4800);
+ cfsetospeed(&opts, B4800);
+ break;
+ case 9600 :
+ cfsetispeed(&opts, B9600);
+ cfsetospeed(&opts, B9600);
+ break;
+ case 19200 :
+ cfsetispeed(&opts, B19200);
+ cfsetospeed(&opts, B19200);
+ break;
+ case 38400 :
+ cfsetispeed(&opts, B38400);
+ cfsetospeed(&opts, B38400);
+ break;
+# ifdef B57600
+ case 57600 :
+ cfsetispeed(&opts, B57600);
+ cfsetospeed(&opts, B57600);
+ break;
+# endif /* B57600 */
+# ifdef B115200
+ case 115200 :
+ cfsetispeed(&opts, B115200);
+ cfsetospeed(&opts, B115200);
+ break;
+# endif /* B115200 */
+# ifdef B230400
+ case 230400 :
+ cfsetispeed(&opts, B230400);
+ cfsetospeed(&opts, B230400);
+ break;
+# endif /* B230400 */
+ default :
+ fprintf(stderr, "WARNING: Unsupported baud rate: %s\n", value);
+ break;
+ }
+#endif /* B19200 == 19200 */
+ }
+ else if (!strcasecmp(name, "bits"))
+ {
+ /*
+ * Set number of data bits...
+ */
+
+ switch (atoi(value))
+ {
+ case 7 :
+ opts.c_cflag &= ~CSIZE;
+ opts.c_cflag |= CS7;
+ opts.c_cflag |= PARENB;
+ opts.c_cflag &= ~PARODD;
+ break;
+ case 8 :
+ opts.c_cflag &= ~CSIZE;
+ opts.c_cflag |= CS8;
+ opts.c_cflag &= ~PARENB;
+ break;
+ }
+ }
+ else if (!strcasecmp(name, "parity"))
+ {
+ /*
+ * Set parity checking...
+ */
+
+ if (!strcasecmp(value, "even"))
+ {
+ opts.c_cflag |= PARENB;
+ opts.c_cflag &= ~PARODD;
+ }
+ else if (!strcasecmp(value, "odd"))
+ {
+ opts.c_cflag |= PARENB;
+ opts.c_cflag |= PARODD;
+ }
+ else if (!strcasecmp(value, "none"))
+ opts.c_cflag &= ~PARENB;
+ else if (!strcasecmp(value, "space"))
+ {
+ /*
+ * Note: we only support space parity with 7 bits per character...
+ */
+
+ opts.c_cflag &= ~CSIZE;
+ opts.c_cflag |= CS8;
+ opts.c_cflag &= ~PARENB;
+ }
+ else if (!strcasecmp(value, "mark"))
+ {
+ /*
+ * Note: we only support mark parity with 7 bits per character
+ * and 1 stop bit...
+ */
+
+ opts.c_cflag &= ~CSIZE;
+ opts.c_cflag |= CS7;
+ opts.c_cflag &= ~PARENB;
+ opts.c_cflag |= CSTOPB;
+ }
+ }
+ else if (!strcasecmp(name, "flow"))
+ {
+ /*
+ * Set flow control...
+ */
+
+ if (!strcasecmp(value, "none"))
+ {
+ opts.c_iflag &= ~(IXON | IXOFF);
+ opts.c_cflag &= ~CRTSCTS;
+ }
+ else if (!strcasecmp(value, "soft"))
+ {
+ opts.c_iflag |= IXON | IXOFF;
+ opts.c_cflag &= ~CRTSCTS;
+ }
+ else if (!strcasecmp(value, "hard") ||
+ !strcasecmp(value, "rtscts"))
+ {
+ opts.c_iflag &= ~(IXON | IXOFF);
+ opts.c_cflag |= CRTSCTS;
+ }
+ else if (!strcasecmp(value, "dtrdsr"))
+ {
+ opts.c_iflag &= ~(IXON | IXOFF);
+ opts.c_cflag &= ~CRTSCTS;
+
+ dtrdsr = 1;
+ }
+ }
+ else if (!strcasecmp(name, "stop"))
+ {
+ switch (atoi(value))
+ {
+ case 1 :
+ opts.c_cflag &= ~CSTOPB;
+ break;
+
+ case 2 :
+ opts.c_cflag |= CSTOPB;
+ break;
+ }
+ }
+ }
+ }
+
+ tcsetattr(device_fd, TCSANOW, &opts);
+ fcntl(device_fd, F_SETFL, 0);
+
+ /*
+ * Now that we are "connected" to the port, ignore SIGTERM so that we
+ * can finish out any page data the driver sends (e.g. to eject the
+ * current page... Only ignore SIGTERM if we are printing data from
+ * stdin (otherwise you can't cancel raw jobs...)
+ */
+
+ if (!print_fd)
+ {
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, SIG_IGN);
+#endif /* HAVE_SIGSET */
+ }
+
+ /*
+ * Figure out the maximum file descriptor value to use with select()...
+ */
+
+ nfds = (print_fd > device_fd ? print_fd : device_fd) + 1;
+
+ /*
+ * Finally, send the print file. Ordinarily we would just use the
+ * backendRunLoop() function, however since we need to use smaller
+ * writes and may need to do DSR/DTR flow control, we duplicate much
+ * of the code here instead...
+ */
+
+ if (print_size > sizeof(print_buffer))
+ print_size = sizeof(print_buffer);
+
+ total_bytes = 0;
+
+ while (copies > 0)
+ {
+ copies --;
+
+ if (print_fd != 0)
+ {
+ fputs("PAGE: 1 1\n", stderr);
+ lseek(print_fd, 0, SEEK_SET);
+ }
+
+ /*
+ * Now loop until we are out of data from print_fd...
+ */
+
+ for (print_bytes = 0, print_ptr = print_buffer;;)
+ {
+ /*
+ * Use select() to determine whether we have data to copy around...
+ */
+
+ FD_ZERO(&input);
+ if (!print_bytes)
+ FD_SET(print_fd, &input);
+ FD_SET(device_fd, &input);
+ if (!print_bytes && !side_eof)
+ FD_SET(CUPS_SC_FD, &input);
+
+ FD_ZERO(&output);
+ if (print_bytes)
+ FD_SET(device_fd, &output);
+
+ if (select(nfds, &input, &output, NULL, NULL) < 0)
+ continue; /* Ignore errors here */
+
+ /*
+ * Check if we have a side-channel request ready...
+ */
+
+ if (FD_ISSET(CUPS_SC_FD, &input))
+ {
+ /*
+ * Do the side-channel request, then start back over in the select
+ * loop since it may have read from print_fd...
+ */
+
+ if (side_cb(print_fd, device_fd, 1))
+ side_eof = 1;
+ continue;
+ }
+
+ /*
+ * Check if we have back-channel data ready...
+ */
+
+ if (FD_ISSET(device_fd, &input))
+ {
+ if ((bc_bytes = read(device_fd, bc_buffer, sizeof(bc_buffer))) > 0)
+ {
+ fprintf(stderr, "DEBUG: Received %d bytes of back-channel data.\n",
+ (int)bc_bytes);
+ cupsBackChannelWrite(bc_buffer, bc_bytes, 1.0);
+ }
+ }
+
+ /*
+ * Check if we have print data ready...
+ */
+
+ if (FD_ISSET(print_fd, &input))
+ {
+ if ((print_bytes = read(print_fd, print_buffer, print_size)) < 0)
+ {
+ /*
+ * Read error - bail if we don't see EAGAIN or EINTR...
+ */
+
+ if (errno != EAGAIN && errno != EINTR)
+ {
+ perror("DEBUG: Unable to read print data");
+
+ tcsetattr(device_fd, TCSADRAIN, &origopts);
+
+ close(device_fd);
+
+ if (print_fd != 0)
+ close(print_fd);
+
+ return (CUPS_BACKEND_FAILED);
+ }
+
+ print_bytes = 0;
+ }
+ else if (print_bytes == 0)
+ {
+ /*
+ * End of file, break out of the loop...
+ */
+
+ break;
+ }
+
+ print_ptr = print_buffer;
+ }
+
+ /*
+ * Check if the device is ready to receive data and we have data to
+ * send...
+ */
+
+ if (print_bytes && FD_ISSET(device_fd, &output))
+ {
+ if (dtrdsr)
+ {
+ /*
+ * Check the port and sleep until DSR is set...
+ */
+
+ int status;
+
+
+ if (!ioctl(device_fd, TIOCMGET, &status))
+ if (!(status & TIOCM_DSR))
+ {
+ /*
+ * Wait for DSR to go high...
+ */
+
+ fputs("DEBUG: DSR is low; waiting for device.\n", stderr);
+
+ do
+ {
+ /*
+ * Poll every 100ms...
+ */
+
+ usleep(100000);
+
+ if (ioctl(device_fd, TIOCMGET, &status))
+ break;
+ }
+ while (!(status & TIOCM_DSR));
+
+ fputs("DEBUG: DSR is high; writing to device.\n", stderr);
+ }
+ }
+
+ if ((bytes = write(device_fd, print_ptr, print_bytes)) < 0)
+ {
+ /*
+ * Write error - bail if we don't see an error we can retry...
+ */
+
+ if (errno != EAGAIN && errno != EINTR && errno != ENOTTY)
+ {
+ perror("DEBUG: Unable to write print data");
+
+ tcsetattr(device_fd, TCSADRAIN, &origopts);
+
+ close(device_fd);
+
+ if (print_fd != 0)
+ close(print_fd);
+
+ return (CUPS_BACKEND_FAILED);
+ }
+ }
+ else
+ {
+ fprintf(stderr, "DEBUG: Wrote %d bytes.\n", (int)bytes);
+
+ print_bytes -= bytes;
+ print_ptr += bytes;
+ total_bytes += bytes;
+ }
+ }
+ }
+ }
+
+ /*
+ * Close the serial port and input file and return...
+ */
+
+ tcsetattr(device_fd, TCSADRAIN, &origopts);
+
+ close(device_fd);
+
+ if (print_fd != 0)
+ close(print_fd);
+
+ return (CUPS_BACKEND_OK);
+}
+
+
+/*
+ * 'drain_output()' - Drain pending print data to the device.
+ */
+
+static int /* O - 0 on success, -1 on error */
+drain_output(int print_fd, /* I - Print file descriptor */
+ int device_fd) /* I - Device file descriptor */
+{
+ int nfds; /* Maximum file descriptor value + 1 */
+ fd_set input; /* Input set for reading */
+ ssize_t print_bytes, /* Print bytes read */
+ bytes; /* Bytes written */
+ char print_buffer[8192], /* Print data buffer */
+ *print_ptr; /* Pointer into print data buffer */
+ struct timeval timeout; /* Timeout for read... */
+
+
+ /*
+ * Figure out the maximum file descriptor value to use with select()...
+ */
+
+ nfds = (print_fd > device_fd ? print_fd : device_fd) + 1;
+
+ /*
+ * Now loop until we are out of data from print_fd...
+ */
+
+ for (;;)
+ {
+ /*
+ * Use select() to determine whether we have data to copy around...
+ */
+
+ FD_ZERO(&input);
+ FD_SET(print_fd, &input);
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+
+ if (select(nfds, &input, NULL, NULL, &timeout) < 0)
+ return (-1);
+
+ if (!FD_ISSET(print_fd, &input))
+ return (0);
+
+ if ((print_bytes = read(print_fd, print_buffer,
+ sizeof(print_buffer))) < 0)
+ {
+ /*
+ * Read error - bail if we don't see EAGAIN or EINTR...
+ */
+
+ if (errno != EAGAIN && errno != EINTR)
+ {
+ perror("ERROR: Unable to read print data");
+ return (-1);
+ }
+
+ print_bytes = 0;
+ }
+ else if (print_bytes == 0)
+ {
+ /*
+ * End of file, return...
+ */
+
+ return (0);
+ }
+
+ fprintf(stderr, "DEBUG: Read %d bytes of print data.\n",
+ (int)print_bytes);
+
+ for (print_ptr = print_buffer; print_bytes > 0;)
+ {
+ if ((bytes = write(device_fd, print_ptr, print_bytes)) < 0)
+ {
+ /*
+ * Write error - bail if we don't see an error we can retry...
+ */
+
+ if (errno != ENOSPC && errno != ENXIO && errno != EAGAIN &&
+ errno != EINTR && errno != ENOTTY)
+ {
+ perror("ERROR: Unable to write print data");
+ return (-1);
+ }
+ }
+ else
+ {
+ fprintf(stderr, "DEBUG: Wrote %d bytes of print data.\n", (int)bytes);
+
+ print_bytes -= bytes;
+ print_ptr += bytes;
+ }
+ }
+ }
+}
+
+
+/*
+ * 'list_devices()' - List all serial devices.
+ */
+
+static void
+list_devices(void)
+{
+#if defined(__sun) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
+ static char *funky_hex = "0123456789abcdefghijklmnopqrstuvwxyz";
+ /* Funky hex numbering used for some *
+ * devices */
+#endif /* __sun || __FreeBSD__ || __OpenBSD__ || __FreeBSD_kernel__ */
+
+
+#ifdef __linux
+ int i, j; /* Looping vars */
+ int fd; /* File descriptor */
+ char device[255]; /* Device filename */
+ char info[255]; /* Device info/description */
+# ifdef TIOCGSERIAL
+ struct serial_struct serinfo; /* serial port info */
+# endif /* TIOCGSERIAL */
+
+
+ for (i = 0; i < 100; i ++)
+ {
+ sprintf(device, "/dev/ttyS%d", i);
+
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+# ifdef TIOCGSERIAL
+ /*
+ * See if this port exists...
+ */
+
+ serinfo.reserved_char[0] = 0;
+
+ if (!ioctl(fd, TIOCGSERIAL, &serinfo))
+ {
+ if (serinfo.type == PORT_UNKNOWN)
+ {
+ /*
+ * Nope...
+ */
+
+ close(fd);
+ continue;
+ }
+ }
+# endif /* TIOCGSERIAL */
+
+ close(fd);
+
+ snprintf(info, sizeof(info), "Serial Port #%d", i + 1);
+
+# if defined(_ARCH_PPC) || defined(powerpc) || defined(__powerpc)
+ printf("serial serial:%s?baud=230400 \"Unknown\" \"%s\"\n", device, info);
+# else
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", device, info);
+# endif /* _ARCH_PPC || powerpc || __powerpc */
+ }
+ }
+
+ for (i = 0; i < 16; i ++)
+ {
+ snprintf(info, sizeof(info), "USB Serial Port #%d", i + 1);
+
+ sprintf(device, "/dev/usb/ttyUSB%d", i);
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+ close(fd);
+ printf("serial serial:%s?baud=230400 \"Unknown\" \"%s\"\n", device, info);
+ }
+
+ sprintf(device, "/dev/ttyUSB%d", i);
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+ close(fd);
+ printf("serial serial:%s?baud=230400 \"Unknown\" \"%s\"\n", device, info);
+ }
+ }
+
+ for (i = 0; i < 64; i ++)
+ {
+ for (j = 0; j < 8; j ++)
+ {
+ sprintf(device, "/dev/ttyQ%02de%d", i, j);
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+ close(fd);
+
+ printf("serial serial:%s?baud=115200 \"Unknown\" "
+ "\"Equinox ESP %d Port #%d\"\n", device, i, j + 1);
+ }
+ }
+ }
+#elif defined(__sun)
+ int i, j, n; /* Looping vars */
+ char device[255]; /* Device filename */
+ char info[255]; /* Device info/description */
+
+
+ /*
+ * Standard serial ports...
+ */
+
+ for (i = 0; i < 26; i ++)
+ {
+ sprintf(device, "/dev/cua/%c", 'a' + i);
+ if (!access(device, 0))
+ {
+ snprintf(info, sizeof(info), "Serial Port #%d", i + 1);
+
+# ifdef B115200
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", device, info);
+# else
+ printf("serial serial:%s?baud=38400 \"Unknown\" \"%s\"\n", device, info);
+# endif /* B115200 */
+ }
+ }
+
+ /*
+ * MAGMA serial ports...
+ */
+
+ for (i = 0; i < 40; i ++)
+ {
+ sprintf(device, "/dev/term/%02d", i);
+ if (access(device, 0) == 0)
+ printf("serial serial:%s?baud=38400 \"Unknown\" \"MAGMA Serial Board #%d Port #%d\"\n",
+ device, (i / 10) + 1, (i % 10) + 1);
+ }
+
+ /*
+ * Central Data serial ports...
+ */
+
+ for (i = 0; i < 9; i ++)
+ for (j = 0; j < 8; j ++)
+ for (n = 0; n < 32; n ++)
+ {
+ if (i == 8) /* EtherLite */
+ sprintf(device, "/dev/sts/ttyN%d%c", j, funky_hex[n]);
+ else
+ sprintf(device, "/dev/sts/tty%c%d%c", i + 'C', j,
+ funky_hex[n]);
+
+ if (access(device, 0) == 0)
+ {
+ if (i == 8)
+ printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data EtherLite Serial Port, ID %d, port %d\"\n",
+ device, j, n);
+ else
+ printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data SCSI Serial Port, logical bus %d, ID %d, port %d\"\n",
+ device, i, j, n);
+ }
+ }
+#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
+ int i, j; /* Looping vars */
+ int fd; /* File descriptor */
+ char device[255]; /* Device filename */
+ char info[255]; /* Device info/description */
+
+
+ /*
+ * SIO ports...
+ */
+
+ for (i = 0; i < 32; i ++)
+ {
+ sprintf(device, "/dev/ttyd%c", funky_hex[i]);
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+ close(fd);
+
+ snprintf(info, sizeof(info), "Serial Port #%d", i + 1);
+
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", device, info);
+ }
+ }
+
+ /*
+ * Cyclades ports...
+ */
+
+ for (i = 0; i < 16; i ++) /* Should be up to 65536 boards... */
+ for (j = 0; j < 32; j ++)
+ {
+ sprintf(device, "/dev/ttyc%d%c", i, funky_hex[j]);
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+ close(fd);
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"Cyclades #%d Serial Port #%d\"\n",
+ device, i, j + 1);
+ }
+
+ sprintf(device, "/dev/ttyC%d%c", i, funky_hex[j]);
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+ close(fd);
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"Cyclades #%d Serial Port #%d\"\n",
+ device, i, j + 1);
+ }
+ }
+
+ /*
+ * Digiboard ports...
+ */
+
+ for (i = 0; i < 16; i ++) /* Should be up to 65536 boards... */
+ for (j = 0; j < 32; j ++)
+ {
+ sprintf(device, "/dev/ttyD%d%c", i, funky_hex[j]);
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+ close(fd);
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"Digiboard #%d Serial Port #%d\"\n",
+ device, i, j + 1);
+ }
+ }
+
+ /*
+ * Stallion ports...
+ */
+
+ for (i = 0; i < 32; i ++)
+ {
+ sprintf(device, "/dev/ttyE%c", funky_hex[i]);
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+ close(fd);
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"Stallion Serial Port #%d\"\n",
+ device, i + 1);
+ }
+ }
+
+ /*
+ * SX ports...
+ */
+
+ for (i = 0; i < 128; i ++)
+ {
+ sprintf(device, "/dev/ttyA%d", i + 1);
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+ close(fd);
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"SX Serial Port #%d\"\n",
+ device, i + 1);
+ }
+ }
+#elif defined(__NetBSD__)
+ int i, j; /* Looping vars */
+ int fd; /* File descriptor */
+ char device[255]; /* Device filename */
+ char info[255]; /* Device info/description */
+
+
+ /*
+ * Standard serial ports...
+ */
+
+ for (i = 0; i < 4; i ++)
+ {
+ sprintf(device, "/dev/tty%02d", i);
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+ close(fd);
+
+ snprintf(info, sizeof(info), "Serial Port #%d", i + 1);
+
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", device, info);
+ }
+ }
+
+ /*
+ * Cyclades-Z ports...
+ */
+
+ for (i = 0; i < 16; i ++) /* Should be up to 65536 boards... */
+ for (j = 0; j < 64; j ++)
+ {
+ sprintf(device, "/dev/ttyCZ%02d%02d", i, j);
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+ close(fd);
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"Cyclades #%d Serial Prt #%d\"\n",
+ device, i, j + 1);
+ }
+ }
+#elif defined(__APPLE__)
+ /*
+ * Standard serial ports on MacOS X...
+ */
+
+ kern_return_t kernResult;
+ mach_port_t masterPort;
+ io_iterator_t serialPortIterator;
+ CFMutableDictionaryRef classesToMatch;
+ io_object_t serialService;
+
+
+ kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort);
+ if (KERN_SUCCESS != kernResult)
+ return;
+
+ /*
+ * Serial devices are instances of class IOSerialBSDClient.
+ */
+
+ classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue);
+ if (classesToMatch != NULL)
+ {
+ CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey),
+ CFSTR(kIOSerialBSDRS232Type));
+
+ kernResult = IOServiceGetMatchingServices(masterPort, classesToMatch,
+ &serialPortIterator);
+ if (kernResult == KERN_SUCCESS)
+ {
+ while ((serialService = IOIteratorNext(serialPortIterator)))
+ {
+ CFTypeRef serialNameAsCFString;
+ CFTypeRef bsdPathAsCFString;
+ CFTypeRef hiddenVal;
+ char serialName[128];
+ char bsdPath[1024];
+ Boolean result;
+
+
+ /* Check if hidden... */
+ hiddenVal = IORegistryEntrySearchCFProperty(serialService,
+ kIOServicePlane,
+ CFSTR("HiddenPort"),
+ kCFAllocatorDefault,
+ kIORegistryIterateRecursively |
+ kIORegistryIterateParents);
+ if (hiddenVal)
+ CFRelease(hiddenVal); /* This interface should not be used */
+ else
+ {
+ serialNameAsCFString =
+ IORegistryEntryCreateCFProperty(serialService,
+ CFSTR(kIOTTYDeviceKey),
+ kCFAllocatorDefault, 0);
+ if (serialNameAsCFString)
+ {
+ result = CFStringGetCString(serialNameAsCFString, serialName,
+ sizeof(serialName),
+ kCFStringEncodingASCII);
+ CFRelease(serialNameAsCFString);
+
+ if (result)
+ {
+ bsdPathAsCFString =
+ IORegistryEntryCreateCFProperty(serialService,
+ CFSTR(kIOCalloutDeviceKey),
+ kCFAllocatorDefault, 0);
+ if (bsdPathAsCFString)
+ {
+ result = CFStringGetCString(bsdPathAsCFString, bsdPath,
+ sizeof(bsdPath),
+ kCFStringEncodingASCII);
+ CFRelease(bsdPathAsCFString);
+
+ if (result)
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n",
+ bsdPath, serialName);
+ }
+ }
+ }
+ }
+
+ IOObjectRelease(serialService);
+ }
+
+ /*
+ * Release the iterator.
+ */
+
+ IOObjectRelease(serialPortIterator);
+ }
+ }
+#endif
+}
+
+
+/*
+ * 'side_cb()' - Handle side-channel requests...
+ */
+
+static int /* O - 0 on success, -1 on error */
+side_cb(int print_fd, /* I - Print file */
+ int device_fd, /* I - Device file */
+ int use_bc) /* I - Using back-channel? */
+{
+ cups_sc_command_t command; /* Request command */
+ cups_sc_status_t status; /* Request/response status */
+ char data[2048]; /* Request/response data */
+ int datalen; /* Request/response data size */
+
+
+ datalen = sizeof(data);
+
+ if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0))
+ return (-1);
+
+ switch (command)
+ {
+ case CUPS_SC_CMD_DRAIN_OUTPUT :
+ if (drain_output(print_fd, device_fd))
+ status = CUPS_SC_STATUS_IO_ERROR;
+ else if (tcdrain(device_fd))
+ status = CUPS_SC_STATUS_IO_ERROR;
+ else
+ status = CUPS_SC_STATUS_OK;
+
+ datalen = 0;
+ break;
+
+ case CUPS_SC_CMD_GET_BIDI :
+ status = CUPS_SC_STATUS_OK;
+ data[0] = use_bc;
+ datalen = 1;
+ break;
+
+ default :
+ status = CUPS_SC_STATUS_NOT_IMPLEMENTED;
+ datalen = 0;
+ break;
+ }
+
+ return (cupsSideChannelWrite(command, status, data, datalen, 1.0));
+}
diff --git a/backend/test1284.c b/backend/test1284.c
new file mode 100644
index 000000000..dab2f533c
--- /dev/null
+++ b/backend/test1284.c
@@ -0,0 +1,76 @@
+/*
+ * IEEE-1284 support functions test program for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * main() - Test the device-ID functions.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include <config.h>
+#include <string.h>
+#include <ctype.h>
+#ifdef WIN32
+# include <io.h>
+#else
+# include <unistd.h>
+# include <fcntl.h>
+#endif /* WIN32 */
+
+#include "backend-private.h"
+
+
+/*
+ * 'main()' - Test the device-ID functions.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line args */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i, /* Looping var */
+ fd; /* File descriptor */
+ char device_id[1024], /* 1284 device ID string */
+ make_model[1024], /* make-and-model string */
+ uri[1024]; /* URI string */
+
+
+ if (argc < 2)
+ {
+ puts("Usage: test1284 device-file [... device-file-N]");
+ exit(1);
+ }
+
+ for (i = 1; i < argc; i ++)
+ {
+ if ((fd = open(argv[i], O_RDWR)) < 0)
+ {
+ perror(argv[i]);
+ return (errno);
+ }
+
+ printf("%s:\n", argv[i]);
+
+ backendGetDeviceID(fd, device_id, sizeof(device_id), make_model,
+ sizeof(make_model), "test", uri, sizeof(uri));
+
+ printf(" device_id=\"%s\"\n", device_id);
+ printf(" make_model=\"%s\"\n", make_model);
+ printf(" uri=\"%s\"\n", uri);
+
+ close(fd);
+ }
+
+ return (0);
+}
diff --git a/banners/classified b/banners/classified
new file mode 100644
index 000000000..2de5c1c38
--- /dev/null
+++ b/banners/classified
@@ -0,0 +1,4 @@
+#PDF-BANNER
+Template classified.pdf
+Show printer-name printer-info printer-location printer-make-and-model printer-driver-name printer-driver-version paper-size imageable-area job-id options time-at-creation time-at-processing
+
diff --git a/banners/confidential b/banners/confidential
new file mode 100644
index 000000000..5d404ab0e
--- /dev/null
+++ b/banners/confidential
@@ -0,0 +1,4 @@
+#PDF-BANNER
+Template confidential.pdf
+Show printer-name printer-info printer-location printer-make-and-model printer-driver-name printer-driver-version paper-size imageable-area job-id options time-at-creation time-at-processing
+
diff --git a/banners/form b/banners/form
new file mode 100644
index 000000000..b1e862cd6
--- /dev/null
+++ b/banners/form
@@ -0,0 +1,4 @@
+#PDF-BANNER
+Template form_english.pdf
+Font UseDefault
+Font-size 11
diff --git a/banners/secret b/banners/secret
new file mode 100644
index 000000000..579d68a14
--- /dev/null
+++ b/banners/secret
@@ -0,0 +1,4 @@
+#PDF-BANNER
+Template secret.pdf
+Show printer-name printer-info printer-location printer-make-and-model printer-driver-name printer-driver-version paper-size imageable-area job-id options time-at-creation time-at-processing
+
diff --git a/banners/standard b/banners/standard
new file mode 100644
index 000000000..788dc8d5d
--- /dev/null
+++ b/banners/standard
@@ -0,0 +1,4 @@
+#PDF-BANNER
+Template standard.pdf
+Show printer-name printer-info printer-location printer-make-and-model printer-driver-name printer-driver-version paper-size imageable-area job-id options time-at-creation time-at-processing
+
diff --git a/banners/topsecret b/banners/topsecret
new file mode 100644
index 000000000..76aefac23
--- /dev/null
+++ b/banners/topsecret
@@ -0,0 +1,4 @@
+#PDF-BANNER
+Template topsecret.pdf
+Show printer-name printer-info printer-location printer-make-and-model printer-driver-name printer-driver-version paper-size imageable-area job-id options time-at-creation time-at-processing
+
diff --git a/banners/unclassified b/banners/unclassified
new file mode 100644
index 000000000..696c100fb
--- /dev/null
+++ b/banners/unclassified
@@ -0,0 +1,4 @@
+#PDF-BANNER
+Template unclassified.pdf
+Show printer-name printer-info printer-location printer-make-and-model printer-driver-name printer-driver-version paper-size imageable-area job-id options time-at-creation time-at-processing
+
diff --git a/charset/pdf.utf-8.heavy b/charset/pdf.utf-8.heavy
new file mode 100644
index 000000000..a610af01f
--- /dev/null
+++ b/charset/pdf.utf-8.heavy
@@ -0,0 +1,40 @@
+charset utf8
+
+#
+# This file defines the font mappings used for Unicode/UTF-8 text printing
+# through PDF.
+#
+# Each line consists of:
+#
+# first last direction width normal bold italic bold-italic
+#
+# First and last are the first and last glyphs in the font mapping
+# that correspond to that font; contrary to PostScript printing
+# they only select the font. To find the glyph the complete unicode
+# character will be looked up in the (3,1) resp. (3,0) cmap of the
+# TrueType font. The glyph values are hexadecimal.
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+0000 00FF ltor single CourierNew CourierNew:bold CourierNew:italic CourierNew:bold:italic
+0100 02FF ltor single DejaVuSansMono DejaVuSansMono:bold DejaVuSansMono:oblique DejaVuSansMono:bold:oblique
+0300 03FF ltor single DejaVuSansMono
+0400 04FF ltor single DejaVuSansMono DejaVuSansMono:bold DejaVuSansMono:oblique DejaVuSansMono:bold:oblique
+0500 05FF rtol single FreeMono
+1E00 1EFF ltor single CourierNew CourierNew:bold CourierNew:italic CourierNew:bold:italic
+2000 21FF ltor single DejaVuSansMono DejaVuSansMono:bold DejaVuSansMono:oblique DejaVuSansMono:bold:oblique
+2200 23FF ltor single Symbol
+3000 9FFF ltor double ARPLUMingCN
+#0400 04FF ltor single FreeMono FreeMono:bold FreeMono:oblique FreeMono:bold:oblique
diff --git a/charset/pdf.utf-8.simple b/charset/pdf.utf-8.simple
new file mode 100644
index 000000000..1280f25c8
--- /dev/null
+++ b/charset/pdf.utf-8.simple
@@ -0,0 +1,32 @@
+charset utf8
+
+#
+# This file defines the font mappings used for Unicode/UTF-8 text printing
+# through PDF.
+#
+# Each line consists of:
+#
+# first last direction width normal bold italic bold-italic
+#
+# First and last are the first and last glyphs in the font mapping
+# that correspond to that font; contrary to PostScript printing
+# they only select the font. To find the glyph the complete unicode
+# character will be looked up in the (3,1) resp. (3,0) cmap of the
+# TrueType font. The glyph values are hexadecimal.
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+0000 04FF ltor single monospace monospace:bold monospace:oblique monospace:bold:oblique
+0500 05FF rtol single monospace
diff --git a/compile b/compile
new file mode 100755
index 000000000..a85b723c7
--- /dev/null
+++ b/compile
@@ -0,0 +1,347 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-10-14.11; # UTC
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" "" $nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+ file=$1
+ case $file in
+ / | /[!/]*) # absolute file, and not a UNC file
+ if test -z "$file_conv"; then
+ # lazily determine how to convert abs files
+ case `uname -s` in
+ MINGW*)
+ file_conv=mingw
+ ;;
+ CYGWIN*)
+ file_conv=cygwin
+ ;;
+ *)
+ file_conv=wine
+ ;;
+ esac
+ fi
+ case $file_conv/,$2, in
+ *,$file_conv,*)
+ ;;
+ mingw/*)
+ file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+ ;;
+ cygwin/*)
+ file=`cygpath -m "$file" || echo "$file"`
+ ;;
+ wine/*)
+ file=`winepath -w "$file" || echo "$file"`
+ ;;
+ esac
+ ;;
+ esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+ func_file_conv "$1"
+ if test -z "$lib_path"; then
+ lib_path=$file
+ else
+ lib_path="$lib_path;$file"
+ fi
+ linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+ lib=$1
+ found=no
+ save_IFS=$IFS
+ IFS=';'
+ for dir in $lib_path $LIB
+ do
+ IFS=$save_IFS
+ if $shared && test -f "$dir/$lib.dll.lib"; then
+ found=yes
+ lib=$dir/$lib.dll.lib
+ break
+ fi
+ if test -f "$dir/$lib.lib"; then
+ found=yes
+ lib=$dir/$lib.lib
+ break
+ fi
+ if test -f "$dir/lib$lib.a"; then
+ found=yes
+ lib=$dir/lib$lib.a
+ break
+ fi
+ done
+ IFS=$save_IFS
+
+ if test "$found" != yes; then
+ lib=$lib.lib
+ fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+ # Assume a capable shell
+ lib_path=
+ shared=:
+ linker_opts=
+ for arg
+ do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as 'compile cc -o foo foo.c'.
+ eat=1
+ case $2 in
+ *.o | *.[oO][bB][jJ])
+ func_file_conv "$2"
+ set x "$@" -Fo"$file"
+ shift
+ ;;
+ *)
+ func_file_conv "$2"
+ set x "$@" -Fe"$file"
+ shift
+ ;;
+ esac
+ ;;
+ -I)
+ eat=1
+ func_file_conv "$2" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
+ -I*)
+ func_file_conv "${1#-I}" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
+ -l)
+ eat=1
+ func_cl_dashl "$2"
+ set x "$@" "$lib"
+ shift
+ ;;
+ -l*)
+ func_cl_dashl "${1#-l}"
+ set x "$@" "$lib"
+ shift
+ ;;
+ -L)
+ eat=1
+ func_cl_dashL "$2"
+ ;;
+ -L*)
+ func_cl_dashL "${1#-L}"
+ ;;
+ -static)
+ shared=false
+ ;;
+ -Wl,*)
+ arg=${1#-Wl,}
+ save_ifs="$IFS"; IFS=','
+ for flag in $arg; do
+ IFS="$save_ifs"
+ linker_opts="$linker_opts $flag"
+ done
+ IFS="$save_ifs"
+ ;;
+ -Xlinker)
+ eat=1
+ linker_opts="$linker_opts $2"
+ ;;
+ -*)
+ set x "$@" "$1"
+ shift
+ ;;
+ *.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+ func_file_conv "$1"
+ set x "$@" -Tp"$file"
+ shift
+ ;;
+ *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+ func_file_conv "$1" mingw
+ set x "$@" "$file"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+ done
+ if test -n "$linker_opts"; then
+ linker_opts="-link$linker_opts"
+ fi
+ exec "$@" $linker_opts
+ exit 1
+}
+
+eat=
+
+case $1 in
+ '')
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "compile $scriptversion"
+ exit $?
+ ;;
+ cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+ func_cl_wrapper "$@" # Doesn't return...
+ ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as 'compile cc -o foo foo.c'.
+ # So we strip '-o arg' only if arg is an object.
+ eat=1
+ case $2 in
+ *.o | *.obj)
+ ofile=$2
+ ;;
+ *)
+ set x "$@" -o "$2"
+ shift
+ ;;
+ esac
+ ;;
+ *.c)
+ cfile=$1
+ set x "$@" "$1"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+ # If no '-o' option was seen then we might have been invoked from a
+ # pattern rule where we don't need one. That is ok -- this is a
+ # normal compilation that the losing compiler can handle. If no
+ # '.c' file was seen then we are probably linking. That is also
+ # ok.
+ exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file. Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+ if mkdir "$lockdir" >/dev/null 2>&1; then
+ break
+ fi
+ sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+ test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+ test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# 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/config.guess b/config.guess
new file mode 100755
index 000000000..2e9ad7fe8
--- /dev/null
+++ b/config.guess
@@ -0,0 +1,1462 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright 1992-2016 Free Software Foundation, Inc.
+
+timestamp='2016-10-02'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This 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/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+#
+# Please send patches to <config-patches@gnu.org>.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright 1992-2016 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."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ LIBC=gnu
+
+ eval $set_cc_for_build
+ cat <<-EOF > $dummy.c
+ #include <features.h>
+ #if defined(__UCLIBC__)
+ LIBC=uclibc
+ #elif defined(__dietlibc__)
+ LIBC=dietlibc
+ #else
+ LIBC=gnu
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ ;;
+esac
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+ /sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || \
+ echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ earmv*)
+ arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+ endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
+ machine=${arch}${endian}-unknown
+ ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently (or will in the future) and ABI.
+ case "${UNAME_MACHINE_ARCH}" in
+ earm*)
+ os=netbsdelf
+ ;;
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ELF__
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # Determine ABI tags.
+ case "${UNAME_MACHINE_ARCH}" in
+ earm*)
+ expr='s/^earmv[0-9]/-eabi/;s/eb$//'
+ abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}${abi}"
+ exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:LibertyBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:Sortix:*:*)
+ echo ${UNAME_MACHINE}-unknown-sortix
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE=alpha ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE=alpha ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE=alpha ;;
+ "EV5 (21164)")
+ UNAME_MACHINE=alphaev5 ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE=alphaev56 ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE=alphapca56 ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE=alphapca57 ;;
+ "EV6 (21264)")
+ UNAME_MACHINE=alphaev6 ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE=alphaev67 ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE=alphaev68 ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE=alphaev68 ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE=alphaev68 ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE=alphaev69 ;;
+ "EV7 (21364)")
+ UNAME_MACHINE=alphaev7 ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE=alphaev79 ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH=i386
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH=x86_64
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/lslpp ] ; then
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH=hppa2.0n ;;
+ 64) HP_ARCH=hppa2.0w ;;
+ '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = hppa2.0w ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+ HP_ARCH=hppa2.0w
+ else
+ HP_ARCH=hppa64
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW64*:*)
+ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ *:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ cris:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ crisv32:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ e2k:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ frv:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ hexagon:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:Linux:*:*)
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ k1om:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ ;;
+ mips64el:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ openrisc*:Linux:*:*)
+ echo or1k-unknown-linux-${LIBC}
+ exit ;;
+ or32:Linux:*:* | or1k*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-${LIBC}
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-${LIBC}
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+ *) echo hppa-unknown-linux-${LIBC} ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-${LIBC}
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-${LIBC}
+ exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-${LIBC}
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
+ exit ;;
+ riscv32:Linux:*:* | riscv64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ exit ;;
+ x86_64:Linux:*:*)
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configure will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-ACE:SUPER-UX:*:*)
+ echo sxace-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ eval $set_cc_for_build
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ fi
+ elif test "$UNAME_PROCESSOR" = i386 ; then
+ # Avoid executing cc on OS X 10.9, as it ships with a stub
+ # that puts up a graphical alert prompting to install
+ # developer tools. Any system running Mac OS X 10.7 or
+ # later (Darwin 11 and later) is required to have a 64-bit
+ # processor. This is not true of the ARM version of Darwin
+ # that Apple uses in portable devices.
+ UNAME_PROCESSOR=x86_64
+ fi
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = x86; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-*:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = 386; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'`
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
+ amd64:Isilon\ OneFS:*:*)
+ echo x86_64-unknown-onefs
+ exit ;;
+esac
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script (version $timestamp), has failed to recognize the
+operating system you are using. If your script is old, overwrite
+config.guess and config.sub with the latest versions from:
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+
+If $0 has already been updated, send the following data and any
+information you think might be pertinent to config-patches@gnu.org to
+provide the necessary information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config.h.in b/config.h.in
new file mode 100644
index 000000000..59afb6114
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,270 @@
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Directory where bannertopdf finds its data files (PDF templates) */
+#undef BANNERTOPDF_DATADIR
+
+/* CUPS Version is 1.4 or newer */
+#undef CUPS_1_4
+
+/* acroread binary to use. */
+#undef CUPS_ACROREAD
+
+/* CUPS datadir */
+#undef CUPS_DATADIR
+
+/* "Domain socket of CUPS" */
+#undef CUPS_DEFAULT_DOMAINSOCKET
+
+/* Path to CUPS fonts dir */
+#undef CUPS_FONTPATH
+
+/* gs binary to use */
+#undef CUPS_GHOSTSCRIPT
+
+/* ippfind binary to use. */
+#undef CUPS_IPPFIND
+
+/* mutool binary to use */
+#undef CUPS_MUTOOL
+
+/* max resolution used for pdftops when converting images */
+#undef CUPS_PDFTOPS_MAX_RESOLUTION
+
+/* Define default renderer */
+#undef CUPS_PDFTOPS_RENDERER
+
+/* pdftocairo binary to use. */
+#undef CUPS_POPPLER_PDFTOCAIRO
+
+/* pdftops binary to use. */
+#undef CUPS_POPPLER_PDFTOPS
+
+/* Path to CUPS binaries dir */
+#undef CUPS_SERVERBIN
+
+/* CUPS serverroot */
+#undef CUPS_SERVERROOT
+
+/* Transient run-time state dir of CUPS */
+#undef CUPS_STATEDIR
+
+/* Auto-setup driverless IPP network printers? */
+#undef DRIVERLESS_IPP_PRINTERS_AUTO_SETUP
+
+/* Define if you have the avahi library */
+#undef HAVE_AVAHI
+
+/* Define if you have Poppler's "cpp/poppler-version.h" header file. */
+#undef HAVE_CPP_POPPLER_VERSION_H
+
+/* define if the compiler supports basic C++11 syntax */
+#undef HAVE_CXX11
+
+/* Define to 1 if you have the <dirent.h> header file. */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <endian.h> header file. */
+#undef HAVE_ENDIAN_H
+
+/* Have FreeType2 include files */
+#undef HAVE_FREETYPE_H
+
+/* Define to 1 if you have the `getline' function. */
+#undef HAVE_GETLINE
+
+/* Define that we provide ghostscript binary */
+#undef HAVE_GHOSTSCRIPT
+
+/* gs supports ps2write */
+#undef HAVE_GHOSTSCRIPT_PS2WRITE
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <jpeglib.h> header file. */
+#undef HAVE_JPEGLIB_H
+
+/* Define if LDAP support should be enabled */
+#undef HAVE_LDAP
+
+/* If libldap implements ldap_set_rebind_proc */
+#undef HAVE_LDAP_REBIND_PROC
+
+/* If LDAP has SSL/TLS support enabled */
+#undef HAVE_LDAP_SSL
+
+/* Define to 1 if you have the <ldap_ssl.h> header file. */
+#undef HAVE_LDAP_SSL_H
+
+/* Defines if we provide jpeg library. */
+#undef HAVE_LIBJPEG
+
+/* Defines if we provide png library. */
+#undef HAVE_LIBPNG
+
+/* Defines if we provide tiff library. */
+#undef HAVE_LIBTIFF
+
+/* Define that we use zlib */
+#undef HAVE_LIBZ
+
+/* Platform supports long long type */
+#undef HAVE_LONG_LONG
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* If LDAP support is that of Mozilla */
+#undef HAVE_MOZILLA_LDAP
+
+/* If LDAP support is that of OpenLDAP */
+#undef HAVE_OPENLDAP
+
+/* Define to 1 if you have the `open_memstream' function. */
+#undef HAVE_OPEN_MEMSTREAM
+
+/* Define that we provide poppler pdftops. */
+#undef HAVE_POPPLER_PDFTOPS
+
+/* pdftops supports -origpagesizes. */
+#undef HAVE_POPPLER_PDFTOPS_WITH_ORIGPAGESIZES
+
+/* pdftops supports -r argument. */
+#undef HAVE_POPPLER_PDFTOPS_WITH_RESOLUTION
+
+/* Define to 1 if you have the <qpdf/Pl_RunLength.hh> header file. */
+#undef HAVE_QPDF_PL_RUNLENGTH_HH
+
+/* Define to 1 if you have the `sigaction' function. */
+#undef HAVE_SIGACTION
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strcasestr' function. */
+#undef HAVE_STRCASESTR
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strlcat' function. */
+#undef HAVE_STRLCAT
+
+/* Define to 1 if you have the `strlcpy' function. */
+#undef HAVE_STRLCPY
+
+/* Define to 1 if you have the `strtoll' function. */
+#undef HAVE_STRTOLL
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <tiff.h> header file. */
+#undef HAVE_TIFF_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `wait3' function. */
+#undef HAVE_WAIT3
+
+/* Define to 1 if you have the `waitpid' function. */
+#undef HAVE_WAITPID
+
+/* Define to 1 if you have the <zlib.h> header file. */
+#undef HAVE_ZLIB_H
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#undef LT_OBJDIR
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Needed for pdftopdf filter compilation */
+#undef PDFTOPDF
+
+/* QPDF has PCLm support? */
+#undef QPDF_HAVE_PCLM
+
+/* Path for a modern shell */
+#undef SHELL
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Path to font used in tests */
+#undef TESTFONT
+
+/* Defines if use lcms1 */
+#undef USE_LCMS1
+
+/* Version number of package */
+#undef VERSION
+
+/* Enable large inode numbers on Mac OS X 10.5. */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
+
+#ifdef HAVE_LONG_LONG
+# define CUPS_LLFMT "%lld"
+# define CUPS_LLCAST (long long)
+#else
+# define CUPS_LLFMT "%ld"
+# define CUPS_LLCAST (long)
+#endif /* HAVE_LONG_LONG */
+
+#ifdef HAVE_ARC4RANDOM
+# define CUPS_RAND() arc4random()
+# define CUPS_SRAND(v) arc4random_stir()
+#elif defined(HAVE_RANDOM)
+# define CUPS_RAND() random()
+# define CUPS_SRAND(v) srandom(v)
+#elif defined(HAVE_LRAND48)
+# define CUPS_RAND() lrand48()
+# define CUPS_SRAND(v) srand48(v)
+#else
+# define CUPS_RAND() rand()
+# define CUPS_SRAND(v) srand(v)
+#endif /* HAVE_ARC4RANDOM */
+
diff --git a/config.sub b/config.sub
new file mode 100755
index 000000000..dd2ca93c6
--- /dev/null
+++ b/config.sub
@@ -0,0 +1,1825 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright 1992-2016 Free Software Foundation, Inc.
+
+timestamp='2016-11-04'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This 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/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2016 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."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
+ kopensolaris*-gnu* | cloudabi*-eabi* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze*)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arceb \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | ba \
+ | be32 | be64 \
+ | bfin \
+ | c4x | c8051 | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | e2k | epiphany \
+ | fido | fr30 | frv | ft32 \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | k1om \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r6 | mipsisa32r6el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r6 | mipsisa64r6el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 | nios2eb | nios2el \
+ | ns16k | ns32k \
+ | open8 | or1k | or1knd | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pru \
+ | pyramid \
+ | riscv32 | riscv64 \
+ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | visium \
+ | we32k \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ leon|leon[3-9])
+ basic_machine=sparc-$basic_machine
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | ba-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | e2k-* | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | k1om-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa32r6-* | mipsisa32r6el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64r6-* | mipsisa64r6el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | or1k*-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pru-* \
+ | pyramid-* \
+ | riscv32-* | riscv64-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | visium-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ asmjs)
+ basic_machine=asmjs-unknown
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ e500v[12])
+ basic_machine=powerpc-unknown
+ os=$os"spe"
+ ;;
+ e500v[12]-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=$os"spe"
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ leon-*|leon[3-9]-*)
+ basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
+ mingw32)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ moxiebox)
+ basic_machine=moxie-unknown
+ os=-moxiebox
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ msys)
+ basic_machine=i686-pc
+ os=-msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* | -plan9* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* | -cloudabi* | -sortix* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
+ | -onefs* | -tirtos* | -phoenix* | -fuchsia*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
+ -ios)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ c8051-*)
+ os=-elf
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/configure b/configure
new file mode 100755
index 000000000..e2bdd21fb
--- /dev/null
+++ b/configure
@@ -0,0 +1,23911 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for cups-filters 1.17.9.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+
+ test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='cups-filters'
+PACKAGE_TARNAME='cups-filters'
+PACKAGE_VERSION='1.17.9'
+PACKAGE_STRING='cups-filters 1.17.9'
+PACKAGE_BUGREPORT=''
+PACKAGE_URL=''
+
+ac_default_prefix=/
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+TABLESDIR
+ENABLE_BRAILLE_FALSE
+ENABLE_BRAILLE_TRUE
+PHPDIR
+PHPCONFIG
+WITH_PHP_FALSE
+WITH_PHP_TRUE
+ENABLE_FOOMATIC_FALSE
+ENABLE_FOOMATIC_TRUE
+CUPS_PDFTOPS
+ENABLE_MUTOOL_FALSE
+ENABLE_MUTOOL_TRUE
+CUPS_MUTOOL
+ENABLE_GHOSTSCRIPT_FALSE
+ENABLE_GHOSTSCRIPT_TRUE
+CUPS_GHOSTSCRIPT
+ENABLE_IJS_FALSE
+ENABLE_IJS_TRUE
+LARGEFILE
+DBUS_LIBS
+DBUS_CFLAGS
+BUILD_DBUS_FALSE
+BUILD_DBUS_TRUE
+POPPLER_LIBS
+POPPLER_CFLAGS
+ENABLE_POPPLER_FALSE
+ENABLE_POPPLER_TRUE
+QPDF_NO_PCLM
+LIBQPDF_LIBS
+LIBQPDF_CFLAGS
+ZLIB_LIBS
+ZLIB_CFLAGS
+IJS_LIBS
+IJS_CFLAGS
+FONTCONFIG_LIBS
+FONTCONFIG_CFLAGS
+FREETYPE_LIBS
+FREETYPE_CFLAGS
+LCMS_LIBS
+LCMS_CFLAGS
+RCSTOP
+RCSTART
+RCLEVELS
+INITDDIR
+INITDIR
+RCLINKS_FALSE
+RCLINKS_TRUE
+BROWSEREMOTEPROTOCOLS
+GIO_UNIX_LIBS
+GIO_UNIX_CFLAGS
+GIO_LIBS
+GIO_CFLAGS
+AVAHI_GLIB_LIBS
+AVAHI_GLIB_CFLAGS
+GLIB_LIBS
+GLIB_CFLAGS
+AVAHI_LIBS
+AVAHI_CFLAGS
+ENABLE_AVAHI_FALSE
+ENABLE_AVAHI_TRUE
+LIBTIFF_LIBS
+LIBPNG_LIBS
+LIBPNG_CFLAGS
+LIBJPEG_LIBS
+ENABLE_IMAGEFILTERS_FALSE
+ENABLE_IMAGEFILTERS_TRUE
+STRCASESTR
+GETLINE
+CUPS_DEFAULT_DOMAINSOCKET
+CUPS_STATEDIR
+DLOPEN_LIBS
+BANNERTOPDF_DATADIR
+APPLE_RASTER_FILTER
+ENABLE_URFTOPDF_FALSE
+ENABLE_URFTOPDF_TRUE
+ENABLE_DRIVERLESS_FALSE
+ENABLE_DRIVERLESS_TRUE
+CUPS_SERVERBIN
+CUPS_FONTPATH
+CUPS_SERVERROOT
+CUPS_DATADIR
+CUPS_LIBS
+CUPS_CFLAGS
+CUPSCONFIG
+FONTDIR
+PKG_CONFIG_LIBDIR
+PKG_CONFIG_PATH
+PKG_CONFIG
+CXXCPP
+LT_SYS_LIBRARY_PATH
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+ac_ct_AR
+AR
+DLLTOOL
+OBJDUMP
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+EGREP
+GREP
+SED
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+LIBTOOL
+LN_S
+CPP
+HAVE_CXX11
+am__fastdepCXX_FALSE
+am__fastdepCXX_TRUE
+CXXDEPMODE
+ac_ct_CXX
+CXXFLAGS
+CXX
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+runstatedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_silent_rules
+enable_dependency_tracking
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_aix_soname
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+with_fontdir
+with_cups_config
+enable_driverless
+with_apple_raster_filter
+enable_auto_setup_driverless
+with_cups_rundir
+with_cups_domainsocket
+enable_imagefilters
+with_jpeg
+with_png
+with_tiff
+enable_avahi
+with_avahi_libs
+with_avahi_includes
+enable_ldap
+with_ldap_libs
+with_ldap_includes
+with_browseremoteprotocols
+with_rcdir
+with_rclevels
+with_rcstart
+with_rcstop
+enable_pclm
+enable_poppler
+enable_dbus
+enable_largefile
+enable_mutool
+with_mutool_path
+enable_ghostscript
+enable_ijs
+with_pdftops
+with_gs_path
+with_pdftops_path
+with_pdftocairo_path
+with_acroread_path
+with_ippfind_path
+with_pdftops_maxres
+enable_gs_ps2write
+enable_foomatic
+with_php
+with_php_config
+with_test_font_path
+enable_werror
+enable_braille
+with_shell
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CXX
+CXXFLAGS
+CCC
+CPP
+LT_SYS_LIBRARY_PATH
+CXXCPP
+PKG_CONFIG
+PKG_CONFIG_PATH
+PKG_CONFIG_LIBDIR
+LIBPNG_CFLAGS
+LIBPNG_LIBS
+AVAHI_CFLAGS
+AVAHI_LIBS
+GLIB_CFLAGS
+GLIB_LIBS
+AVAHI_GLIB_CFLAGS
+AVAHI_GLIB_LIBS
+GIO_CFLAGS
+GIO_LIBS
+GIO_UNIX_CFLAGS
+GIO_UNIX_LIBS
+LCMS_CFLAGS
+LCMS_LIBS
+FREETYPE_CFLAGS
+FREETYPE_LIBS
+FONTCONFIG_CFLAGS
+FONTCONFIG_LIBS
+IJS_CFLAGS
+IJS_LIBS
+ZLIB_CFLAGS
+ZLIB_LIBS
+LIBQPDF_CFLAGS
+LIBQPDF_LIBS
+POPPLER_CFLAGS
+POPPLER_LIBS
+DBUS_CFLAGS
+DBUS_LIBS'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -runstatedir | --runstatedir | --runstatedi | --runstated \
+ | --runstate | --runstat | --runsta | --runst | --runs \
+ | --run | --ru | --r)
+ ac_prev=runstatedir ;;
+ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+ | --run=* | --ru=* | --r=*)
+ runstatedir=$ac_optarg ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir runstatedir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures cups-filters 1.17.9 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking ...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/cups-filters]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of cups-filters 1.17.9:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-silent-rules less verbose build output (undo: "make V=1")
+ --disable-silent-rules verbose build output (undo: "make V=0")
+ --enable-dependency-tracking
+ do not reject slow dependency extractors
+ --disable-dependency-tracking
+ speeds up one-time build
+ --enable-shared[=PKGS] build shared libraries [default=yes]
+ --enable-static[=PKGS] build static libraries [default=yes]
+ --enable-fast-install[=PKGS]
+ optimize for fast installation [default=yes]
+ --disable-libtool-lock avoid locking (might break parallel builds)
+ --enable-driverless enable PPD generator for driverless printing in
+ /usr/lib/cups/driver/, for manual setup of
+ driverless printers with printer setup tool.
+ --enable-auto-setup-driverless
+ enable automatic setup of IPP network printers with
+ driverless printing support.
+ --disable-imagefilters Build the image filters.
+ --disable-avahi Disable DNS Service Discovery support using Avahi.
+ --disable-ldap disable LDAP support.
+ --enable-pclm enable PCLm printing.
+ --enable-poppler enable Poppler-based filters
+ --enable-dbus enable DBus CMS code
+ --disable-largefile omit support for large files
+ --disable-mutool Disable filters using mutool.
+ --disable-ghostscript Disable filters using Ghostscript.
+ --disable-ijs Disable filters using IJS.
+ --disable-gs-ps2write Ghostscript doesn't support ps2write device.
+ --disable-foomatic Disable Foomatic-based filters.
+ --enable-werror Treat all warnings as errors, useful for
+ development.
+ --enable-braille enable Braille embosing filters, requires liblouis
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use
+ both]
+ --with-aix-soname=aix|svr4|both
+ shared library versioning (aka "SONAME") variant to
+ provide on AIX, [default=aix].
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]
+ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the
+ compiler's sysroot if not specified).
+ --with-fontdir=path Specify path to font config directory (default:
+ fonts/conf.d/).
+ --with-cups-config=path Specify path to cups-config executable.
+ --with-apple-raster-filter=rastertopdf|urftopdf
+ Select filter for Apple Raster input. Default:
+ rastertopdf for CUPS 2.2.2+, urftopdf for older CUPS
+ --with-cups-rundir set transient run-time state directory of CUPS
+ --with-cups-domainsocket set unix domain socket name used by CUPS
+
+ --without-jpeg Disable jpeg support.
+ --without-png Disable png support.
+ --without-tiff Disable tiff support.
+ --with-avahi-libs Set directory for Avahi library.
+ --with-avahi-includes Set directory for Avahi includes
+ --with-ldap-libs set directory for LDAP library.
+ --with-ldap-includes set directory for LDAP includes.
+ --with-browseremoteprotocols=value
+ Set which protocols to listen for in cups-browsed
+ (default: dnssd cups)
+ --with-rcdir Set path for rc scripts
+ --with-rclevels Set run levels for rc scripts
+ --with-rcstart Set start number for rc scripts
+ --with-rcstop Set stop number for rc scripts
+ --with-mutool-path=value
+ Set path to mutool binary (default: system).
+ --with-pdftops=value Set which pdftops to use
+ (gs,pdftops,pdftocairo,acroread,mupdf,hybrid).
+ --with-gs-path=value Set path to ghostcript binary (default: system).
+ --with-pdftops-path=value
+ Set path to pdftops/ghostscript binary (default:
+ system).
+ --with-pdftocairo-path=value
+ Set path to pdftocairo binary (default: system).
+ --with-acroread-path=value
+ Set path to acroread binary (default: system).
+ --with-ippfind-path=value
+ Set path to ippfind binary (default: system).
+ --with-pdftops-maxres=value
+ Set maximum image rendering resolution for pdftops
+ filter (0, 75, 150, 300, 600, 1200, 2400, 4800, 90,
+ 180, 360, 720, 1440, 2880, 5760, unlimited).
+ Default: 1440
+ --with-php Determine whether to build php cups extension.
+ --with-php-config=path Specify path to php-config executable.
+ --with-test-font-path=value
+ Set path to font used for tests (default:
+ /usr/share/fonts/dejavu/DejaVuSans.ttf).
+ --with-shell=path Specify path for a modern shell.
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CXX C++ compiler command
+ CXXFLAGS C++ compiler flags
+ CPP C preprocessor
+ LT_SYS_LIBRARY_PATH
+ User-defined run-time library search path.
+ CXXCPP C++ preprocessor
+ PKG_CONFIG path to pkg-config utility
+ PKG_CONFIG_PATH
+ directories to add to pkg-config's search path
+ PKG_CONFIG_LIBDIR
+ path overriding pkg-config's built-in search path
+ LIBPNG_CFLAGS
+ C compiler flags for LIBPNG, overriding pkg-config
+ LIBPNG_LIBS linker flags for LIBPNG, overriding pkg-config
+ AVAHI_CFLAGS
+ C compiler flags for AVAHI, overriding pkg-config
+ AVAHI_LIBS linker flags for AVAHI, overriding pkg-config
+ GLIB_CFLAGS C compiler flags for GLIB, overriding pkg-config
+ GLIB_LIBS linker flags for GLIB, overriding pkg-config
+ AVAHI_GLIB_CFLAGS
+ C compiler flags for AVAHI_GLIB, overriding pkg-config
+ AVAHI_GLIB_LIBS
+ linker flags for AVAHI_GLIB, overriding pkg-config
+ GIO_CFLAGS C compiler flags for GIO, overriding pkg-config
+ GIO_LIBS linker flags for GIO, overriding pkg-config
+ GIO_UNIX_CFLAGS
+ C compiler flags for GIO_UNIX, overriding pkg-config
+ GIO_UNIX_LIBS
+ linker flags for GIO_UNIX, overriding pkg-config
+ LCMS_CFLAGS C compiler flags for LCMS, overriding pkg-config
+ LCMS_LIBS linker flags for LCMS, overriding pkg-config
+ FREETYPE_CFLAGS
+ C compiler flags for FREETYPE, overriding pkg-config
+ FREETYPE_LIBS
+ linker flags for FREETYPE, overriding pkg-config
+ FONTCONFIG_CFLAGS
+ C compiler flags for FONTCONFIG, overriding pkg-config
+ FONTCONFIG_LIBS
+ linker flags for FONTCONFIG, overriding pkg-config
+ IJS_CFLAGS C compiler flags for IJS, overriding pkg-config
+ IJS_LIBS linker flags for IJS, overriding pkg-config
+ ZLIB_CFLAGS C compiler flags for ZLIB, overriding pkg-config
+ ZLIB_LIBS linker flags for ZLIB, overriding pkg-config
+ LIBQPDF_CFLAGS
+ C compiler flags for LIBQPDF, overriding pkg-config
+ LIBQPDF_LIBS
+ linker flags for LIBQPDF, overriding pkg-config
+ POPPLER_CFLAGS
+ C compiler flags for POPPLER, overriding pkg-config
+ POPPLER_LIBS
+ linker flags for POPPLER, overriding pkg-config
+ DBUS_CFLAGS C compiler flags for DBUS, overriding pkg-config
+ DBUS_LIBS linker flags for DBUS, overriding pkg-config
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to the package provider.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+cups-filters configure 1.17.9
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_cxx_try_cpp LINENO
+# ------------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_cpp
+
+# ac_fn_cxx_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_link
+
+# ac_fn_cxx_check_func LINENO FUNC VAR
+# ------------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_cxx_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_func
+
+# ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES
+# ---------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_cxx_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_header_mongrel
+
+# ac_fn_cxx_check_header_compile LINENO HEADER VAR INCLUDES
+# ---------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_cxx_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_header_compile
+
+# ac_fn_cxx_check_type LINENO TYPE VAR INCLUDES
+# ---------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_cxx_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_type
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by cups-filters $as_me 1.17.9, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_compare_version.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
+#
+# DESCRIPTION
+#
+# This macro compares two version strings. Due to the various number of
+# minor-version numbers that can exist, and the fact that string
+# comparisons are not compatible with numeric comparisons, this is not
+# necessarily trivial to do in a autoconf script. This macro makes doing
+# these comparisons easy.
+#
+# The six basic comparisons are available, as well as checking equality
+# limited to a certain number of minor-version levels.
+#
+# The operator OP determines what type of comparison to do, and can be one
+# of:
+#
+# eq - equal (test A == B)
+# ne - not equal (test A != B)
+# le - less than or equal (test A <= B)
+# ge - greater than or equal (test A >= B)
+# lt - less than (test A < B)
+# gt - greater than (test A > B)
+#
+# Additionally, the eq and ne operator can have a number after it to limit
+# the test to that number of minor versions.
+#
+# eq0 - equal up to the length of the shorter version
+# ne0 - not equal up to the length of the shorter version
+# eqN - equal up to N sub-version levels
+# neN - not equal up to N sub-version levels
+#
+# When the condition is true, shell commands ACTION-IF-TRUE are run,
+# otherwise shell commands ACTION-IF-FALSE are run. The environment
+# variable 'ax_compare_version' is always set to either 'true' or 'false'
+# as well.
+#
+# Examples:
+#
+# AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8])
+# AX_COMPARE_VERSION([3.15],[lt],[3.15.8])
+#
+# would both be true.
+#
+# AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8])
+# AX_COMPARE_VERSION([3.15],[gt],[3.15.8])
+#
+# would both be false.
+#
+# AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8])
+#
+# would be true because it is only comparing two minor versions.
+#
+# AX_COMPARE_VERSION([3.15.7],[eq0],[3.15])
+#
+# would be true because it is only comparing the lesser number of minor
+# versions of the two values.
+#
+# Note: The characters that separate the version numbers do not matter. An
+# empty string is the same as version 0. OP is evaluated by autoconf, not
+# configure, so must be a string, not a variable.
+#
+# The author would like to acknowledge Guido Draheim whose advice about
+# the m4_case and m4_ifvaln functions make this macro only include the
+# portions necessary to perform the specific comparison specified by the
+# OP argument in the final configure script.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Tim Toolan <toolan@ele.uri.edu>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 11
+
+
+
+
+
+if test "$prefix" = "NONE"; then
+ prefix="/"
+fi
+
+if test "$exec_prefix" = "NONE"; then
+ if test "$prefix" = "/"; then
+ exec_prefix="/usr"
+ else
+ exec_prefix="$prefix"
+ fi
+fi
+
+if test "$bindir" = "\${exec_prefix}/bin"; then
+ bindir="$exec_prefix/bin"
+fi
+
+if test "$sbindir" = "\${exec_prefix}/sbin"; then
+ sbindir="$exec_prefix/sbin"
+fi
+
+if test "$sharedstatedir" = "\${prefix}/com" -a "$prefix" = "/"; then
+ sharedstatedir="/usr/com"
+fi
+
+if test "$datarootdir" = "\${prefix}/share"; then
+ if test "$prefix" = "/"; then
+ datarootdir="/usr/share"
+ else
+ datarootdir="$prefix/share"
+ fi
+fi
+
+if test "$datadir" = "\${prefix}/share"; then
+ if test "$prefix" = "/"; then
+ datadir="/usr/share"
+ else
+ datadir="$prefix/share"
+ fi
+elif test "$datadir" = "\${datarootdir}"; then
+ datadir="$datarootdir"
+fi
+
+if test "$includedir" = "\${prefix}/include" -a "$prefix" = "/"; then
+ includedir="/usr/include"
+fi
+
+if test "$localstatedir" = "\${prefix}/var"; then
+ if test "$prefix" = "/"; then
+ if test "$uname" = Darwin; then
+ localstatedir="/private/var"
+ else
+ localstatedir="/var"
+ fi
+ else
+ localstatedir="$prefix/var"
+ fi
+fi
+
+if test "$sysconfdir" = "\${prefix}/etc"; then
+ if test "$prefix" = "/"; then
+ if test "$uname" = Darwin; then
+ sysconfdir="/private/etc"
+ else
+ sysconfdir="/etc"
+ fi
+ else
+ sysconfdir="$prefix/etc"
+ fi
+fi
+
+if test "$libdir" = "\${exec_prefix}/lib"; then
+ case "$uname" in
+ Linux*)
+ if test -d /usr/lib64 -a ! -d /usr/lib64/fakeroot; then
+ libdir="$exec_prefix/lib64"
+ fi
+ ;;
+ esac
+fi
+
+
+am__api_version='1.15'
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[\\\"\#\$\&\'\`$am_lf]*)
+ as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+ *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
+ alias in your environment" "$LINENO" 5
+ fi
+ if test "$2" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
+
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
+else
+ am_missing_run=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if ${ac_cv_path_mkdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+ done
+IFS=$as_save_IFS
+
+fi
+
+ test -d ./--version && rmdir ./--version
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+ enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='cups-filters'
+ VERSION='1.17.9'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
+# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar pax cpio none'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+ fi
+fi
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+ enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=0;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ac_config_headers="$ac_config_headers config.h"
+
+# Extra defines for the config.h
+
+
+# ===========================
+# Find required base packages
+# ===========================
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+ ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+ enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CXX="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX="g++"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CXX=$ac_ct_CXX
+ fi
+fi
+
+ fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if ${ac_cv_cxx_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+ ac_cxx_werror_flag=yes
+ ac_cv_prog_cxx_g=no
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+else
+ CXXFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+depcc="$CXX" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CXX_dependencies_compiler_type+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CXX_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CXX_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+ am__fastdepCXX_TRUE=
+ am__fastdepCXX_FALSE='#'
+else
+ am__fastdepCXX_TRUE='#'
+ am__fastdepCXX_FALSE=
+fi
+
+
+
+ ax_cxx_compile_alternatives="11 0x" ax_cxx_compile_cxx11_required=true
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+ ac_success=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5
+$as_echo_n "checking whether $CXX supports C++11 features by default... " >&6; }
+if ${ax_cv_cxx_compile_cxx11+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+// If the compiler admits that it is not ready for C++11, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201103L
+
+#error "This is not a C++11 compiler"
+
+#else
+
+namespace cxx11
+{
+
+ namespace test_static_assert
+ {
+
+ template <typename T>
+ struct check
+ {
+ static_assert(sizeof(int) <= sizeof(T), "not big enough");
+ };
+
+ }
+
+ namespace test_final_override
+ {
+
+ struct Base
+ {
+ virtual void f() {}
+ };
+
+ struct Derived : public Base
+ {
+ virtual void f() override {}
+ };
+
+ }
+
+ namespace test_double_right_angle_brackets
+ {
+
+ template < typename T >
+ struct check {};
+
+ typedef check<void> single_type;
+ typedef check<check<void>> double_type;
+ typedef check<check<check<void>>> triple_type;
+ typedef check<check<check<check<void>>>> quadruple_type;
+
+ }
+
+ namespace test_decltype
+ {
+
+ int
+ f()
+ {
+ int a = 1;
+ decltype(a) b = 2;
+ return a + b;
+ }
+
+ }
+
+ namespace test_type_deduction
+ {
+
+ template < typename T1, typename T2 >
+ struct is_same
+ {
+ static const bool value = false;
+ };
+
+ template < typename T >
+ struct is_same<T, T>
+ {
+ static const bool value = true;
+ };
+
+ template < typename T1, typename T2 >
+ auto
+ add(T1 a1, T2 a2) -> decltype(a1 + a2)
+ {
+ return a1 + a2;
+ }
+
+ int
+ test(const int c, volatile int v)
+ {
+ static_assert(is_same<int, decltype(0)>::value == true, "");
+ static_assert(is_same<int, decltype(c)>::value == false, "");
+ static_assert(is_same<int, decltype(v)>::value == false, "");
+ auto ac = c;
+ auto av = v;
+ auto sumi = ac + av + 'x';
+ auto sumf = ac + av + 1.0;
+ static_assert(is_same<int, decltype(ac)>::value == true, "");
+ static_assert(is_same<int, decltype(av)>::value == true, "");
+ static_assert(is_same<int, decltype(sumi)>::value == true, "");
+ static_assert(is_same<int, decltype(sumf)>::value == false, "");
+ static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
+ return (sumf > 0.0) ? sumi : add(c, v);
+ }
+
+ }
+
+ namespace test_noexcept
+ {
+
+ int f() { return 0; }
+ int g() noexcept { return 0; }
+
+ static_assert(noexcept(f()) == false, "");
+ static_assert(noexcept(g()) == true, "");
+
+ }
+
+ namespace test_constexpr
+ {
+
+ template < typename CharT >
+ unsigned long constexpr
+ strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
+ {
+ return *s ? strlen_c_r(s + 1, acc + 1) : acc;
+ }
+
+ template < typename CharT >
+ unsigned long constexpr
+ strlen_c(const CharT *const s) noexcept
+ {
+ return strlen_c_r(s, 0UL);
+ }
+
+ static_assert(strlen_c("") == 0UL, "");
+ static_assert(strlen_c("1") == 1UL, "");
+ static_assert(strlen_c("example") == 7UL, "");
+ static_assert(strlen_c("another\0example") == 7UL, "");
+
+ }
+
+ namespace test_rvalue_references
+ {
+
+ template < int N >
+ struct answer
+ {
+ static constexpr int value = N;
+ };
+
+ answer<1> f(int&) { return answer<1>(); }
+ answer<2> f(const int&) { return answer<2>(); }
+ answer<3> f(int&&) { return answer<3>(); }
+
+ void
+ test()
+ {
+ int i = 0;
+ const int c = 0;
+ static_assert(decltype(f(i))::value == 1, "");
+ static_assert(decltype(f(c))::value == 2, "");
+ static_assert(decltype(f(0))::value == 3, "");
+ }
+
+ }
+
+ namespace test_uniform_initialization
+ {
+
+ struct test
+ {
+ static const int zero {};
+ static const int one {1};
+ };
+
+ static_assert(test::zero == 0, "");
+ static_assert(test::one == 1, "");
+
+ }
+
+ namespace test_lambdas
+ {
+
+ void
+ test1()
+ {
+ auto lambda1 = [](){};
+ auto lambda2 = lambda1;
+ lambda1();
+ lambda2();
+ }
+
+ int
+ test2()
+ {
+ auto a = [](int i, int j){ return i + j; }(1, 2);
+ auto b = []() -> int { return '0'; }();
+ auto c = [=](){ return a + b; }();
+ auto d = [&](){ return c; }();
+ auto e = [a, &b](int x) mutable {
+ const auto identity = [](int y){ return y; };
+ for (auto i = 0; i < a; ++i)
+ a += b--;
+ return x + identity(a + b);
+ }(0);
+ return a + b + c + d + e;
+ }
+
+ int
+ test3()
+ {
+ const auto nullary = [](){ return 0; };
+ const auto unary = [](int x){ return x; };
+ using nullary_t = decltype(nullary);
+ using unary_t = decltype(unary);
+ const auto higher1st = [](nullary_t f){ return f(); };
+ const auto higher2nd = [unary](nullary_t f1){
+ return [unary, f1](unary_t f2){ return f2(unary(f1())); };
+ };
+ return higher1st(nullary) + higher2nd(nullary)(unary);
+ }
+
+ }
+
+ namespace test_variadic_templates
+ {
+
+ template <int...>
+ struct sum;
+
+ template <int N0, int... N1toN>
+ struct sum<N0, N1toN...>
+ {
+ static constexpr auto value = N0 + sum<N1toN...>::value;
+ };
+
+ template <>
+ struct sum<>
+ {
+ static constexpr auto value = 0;
+ };
+
+ static_assert(sum<>::value == 0, "");
+ static_assert(sum<1>::value == 1, "");
+ static_assert(sum<23>::value == 23, "");
+ static_assert(sum<1, 2>::value == 3, "");
+ static_assert(sum<5, 5, 11>::value == 21, "");
+ static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
+
+ }
+
+ // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
+ // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
+ // because of this.
+ namespace test_template_alias_sfinae
+ {
+
+ struct foo {};
+
+ template<typename T>
+ using member = typename T::member_type;
+
+ template<typename T>
+ void func(...) {}
+
+ template<typename T>
+ void func(member<T>*) {}
+
+ void test();
+
+ void test() { func<foo>(0); }
+
+ }
+
+} // namespace cxx11
+
+#endif // __cplusplus >= 201103L
+
+
+
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ax_cv_cxx_compile_cxx11=yes
+else
+ ax_cv_cxx_compile_cxx11=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx11" >&5
+$as_echo "$ax_cv_cxx_compile_cxx11" >&6; }
+ if test x$ax_cv_cxx_compile_cxx11 = xyes; then
+ ac_success=yes
+ fi
+
+
+
+ if test x$ac_success = xno; then
+ for alternative in ${ax_cxx_compile_alternatives}; do
+ for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
+ cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5
+$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; }
+if eval \${$cachevar+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_CXX="$CXX"
+ CXX="$CXX $switch"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+// If the compiler admits that it is not ready for C++11, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201103L
+
+#error "This is not a C++11 compiler"
+
+#else
+
+namespace cxx11
+{
+
+ namespace test_static_assert
+ {
+
+ template <typename T>
+ struct check
+ {
+ static_assert(sizeof(int) <= sizeof(T), "not big enough");
+ };
+
+ }
+
+ namespace test_final_override
+ {
+
+ struct Base
+ {
+ virtual void f() {}
+ };
+
+ struct Derived : public Base
+ {
+ virtual void f() override {}
+ };
+
+ }
+
+ namespace test_double_right_angle_brackets
+ {
+
+ template < typename T >
+ struct check {};
+
+ typedef check<void> single_type;
+ typedef check<check<void>> double_type;
+ typedef check<check<check<void>>> triple_type;
+ typedef check<check<check<check<void>>>> quadruple_type;
+
+ }
+
+ namespace test_decltype
+ {
+
+ int
+ f()
+ {
+ int a = 1;
+ decltype(a) b = 2;
+ return a + b;
+ }
+
+ }
+
+ namespace test_type_deduction
+ {
+
+ template < typename T1, typename T2 >
+ struct is_same
+ {
+ static const bool value = false;
+ };
+
+ template < typename T >
+ struct is_same<T, T>
+ {
+ static const bool value = true;
+ };
+
+ template < typename T1, typename T2 >
+ auto
+ add(T1 a1, T2 a2) -> decltype(a1 + a2)
+ {
+ return a1 + a2;
+ }
+
+ int
+ test(const int c, volatile int v)
+ {
+ static_assert(is_same<int, decltype(0)>::value == true, "");
+ static_assert(is_same<int, decltype(c)>::value == false, "");
+ static_assert(is_same<int, decltype(v)>::value == false, "");
+ auto ac = c;
+ auto av = v;
+ auto sumi = ac + av + 'x';
+ auto sumf = ac + av + 1.0;
+ static_assert(is_same<int, decltype(ac)>::value == true, "");
+ static_assert(is_same<int, decltype(av)>::value == true, "");
+ static_assert(is_same<int, decltype(sumi)>::value == true, "");
+ static_assert(is_same<int, decltype(sumf)>::value == false, "");
+ static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
+ return (sumf > 0.0) ? sumi : add(c, v);
+ }
+
+ }
+
+ namespace test_noexcept
+ {
+
+ int f() { return 0; }
+ int g() noexcept { return 0; }
+
+ static_assert(noexcept(f()) == false, "");
+ static_assert(noexcept(g()) == true, "");
+
+ }
+
+ namespace test_constexpr
+ {
+
+ template < typename CharT >
+ unsigned long constexpr
+ strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
+ {
+ return *s ? strlen_c_r(s + 1, acc + 1) : acc;
+ }
+
+ template < typename CharT >
+ unsigned long constexpr
+ strlen_c(const CharT *const s) noexcept
+ {
+ return strlen_c_r(s, 0UL);
+ }
+
+ static_assert(strlen_c("") == 0UL, "");
+ static_assert(strlen_c("1") == 1UL, "");
+ static_assert(strlen_c("example") == 7UL, "");
+ static_assert(strlen_c("another\0example") == 7UL, "");
+
+ }
+
+ namespace test_rvalue_references
+ {
+
+ template < int N >
+ struct answer
+ {
+ static constexpr int value = N;
+ };
+
+ answer<1> f(int&) { return answer<1>(); }
+ answer<2> f(const int&) { return answer<2>(); }
+ answer<3> f(int&&) { return answer<3>(); }
+
+ void
+ test()
+ {
+ int i = 0;
+ const int c = 0;
+ static_assert(decltype(f(i))::value == 1, "");
+ static_assert(decltype(f(c))::value == 2, "");
+ static_assert(decltype(f(0))::value == 3, "");
+ }
+
+ }
+
+ namespace test_uniform_initialization
+ {
+
+ struct test
+ {
+ static const int zero {};
+ static const int one {1};
+ };
+
+ static_assert(test::zero == 0, "");
+ static_assert(test::one == 1, "");
+
+ }
+
+ namespace test_lambdas
+ {
+
+ void
+ test1()
+ {
+ auto lambda1 = [](){};
+ auto lambda2 = lambda1;
+ lambda1();
+ lambda2();
+ }
+
+ int
+ test2()
+ {
+ auto a = [](int i, int j){ return i + j; }(1, 2);
+ auto b = []() -> int { return '0'; }();
+ auto c = [=](){ return a + b; }();
+ auto d = [&](){ return c; }();
+ auto e = [a, &b](int x) mutable {
+ const auto identity = [](int y){ return y; };
+ for (auto i = 0; i < a; ++i)
+ a += b--;
+ return x + identity(a + b);
+ }(0);
+ return a + b + c + d + e;
+ }
+
+ int
+ test3()
+ {
+ const auto nullary = [](){ return 0; };
+ const auto unary = [](int x){ return x; };
+ using nullary_t = decltype(nullary);
+ using unary_t = decltype(unary);
+ const auto higher1st = [](nullary_t f){ return f(); };
+ const auto higher2nd = [unary](nullary_t f1){
+ return [unary, f1](unary_t f2){ return f2(unary(f1())); };
+ };
+ return higher1st(nullary) + higher2nd(nullary)(unary);
+ }
+
+ }
+
+ namespace test_variadic_templates
+ {
+
+ template <int...>
+ struct sum;
+
+ template <int N0, int... N1toN>
+ struct sum<N0, N1toN...>
+ {
+ static constexpr auto value = N0 + sum<N1toN...>::value;
+ };
+
+ template <>
+ struct sum<>
+ {
+ static constexpr auto value = 0;
+ };
+
+ static_assert(sum<>::value == 0, "");
+ static_assert(sum<1>::value == 1, "");
+ static_assert(sum<23>::value == 23, "");
+ static_assert(sum<1, 2>::value == 3, "");
+ static_assert(sum<5, 5, 11>::value == 21, "");
+ static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
+
+ }
+
+ // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
+ // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
+ // because of this.
+ namespace test_template_alias_sfinae
+ {
+
+ struct foo {};
+
+ template<typename T>
+ using member = typename T::member_type;
+
+ template<typename T>
+ void func(...) {}
+
+ template<typename T>
+ void func(member<T>*) {}
+
+ void test();
+
+ void test() { func<foo>(0); }
+
+ }
+
+} // namespace cxx11
+
+#endif // __cplusplus >= 201103L
+
+
+
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ eval $cachevar=yes
+else
+ eval $cachevar=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CXX="$ac_save_CXX"
+fi
+eval ac_res=\$$cachevar
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ if eval test x\$$cachevar = xyes; then
+ CXX="$CXX $switch"
+ if test -n "$CXXCPP" ; then
+ CXXCPP="$CXXCPP $switch"
+ fi
+ ac_success=yes
+ break
+ fi
+ done
+ if test x$ac_success = xyes; then
+ break
+ fi
+ done
+ fi
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ if test x$ax_cxx_compile_cxx11_required = xtrue; then
+ if test x$ac_success = xno; then
+ as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5
+ fi
+ fi
+ if test x$ac_success = xno; then
+ HAVE_CXX11=0
+ { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5
+$as_echo "$as_me: No compiler with C++11 support was found" >&6;}
+ else
+ HAVE_CXX11=1
+
+$as_echo "#define HAVE_CXX11 1" >>confdefs.h
+
+ fi
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+case `pwd` in
+ *\ * | *\ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.6'
+macro_revision='2.4.6'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain=$ac_aux_dir/ltmain.sh
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO ""
+}
+
+case $ECHO in
+ printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+ print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+ then ac_cv_path_FGREP="$GREP -F"
+ else
+ if test -z "$FGREP"; then
+ ac_path_FGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in fgrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_FGREP" || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+ # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'FGREP' >> "conftest.nl"
+ "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_FGREP="$ac_path_FGREP"
+ ac_path_FGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_FGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_FGREP"; then
+ as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_FGREP=$FGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+ withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test yes = "$GCC"; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return, which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD=$ac_prog
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test yes = "$with_gnu_ld"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD=$ac_dir/$ac_prog
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test no != "$with_gnu_ld" && break
+ ;;
+ *)
+ test yes != "$with_gnu_ld" && break
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+else
+ lt_cv_path_LD=$LD # Let the user override the test with a path.
+fi
+fi
+
+LD=$lt_cv_path_LD
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM=$NM
+else
+ lt_nm_to_check=${ac_tool_prefix}nm
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/$lt_tmp_nm
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
+ case $build_os in
+ mingw*) lt_bad_file=conftest.nm/nofile ;;
+ *) lt_bad_file=/dev/null ;;
+ esac
+ case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
+ *$lt_bad_file* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break 2
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break 2
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+ done
+ : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test no != "$lt_cv_path_NM"; then
+ NM=$lt_cv_path_NM
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in dumpbin "link -dump"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DUMPBIN"; then
+ ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DUMPBIN" && break
+ done
+fi
+if test -z "$DUMPBIN"; then
+ ac_ct_DUMPBIN=$DUMPBIN
+ for ac_prog in dumpbin "link -dump"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DUMPBIN"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_DUMPBIN" && break
+done
+
+ if test "x$ac_ct_DUMPBIN" = x; then
+ DUMPBIN=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DUMPBIN=$ac_ct_DUMPBIN
+ fi
+fi
+
+ case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols -headers"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+
+ if test : != "$DUMPBIN"; then
+ NM=$DUMPBIN
+ fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if ${lt_cv_sys_max_cmd_len+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ i=0
+ teststring=ABCD
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len" && \
+ test undefined != "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test 17 != "$i" # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+
+fi
+
+if test -n "$lt_cv_sys_max_cmd_len"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if ${lt_cv_ld_reload_flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test yes != "$GCC"; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test yes = "$GCC"; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if ${lt_cv_deplibs_check_method+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# 'unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# that responds to the $file_magic_cmd with a given extended regex.
+# If you have 'file' or equivalent on your system and you're not sure
+# whether 'pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[45]*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ if ( file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[3-9]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd* | bitrig*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+os2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh;
+ # decide which one to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd=$ECHO
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in ar
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AR" && break
+ done
+fi
+if test -z "$AR"; then
+ ac_ct_AR=$AR
+ for ac_prog in ar
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_AR" && break
+done
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ar_at_file=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test 0 -eq "$ac_status"; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test 0 -ne "$ac_status"; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test no = "$lt_cv_ar_at_file"; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ bitrig* | openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ if test ia64 = "$host_cpu"; then
+ symcode='[ABCDEGRST]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[BCDEGRST]'
+ ;;
+osf*)
+ symcode='[BCDEGQRST]'
+ ;;
+solaris*)
+ symcode='[BDRT]'
+ ;;
+sco3.2v5*)
+ symcode='[DT]'
+ ;;
+sysv4.2uw2*)
+ symcode='[DT]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[ABDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[ABCDGIRSTW]' ;;
+esac
+
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Gets list of data symbols to import.
+ lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
+ # Adjust the below global symbol transforms to fixup imported variables.
+ lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
+ lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'"
+ lt_c_name_lib_hook="\
+ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\
+ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'"
+else
+ # Disable hooks by default.
+ lt_cv_sys_global_symbol_to_import=
+ lt_cdecl_hook=
+ lt_c_name_hook=
+ lt_c_name_lib_hook=
+fi
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n"\
+$lt_cdecl_hook\
+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
+$lt_c_name_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'"
+
+# Transform an extracted symbol line into symbol name with lib prefix and
+# symbol address.
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
+$lt_c_name_lib_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function,
+ # D for any global variable and I for any imported variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK '"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
+" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
+" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
+" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
+" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS=conftstm.$ac_objext
+ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest$ac_exeext; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test yes = "$pipe_works"; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+ withval=$with_sysroot;
+else
+ with_sysroot=no
+fi
+
+
+lt_sysroot=
+case $with_sysroot in #(
+ yes)
+ if test yes = "$GCC"; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5
+$as_echo "$with_sysroot" >&6; }
+ as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+ ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5
+$as_echo_n "checking for a working dd... " >&6; }
+if ${ac_cv_path_lt_DD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+: ${lt_DD:=$DD}
+if test -z "$lt_DD"; then
+ ac_path_lt_DD_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in dd; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_lt_DD" || continue
+if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
+fi
+ $ac_path_lt_DD_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_lt_DD"; then
+ :
+ fi
+else
+ ac_cv_path_lt_DD=$lt_DD
+fi
+
+rm -f conftest.i conftest2.i conftest.out
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5
+$as_echo "$ac_cv_path_lt_DD" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5
+$as_echo_n "checking how to truncate binary pipes... " >&6; }
+if ${lt_cv_truncate_bin+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+lt_cv_truncate_bin=
+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
+fi
+rm -f conftest.i conftest2.i conftest.out
+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5
+$as_echo "$lt_cv_truncate_bin" >&6; }
+
+
+
+
+
+
+
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+ for cc_temp in $*""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+ done
+ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+ enableval=$enable_libtool_lock;
+fi
+
+test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out what ABI is being produced by ac_compile, and set mode
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE=32
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE=64
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+mips64*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ emul=elf
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ emul="${emul}32"
+ ;;
+ *64-bit*)
+ emul="${emul}64"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *MSB*)
+ emul="${emul}btsmip"
+ ;;
+ *LSB*)
+ emul="${emul}ltsmip"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *N32*)
+ emul="${emul}n32"
+ ;;
+ esac
+ LD="${LD-ld} -m $emul"
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly. Note that the listed cases only cover the
+ # situations where additional linker options are needed (such as when
+ # doing 32-bit compilation for a host where ld defaults to 64-bit, or
+ # vice versa); the common cases where no linker options are needed do
+ # not appear in the list.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
+ ;;
+ powerpc64le-*linux*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ powerpcle-*linux*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS=$CFLAGS
+ CFLAGS="$CFLAGS -belf"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if ${lt_cv_cc_needs_belf+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_cc_needs_belf=yes
+else
+ lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+ if test yes != "$lt_cv_cc_needs_belf"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS=$SAVE_CFLAGS
+ fi
+ ;;
+*-*solaris*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*|x86_64-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD=${LD-ld}_sol2
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks=$enable_libtool_lock
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$MANIFEST_TOOL"; then
+ ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+ ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+ # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_MANIFEST_TOOL"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_MANIFEST_TOOL" = x; then
+ MANIFEST_TOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+ fi
+else
+ MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&5
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test yes != "$lt_cv_path_mainfest_tool"; then
+ MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+ case $host_os in
+ rhapsody* | darwin*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DSYMUTIL"; then
+ ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+ ac_ct_DSYMUTIL=$DSYMUTIL
+ # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DSYMUTIL"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DSYMUTIL" = x; then
+ DSYMUTIL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DSYMUTIL=$ac_ct_DSYMUTIL
+ fi
+else
+ DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NMEDIT"; then
+ ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+ ac_ct_NMEDIT=$NMEDIT
+ # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_NMEDIT"; then
+ ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_NMEDIT="nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_NMEDIT" = x; then
+ NMEDIT=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ NMEDIT=$ac_ct_NMEDIT
+ fi
+else
+ NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LIPO"; then
+ ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+ ac_ct_LIPO=$LIPO
+ # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_LIPO"; then
+ ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_LIPO="lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_LIPO" = x; then
+ LIPO=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ LIPO=$ac_ct_LIPO
+ fi
+else
+ LIPO="$ac_cv_prog_LIPO"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL"; then
+ ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+ ac_ct_OTOOL=$OTOOL
+ # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL"; then
+ ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL="otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL" = x; then
+ OTOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL=$ac_ct_OTOOL
+ fi
+else
+ OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL64"; then
+ ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+ ac_ct_OTOOL64=$OTOOL64
+ # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL64"; then
+ ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL64="otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL64" = x; then
+ OTOOL64=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL64=$ac_ct_OTOOL64
+ fi
+else
+ OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if ${lt_cv_apple_cc_single_mod+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_apple_cc_single_mod=no
+ if test -z "$LT_MULTI_MODULE"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&5
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_ld_exported_symbols_list=yes
+else
+ lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+ echo "$AR cru libconftest.a conftest.o" >&5
+ $AR cru libconftest.a conftest.o 2>&5
+ echo "$RANLIB libconftest.a" >&5
+ $RANLIB libconftest.a 2>&5
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&5
+ elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ 10.[012][,.]*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test yes = "$lt_cv_apple_cc_single_mod"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test yes = "$lt_cv_ld_exported_symbols_list"; then
+ _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+ fi
+ if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+
+# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+# string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+# string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+# "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+# VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+ case x$2 in
+ x)
+ ;;
+ *:)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
+ ;;
+ x:*)
+ eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ *::*)
+ eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+ eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
+ ;;
+ *)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ esac
+}
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in dlfcn.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+func_stripname_cnf ()
+{
+ case $2 in
+ .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;;
+ *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;;
+ esac
+} # func_stripname_cnf
+
+
+
+
+
+# Set options
+
+
+
+ enable_dlopen=no
+
+
+ enable_win32_dll=no
+
+
+ # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+ # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+ enableval=$enable_static; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+ withval=$with_pic; lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for lt_pkg in $withval; do
+ IFS=$lt_save_ifs
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ pic_mode=default
+fi
+
+
+
+
+
+
+
+
+ # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+ enableval=$enable_fast_install; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+ shared_archive_member_spec=
+case $host,$enable_shared in
+power*-*-aix[5-9]*,yes)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5
+$as_echo_n "checking which variant of shared library versioning to provide... " >&6; }
+
+# Check whether --with-aix-soname was given.
+if test "${with_aix_soname+set}" = set; then :
+ withval=$with_aix_soname; case $withval in
+ aix|svr4|both)
+ ;;
+ *)
+ as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5
+ ;;
+ esac
+ lt_cv_with_aix_soname=$with_aix_soname
+else
+ if ${lt_cv_with_aix_soname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_with_aix_soname=aix
+fi
+
+ with_aix_soname=$lt_cv_with_aix_soname
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5
+$as_echo "$with_aix_soname" >&6; }
+ if test aix != "$with_aix_soname"; then
+ # For the AIX way of multilib, we name the shared archive member
+ # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
+ # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
+ # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
+ # the AIX toolchain works better with OBJECT_MODE set (default 32).
+ if test 64 = "${OBJECT_MODE-32}"; then
+ shared_archive_member_spec=shr_64
+ else
+ shared_archive_member_spec=shr
+ fi
+ fi
+ ;;
+*)
+ with_aix_soname=aix
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS=$ltmain
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if ${lt_cv_objdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+old_CC=$CC
+old_CFLAGS=$CFLAGS
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+func_cc_basename $compiler
+cc_basename=$func_cc_basename_result
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/${ac_tool_prefix}file"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
+ ;;
+esac
+fi
+
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/file"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
+ ;;
+esac
+fi
+
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC=$CC
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test yes = "$GCC"; then
+ case $cc_basename in
+ nvcc*)
+ lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+ *)
+ lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_rtti_exceptions=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_rtti_exceptions=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then
+ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+ :
+fi
+
+fi
+
+
+
+
+
+
+ lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+
+ if test yes = "$GCC"; then
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_static='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ case $host_os in
+ os2*)
+ lt_prog_compiler_static='$wl-static'
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ lt_prog_compiler_wl='-Xlinker '
+ if test -n "$lt_prog_compiler_pic"; then
+ lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl='-Wl,'
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ else
+ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ case $cc_basename in
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ esac
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ case $host_os in
+ os2*)
+ lt_prog_compiler_static='$wl-static'
+ ;;
+ esac
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static='$wl-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ # old Intel for x86_64, which still supported -KPIC.
+ ecc*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='--shared'
+ lt_prog_compiler_static='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-qpic'
+ lt_prog_compiler_static='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ *Intel*\ [CF]*Compiler*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ *Portland\ Group*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ lt_prog_compiler_wl='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl='-Qoption ld '
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic='-Kconform_pic'
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_can_build_shared=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic='-pic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms that do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic=
+ ;;
+ *)
+ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_pic_works"; then
+ case $lt_prog_compiler_pic in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+ esac
+else
+ lt_prog_compiler_pic=
+ lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_static_works"; then
+ :
+else
+ lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links=nottested
+if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test no = "$hard_links"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ runpath_var=
+ allow_undefined_flag=
+ always_export_symbols=no
+ archive_cmds=
+ archive_expsym_cmds=
+ compiler_needs_object=no
+ enable_shared_with_static_runtimes=no
+ export_dynamic_flag_spec=
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic=no
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_separator=
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=unsupported
+ inherit_rpath=no
+ link_all_deplibs=unknown
+ module_cmds=
+ module_expsym_cmds=
+ old_archive_from_new_cmds=
+ old_archive_from_expsyms_cmds=
+ thread_safe_flag_spec=
+ whole_archive_flag_spec=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ include_expsyms=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ' (' and ')$', so one must not match beginning or
+ # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
+ # as well as any symbol that contains 'd'.
+ exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test yes != "$GCC"; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd* | bitrig*)
+ with_gnu_ld=no
+ ;;
+ linux* | k*bsd*-gnu | gnu*)
+ link_all_deplibs=no
+ ;;
+ esac
+
+ ld_shlibs=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test yes = "$with_gnu_ld"; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+ *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test yes = "$lt_use_gnu_ld_interface"; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='$wl'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ export_dynamic_flag_spec='$wl--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test ia64 != "$host_cpu"; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ export_dynamic_flag_spec='$wl--export-all-symbols'
+ allow_undefined_flag=unsupported
+ always_export_symbols=no
+ enable_shared_with_static_runtimes=yes
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ haiku*)
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ link_all_deplibs=yes
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ shrext_cmds=.dll
+ archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ enable_shared_with_static_runtimes=yes
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ export_dynamic_flag_spec='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test linux-dietlibc = "$host_os"; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test no = "$tmp_diet"
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ whole_archive_flag_spec=
+ tmp_sharedflag='--shared' ;;
+ nagfor*) # NAGFOR 5.3
+ tmp_sharedflag='-Wl,-shared' ;;
+ xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ compiler_needs_object=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ compiler_needs_object=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+
+ if test yes = "$supports_anon_versioning"; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ tcc*)
+ export_dynamic_flag_spec='-rdynamic'
+ ;;
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test no = "$ld_shlibs"; then
+ runpath_var=
+ hardcode_libdir_flag_spec=
+ export_dynamic_flag_spec=
+ whole_archive_flag_spec=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+ # Without the "-l" option, or with the "-B" option, AIX nm treats
+ # weak defined symbols like other global defined symbols, whereas
+ # GNU nm marks them as "W".
+ # While the 'weak' keyword is ignored in the Export File, we need
+ # it in the Import File for the 'aix-soname' feature, so we have
+ # to replace the "-B" option with "-P" for AIX nm.
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # have runtime linking enabled, and use it for executables.
+ # For shared libraries, we enable/disable runtime linking
+ # depending on the kind of the shared library created -
+ # when "with_aix_soname,aix_use_runtimelinking" is:
+ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
+ # "aix,yes" lib.so shared, rtl:yes, for executables
+ # lib.a static archive
+ # "both,no" lib.so.V(shr.o) shared, rtl:yes
+ # lib.a(lib.so.V) shared, rtl:no, for executables
+ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a(lib.so.V) shared, rtl:no
+ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a static archive
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # With aix-soname=svr4, we create the lib.so.V shared archives only,
+ # so we don't have lib.a shared libs to link our executables.
+ # We have to force runtime linking in this case.
+ aix_use_runtimelinking=yes
+ LDFLAGS="$LDFLAGS -Wl,-brtl"
+ fi
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds=''
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ file_list_spec='$wl-f,'
+ case $with_aix_soname,$aix_use_runtimelinking in
+ aix,*) ;; # traditional, no import file
+ svr4,* | *,yes) # use import file
+ # The Import File defines what to hardcode.
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ ;;
+ esac
+
+ if test yes = "$GCC"; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag="$shared_flag "'$wl-G'
+ fi
+ # Need to ensure runtime linking is disabled for the traditional
+ # shared library, or the linker may eventually find shared libraries
+ # /with/ Import File - we do not want to mix them.
+ shared_flag_aix='-shared'
+ shared_flag_svr4='-shared $wl-G'
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ shared_flag_aix='$wl-bM:SRE'
+ shared_flag_svr4='$wl-G'
+ fi
+ fi
+
+ export_dynamic_flag_spec='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols=yes
+ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=/usr/lib:/lib
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=/usr/lib:/lib
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag=' $wl-bernotok'
+ allow_undefined_flag=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec='$convenience'
+ fi
+ archive_cmds_need_lc=yes
+ archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+ # -brtl affects multiple linker settings, -berok does not and is overridden later
+ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`'
+ if test svr4 != "$with_aix_soname"; then
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+ fi
+ if test aix != "$with_aix_soname"; then
+ archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+ else
+ # used by -dlpreopen to get the symbols
+ archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
+ fi
+ archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ file_list_spec='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+ enable_shared_with_static_runtimes=yes
+ exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ old_postinstall_cmds='chmod 644 $oldlib'
+ postlink_cmds='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ enable_shared_with_static_runtimes=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc=no
+ hardcode_direct=no
+ hardcode_automatic=yes
+ hardcode_shlibpath_var=unsupported
+ if test yes = "$lt_cv_ld_force_load"; then
+ whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+ else
+ whole_archive_flag_spec=''
+ fi
+ link_all_deplibs=yes
+ allow_undefined_flag=$_lt_dar_allow_undefined
+ case $cc_basename in
+ ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test yes = "$_lt_dar_can_shared"; then
+ output_verbose_link_cmd=func_echo_all
+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+ archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+ module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+
+ else
+ ld_shlibs=no
+ fi
+
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ if test yes = "$GCC"; then
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ fi
+ hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='$wl-E'
+ ;;
+
+ hpux10*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test no = "$with_gnu_ld"; then
+ hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='$wl-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler__b=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -b"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler__b=yes
+ fi
+ else
+ lt_cv_prog_compiler__b=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test yes = "$lt_cv_prog_compiler__b"; then
+ archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+ ;;
+ esac
+ fi
+ if test no = "$with_gnu_ld"; then
+ hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ hardcode_libdir_separator=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ ;;
+ *)
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='$wl-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo (void) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_irix_exported_symbol=yes
+else
+ lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+ if test yes = "$lt_cv_irix_exported_symbol"; then
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+ fi
+ link_all_deplibs=no
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ inherit_rpath=yes
+ link_all_deplibs=yes
+ ;;
+
+ linux*)
+ case $cc_basename in
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ ld_shlibs=yes
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ hardcode_direct_absolute=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ export_dynamic_flag_spec='$wl-E'
+ else
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ shrext_cmds=.dll
+ archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ enable_shared_with_static_runtimes=yes
+ ;;
+
+ osf3*)
+ if test yes = "$GCC"; then
+ allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test yes = "$GCC"; then
+ allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+ archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_separator=:
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z defs'
+ if test yes = "$GCC"; then
+ wlarc='$wl'
+ archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='$wl'
+ archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'. GCC discards it without '$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test yes = "$GCC"; then
+ whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test sequent = "$host_vendor"; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag='$wl-z,text'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag='$wl-z,text'
+ allow_undefined_flag='$wl-z,nodefs'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='$wl-R,$libdir'
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ export_dynamic_flag_spec='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+
+ if test sni = "$host_vendor"; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec='$wl-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test no = "$ld_shlibs" && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc=yes
+
+ if test yes,yes = "$GCC,$enable_shared"; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+ archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test yes = "$GCC"; then
+ case $host_os in
+ darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
+ *) lt_awk_arg='/^libraries:/' ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;;
+ *) lt_sed_strip_eq='s|=/|/|g' ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary...
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ # ...but if some path component already ends with the multilib dir we assume
+ # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
+ case "$lt_multi_os_dir; $lt_search_path_spec " in
+ "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
+ lt_multi_os_dir=
+ ;;
+ esac
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
+ elif test -n "$lt_multi_os_dir"; then
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS = " "; FS = "/|\n";} {
+ lt_foo = "";
+ lt_count = 0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo = "/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[lt_foo]++; }
+ if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's|/\([A-Za-z]:\)|\1|g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=.so
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 supports IA64
+ library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line '#! .'. This would cause the generated library to
+ # depend on '.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # Using Import Files as archive members, it is possible to support
+ # filename-based versioning of shared library archives on AIX. While
+ # this would work for both with and without runtime linking, it will
+ # prevent static linking of such archives. So we do filename-based
+ # shared library versioning with .so extension only, which is used
+ # when both runtime linking and shared linking is enabled.
+ # Unfortunately, runtime linking may impact performance, so we do
+ # not want this to be the default eventually. Also, we use the
+ # versioned .so libs for executables only if there is the -brtl
+ # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
+ # To allow for filename-based versioning support, we need to create
+ # libNAME.so.V as an archive file, containing:
+ # *) an Import File, referring to the versioned filename of the
+ # archive as well as the shared archive member, telling the
+ # bitwidth (32 or 64) of that shared object, and providing the
+ # list of exported symbols of that shared object, eventually
+ # decorated with the 'weak' keyword
+ # *) the shared object with the F_LOADONLY flag set, to really avoid
+ # it being seen by the linker.
+ # At run time we better use the real file rather than another symlink,
+ # but for link time we create the symlink libNAME.so -> libNAME.so.V
+
+ case $with_aix_soname,$aix_use_runtimelinking in
+ # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ aix,yes) # traditional libtool
+ dynamic_linker='AIX unversionable lib.so'
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ aix,no) # traditional AIX only
+ dynamic_linker='AIX lib.a(lib.so.V)'
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ svr4,*) # full svr4 only
+ dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,yes) # both, prefer svr4
+ dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # unpreferred sharedlib libNAME.a needs extra handling
+ postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
+ postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,no) # both, prefer aix
+ dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)"
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
+ postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
+ postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
+ ;;
+ esac
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='$libname$shared_ext'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ library_names_spec='$libname.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec=$LIB
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$major$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[23].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ if test 32 = "$HPUX_IA64_MODE"; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux32
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux64
+ fi
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[3-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+ sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+linux*android*)
+ version_type=none # Android doesn't support versioned libraries.
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext'
+ soname_spec='$libname$release$shared_ext'
+ finish_cmds=
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ dynamic_linker='Android linker'
+ # Don't embed -rpath directories since the linker doesn't support them.
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Ideally, we could use ldconfig to report *all* directores which are
+ # searched for libraries, however this is still not possible. Aside from not
+ # being certain /sbin/ldconfig is available, command
+ # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
+ # even though it is searched at run-time. Try to do the best guess by
+ # appending ld.so.conf contents (and includes) to the search path.
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd* | bitrig*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec=/usr/lib
+ need_lib_prefix=no
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ need_version=no
+ else
+ need_version=yes
+ fi
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+os2*)
+ libname_spec='$name'
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+ # OS/2 can only load a DLL with a base name of 8 characters or less.
+ soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
+ v=$($ECHO $release$versuffix | tr -d .-);
+ n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
+ $ECHO $n$v`$shared_ext'
+ library_names_spec='${libname}_dll.$libext'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=BEGINLIBPATH
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test yes = "$with_gnu_ld"; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+ soname_spec='$libname$shared_ext.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=sco
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test yes = "$with_gnu_ld"; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test no = "$dynamic_linker" && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test yes = "$GCC"; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+ sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+fi
+
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+ sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+fi
+
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
+
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+ test -n "$runpath_var" ||
+ test yes = "$hardcode_automatic"; then
+
+ # We can hardcode non-existent directories.
+ if test no != "$hardcode_direct" &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" &&
+ test no != "$hardcode_minus_L"; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test relink = "$hardcode_action" ||
+ test yes = "$inherit_rpath"; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test yes = "$shlibpath_overrides_runpath" ||
+ test no = "$enable_shared"; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+ if test yes != "$enable_dlopen"; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen=load_add_on
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen=LoadLibrary
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+else
+
+ lt_cv_dlopen=dyld
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+
+fi
+
+ ;;
+
+ tpf*)
+ # Don't try to run any link tests for TPF. We know it's impossible
+ # because TPF is a cross-compiler, and we know how we open DSOs.
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=no
+ ;;
+
+ *)
+ ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = xyes; then :
+ lt_cv_dlopen=shl_load
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_shl_load=yes
+else
+ ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+ lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld
+else
+ ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if ${ac_cv_lib_svld_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_svld_dlopen=yes
+else
+ ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if ${ac_cv_lib_dld_dld_link+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_dld_link=yes
+else
+ ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+ lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test no = "$lt_cv_dlopen"; then
+ enable_dlopen=no
+ else
+ enable_dlopen=yes
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS=$CPPFLAGS
+ test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS=$LDFLAGS
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS=$LIBS
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test yes = "$cross_compiling"; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+ if test yes = "$lt_cv_dlopen_self"; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self_static+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test yes = "$cross_compiling"; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+ fi
+
+ CPPFLAGS=$save_CPPFLAGS
+ LDFLAGS=$save_LDFLAGS
+ LIBS=$save_LIBS
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP"; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+ # Report what library types will actually be built
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+CC=$lt_save_CC
+
+ if test -n "$CXX" && ( test no != "$CXX" &&
+ ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
+ (test g++ != "$CXX"))); then
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
+$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
+if test -z "$CXXCPP"; then
+ if ${ac_cv_prog_CXXCPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CXXCPP needs to be expanded
+ for CXXCPP in "$CXX -E" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+ CXXCPP=$ac_cv_prog_CXXCPP
+else
+ ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+else
+ _lt_caught_CXX_error=yes
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+archive_cmds_need_lc_CXX=no
+allow_undefined_flag_CXX=
+always_export_symbols_CXX=no
+archive_expsym_cmds_CXX=
+compiler_needs_object_CXX=no
+export_dynamic_flag_spec_CXX=
+hardcode_direct_CXX=no
+hardcode_direct_absolute_CXX=no
+hardcode_libdir_flag_spec_CXX=
+hardcode_libdir_separator_CXX=
+hardcode_minus_L_CXX=no
+hardcode_shlibpath_var_CXX=unsupported
+hardcode_automatic_CXX=no
+inherit_rpath_CXX=no
+module_cmds_CXX=
+module_expsym_cmds_CXX=
+link_all_deplibs_CXX=unknown
+old_archive_cmds_CXX=$old_archive_cmds
+reload_flag_CXX=$reload_flag
+reload_cmds_CXX=$reload_cmds
+no_undefined_flag_CXX=
+whole_archive_flag_spec_CXX=
+enable_shared_with_static_runtimes_CXX=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+objext_CXX=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_caught_CXX_error"; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="int some_variable = 0;"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code='int main(int, char *[]) { return(0); }'
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+ # save warnings/boilerplate of simple test code
+ ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_CFLAGS=$CFLAGS
+ lt_save_LD=$LD
+ lt_save_GCC=$GCC
+ GCC=$GXX
+ lt_save_with_gnu_ld=$with_gnu_ld
+ lt_save_path_LD=$lt_cv_path_LD
+ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+ else
+ $as_unset lt_cv_prog_gnu_ld
+ fi
+ if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+ else
+ $as_unset lt_cv_path_LD
+ fi
+ test -z "${LDCXX+set}" || LD=$LDCXX
+ CC=${CXX-"c++"}
+ CFLAGS=$CXXFLAGS
+ compiler=$CC
+ compiler_CXX=$CC
+ func_cc_basename $compiler
+cc_basename=$func_cc_basename_result
+
+
+ if test -n "$compiler"; then
+ # We don't want -fno-exception when compiling C++ code, so set the
+ # no_builtin_flag separately
+ if test yes = "$GXX"; then
+ lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
+ else
+ lt_prog_compiler_no_builtin_flag_CXX=
+ fi
+
+ if test yes = "$GXX"; then
+ # Set up default GNU C++ configuration
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+ withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test yes = "$GCC"; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return, which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD=$ac_prog
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test yes = "$with_gnu_ld"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD=$ac_dir/$ac_prog
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test no != "$with_gnu_ld" && break
+ ;;
+ *)
+ test yes != "$with_gnu_ld" && break
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+else
+ lt_cv_path_LD=$LD # Let the user override the test with a path.
+fi
+fi
+
+LD=$lt_cv_path_LD
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test yes = "$with_gnu_ld"; then
+ archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+
+ hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
+ export_dynamic_flag_spec_CXX='$wl--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='$wl'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+ $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ whole_archive_flag_spec_CXX=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+ fi
+
+ # PORTME: fill in a description of your system's C++ link characteristics
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+ ld_shlibs_CXX=yes
+ case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ aix[4-9]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # have runtime linking enabled, and use it for executables.
+ # For shared libraries, we enable/disable runtime linking
+ # depending on the kind of the shared library created -
+ # when "with_aix_soname,aix_use_runtimelinking" is:
+ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
+ # "aix,yes" lib.so shared, rtl:yes, for executables
+ # lib.a static archive
+ # "both,no" lib.so.V(shr.o) shared, rtl:yes
+ # lib.a(lib.so.V) shared, rtl:no, for executables
+ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a(lib.so.V) shared, rtl:no
+ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a static archive
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # With aix-soname=svr4, we create the lib.so.V shared archives only,
+ # so we don't have lib.a shared libs to link our executables.
+ # We have to force runtime linking in this case.
+ aix_use_runtimelinking=yes
+ LDFLAGS="$LDFLAGS -Wl,-brtl"
+ fi
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds_CXX=''
+ hardcode_direct_CXX=yes
+ hardcode_direct_absolute_CXX=yes
+ hardcode_libdir_separator_CXX=':'
+ link_all_deplibs_CXX=yes
+ file_list_spec_CXX='$wl-f,'
+ case $with_aix_soname,$aix_use_runtimelinking in
+ aix,*) ;; # no import file
+ svr4,* | *,yes) # use import file
+ # The Import File defines what to hardcode.
+ hardcode_direct_CXX=no
+ hardcode_direct_absolute_CXX=no
+ ;;
+ esac
+
+ if test yes = "$GXX"; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct_CXX=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L_CXX=yes
+ hardcode_libdir_flag_spec_CXX='-L$libdir'
+ hardcode_libdir_separator_CXX=
+ fi
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag=$shared_flag' $wl-G'
+ fi
+ # Need to ensure runtime linking is disabled for the traditional
+ # shared library, or the linker may eventually find shared libraries
+ # /with/ Import File - we do not want to mix them.
+ shared_flag_aix='-shared'
+ shared_flag_svr4='-shared $wl-G'
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ shared_flag_aix='$wl-bM:SRE'
+ shared_flag_svr4='$wl-G'
+ fi
+ fi
+
+ export_dynamic_flag_spec_CXX='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to
+ # export.
+ always_export_symbols_CXX=yes
+ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ # The "-G" linker flag allows undefined symbols.
+ no_undefined_flag_CXX='-bernotok'
+ # Determine the default libpath from the value encoded in an empty
+ # executable.
+ if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath__CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath__CXX"; then
+ lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath__CXX"; then
+ lt_cv_aix_libpath__CXX=/usr/lib:/lib
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+ hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath"
+
+ archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag_CXX="-z nodefs"
+ archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath__CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath__CXX"; then
+ lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath__CXX"; then
+ lt_cv_aix_libpath__CXX=/usr/lib:/lib
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+ hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag_CXX=' $wl-bernotok'
+ allow_undefined_flag_CXX=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec_CXX='$convenience'
+ fi
+ archive_cmds_need_lc_CXX=yes
+ archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+ # -brtl affects multiple linker settings, -berok does not and is overridden later
+ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`'
+ if test svr4 != "$with_aix_soname"; then
+ # This is similar to how AIX traditionally builds its shared
+ # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
+ archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+ fi
+ if test aix != "$with_aix_soname"; then
+ archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+ else
+ # used by -dlpreopen to get the symbols
+ archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
+ fi
+ archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag_CXX=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ ld_shlibs_CXX=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $GXX,$cc_basename in
+ ,cl* | no,cl*)
+ # Native MSVC
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec_CXX=' '
+ allow_undefined_flag_CXX=unsupported
+ always_export_symbols_CXX=yes
+ file_list_spec_CXX='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true'
+ enable_shared_with_static_runtimes_CXX=yes
+ # Don't use ranlib
+ old_postinstall_cmds_CXX='chmod 644 $oldlib'
+ postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ func_to_tool_file "$lt_outputfile"~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # g++
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec_CXX='-L$libdir'
+ export_dynamic_flag_spec_CXX='$wl--export-all-symbols'
+ allow_undefined_flag_CXX=unsupported
+ always_export_symbols_CXX=no
+ enable_shared_with_static_runtimes_CXX=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc_CXX=no
+ hardcode_direct_CXX=no
+ hardcode_automatic_CXX=yes
+ hardcode_shlibpath_var_CXX=unsupported
+ if test yes = "$lt_cv_ld_force_load"; then
+ whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+ else
+ whole_archive_flag_spec_CXX=''
+ fi
+ link_all_deplibs_CXX=yes
+ allow_undefined_flag_CXX=$_lt_dar_allow_undefined
+ case $cc_basename in
+ ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test yes = "$_lt_dar_can_shared"; then
+ output_verbose_link_cmd=func_echo_all
+ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+ archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+ module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+ if test yes != "$lt_cv_apple_cc_single_mod"; then
+ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
+ archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
+ fi
+
+ else
+ ld_shlibs_CXX=no
+ fi
+
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec_CXX='-L$libdir'
+ hardcode_minus_L_CXX=yes
+ allow_undefined_flag_CXX=unsupported
+ shrext_cmds=.dll
+ archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ enable_shared_with_static_runtimes_CXX=yes
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ freebsd2.*)
+ # C++ shared libraries reported to be fairly broken before
+ # switch to ELF
+ ld_shlibs_CXX=no
+ ;;
+
+ freebsd-elf*)
+ archive_cmds_need_lc_CXX=no
+ ;;
+
+ freebsd* | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ ld_shlibs_CXX=yes
+ ;;
+
+ haiku*)
+ archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ link_all_deplibs_CXX=yes
+ ;;
+
+ hpux9*)
+ hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir'
+ hardcode_libdir_separator_CXX=:
+ export_dynamic_flag_spec_CXX='$wl-E'
+ hardcode_direct_CXX=yes
+ hardcode_minus_L_CXX=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ aCC*)
+ archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ esac
+ ;;
+
+ hpux10*|hpux11*)
+ if test no = "$with_gnu_ld"; then
+ hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir'
+ hardcode_libdir_separator_CXX=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ export_dynamic_flag_spec_CXX='$wl-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ ;;
+ *)
+ hardcode_direct_CXX=yes
+ hardcode_direct_absolute_CXX=yes
+ hardcode_minus_L_CXX=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ if test no = "$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
+ export_dynamic_flag_spec_CXX='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ if test no = "$with_gnu_ld"; then
+ archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
+ fi
+ fi
+ link_all_deplibs_CXX=yes
+ ;;
+ esac
+ hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator_CXX=:
+ inherit_rpath_CXX=yes
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+ hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
+ export_dynamic_flag_spec_CXX='$wl--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc* | ecpc* )
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ archive_cmds_need_lc_CXX=no
+ hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
+ export_dynamic_flag_spec_CXX='$wl--export-dynamic'
+ whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ case `$CC -V` in
+ *pgCC\ [1-5].* | *pgcpp\ [1-5].*)
+ prelink_cmds_CXX='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+ old_archive_cmds_CXX='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+ $RANLIB $oldlib'
+ archive_cmds_CXX='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 6 and above use weak symbols
+ archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+
+ hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir'
+ export_dynamic_flag_spec_CXX='$wl--export-dynamic'
+ whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+ hardcode_libdir_separator_CXX=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+ ;;
+ xl* | mpixl* | bgxl*)
+ # IBM XL 8.0 on PPC, with GNU ld
+ hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
+ export_dynamic_flag_spec_CXX='$wl--export-dynamic'
+ archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ no_undefined_flag_CXX=' -zdefs'
+ archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
+ hardcode_libdir_flag_spec_CXX='-R$libdir'
+ whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ compiler_needs_object_CXX=yes
+
+ # Not sure whether something based on
+ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+ # would be better.
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+
+ m88k*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ hardcode_libdir_flag_spec_CXX='-R$libdir'
+ hardcode_direct_CXX=yes
+ hardcode_shlibpath_var_CXX=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+
+ *nto* | *qnx*)
+ ld_shlibs_CXX=yes
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct_CXX=yes
+ hardcode_shlibpath_var_CXX=no
+ hardcode_direct_absolute_CXX=yes
+ archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
+ archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
+ export_dynamic_flag_spec_CXX='$wl-E'
+ whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ fi
+ output_verbose_link_cmd=func_echo_all
+ else
+ ld_shlibs_CXX=no
+ fi
+ ;;
+
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
+ hardcode_libdir_separator_CXX=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ case $host in
+ osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;;
+ *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;;
+ esac
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ cxx*)
+ case $host in
+ osf3*)
+ allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*'
+ archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
+ ;;
+ *)
+ allow_undefined_flag_CXX=' -expect_unresolved \*'
+ archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
+ $RM $lib.exp'
+ hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+ ;;
+ esac
+
+ hardcode_libdir_separator_CXX=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes,no = "$GXX,$with_gnu_ld"; then
+ allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*'
+ case $host in
+ osf3*)
+ archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ ;;
+ esac
+
+ hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator_CXX=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ esac
+ ;;
+
+ psos*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ archive_cmds_need_lc_CXX=yes
+ no_undefined_flag_CXX=' -zdefs'
+ archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ hardcode_libdir_flag_spec_CXX='-R$libdir'
+ hardcode_shlibpath_var_CXX=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
+ ;;
+ esac
+ link_all_deplibs_CXX=yes
+
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test yes,no = "$GXX,$with_gnu_ld"; then
+ no_undefined_flag_CXX=' $wl-z ${wl}defs'
+ if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+ archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ else
+ # g++ 2.7 appears to require '-G' NOT '-shared' on this
+ # platform.
+ archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ fi
+
+ hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir'
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag_CXX='$wl-z,text'
+ archive_cmds_need_lc_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag_CXX='$wl-z,text'
+ allow_undefined_flag_CXX='$wl-z,nodefs'
+ archive_cmds_need_lc_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ hardcode_libdir_flag_spec_CXX='$wl-R,$libdir'
+ hardcode_libdir_separator_CXX=':'
+ link_all_deplibs_CXX=yes
+ export_dynamic_flag_spec_CXX='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~
+ '"$old_archive_cmds_CXX"
+ reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~
+ '"$reload_cmds_CXX"
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+ test no = "$ld_shlibs_CXX" && can_build_shared=no
+
+ GCC_CXX=$GXX
+ LD_CXX=$LD
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ # Dependencies to place before and after the object being linked:
+predep_objects_CXX=
+postdep_objects_CXX=
+predeps_CXX=
+postdeps_CXX=
+compiler_lib_search_path_CXX=
+
+cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+_LT_EOF
+
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ for p in `eval "$output_verbose_link_cmd"`; do
+ case $prev$p in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test x-L = "$p" ||
+ test x-R = "$p"; then
+ prev=$p
+ continue
+ fi
+
+ # Expand the sysroot to ease extracting the directories later.
+ if test -z "$prev"; then
+ case $p in
+ -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+ -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+ -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+ esac
+ fi
+ case $p in
+ =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+ esac
+ if test no = "$pre_test_object_deps_done"; then
+ case $prev in
+ -L | -R)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$compiler_lib_search_path_CXX"; then
+ compiler_lib_search_path_CXX=$prev$p
+ else
+ compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$postdeps_CXX"; then
+ postdeps_CXX=$prev$p
+ else
+ postdeps_CXX="${postdeps_CXX} $prev$p"
+ fi
+ fi
+ prev=
+ ;;
+
+ *.lto.$objext) ;; # Ignore GCC LTO objects
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test no = "$pre_test_object_deps_done"; then
+ if test -z "$predep_objects_CXX"; then
+ predep_objects_CXX=$p
+ else
+ predep_objects_CXX="$predep_objects_CXX $p"
+ fi
+ else
+ if test -z "$postdep_objects_CXX"; then
+ postdep_objects_CXX=$p
+ else
+ postdep_objects_CXX="$postdep_objects_CXX $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling CXX test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+case $host_os in
+interix[3-9]*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ predep_objects_CXX=
+ postdep_objects_CXX=
+ postdeps_CXX=
+ ;;
+esac
+
+
+case " $postdeps_CXX " in
+*" -lc "*) archive_cmds_need_lc_CXX=no ;;
+esac
+ compiler_lib_search_dirs_CXX=
+if test -n "${compiler_lib_search_path_CXX}"; then
+ compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'`
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ lt_prog_compiler_wl_CXX=
+lt_prog_compiler_pic_CXX=
+lt_prog_compiler_static_CXX=
+
+
+ # C++ specific cases for pic, static, wl, etc.
+ if test yes = "$GXX"; then
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_static_CXX='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static_CXX='-Bstatic'
+ fi
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+ case $host_os in
+ os2*)
+ lt_prog_compiler_static_CXX='$wl-static'
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic_CXX='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ lt_prog_compiler_pic_CXX=
+ ;;
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static_CXX=
+ ;;
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic_CXX=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ ;;
+ *)
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+ esac
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic_CXX='-fPIC -shared'
+ ;;
+ *)
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix[4-9]*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static_CXX='-Bstatic'
+ else
+ lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ lt_prog_compiler_pic_CXX='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ lt_prog_compiler_pic_CXX='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_static_CXX='$wl-a ${wl}archive'
+ if test ia64 != "$host_cpu"; then
+ lt_prog_compiler_pic_CXX='+Z'
+ fi
+ ;;
+ aCC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_static_CXX='$wl-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic_CXX='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_static_CXX='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ lt_prog_compiler_wl_CXX='--backend -Wl,'
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+ ecpc* )
+ # old Intel C++ for x86_64, which still supported -KPIC.
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-static'
+ ;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-fPIC'
+ lt_prog_compiler_static_CXX='-static'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-fpic'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ lt_prog_compiler_pic_CXX=
+ lt_prog_compiler_static_CXX='-non_shared'
+ ;;
+ xlc* | xlC* | bgxl[cC]* | mpixl[cC]*)
+ # IBM XL 8.0, 9.0 on PPC and BlueGene
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-qpic'
+ lt_prog_compiler_static_CXX='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ lt_prog_compiler_wl_CXX='-Qoption ld '
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ lt_prog_compiler_pic_CXX='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd* | netbsdelf*-gnu)
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic_CXX='-fPIC -shared'
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ lt_prog_compiler_wl_CXX='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ lt_prog_compiler_pic_CXX='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ lt_prog_compiler_wl_CXX='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ lt_prog_compiler_pic_CXX=
+ lt_prog_compiler_static_CXX='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ lt_prog_compiler_wl_CXX='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ lt_prog_compiler_pic_CXX='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ lt_prog_compiler_pic_CXX='-pic'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ lt_prog_compiler_pic_CXX='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ lt_prog_compiler_pic_CXX='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ lt_prog_compiler_can_build_shared_CXX=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms that do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic_CXX=
+ ;;
+ *)
+ lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; }
+lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works_CXX=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works_CXX=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then
+ case $lt_prog_compiler_pic_CXX in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
+ esac
+else
+ lt_prog_compiler_pic_CXX=
+ lt_prog_compiler_can_build_shared_CXX=no
+fi
+
+fi
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works_CXX=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works_CXX=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works_CXX=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then
+ :
+else
+ lt_prog_compiler_static_CXX=
+fi
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o_CXX=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o_CXX=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o_CXX=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o_CXX=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+
+hard_links=nottested
+if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test no = "$hard_links"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ case $host_os in
+ aix[4-9]*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+ # Without the "-l" option, or with the "-B" option, AIX nm treats
+ # weak defined symbols like other global defined symbols, whereas
+ # GNU nm marks them as "W".
+ # While the 'weak' keyword is ignored in the Export File, we need
+ # it in the Import File for the 'aix-soname' feature, so we have
+ # to replace the "-B" option with "-P" for AIX nm.
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ export_symbols_cmds_CXX=$ltdll_cmds
+ ;;
+ cygwin* | mingw* | cegcc*)
+ case $cc_basename in
+ cl*)
+ exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ ;;
+ *)
+ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | gnu*)
+ link_all_deplibs_CXX=no
+ ;;
+ *)
+ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+test no = "$ld_shlibs_CXX" && can_build_shared=no
+
+with_gnu_ld_CXX=$with_gnu_ld
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_CXX" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc_CXX=yes
+
+ if test yes,yes = "$GCC,$enable_shared"; then
+ case $archive_cmds_CXX in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl_CXX
+ pic_flag=$lt_prog_compiler_pic_CXX
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
+ allow_undefined_flag_CXX=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ lt_cv_archive_cmds_need_lc_CXX=no
+ else
+ lt_cv_archive_cmds_need_lc_CXX=yes
+ fi
+ allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; }
+ archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=.so
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 supports IA64
+ library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line '#! .'. This would cause the generated library to
+ # depend on '.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # Using Import Files as archive members, it is possible to support
+ # filename-based versioning of shared library archives on AIX. While
+ # this would work for both with and without runtime linking, it will
+ # prevent static linking of such archives. So we do filename-based
+ # shared library versioning with .so extension only, which is used
+ # when both runtime linking and shared linking is enabled.
+ # Unfortunately, runtime linking may impact performance, so we do
+ # not want this to be the default eventually. Also, we use the
+ # versioned .so libs for executables only if there is the -brtl
+ # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
+ # To allow for filename-based versioning support, we need to create
+ # libNAME.so.V as an archive file, containing:
+ # *) an Import File, referring to the versioned filename of the
+ # archive as well as the shared archive member, telling the
+ # bitwidth (32 or 64) of that shared object, and providing the
+ # list of exported symbols of that shared object, eventually
+ # decorated with the 'weak' keyword
+ # *) the shared object with the F_LOADONLY flag set, to really avoid
+ # it being seen by the linker.
+ # At run time we better use the real file rather than another symlink,
+ # but for link time we create the symlink libNAME.so -> libNAME.so.V
+
+ case $with_aix_soname,$aix_use_runtimelinking in
+ # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ aix,yes) # traditional libtool
+ dynamic_linker='AIX unversionable lib.so'
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ aix,no) # traditional AIX only
+ dynamic_linker='AIX lib.a(lib.so.V)'
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ svr4,*) # full svr4 only
+ dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,yes) # both, prefer svr4
+ dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # unpreferred sharedlib libNAME.a needs extra handling
+ postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
+ postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,no) # both, prefer aix
+ dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)"
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
+ postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
+ postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
+ ;;
+ esac
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='$libname$shared_ext'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ library_names_spec='$libname.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec=$LIB
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$major$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[23].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ if test 32 = "$HPUX_IA64_MODE"; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux32
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux64
+ fi
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[3-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+ sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+linux*android*)
+ version_type=none # Android doesn't support versioned libraries.
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext'
+ soname_spec='$libname$release$shared_ext'
+ finish_cmds=
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ dynamic_linker='Android linker'
+ # Don't embed -rpath directories since the linker doesn't support them.
+ hardcode_libdir_flag_spec_CXX='-L$libdir'
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Ideally, we could use ldconfig to report *all* directores which are
+ # searched for libraries, however this is still not possible. Aside from not
+ # being certain /sbin/ldconfig is available, command
+ # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
+ # even though it is searched at run-time. Try to do the best guess by
+ # appending ld.so.conf contents (and includes) to the search path.
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd* | bitrig*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec=/usr/lib
+ need_lib_prefix=no
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ need_version=no
+ else
+ need_version=yes
+ fi
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+os2*)
+ libname_spec='$name'
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+ # OS/2 can only load a DLL with a base name of 8 characters or less.
+ soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
+ v=$($ECHO $release$versuffix | tr -d .-);
+ n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
+ $ECHO $n$v`$shared_ext'
+ library_names_spec='${libname}_dll.$libext'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=BEGINLIBPATH
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test yes = "$with_gnu_ld"; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+ soname_spec='$libname$shared_ext.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=sco
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test yes = "$with_gnu_ld"; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test no = "$dynamic_linker" && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test yes = "$GCC"; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+ sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+fi
+
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+ sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+fi
+
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
+
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action_CXX=
+if test -n "$hardcode_libdir_flag_spec_CXX" ||
+ test -n "$runpath_var_CXX" ||
+ test yes = "$hardcode_automatic_CXX"; then
+
+ # We can hardcode non-existent directories.
+ if test no != "$hardcode_direct_CXX" &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" &&
+ test no != "$hardcode_minus_L_CXX"; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action_CXX=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action_CXX=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action_CXX=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5
+$as_echo "$hardcode_action_CXX" >&6; }
+
+if test relink = "$hardcode_action_CXX" ||
+ test yes = "$inherit_rpath_CXX"; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test yes = "$shlibpath_overrides_runpath" ||
+ test no = "$enable_shared"; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+
+ fi # test -n "$compiler"
+
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+ LDCXX=$LD
+ LD=$lt_save_LD
+ GCC=$lt_save_GCC
+ with_gnu_ld=$lt_save_with_gnu_ld
+ lt_cv_path_LDCXX=$lt_cv_path_LD
+ lt_cv_path_LD=$lt_save_path_LD
+ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test yes != "$_lt_caught_CXX_error"
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+
+
+
+
+
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PKG_CONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $PKG_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+ ac_pt_PKG_CONFIG=$PKG_CONFIG
+ # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $ac_pt_PKG_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+if test -n "$ac_pt_PKG_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+$as_echo "$ac_pt_PKG_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_pt_PKG_CONFIG" = x; then
+ PKG_CONFIG=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ PKG_CONFIG=$ac_pt_PKG_CONFIG
+ fi
+else
+ PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+fi
+
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=0.20
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ PKG_CONFIG=""
+ fi
+fi
+
+# ========================================
+# Specify the fontdir patch if not default
+# ========================================
+
+# Check whether --with-fontdir was given.
+if test "${with_fontdir+set}" = set; then :
+ withval=$with_fontdir; FONTDIR="$withval"
+else
+ FONTDIR="fonts/conf.d"
+
+fi
+
+
+
+# ================================
+# Find CUPS internals (no pc file)
+# ================================
+
+# Check whether --with-cups-config was given.
+if test "${with_cups_config+set}" = set; then :
+ withval=$with_cups_config; with_cups_config="$withval"
+else
+ with_cups_config=system
+
+fi
+
+
+if test "x$with_cups_config" != "xsystem"; then :
+
+ CUPSCONFIG=$with_cups_config
+
+else
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cups-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cups-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_CUPSCONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $CUPSCONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_CUPSCONFIG="$CUPSCONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_CUPSCONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+CUPSCONFIG=$ac_cv_path_CUPSCONFIG
+if test -n "$CUPSCONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CUPSCONFIG" >&5
+$as_echo "$CUPSCONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_CUPSCONFIG"; then
+ ac_pt_CUPSCONFIG=$CUPSCONFIG
+ # Extract the first word of "cups-config", so it can be a program name with args.
+set dummy cups-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_CUPSCONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $ac_pt_CUPSCONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ac_pt_CUPSCONFIG="$ac_pt_CUPSCONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_ac_pt_CUPSCONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+ac_pt_CUPSCONFIG=$ac_cv_path_ac_pt_CUPSCONFIG
+if test -n "$ac_pt_CUPSCONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CUPSCONFIG" >&5
+$as_echo "$ac_pt_CUPSCONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_pt_CUPSCONFIG" = x; then
+ CUPSCONFIG=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CUPSCONFIG=$ac_pt_CUPSCONFIG
+ fi
+else
+ CUPSCONFIG="$ac_cv_path_CUPSCONFIG"
+fi
+
+ if test -z "$CUPSCONFIG"; then :
+
+ as_fn_error $? "Required cups-config is missing. Please install CUPS developer packages." "$LINENO" 5
+
+fi
+
+fi
+CUPS_CFLAGS=`$CUPSCONFIG --cflags`
+CUPS_LIBS=`$CUPSCONFIG --image --libs`
+CUPS_VERSION=`$CUPSCONFIG --version`
+
+
+
+CUPS_DATADIR="`$CUPSCONFIG --datadir`"
+
+cat >>confdefs.h <<_ACEOF
+#define CUPS_DATADIR "$CUPS_DATADIR"
+_ACEOF
+
+
+
+CUPS_SERVERROOT="`$CUPSCONFIG --serverroot`"
+
+cat >>confdefs.h <<_ACEOF
+#define CUPS_SERVERROOT "$CUPS_SERVERROOT"
+_ACEOF
+
+
+
+CUPS_FONTPATH="$CUPS_DATADIR/fonts"
+
+cat >>confdefs.h <<_ACEOF
+#define CUPS_FONTPATH "$CUPS_FONTPATH"
+_ACEOF
+
+
+
+CUPS_SERVERBIN="`$CUPSCONFIG --serverbin`"
+
+cat >>confdefs.h <<_ACEOF
+#define CUPS_SERVERBIN "$CUPS_SERVERBIN"
+_ACEOF
+
+
+
+
+
+
+ # Used to indicate true or false condition
+ ax_compare_version=false
+
+ # Convert the two version strings to be compared into a format that
+ # allows a simple string comparison. The end result is that a version
+ # string of the form 1.12.5-r617 will be converted to the form
+ # 0001001200050617. In other words, each number is zero padded to four
+ # digits, and non digits are removed.
+
+ ax_compare_version_A=`echo "$CUPS_VERSION" | sed -e 's/\([0-9]*\)/Z\1Z/g' \
+ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \
+ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \
+ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \
+ -e 's/[^0-9]//g'`
+
+
+ ax_compare_version_B=`echo "1.4" | sed -e 's/\([0-9]*\)/Z\1Z/g' \
+ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \
+ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \
+ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \
+ -e 's/[^0-9]//g'`
+
+
+ ax_compare_version=`echo "x$ax_compare_version_A
+x$ax_compare_version_B" | sed 's/^ *//' | sort | sed "s/x${ax_compare_version_A}/false/;s/x${ax_compare_version_B}/true/;1q"`
+
+
+
+ if test "$ax_compare_version" = "true" ; then
+
+
+$as_echo "#define CUPS_1_4 1" >>confdefs.h
+
+
+ fi
+
+
+# Check whether --enable-driverless was given.
+if test "${enable_driverless+set}" = set; then :
+ enableval=$enable_driverless; enable_driverless="$enableval"
+else
+ enable_driverless=yes
+
+fi
+
+
+
+
+ # Used to indicate true or false condition
+ ax_compare_version=false
+
+ # Convert the two version strings to be compared into a format that
+ # allows a simple string comparison. The end result is that a version
+ # string of the form 1.12.5-r617 will be converted to the form
+ # 0001001200050617. In other words, each number is zero padded to four
+ # digits, and non digits are removed.
+
+ ax_compare_version_A=`echo "$CUPS_VERSION" | sed -e 's/\([0-9]*\)/Z\1Z/g' \
+ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \
+ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \
+ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \
+ -e 's/[^0-9]//g'`
+
+
+ ax_compare_version_B=`echo "1.6" | sed -e 's/\([0-9]*\)/Z\1Z/g' \
+ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \
+ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \
+ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \
+ -e 's/[^0-9]//g'`
+
+
+ ax_compare_version=`echo "x$ax_compare_version_A
+x$ax_compare_version_B" | sed 's/^ *//' | sort -r | sed "s/x${ax_compare_version_A}/true/;s/x${ax_compare_version_B}/false/;1q"`
+
+
+
+ if test "$ax_compare_version" = "true" ; then
+
+ if test "x$enable_driverless" != "xno"; then
+ ENABLE_DRIVERLESS_TRUE=
+ ENABLE_DRIVERLESS_FALSE='#'
+else
+ ENABLE_DRIVERLESS_TRUE='#'
+ ENABLE_DRIVERLESS_FALSE=
+fi
+
+
+ fi
+
+
+APPLE_RASTER_FILTER=rastertopdf
+
+
+
+ # Used to indicate true or false condition
+ ax_compare_version=false
+
+ # Convert the two version strings to be compared into a format that
+ # allows a simple string comparison. The end result is that a version
+ # string of the form 1.12.5-r617 will be converted to the form
+ # 0001001200050617. In other words, each number is zero padded to four
+ # digits, and non digits are removed.
+
+ ax_compare_version_A=`echo "$CUPS_VERSION" | sed -e 's/\([0-9]*\)/Z\1Z/g' \
+ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \
+ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \
+ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \
+ -e 's/[^0-9]//g'`
+
+
+ ax_compare_version_B=`echo "2.2.2" | sed -e 's/\([0-9]*\)/Z\1Z/g' \
+ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \
+ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \
+ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \
+ -e 's/[^0-9]//g'`
+
+
+ ax_compare_version=`echo "x$ax_compare_version_A
+x$ax_compare_version_B" | sed 's/^ *//' | sort -r | sed "s/x${ax_compare_version_A}/false/;s/x${ax_compare_version_B}/true/;1q"`
+
+
+
+ if test "$ax_compare_version" = "true" ; then
+
+ APPLE_RASTER_FILTER=urftopdf
+
+ fi
+
+
+# Check whether --with-apple-raster-filter was given.
+if test "${with_apple_raster_filter+set}" = set; then :
+ withval=$with_apple_raster_filter; with_apple_raster_filter="$withval"
+else
+ with_apple_raster_filter="$APPLE_RASTER_FILTER"
+
+fi
+
+case x$with_apple_raster_filter in #(
+ xrastertopdf|xurftopdf) :
+ APPLE_RASTER_FILTER=$with_apple_raster_filter ;; #(
+ *) :
+ as_fn_error $? "Unknown value of with-apple-raster-filter provided: $with_apple_raster_filter" "$LINENO" 5
+ ;;
+esac
+ if test "x$APPLE_RASTER_FILTER" == "xurftopdf"; then
+ ENABLE_URFTOPDF_TRUE=
+ ENABLE_URFTOPDF_FALSE='#'
+else
+ ENABLE_URFTOPDF_TRUE='#'
+ ENABLE_URFTOPDF_FALSE=
+fi
+
+
+
+
+$as_echo "#define PDFTOPDF /**/" >>confdefs.h
+
+
+ prefix_NONE=
+ exec_prefix_NONE=
+ test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix
+ test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix
+ eval ac_define_dir="\"$"{CUPS_DATADIR}/data"\""
+ eval ac_define_dir="\"$ac_define_dir\""
+ BANNERTOPDF_DATADIR="$ac_define_dir"
+
+
+cat >>confdefs.h <<_ACEOF
+#define BANNERTOPDF_DATADIR "$ac_define_dir"
+_ACEOF
+
+ test "$prefix_NONE" && prefix=NONE
+ test "$exec_prefix_NONE" && exec_prefix=NONE
+
+
+# Check whether --enable-auto-setup-driverless was given.
+if test "${enable_auto_setup_driverless+set}" = set; then :
+ enableval=$enable_auto_setup_driverless; enable_auto_setup_driverless="$enableval"
+else
+ enable_auto_setup_driverless=no
+
+fi
+
+if test "x$enable_auto_setup_driverless" != "xno"; then
+
+$as_echo "#define DRIVERLESS_IPP_PRINTERS_AUTO_SETUP /**/" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5
+$as_echo_n "checking for library containing dlopen... " >&6; }
+if ${ac_cv_search_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' dl; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_search_dlopen=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_dlopen+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_dlopen+:} false; then :
+
+else
+ ac_cv_search_dlopen=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5
+$as_echo "$ac_cv_search_dlopen" >&6; }
+ac_res=$ac_cv_search_dlopen
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+ if test "$ac_cv_search_dlopen" != "none required"; then :
+
+ DLOPEN_LIBS="$ac_cv_search_dlopen"
+
+fi
+else
+ as_fn_error $? "unable to find the dlopen() function" "$LINENO" 5
+
+fi
+
+
+
+# Transient run-time state dir of CUPS
+CUPS_STATEDIR=""
+
+# Check whether --with-cups-rundir was given.
+if test "${with_cups_rundir+set}" = set; then :
+ withval=$with_cups_rundir; CUPS_STATEDIR="$withval"
+else
+
+ case "$uname" in
+ Darwin*)
+ # Darwin (OS X)
+ CUPS_STATEDIR="$CUPS_SERVERROOT"
+ ;;
+ *)
+ # All others
+ CUPS_STATEDIR="$localstatedir/run/cups"
+ ;;
+ esac
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define CUPS_STATEDIR "$CUPS_STATEDIR"
+_ACEOF
+
+
+
+# Domain socket of CUPS...
+CUPS_DEFAULT_DOMAINSOCKET=""
+
+# Check whether --with-cups-domainsocket was given.
+if test "${with_cups_domainsocket+set}" = set; then :
+ withval=$with_cups_domainsocket; default_domainsocket="$withval"
+else
+ default_domainsocket=""
+fi
+
+
+if test x$enable_domainsocket != xno -a x$default_domainsocket != xno; then
+ if test "x$default_domainsocket" = x; then
+ case "$uname" in
+ Darwin*)
+ # Darwin and MaxOS X do their own thing...
+ CUPS_DEFAULT_DOMAINSOCKET="$localstatedir/run/cupsd"
+ ;;
+ *)
+ # All others use FHS standard...
+ CUPS_DEFAULT_DOMAINSOCKET="$CUPS_STATEDIR/cups.sock"
+ ;;
+ esac
+ else
+ CUPS_DEFAULT_DOMAINSOCKET="$default_domainsocket"
+ fi
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define CUPS_DEFAULT_DOMAINSOCKET "$CUPS_DEFAULT_DOMAINSOCKET"
+_ACEOF
+
+
+
+# ======================
+# Check system functions
+# ======================
+for ac_func in strlcat
+do :
+ ac_fn_cxx_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat"
+if test "x$ac_cv_func_strlcat" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STRLCAT 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strlcpy
+do :
+ ac_fn_cxx_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy"
+if test "x$ac_cv_func_strlcpy" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STRLCPY 1
+_ACEOF
+
+fi
+done
+
+for ac_func in sigaction
+do :
+ ac_fn_cxx_check_func "$LINENO" "sigaction" "ac_cv_func_sigaction"
+if test "x$ac_cv_func_sigaction" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SIGACTION 1
+_ACEOF
+
+fi
+done
+
+for ac_func in waitpid wait3
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strtoll
+do :
+ ac_fn_cxx_check_func "$LINENO" "strtoll" "ac_cv_func_strtoll"
+if test "x$ac_cv_func_strtoll" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STRTOLL 1
+_ACEOF
+
+fi
+done
+
+for ac_func in open_memstream
+do :
+ ac_fn_cxx_check_func "$LINENO" "open_memstream" "ac_cv_func_open_memstream"
+if test "x$ac_cv_func_open_memstream" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_OPEN_MEMSTREAM 1
+_ACEOF
+
+fi
+done
+
+for ac_func in getline
+do :
+ ac_fn_cxx_check_func "$LINENO" "getline" "ac_cv_func_getline"
+if test "x$ac_cv_func_getline" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETLINE 1
+_ACEOF
+
+else
+ GETLINE='bannertopdf-getline.$(OBJEXT)'
+
+fi
+done
+
+for ac_func in strcasestr
+do :
+ ac_fn_cxx_check_func "$LINENO" "strcasestr" "ac_cv_func_strcasestr"
+if test "x$ac_cv_func_strcasestr" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STRCASESTR 1
+_ACEOF
+
+else
+ STRCASESTR='pdftops-strcasestr.$(OBJEXT)'
+
+fi
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pow" >&5
+$as_echo_n "checking for library containing pow... " >&6; }
+if ${ac_cv_search_pow+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pow ();
+int
+main ()
+{
+return pow ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' m; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_search_pow=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_pow+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_pow+:} false; then :
+
+else
+ ac_cv_search_pow=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pow" >&5
+$as_echo "$ac_cv_search_pow" >&6; }
+ac_res=$ac_cv_search_pow
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+
+# ========================
+# Check for system headers
+# ========================
+
+for ac_header in stdlib.h
+do :
+ ac_fn_cxx_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STDLIB_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in sys/stat.h
+do :
+ ac_fn_cxx_check_header_mongrel "$LINENO" "sys/stat.h" "ac_cv_header_sys_stat_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_stat_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_STAT_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in sys/types.h
+do :
+ ac_fn_cxx_check_header_mongrel "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_types_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_TYPES_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in unistd.h
+do :
+ ac_fn_cxx_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default"
+if test "x$ac_cv_header_unistd_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_UNISTD_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in zlib.h
+do :
+ ac_fn_cxx_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_zlib_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_ZLIB_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in endian.h
+do :
+ ac_fn_cxx_check_header_mongrel "$LINENO" "endian.h" "ac_cv_header_endian_h" "$ac_includes_default"
+if test "x$ac_cv_header_endian_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_ENDIAN_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in dirent.h
+do :
+ ac_fn_cxx_check_header_mongrel "$LINENO" "dirent.h" "ac_cv_header_dirent_h" "$ac_includes_default"
+if test "x$ac_cv_header_dirent_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DIRENT_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in sys/ioctl.h
+do :
+ ac_fn_cxx_check_header_mongrel "$LINENO" "sys/ioctl.h" "ac_cv_header_sys_ioctl_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_ioctl_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_IOCTL_H 1
+_ACEOF
+
+fi
+
+done
+
+
+# =============
+# Image options
+# =============
+# Check whether --enable-imagefilters was given.
+if test "${enable_imagefilters+set}" = set; then :
+ enableval=$enable_imagefilters; enable_imagefilters="$enableval"
+else
+ enable_imagefilters=yes
+
+fi
+
+ if test "x$enable_imagefilters" != "xno"; then
+ ENABLE_IMAGEFILTERS_TRUE=
+ ENABLE_IMAGEFILTERS_FALSE='#'
+else
+ ENABLE_IMAGEFILTERS_TRUE='#'
+ ENABLE_IMAGEFILTERS_FALSE=
+fi
+
+
+# Libraries
+
+# Check whether --with-jpeg was given.
+if test "${with_jpeg+set}" = set; then :
+ withval=$with_jpeg; with_jpeg="$withval"
+else
+ with_jpeg=yes
+
+fi
+
+if test x"$with_jpeg" != "xno"; then :
+
+
+$as_echo "#define HAVE_LIBJPEG /**/" >>confdefs.h
+
+ for ac_header in jpeglib.h
+do :
+ ac_fn_cxx_check_header_mongrel "$LINENO" "jpeglib.h" "ac_cv_header_jpeglib_h" "$ac_includes_default"
+if test "x$ac_cv_header_jpeglib_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_JPEGLIB_H 1
+_ACEOF
+
+fi
+
+done
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing jpeg_destroy_decompress" >&5
+$as_echo_n "checking for library containing jpeg_destroy_decompress... " >&6; }
+if ${ac_cv_search_jpeg_destroy_decompress+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char jpeg_destroy_decompress ();
+int
+main ()
+{
+return jpeg_destroy_decompress ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' jpeg; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_search_jpeg_destroy_decompress=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_jpeg_destroy_decompress+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_jpeg_destroy_decompress+:} false; then :
+
+else
+ ac_cv_search_jpeg_destroy_decompress=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_jpeg_destroy_decompress" >&5
+$as_echo "$ac_cv_search_jpeg_destroy_decompress" >&6; }
+ac_res=$ac_cv_search_jpeg_destroy_decompress
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+ LIBJPEG_LIBS="-ljpeg"
+else
+ as_fn_error $? "jpeg libraries not found." "$LINENO" 5
+
+fi
+
+
+
+fi
+
+
+# Check whether --with-png was given.
+if test "${with_png+set}" = set; then :
+ withval=$with_png; with_png="$withval"
+else
+ with_png=yes
+
+fi
+
+if test x"$with_png" != "xno"; then :
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBPNG" >&5
+$as_echo_n "checking for LIBPNG... " >&6; }
+
+if test -n "$LIBPNG_CFLAGS"; then
+ pkg_cv_LIBPNG_CFLAGS="$LIBPNG_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpng\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libpng") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_LIBPNG_CFLAGS=`$PKG_CONFIG --cflags "libpng" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$LIBPNG_LIBS"; then
+ pkg_cv_LIBPNG_LIBS="$LIBPNG_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpng\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libpng") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_LIBPNG_LIBS=`$PKG_CONFIG --libs "libpng" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ LIBPNG_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libpng" 2>&1`
+ else
+ LIBPNG_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libpng" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$LIBPNG_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (libpng) were not met:
+
+$LIBPNG_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables LIBPNG_CFLAGS
+and LIBPNG_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables LIBPNG_CFLAGS
+and LIBPNG_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ LIBPNG_CFLAGS=$pkg_cv_LIBPNG_CFLAGS
+ LIBPNG_LIBS=$pkg_cv_LIBPNG_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+$as_echo "#define HAVE_LIBPNG /**/" >>confdefs.h
+
+
+fi
+
+
+# Check whether --with-tiff was given.
+if test "${with_tiff+set}" = set; then :
+ withval=$with_tiff; with_tiff="$withval"
+else
+ with_tiff=yes
+
+fi
+
+if test x"$with_tiff" != "xno"; then :
+
+
+$as_echo "#define HAVE_LIBTIFF /**/" >>confdefs.h
+
+ for ac_header in tiff.h
+do :
+ ac_fn_cxx_check_header_mongrel "$LINENO" "tiff.h" "ac_cv_header_tiff_h" "$ac_includes_default"
+if test "x$ac_cv_header_tiff_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_TIFF_H 1
+_ACEOF
+
+fi
+
+done
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing TIFFReadScanline" >&5
+$as_echo_n "checking for library containing TIFFReadScanline... " >&6; }
+if ${ac_cv_search_TIFFReadScanline+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char TIFFReadScanline ();
+int
+main ()
+{
+return TIFFReadScanline ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' tiff; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_search_TIFFReadScanline=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_TIFFReadScanline+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_TIFFReadScanline+:} false; then :
+
+else
+ ac_cv_search_TIFFReadScanline=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_TIFFReadScanline" >&5
+$as_echo "$ac_cv_search_TIFFReadScanline" >&6; }
+ac_res=$ac_cv_search_TIFFReadScanline
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+ LIBJPEG_LIBS="-ltiff"
+else
+ as_fn_error $? "tiff libraries not found." "$LINENO" 5
+
+fi
+
+
+
+fi
+
+# ==================================
+# Check for modules needed by utils/
+# ==================================
+
+AVAHI_LIBS=""
+AVAHI_CFLAGS=""
+AVAHI_GLIB_CFLAGS=""
+AVAHI_GLIB_LIBS=""
+
+# Check whether --enable-avahi was given.
+if test "${enable_avahi+set}" = set; then :
+ enableval=$enable_avahi; enable_avahi="$enableval"
+else
+ enable_avahi=yes
+
+fi
+
+ if test "x$enable_avahi" != "xno"; then
+ ENABLE_AVAHI_TRUE=
+ ENABLE_AVAHI_FALSE='#'
+else
+ ENABLE_AVAHI_TRUE='#'
+ ENABLE_AVAHI_FALSE=
+fi
+
+
+
+# Check whether --with-avahi-libs was given.
+if test "${with_avahi_libs+set}" = set; then :
+ withval=$with_avahi_libs; AVAHI_LIBS="-L$withval $AVAHI_LIBS"
+fi
+
+
+# Check whether --with-avahi-includes was given.
+if test "${with_avahi_includes+set}" = set; then :
+ withval=$with_avahi_includes; AVAHI_CFLAGS="-I$withval $AVAHI_CFLAGS"
+fi
+
+
+if test "x$enable_avahi" != xno; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for AVAHI" >&5
+$as_echo_n "checking for AVAHI... " >&6; }
+
+if test -n "$AVAHI_CFLAGS"; then
+ pkg_cv_AVAHI_CFLAGS="$AVAHI_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"avahi-client\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "avahi-client") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_AVAHI_CFLAGS=`$PKG_CONFIG --cflags "avahi-client" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$AVAHI_LIBS"; then
+ pkg_cv_AVAHI_LIBS="$AVAHI_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"avahi-client\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "avahi-client") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_AVAHI_LIBS=`$PKG_CONFIG --libs "avahi-client" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ AVAHI_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "avahi-client" 2>&1`
+ else
+ AVAHI_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "avahi-client" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$AVAHI_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (avahi-client) were not met:
+
+$AVAHI_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables AVAHI_CFLAGS
+and AVAHI_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables AVAHI_CFLAGS
+and AVAHI_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ AVAHI_CFLAGS=$pkg_cv_AVAHI_CFLAGS
+ AVAHI_LIBS=$pkg_cv_AVAHI_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_AVAHI /**/" >>confdefs.h
+
+fi
+fi
+
+
+
+
+
+# Check whether --enable-ldap was given.
+if test "${enable_ldap+set}" = set; then :
+ enableval=$enable_ldap; enable_ldap="$enableval"
+else
+ enable_ldap=yes
+
+fi
+
+
+# Check whether --with-ldap-libs was given.
+if test "${with_ldap_libs+set}" = set; then :
+ withval=$with_ldap_libs; LDFLAGS="-L$withval $LDFLAGS"
+ DSOFLAGS="-L$withval $DSOFLAGS"
+fi
+
+
+# Check whether --with-ldap-includes was given.
+if test "${with_ldap_includes+set}" = set; then :
+ withval=$with_ldap_includes; CFLAGS="-I$withval $CFLAGS"
+ CPPFLAGS="-I$withval $CPPFLAGS"
+fi
+
+
+if test x$enable_ldap != xno; then
+
+ ac_fn_cxx_check_header_mongrel "$LINENO" "ldap.h" "ac_cv_header_ldap_h" "$ac_includes_default"
+if test "x$ac_cv_header_ldap_h" = xyes; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ldap_initialize" >&5
+$as_echo_n "checking for library containing ldap_initialize... " >&6; }
+if ${ac_cv_search_ldap_initialize+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ldap_initialize ();
+int
+main ()
+{
+return ldap_initialize ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' ldap; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_search_ldap_initialize=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_ldap_initialize+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_ldap_initialize+:} false; then :
+
+else
+ ac_cv_search_ldap_initialize=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ldap_initialize" >&5
+$as_echo "$ac_cv_search_ldap_initialize" >&6; }
+ac_res=$ac_cv_search_ldap_initialize
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+
+$as_echo "#define HAVE_LDAP /**/" >>confdefs.h
+
+
+$as_echo "#define HAVE_OPENLDAP /**/" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldap_start_tls in -lldap" >&5
+$as_echo_n "checking for ldap_start_tls in -lldap... " >&6; }
+if ${ac_cv_lib_ldap_ldap_start_tls+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lldap $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ldap_start_tls ();
+int
+main ()
+{
+return ldap_start_tls ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_ldap_ldap_start_tls=yes
+else
+ ac_cv_lib_ldap_ldap_start_tls=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ldap_ldap_start_tls" >&5
+$as_echo "$ac_cv_lib_ldap_ldap_start_tls" >&6; }
+if test "x$ac_cv_lib_ldap_ldap_start_tls" = xyes; then :
+
+$as_echo "#define HAVE_LDAP_SSL /**/" >>confdefs.h
+
+fi
+
+else
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldap_init in -lldap" >&5
+$as_echo_n "checking for ldap_init in -lldap... " >&6; }
+if ${ac_cv_lib_ldap_ldap_init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lldap $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ldap_init ();
+int
+main ()
+{
+return ldap_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_ldap_ldap_init=yes
+else
+ ac_cv_lib_ldap_ldap_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ldap_ldap_init" >&5
+$as_echo "$ac_cv_lib_ldap_ldap_init" >&6; }
+if test "x$ac_cv_lib_ldap_ldap_init" = xyes; then :
+
+
+$as_echo "#define HAVE_LDAP /**/" >>confdefs.h
+
+
+$as_echo "#define HAVE_MOZILLA_LDAP /**/" >>confdefs.h
+
+ for ac_header in ldap_ssl.h
+do :
+ ac_fn_cxx_check_header_compile "$LINENO" "ldap_ssl.h" "ac_cv_header_ldap_ssl_h" "#include <ldap.h>
+"
+if test "x$ac_cv_header_ldap_ssl_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LDAP_SSL_H 1
+_ACEOF
+
+fi
+
+done
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldapssl_init in -lldap" >&5
+$as_echo_n "checking for ldapssl_init in -lldap... " >&6; }
+if ${ac_cv_lib_ldap_ldapssl_init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lldap $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ldapssl_init ();
+int
+main ()
+{
+return ldapssl_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_ldap_ldapssl_init=yes
+else
+ ac_cv_lib_ldap_ldapssl_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ldap_ldapssl_init" >&5
+$as_echo "$ac_cv_lib_ldap_ldapssl_init" >&6; }
+if test "x$ac_cv_lib_ldap_ldapssl_init" = xyes; then :
+
+$as_echo "#define HAVE_LDAP_SSL /**/" >>confdefs.h
+
+fi
+
+fi
+
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldap_set_rebind_proc in -lldap" >&5
+$as_echo_n "checking for ldap_set_rebind_proc in -lldap... " >&6; }
+if ${ac_cv_lib_ldap_ldap_set_rebind_proc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lldap $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ldap_set_rebind_proc ();
+int
+main ()
+{
+return ldap_set_rebind_proc ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_ldap_ldap_set_rebind_proc=yes
+else
+ ac_cv_lib_ldap_ldap_set_rebind_proc=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ldap_ldap_set_rebind_proc" >&5
+$as_echo "$ac_cv_lib_ldap_ldap_set_rebind_proc" >&6; }
+if test "x$ac_cv_lib_ldap_ldap_set_rebind_proc" = xyes; then :
+
+$as_echo "#define HAVE_LDAP_REBIND_PROC /**/" >>confdefs.h
+
+fi
+
+
+fi
+
+
+
+fi
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLIB" >&5
+$as_echo_n "checking for GLIB... " >&6; }
+
+if test -n "$GLIB_CFLAGS"; then
+ pkg_cv_GLIB_CFLAGS="$GLIB_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0 >= 2.30.2\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "glib-2.0 >= 2.30.2") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GLIB_CFLAGS=`$PKG_CONFIG --cflags "glib-2.0 >= 2.30.2" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$GLIB_LIBS"; then
+ pkg_cv_GLIB_LIBS="$GLIB_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0 >= 2.30.2\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "glib-2.0 >= 2.30.2") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GLIB_LIBS=`$PKG_CONFIG --libs "glib-2.0 >= 2.30.2" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ GLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "glib-2.0 >= 2.30.2" 2>&1`
+ else
+ GLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "glib-2.0 >= 2.30.2" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$GLIB_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (glib-2.0 >= 2.30.2) were not met:
+
+$GLIB_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables GLIB_CFLAGS
+and GLIB_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables GLIB_CFLAGS
+and GLIB_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ GLIB_CFLAGS=$pkg_cv_GLIB_CFLAGS
+ GLIB_LIBS=$pkg_cv_GLIB_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+
+
+if test x$enable_avahi != xno; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for AVAHI_GLIB" >&5
+$as_echo_n "checking for AVAHI_GLIB... " >&6; }
+
+if test -n "$AVAHI_GLIB_CFLAGS"; then
+ pkg_cv_AVAHI_GLIB_CFLAGS="$AVAHI_GLIB_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"avahi-glib\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "avahi-glib") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_AVAHI_GLIB_CFLAGS=`$PKG_CONFIG --cflags "avahi-glib" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$AVAHI_GLIB_LIBS"; then
+ pkg_cv_AVAHI_GLIB_LIBS="$AVAHI_GLIB_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"avahi-glib\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "avahi-glib") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_AVAHI_GLIB_LIBS=`$PKG_CONFIG --libs "avahi-glib" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ AVAHI_GLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "avahi-glib" 2>&1`
+ else
+ AVAHI_GLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "avahi-glib" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$AVAHI_GLIB_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (avahi-glib) were not met:
+
+$AVAHI_GLIB_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables AVAHI_GLIB_CFLAGS
+and AVAHI_GLIB_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables AVAHI_GLIB_CFLAGS
+and AVAHI_GLIB_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ AVAHI_GLIB_CFLAGS=$pkg_cv_AVAHI_GLIB_CFLAGS
+ AVAHI_GLIB_LIBS=$pkg_cv_AVAHI_GLIB_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+fi
+
+
+
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GIO" >&5
+$as_echo_n "checking for GIO... " >&6; }
+
+if test -n "$GIO_CFLAGS"; then
+ pkg_cv_GIO_CFLAGS="$GIO_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gio-2.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gio-2.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GIO_CFLAGS=`$PKG_CONFIG --cflags "gio-2.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$GIO_LIBS"; then
+ pkg_cv_GIO_LIBS="$GIO_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gio-2.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gio-2.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GIO_LIBS=`$PKG_CONFIG --libs "gio-2.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ GIO_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gio-2.0" 2>&1`
+ else
+ GIO_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gio-2.0" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$GIO_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (gio-2.0) were not met:
+
+$GIO_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables GIO_CFLAGS
+and GIO_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables GIO_CFLAGS
+and GIO_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ GIO_CFLAGS=$pkg_cv_GIO_CFLAGS
+ GIO_LIBS=$pkg_cv_GIO_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GIO_UNIX" >&5
+$as_echo_n "checking for GIO_UNIX... " >&6; }
+
+if test -n "$GIO_UNIX_CFLAGS"; then
+ pkg_cv_GIO_UNIX_CFLAGS="$GIO_UNIX_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gio-unix-2.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gio-unix-2.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GIO_UNIX_CFLAGS=`$PKG_CONFIG --cflags "gio-unix-2.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$GIO_UNIX_LIBS"; then
+ pkg_cv_GIO_UNIX_LIBS="$GIO_UNIX_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gio-unix-2.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gio-unix-2.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GIO_UNIX_LIBS=`$PKG_CONFIG --libs "gio-unix-2.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ GIO_UNIX_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gio-unix-2.0" 2>&1`
+ else
+ GIO_UNIX_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gio-unix-2.0" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$GIO_UNIX_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (gio-unix-2.0) were not met:
+
+$GIO_UNIX_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables GIO_UNIX_CFLAGS
+and GIO_UNIX_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables GIO_UNIX_CFLAGS
+and GIO_UNIX_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ GIO_UNIX_CFLAGS=$pkg_cv_GIO_UNIX_CFLAGS
+ GIO_UNIX_LIBS=$pkg_cv_GIO_UNIX_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+
+
+
+# Check whether --with-browseremoteprotocols was given.
+if test "${with_browseremoteprotocols+set}" = set; then :
+ withval=$with_browseremoteprotocols; with_browseremoteprotocols="$withval"
+else
+ with_browseremoteprotocols="dnssd cups"
+
+fi
+
+BROWSEREMOTEPROTOCOLS="$with_browseremoteprotocols"
+
+
+
+# Check whether --with-rcdir was given.
+if test "${with_rcdir+set}" = set; then :
+ withval=$with_rcdir; rcdir="$withval"
+else
+ rcdir=""
+fi
+
+
+# Check whether --with-rclevels was given.
+if test "${with_rclevels+set}" = set; then :
+ withval=$with_rclevels; rclevels="$withval"
+else
+ rclevels="2 3 5"
+fi
+
+
+# Check whether --with-rcstart was given.
+if test "${with_rcstart+set}" = set; then :
+ withval=$with_rcstart; rcstart="$withval"
+else
+ rcstart="99"
+fi
+
+
+# Check whether --with-rcstop was given.
+if test "${with_rcstop+set}" = set; then :
+ withval=$with_rcstop; rcstop="$withval"
+else
+ rcstop="00"
+fi
+
+
+INITDIR=""
+INITDDIR=""
+RCLEVELS="$rclevels"
+RCSTART="$rcstart"
+RCSTOP="$rcstop"
+
+if test x$rcdir = x; then
+ case "`uname`" in
+ FreeBSD* | OpenBSD* | MirBSD* | ekkoBSD*)
+ # FreeBSD and OpenBSD
+ ;;
+
+ Linux | GNU | GNU/k*BSD*)
+ # Linux/HURD seems to choose an init.d directory at random...
+ if test -d /sbin/init.d; then
+ # SuSE
+ INITDIR="/sbin/init.d"
+ else
+ if test -d /etc/init.d; then
+ # Others
+ INITDIR="/etc"
+ else
+ # RedHat
+ INITDIR="/etc/rc.d"
+ fi
+ fi
+ RCSTART="82"
+ RCSTOP="35"
+ ;;
+
+ NetBSD*)
+ # NetBSD
+ INITDDIR="/etc/rc.d"
+ ;;
+
+ *)
+ INITDIR="/etc"
+ ;;
+
+ esac
+elif test "x$rcdir" != xno; then
+ if test "x$rclevels" = x; then
+ INITDDIR="$rcdir"
+ else
+ INITDIR="$rcdir"
+ fi
+fi
+
+ if test "x$INITDIR" != "x"; then
+ RCLINKS_TRUE=
+ RCLINKS_FALSE='#'
+else
+ RCLINKS_TRUE='#'
+ RCLINKS_FALSE=
+fi
+
+
+if test "x${INITDIR}" != "x" -a "x${INITDDIR}" = "x"; then
+ INITDDIR="${INITDIR}/init.d"
+fi
+
+
+
+
+
+
+
+# ======================================
+# Check for various pdf required modules
+# ======================================
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LCMS" >&5
+$as_echo_n "checking for LCMS... " >&6; }
+
+if test -n "$LCMS_CFLAGS"; then
+ pkg_cv_LCMS_CFLAGS="$LCMS_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"lcms2\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "lcms2") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_LCMS_CFLAGS=`$PKG_CONFIG --cflags "lcms2" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$LCMS_LIBS"; then
+ pkg_cv_LCMS_LIBS="$LCMS_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"lcms2\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "lcms2") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_LCMS_LIBS=`$PKG_CONFIG --libs "lcms2" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ LCMS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "lcms2" 2>&1`
+ else
+ LCMS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "lcms2" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$LCMS_PKG_ERRORS" >&5
+
+ lcms2=no
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ lcms2=no
+else
+ LCMS_CFLAGS=$pkg_cv_LCMS_CFLAGS
+ LCMS_LIBS=$pkg_cv_LCMS_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ lcms2=yes
+fi
+if test x"$lcms2" = "xno"; then :
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LCMS" >&5
+$as_echo_n "checking for LCMS... " >&6; }
+
+if test -n "$LCMS_CFLAGS"; then
+ pkg_cv_LCMS_CFLAGS="$LCMS_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"lcms\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "lcms") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_LCMS_CFLAGS=`$PKG_CONFIG --cflags "lcms" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$LCMS_LIBS"; then
+ pkg_cv_LCMS_LIBS="$LCMS_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"lcms\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "lcms") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_LCMS_LIBS=`$PKG_CONFIG --libs "lcms" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ LCMS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "lcms" 2>&1`
+ else
+ LCMS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "lcms" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$LCMS_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (lcms) were not met:
+
+$LCMS_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables LCMS_CFLAGS
+and LCMS_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables LCMS_CFLAGS
+and LCMS_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ LCMS_CFLAGS=$pkg_cv_LCMS_CFLAGS
+ LCMS_LIBS=$pkg_cv_LCMS_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+$as_echo "#define USE_LCMS1 1" >>confdefs.h
+
+
+fi
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FREETYPE" >&5
+$as_echo_n "checking for FREETYPE... " >&6; }
+
+if test -n "$FREETYPE_CFLAGS"; then
+ pkg_cv_FREETYPE_CFLAGS="$FREETYPE_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"freetype2\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "freetype2") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_FREETYPE_CFLAGS=`$PKG_CONFIG --cflags "freetype2" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$FREETYPE_LIBS"; then
+ pkg_cv_FREETYPE_LIBS="$FREETYPE_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"freetype2\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "freetype2") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_FREETYPE_LIBS=`$PKG_CONFIG --libs "freetype2" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ FREETYPE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "freetype2" 2>&1`
+ else
+ FREETYPE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "freetype2" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$FREETYPE_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (freetype2) were not met:
+
+$FREETYPE_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables FREETYPE_CFLAGS
+and FREETYPE_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables FREETYPE_CFLAGS
+and FREETYPE_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ FREETYPE_CFLAGS=$pkg_cv_FREETYPE_CFLAGS
+ FREETYPE_LIBS=$pkg_cv_FREETYPE_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FREETYPE_H 1" >>confdefs.h
+
+fi
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FONTCONFIG" >&5
+$as_echo_n "checking for FONTCONFIG... " >&6; }
+
+if test -n "$FONTCONFIG_CFLAGS"; then
+ pkg_cv_FONTCONFIG_CFLAGS="$FONTCONFIG_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"fontconfig >= 2.0.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "fontconfig >= 2.0.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_FONTCONFIG_CFLAGS=`$PKG_CONFIG --cflags "fontconfig >= 2.0.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$FONTCONFIG_LIBS"; then
+ pkg_cv_FONTCONFIG_LIBS="$FONTCONFIG_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"fontconfig >= 2.0.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "fontconfig >= 2.0.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_FONTCONFIG_LIBS=`$PKG_CONFIG --libs "fontconfig >= 2.0.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ FONTCONFIG_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "fontconfig >= 2.0.0" 2>&1`
+ else
+ FONTCONFIG_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "fontconfig >= 2.0.0" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$FONTCONFIG_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (fontconfig >= 2.0.0) were not met:
+
+$FONTCONFIG_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables FONTCONFIG_CFLAGS
+and FONTCONFIG_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables FONTCONFIG_CFLAGS
+and FONTCONFIG_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ FONTCONFIG_CFLAGS=$pkg_cv_FONTCONFIG_CFLAGS
+ FONTCONFIG_LIBS=$pkg_cv_FONTCONFIG_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for IJS" >&5
+$as_echo_n "checking for IJS... " >&6; }
+
+if test -n "$IJS_CFLAGS"; then
+ pkg_cv_IJS_CFLAGS="$IJS_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ijs\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "ijs") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_IJS_CFLAGS=`$PKG_CONFIG --cflags "ijs" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$IJS_LIBS"; then
+ pkg_cv_IJS_LIBS="$IJS_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ijs\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "ijs") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_IJS_LIBS=`$PKG_CONFIG --libs "ijs" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ IJS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ijs" 2>&1`
+ else
+ IJS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ijs" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$IJS_PKG_ERRORS" >&5
+
+ have_ijs=no
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ have_ijs=no
+else
+ IJS_CFLAGS=$pkg_cv_IJS_CFLAGS
+ IJS_LIBS=$pkg_cv_IJS_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_ijs=yes
+fi
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ZLIB" >&5
+$as_echo_n "checking for ZLIB... " >&6; }
+
+if test -n "$ZLIB_CFLAGS"; then
+ pkg_cv_ZLIB_CFLAGS="$ZLIB_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "zlib") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_ZLIB_CFLAGS=`$PKG_CONFIG --cflags "zlib" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$ZLIB_LIBS"; then
+ pkg_cv_ZLIB_LIBS="$ZLIB_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "zlib") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_ZLIB_LIBS=`$PKG_CONFIG --libs "zlib" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ ZLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "zlib" 2>&1`
+ else
+ ZLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "zlib" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$ZLIB_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (zlib) were not met:
+
+$ZLIB_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables ZLIB_CFLAGS
+and ZLIB_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables ZLIB_CFLAGS
+and ZLIB_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ ZLIB_CFLAGS=$pkg_cv_ZLIB_CFLAGS
+ ZLIB_LIBS=$pkg_cv_ZLIB_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+$as_echo "#define HAVE_LIBZ /**/" >>confdefs.h
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBQPDF" >&5
+$as_echo_n "checking for LIBQPDF... " >&6; }
+
+if test -n "$LIBQPDF_CFLAGS"; then
+ pkg_cv_LIBQPDF_CFLAGS="$LIBQPDF_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libqpdf >= 3.0.2\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libqpdf >= 3.0.2") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_LIBQPDF_CFLAGS=`$PKG_CONFIG --cflags "libqpdf >= 3.0.2" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$LIBQPDF_LIBS"; then
+ pkg_cv_LIBQPDF_LIBS="$LIBQPDF_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libqpdf >= 3.0.2\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libqpdf >= 3.0.2") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_LIBQPDF_LIBS=`$PKG_CONFIG --libs "libqpdf >= 3.0.2" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ LIBQPDF_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libqpdf >= 3.0.2" 2>&1`
+ else
+ LIBQPDF_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libqpdf >= 3.0.2" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$LIBQPDF_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (libqpdf >= 3.0.2) were not met:
+
+$LIBQPDF_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables LIBQPDF_CFLAGS
+and LIBQPDF_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables LIBQPDF_CFLAGS
+and LIBQPDF_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ LIBQPDF_CFLAGS=$pkg_cv_LIBQPDF_CFLAGS
+ LIBQPDF_LIBS=$pkg_cv_LIBQPDF_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+# ===============================
+# Check for PCLm printing support
+# ===============================
+# Check whether --enable-pclm was given.
+if test "${enable_pclm+set}" = set; then :
+ enableval=$enable_pclm; enable_pclm="$enableval"
+else
+ enable_pclm=yes
+
+fi
+
+if test "x$enable_pclm" != "xno"; then
+ # Do we have QPDF 7.0.0 or newer?
+ for ac_header in qpdf/Pl_RunLength.hh
+do :
+ ac_fn_cxx_check_header_mongrel "$LINENO" "qpdf/Pl_RunLength.hh" "ac_cv_header_qpdf_Pl_RunLength_hh" "$ac_includes_default"
+if test "x$ac_cv_header_qpdf_Pl_RunLength_hh" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_QPDF_PL_RUNLENGTH_HH 1
+_ACEOF
+
+else
+ enable_pclm=no
+
+fi
+
+done
+
+fi
+if test "x$enable_pclm" != "xno"; then
+
+$as_echo "#define QPDF_HAVE_PCLM 1" >>confdefs.h
+
+ QPDF_NO_PCLM=
+else
+ QPDF_NO_PCLM=\#
+fi
+
+
+
+
+# =================
+# Check for Poppler
+# =================
+# Check whether --enable-poppler was given.
+if test "${enable_poppler+set}" = set; then :
+ enableval=$enable_poppler; enable_poppler=$enableval
+else
+ enable_poppler=yes
+fi
+
+ if test x$enable_poppler = xyes; then
+ ENABLE_POPPLER_TRUE=
+ ENABLE_POPPLER_FALSE='#'
+else
+ ENABLE_POPPLER_TRUE='#'
+ ENABLE_POPPLER_FALSE=
+fi
+
+if test x$enable_poppler = xyes; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for POPPLER" >&5
+$as_echo_n "checking for POPPLER... " >&6; }
+
+if test -n "$POPPLER_CFLAGS"; then
+ pkg_cv_POPPLER_CFLAGS="$POPPLER_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"poppler >= 0.18\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "poppler >= 0.18") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_POPPLER_CFLAGS=`$PKG_CONFIG --cflags "poppler >= 0.18" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$POPPLER_LIBS"; then
+ pkg_cv_POPPLER_LIBS="$POPPLER_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"poppler >= 0.18\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "poppler >= 0.18") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_POPPLER_LIBS=`$PKG_CONFIG --libs "poppler >= 0.18" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ POPPLER_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "poppler >= 0.18" 2>&1`
+ else
+ POPPLER_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "poppler >= 0.18" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$POPPLER_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (poppler >= 0.18) were not met:
+
+$POPPLER_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables POPPLER_CFLAGS
+and POPPLER_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables POPPLER_CFLAGS
+and POPPLER_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ POPPLER_CFLAGS=$pkg_cv_POPPLER_CFLAGS
+ POPPLER_LIBS=$pkg_cv_POPPLER_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+ ac_fn_cxx_check_header_mongrel "$LINENO" "poppler/cpp/poppler-version.h" "ac_cv_header_poppler_cpp_poppler_version_h" "$ac_includes_default"
+if test "x$ac_cv_header_poppler_cpp_poppler_version_h" = xyes; then :
+
+$as_echo "#define HAVE_CPP_POPPLER_VERSION_H /**/" >>confdefs.h
+
+fi
+
+
+fi
+
+# ===============
+# Check for D-Bus
+# ===============
+# Check whether --enable-dbus was given.
+if test "${enable_dbus+set}" = set; then :
+ enableval=$enable_dbus; enable_dbus=$enableval
+else
+ enable_dbus=yes
+fi
+
+ if test x$enable_dbus = xyes; then
+ BUILD_DBUS_TRUE=
+ BUILD_DBUS_FALSE='#'
+else
+ BUILD_DBUS_TRUE='#'
+ BUILD_DBUS_FALSE=
+fi
+
+if test x$enable_dbus = xyes; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DBUS" >&5
+$as_echo_n "checking for DBUS... " >&6; }
+
+if test -n "$DBUS_CFLAGS"; then
+ pkg_cv_DBUS_CFLAGS="$DBUS_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-1\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "dbus-1") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_DBUS_CFLAGS=`$PKG_CONFIG --cflags "dbus-1" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$DBUS_LIBS"; then
+ pkg_cv_DBUS_LIBS="$DBUS_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-1\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "dbus-1") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_DBUS_LIBS=`$PKG_CONFIG --libs "dbus-1" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ DBUS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "dbus-1" 2>&1`
+ else
+ DBUS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "dbus-1" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$DBUS_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (dbus-1) were not met:
+
+$DBUS_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables DBUS_CFLAGS
+and DBUS_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables DBUS_CFLAGS
+and DBUS_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ DBUS_CFLAGS=$pkg_cv_DBUS_CFLAGS
+ DBUS_LIBS=$pkg_cv_DBUS_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+fi
+
+# ===================================
+# Check for large files and long long
+# ===================================
+# Check whether --enable-largefile was given.
+if test "${enable_largefile+set}" = set; then :
+ enableval=$enable_largefile;
+fi
+
+if test "$enable_largefile" != no; then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
+$as_echo_n "checking for special C compiler options needed for large files... " >&6; }
+if ${ac_cv_sys_largefile_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_sys_largefile_CC=no
+ if test "$GCC" != yes; then
+ ac_save_CC=$CC
+ while :; do
+ # IRIX 6.2 and later do not support large files by default,
+ # so use the C compiler's -n32 option if that helps.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ if ac_fn_cxx_try_compile "$LINENO"; then :
+ break
+fi
+rm -f core conftest.err conftest.$ac_objext
+ CC="$CC -n32"
+ if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_sys_largefile_CC=' -n32'; break
+fi
+rm -f core conftest.err conftest.$ac_objext
+ break
+ done
+ CC=$ac_save_CC
+ rm -f conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
+$as_echo "$ac_cv_sys_largefile_CC" >&6; }
+ if test "$ac_cv_sys_largefile_CC" != no; then
+ CC=$CC$ac_cv_sys_largefile_CC
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
+if ${ac_cv_sys_file_offset_bits+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_sys_file_offset_bits=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_sys_file_offset_bits=64; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_file_offset_bits=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
+$as_echo "$ac_cv_sys_file_offset_bits" >&6; }
+case $ac_cv_sys_file_offset_bits in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+_ACEOF
+;;
+esac
+rm -rf conftest*
+ if test $ac_cv_sys_file_offset_bits = unknown; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
+$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; }
+if ${ac_cv_sys_large_files+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_sys_large_files=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _LARGE_FILES 1
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_sys_large_files=1; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_large_files=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
+$as_echo "$ac_cv_sys_large_files" >&6; }
+case $ac_cv_sys_large_files in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGE_FILES $ac_cv_sys_large_files
+_ACEOF
+;;
+esac
+rm -rf conftest*
+ fi
+
+
+fi
+
+LARGEFILE=""
+if test x"$enable_largefile" != "xno"; then :
+
+ LARGEFILE="-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE"
+ if test x"$ac_cv_sys_large_files" = "x1"; then :
+ LARGEFILE="$LARGEFILE -D_LARGE_FILES"
+fi
+ if test x"$ac_cv_sys_file_offset_bits" = "x64"; then :
+ LARGEFILE="$LARGEFILE -D_FILE_OFFSET_BITS=64"
+fi
+
+fi
+
+
+ac_fn_cxx_check_type "$LINENO" "long long" "ac_cv_type_long_long" "$ac_includes_default"
+if test "x$ac_cv_type_long_long" = xyes; then :
+ long_long_found=yes
+else
+ long_long_found=no
+fi
+
+if test x"$long_long_found" = "xyes"; then :
+
+
+$as_echo "#define HAVE_LONG_LONG /**/" >>confdefs.h
+
+
+fi
+
+# ================
+# Check for Mutool
+# ================
+# Check whether --enable-mutool was given.
+if test "${enable_mutool+set}" = set; then :
+ enableval=$enable_mutool; enable_mutool="$enableval"
+else
+ enable_mutool=yes
+
+fi
+
+
+
+# Check whether --with-mutool-path was given.
+if test "${with_mutool_path+set}" = set; then :
+ withval=$with_mutool_path; with_mutool_path="$withval"
+else
+ with_mutool_path=system
+
+fi
+
+
+# ================
+# Check for pdf2ps
+# ================
+# Check whether --enable-ghostscript was given.
+if test "${enable_ghostscript+set}" = set; then :
+ enableval=$enable_ghostscript; enable_ghostscript="$enableval"
+else
+ enable_ghostscript=yes
+
+fi
+
+# Check whether --enable-ijs was given.
+if test "${enable_ijs+set}" = set; then :
+ enableval=$enable_ijs; enable_ijs="$enableval"
+else
+ enable_ijs=yes
+
+fi
+
+if test "x$enable_ijs" = "xyes" -a "x$have_ijs" != "xyes"; then :
+
+ as_fn_error $? "IJS not found, but requested." "$LINENO" 5
+
+fi
+ if test "x$enable_ijs" = "xyes"; then
+ ENABLE_IJS_TRUE=
+ ENABLE_IJS_FALSE='#'
+else
+ ENABLE_IJS_TRUE='#'
+ ENABLE_IJS_FALSE=
+fi
+
+
+# Check whether --with-pdftops was given.
+if test "${with_pdftops+set}" = set; then :
+ withval=$with_pdftops; with_pdftops="$withval"
+else
+ with_pdftops=hybrid
+
+fi
+
+case x$with_pdftops in #(
+ xgs|xpdftops|xpdftocairo|xacroread|xmupdf|xhybrid) :
+ ;; #(
+ *) :
+ as_fn_error $? "Unknown value of with-pdftops provided: $with_pdftops" "$LINENO" 5
+ ;;
+esac
+
+# Check whether --with-gs-path was given.
+if test "${with_gs_path+set}" = set; then :
+ withval=$with_gs_path; with_gs_path="$withval"
+else
+ with_gs_path=system
+
+fi
+
+
+# Check whether --with-pdftops-path was given.
+if test "${with_pdftops_path+set}" = set; then :
+ withval=$with_pdftops_path; with_pdftops_path="$withval"
+else
+ with_pdftops_path=system
+
+fi
+
+
+# Check whether --with-pdftocairo-path was given.
+if test "${with_pdftocairo_path+set}" = set; then :
+ withval=$with_pdftocairo_path; with_pdftocairo_path="$withval"
+else
+ with_pdftocairo_path=system
+
+fi
+
+
+# Check whether --with-acroread-path was given.
+if test "${with_acroread_path+set}" = set; then :
+ withval=$with_acroread_path; with_acroread_path="$withval"
+else
+ with_acroread_path=system
+
+fi
+
+
+# Check whether --with-ippfind-path was given.
+if test "${with_ippfind_path+set}" = set; then :
+ withval=$with_ippfind_path; with_ippfind_path="$withval"
+else
+ with_ippfind_path=system
+
+fi
+
+
+# Check whether --with-pdftops-maxres was given.
+if test "${with_pdftops_maxres+set}" = set; then :
+ withval=$with_pdftops_maxres; with_pdftops_maxres="$withval"
+else
+ with_pdftops_maxres=1440
+
+fi
+
+case x$with_pdftops_maxres in #(
+ x0|x75|x150|x300|x600|x1200|x2400|x4800|x90|x180|x360|x720|x1440|x2880|x5760) :
+ CUPS_PDFTOPS_MAXRES=$with_pdftops_maxres ;; #(
+ xunlimited) :
+ CUPS_PDFTOPS_MAXRES=0 ;; #(
+ *) :
+ as_fn_error $? "Unknown value of with-pdftops-maxres provided: $with_pdftops" "$LINENO" 5
+ ;;
+esac
+# Check whether --enable-gs-ps2write was given.
+if test "${enable_gs_ps2write+set}" = set; then :
+ enableval=$enable_gs_ps2write; enable_gs_ps2write="$enableval"
+else
+ enable_gs_ps2write=yes
+
+fi
+
+
+CUPS_GHOSTSCRIPT=""
+if test "x$enable_ghostscript" != "xyes"; then :
+
+ with_gs_path=""
+
+else
+
+ if test "x$with_gs_path" != "xsystem"; then :
+
+ CUPS_GHOSTSCRIPT="$with_gs_path"
+
+else
+
+ if test "x$cross_compiling" = "xyes"; then :
+
+ CUPS_GHOSTSCRIPT="gs"
+
+else
+
+ # Extract the first word of "gs", so it can be a program name with args.
+set dummy gs; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CUPS_GHOSTSCRIPT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CUPS_GHOSTSCRIPT"; then
+ ac_cv_prog_CUPS_GHOSTSCRIPT="$CUPS_GHOSTSCRIPT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CUPS_GHOSTSCRIPT="gs"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CUPS_GHOSTSCRIPT=$ac_cv_prog_CUPS_GHOSTSCRIPT
+if test -n "$CUPS_GHOSTSCRIPT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CUPS_GHOSTSCRIPT" >&5
+$as_echo "$CUPS_GHOSTSCRIPT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+fi
+
+fi
+ if test "x$CUPS_GHOSTSCRIPT" = "x"; then :
+
+ as_fn_error $? "Required gs binary is missing. Please install ghostscript-gpl package." "$LINENO" 5
+
+fi
+
+$as_echo "#define HAVE_GHOSTSCRIPT /**/" >>confdefs.h
+
+ if test x"$with_pdftops" = xgs; then :
+
+cat >>confdefs.h <<_ACEOF
+#define CUPS_PDFTOPS_RENDERER GS
+_ACEOF
+
+fi
+
+ if test x"$enable_gs_ps2write" = "xyes"; then :
+
+
+$as_echo "#define HAVE_GHOSTSCRIPT_PS2WRITE /**/" >>confdefs.h
+
+
+fi
+ if test "x$cross_compiling" != "xyes"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gs supports the ps2write device" >&5
+$as_echo_n "checking whether gs supports the ps2write device... " >&6; }
+ if `$CUPS_GHOSTSCRIPT -h 2>&1 | grep -q ps2write`; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_GHOSTSCRIPT_PS2WRITE /**/" >>confdefs.h
+
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+
+fi
+
+fi
+ if test "x$enable_ghostscript" = xyes; then
+ ENABLE_GHOSTSCRIPT_TRUE=
+ ENABLE_GHOSTSCRIPT_FALSE='#'
+else
+ ENABLE_GHOSTSCRIPT_TRUE='#'
+ ENABLE_GHOSTSCRIPT_FALSE=
+fi
+
+
+
+CUPS_MUTOOL=""
+if test "x$enable_mutool" != "xyes"; then :
+
+ with_mutool_path=""
+
+else
+
+ if test "x$with_mutool_path" != "xsystem"; then :
+
+ CUPS_MUTOOL="$with_mutool_path"
+
+else
+
+ if test "x$cross_compiling" = "xyes"; then :
+
+ CUPS_MUTOOL="mutool"
+
+else
+
+ # Extract the first word of "mutool", so it can be a program name with args.
+set dummy mutool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CUPS_MUTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CUPS_MUTOOL"; then
+ ac_cv_prog_CUPS_MUTOOL="$CUPS_MUTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CUPS_MUTOOL="mutool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CUPS_MUTOOL=$ac_cv_prog_CUPS_MUTOOL
+if test -n "$CUPS_MUTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CUPS_MUTOOL" >&5
+$as_echo "$CUPS_MUTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+fi
+
+fi
+ if test "x$CUPS_MUTOOL" = "x"; then :
+
+ as_fn_error $? "Required mutool binary is missing. Please install mutool." "$LINENO" 5
+
+fi
+ if test x"$with_pdftops" = xmupdf; then :
+
+cat >>confdefs.h <<_ACEOF
+#define CUPS_PDFTOPS_RENDERER MUPDF
+_ACEOF
+
+fi
+
+fi
+ if test "x$enable_mutool" = xyes; then
+ ENABLE_MUTOOL_TRUE=
+ ENABLE_MUTOOL_FALSE='#'
+else
+ ENABLE_MUTOOL_TRUE='#'
+ ENABLE_MUTOOL_FALSE=
+fi
+
+
+
+if test "x$with_pdftops_path" != "xsystem"; then :
+
+ CUPS_PDFTOPS="$with_pdftops_path"
+
+else
+
+ if test "x$cross_compiling" = "xyes"; then :
+
+ CUPS_PDFTOPS="pdftops"
+
+else
+
+ # Extract the first word of "pdftops", so it can be a program name with args.
+set dummy pdftops; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CUPS_PDFTOPS+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CUPS_PDFTOPS"; then
+ ac_cv_prog_CUPS_PDFTOPS="$CUPS_PDFTOPS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CUPS_PDFTOPS="/usr/bin/pdftops"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CUPS_PDFTOPS=$ac_cv_prog_CUPS_PDFTOPS
+if test -n "$CUPS_PDFTOPS"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CUPS_PDFTOPS" >&5
+$as_echo "$CUPS_PDFTOPS" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+fi
+ if test "x$CUPS_PDFTOPS" = "x"; then :
+
+ as_fn_error $? "Required pdftops is missing. Please install the pdftops utility of Poppler." "$LINENO" 5
+
+fi
+
+fi
+if test "x$CUPS_PDFTOPS" != "x"; then :
+
+
+$as_echo "#define HAVE_POPPLER_PDFTOPS /**/" >>confdefs.h
+
+ if test x"$with_pdftops" = xpdftops; then :
+
+cat >>confdefs.h <<_ACEOF
+#define CUPS_PDFTOPS_RENDERER PDFTOPS
+_ACEOF
+
+fi
+
+ if test "x$cross_compiling" != "xyes"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pdftops supports -origpagesizes" >&5
+$as_echo_n "checking whether pdftops supports -origpagesizes... " >&6; }
+ if `$CUPS_PDFTOPS -h 2>&1 | grep -q -- -origpagesizes`; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_POPPLER_PDFTOPS_WITH_ORIGPAGESIZES " >>confdefs.h
+
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pdftops supports -r" >&5
+$as_echo_n "checking whether pdftops supports -r... " >&6; }
+ if `$CUPS_PDFTOPS -h 2>&1 | grep -q -- '-r '`; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_POPPLER_PDFTOPS_WITH_RESOLUTION " >>confdefs.h
+
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+
+fi
+
+fi
+if test "x$with_pdftocairo_path" != "xsystem"; then :
+
+ CUPS_PDFTOCAIRO="$with_pdftocairo_path"
+
+else
+
+ CUPS_PDFTOCAIRO="pdftocairo"
+
+fi
+if test "x$CUPS_PDFTOCAIRO" != "x"; then :
+
+ if test x"$with_pdftops" = xpdftocairo; then :
+
+cat >>confdefs.h <<_ACEOF
+#define CUPS_PDFTOPS_RENDERER PDFTOCAIRO
+_ACEOF
+
+fi
+
+else
+
+ as_fn_error $? "Required pdftocairo is missing. Please install Poppler developer packages." "$LINENO" 5
+
+fi
+if test "x$with_acroread_path" != "xsystem"; then :
+
+ CUPS_ACROREAD="$with_acroread_path"
+
+else
+
+ CUPS_ACROREAD="acroread"
+
+fi
+if test "x$CUPS_ACROREAD" != "x"; then :
+
+ if test x"$with_pdftops" = xacroread; then :
+
+cat >>confdefs.h <<_ACEOF
+#define CUPS_PDFTOPS_RENDERER ACROREAD
+_ACEOF
+
+fi
+
+fi
+if test "x$with_ippfind_path" != "xsystem"; then :
+
+ CUPS_IPPFIND="$with_ippfind_path"
+
+else
+
+ CUPS_IPPFIND="ippfind"
+
+fi
+
+if test "x$CUPS_GHOSTSCRIPT" != "x" -a "x$CUPS_PDFTOPS" != "x"; then :
+
+ if test x"$with_pdftops" = xhybrid; then :
+
+cat >>confdefs.h <<_ACEOF
+#define CUPS_PDFTOPS_RENDERER HYBRID
+_ACEOF
+
+fi
+
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define CUPS_GHOSTSCRIPT "$CUPS_GHOSTSCRIPT"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define CUPS_MUTOOL "$CUPS_MUTOOL"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define CUPS_POPPLER_PDFTOPS "$CUPS_PDFTOPS"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define CUPS_POPPLER_PDFTOCAIRO "$CUPS_PDFTOCAIRO"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define CUPS_ACROREAD "$CUPS_ACROREAD"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define CUPS_IPPFIND "$CUPS_IPPFIND"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define CUPS_PDFTOPS_MAX_RESOLUTION $CUPS_PDFTOPS_MAXRES
+_ACEOF
+
+
+# ==================
+# Check for foomatic
+# ==================
+# Check whether --enable-foomatic was given.
+if test "${enable_foomatic+set}" = set; then :
+ enableval=$enable_foomatic; enable_foomatic="$enableval"
+else
+ enable_foomatic=yes
+
+fi
+
+ if test "x$enable_foomatic" = "xyes"; then
+ ENABLE_FOOMATIC_TRUE=
+ ENABLE_FOOMATIC_FALSE='#'
+else
+ ENABLE_FOOMATIC_TRUE='#'
+ ENABLE_FOOMATIC_FALSE=
+fi
+
+
+# =============
+# Check for php
+# =============
+# NOTE: This stuff is broken, requires internal cups headers.
+
+# Check whether --with-php was given.
+if test "${with_php+set}" = set; then :
+ withval=$with_php; with_php="$withval"
+else
+ with_php=no
+
+fi
+
+
+# Check whether --with-php-config was given.
+if test "${with_php_config+set}" = set; then :
+ withval=$with_php_config; with_php_config="$withval"
+else
+ with_php_config=system
+
+fi
+
+ if test "x$with_php" = "xyes"; then
+ WITH_PHP_TRUE=
+ WITH_PHP_FALSE='#'
+else
+ WITH_PHP_TRUE='#'
+ WITH_PHP_FALSE=
+fi
+
+if test x"$with_php" = "xyes"; then :
+
+ if test "x$with_php_config" != "xsystem"; then :
+
+ PHPCONFIG=$with_php_config
+
+else
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}php-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}php-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PHPCONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $PHPCONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PHPCONFIG="$PHPCONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_PHPCONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+PHPCONFIG=$ac_cv_path_PHPCONFIG
+if test -n "$PHPCONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PHPCONFIG" >&5
+$as_echo "$PHPCONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_PHPCONFIG"; then
+ ac_pt_PHPCONFIG=$PHPCONFIG
+ # Extract the first word of "php-config", so it can be a program name with args.
+set dummy php-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_PHPCONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $ac_pt_PHPCONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ac_pt_PHPCONFIG="$ac_pt_PHPCONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_ac_pt_PHPCONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+ac_pt_PHPCONFIG=$ac_cv_path_ac_pt_PHPCONFIG
+if test -n "$ac_pt_PHPCONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PHPCONFIG" >&5
+$as_echo "$ac_pt_PHPCONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_pt_PHPCONFIG" = x; then
+ PHPCONFIG=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ PHPCONFIG=$ac_pt_PHPCONFIG
+ fi
+else
+ PHPCONFIG="$ac_cv_path_PHPCONFIG"
+fi
+
+ if test -z "$PHPCONFIG"; then :
+
+ as_fn_error $? "Required php-config is missing. Please install PHP developer packages." "$LINENO" 5
+
+fi
+
+fi
+ PHPDIR="`$PHPCONFIG --extension-dir`"
+
+
+fi
+
+# =========
+# Test ARGS
+# =========
+
+# Check whether --with-test-font-path was given.
+if test "${with_test_font_path+set}" = set; then :
+ withval=$with_test_font_path; with_test_font_path="$withval"
+else
+ with_test_font_path="/usr/share/fonts/dejavu/DejaVuSans.ttf"
+
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define TESTFONT "$with_test_font_path"
+_ACEOF
+
+
+# ================
+# Check for cflags
+# ================
+# Check whether --enable-werror was given.
+if test "${enable_werror+set}" = set; then :
+ enableval=$enable_werror; enable_werror="$enableval"
+else
+ enable_werror=no
+
+fi
+
+if test x"$enable_werror" = "xyes"; then :
+
+ CFLAGS="$CFLAGS -Werror"
+
+fi
+if test x"$GCC" = "xyes"; then :
+
+ # Be tough with warnings and produce less careless code
+ CFLAGS="$CFLAGS -Wall -std=gnu11"
+ CXXFLAGS="$CXXFLAGS -Wall " # -Weffc++" # TODO: enable when it does not print 1MB of warnings
+
+fi
+CFLAGS="$CFLAGS -D_GNU_SOURCE"
+CXXFLAGS="$CXXFLAGS -D_GNU_SOURCE"
+
+# ==========================
+# Braille embossing/liblouis
+# ==========================
+# Check whether --enable-braille was given.
+if test "${enable_braille+set}" = set; then :
+ enableval=$enable_braille; enable_braille=$enableval
+else
+ enable_braille=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblouis" >&5
+$as_echo_n "checking for liblouis... " >&6; }
+if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblouis\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "liblouis") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ if test "x$enable_braille" = xyes; then
+ TABLESDIR=`$PKG_CONFIG --variable=tablesdir liblouis`
+ else
+ TABLESDIR=/usr/share/liblouis/tables
+ fi
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ TABLESDIR=/usr/share/liblouis/tables
+
+fi
+ if test "x$enable_braille" = xyes; then
+ ENABLE_BRAILLE_TRUE=
+ ENABLE_BRAILLE_FALSE='#'
+else
+ ENABLE_BRAILLE_TRUE='#'
+ ENABLE_BRAILLE_FALSE=
+fi
+
+
+
+# =========================================================
+# Select a different shell instead of the default /bin/bash
+# =========================================================
+
+# Check whether --with-shell was given.
+if test "${with_shell+set}" = set; then :
+ withval=$with_shell; with_shell="$withval"
+else
+ with_shell="/bin/bash"
+
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define SHELL "$with_shell"
+_ACEOF
+
+
+# =====================
+# Prepare all .in files
+# =====================
+ac_config_files="$ac_config_files libcupsfilters.pc libfontembed.pc Makefile utils/cups-browsed utils/cups-browsed.conf filter/foomatic-rip/foomatic-rip.1 filter/braille/drivers/index/indexv4.sh filter/braille/drivers/index/indexv3.sh filter/braille/drivers/index/index.sh filter/braille/drivers/index/textbrftoindexv3 filter/braille/drivers/index/imageubrltoindexv3 filter/braille/drivers/index/imageubrltoindexv4 filter/braille/drivers/generic/brftoembosser filter/braille/filters/cups-braille.sh filter/braille/filters/imagetobrf filter/braille/filters/texttobrf filter/braille/filters/vectortopdf filter/braille/filters/vectortobrf filter/braille/filters/musicxmltobrf filter/braille/filters/liblouis1.defs.gen mime/cupsfilters.convs"
+
+ac_config_commands="$ac_config_commands executable-scripts"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+ if test -n "$EXEEXT"; then
+ am__EXEEXT_TRUE=
+ am__EXEEXT_FALSE='#'
+else
+ am__EXEEXT_TRUE='#'
+ am__EXEEXT_FALSE=
+fi
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ as_fn_error $? "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+ as_fn_error $? "conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_DRIVERLESS_TRUE}" && test -z "${ENABLE_DRIVERLESS_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_DRIVERLESS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_URFTOPDF_TRUE}" && test -z "${ENABLE_URFTOPDF_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_URFTOPDF\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_IMAGEFILTERS_TRUE}" && test -z "${ENABLE_IMAGEFILTERS_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_IMAGEFILTERS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_AVAHI_TRUE}" && test -z "${ENABLE_AVAHI_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_AVAHI\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${RCLINKS_TRUE}" && test -z "${RCLINKS_FALSE}"; then
+ as_fn_error $? "conditional \"RCLINKS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_POPPLER_TRUE}" && test -z "${ENABLE_POPPLER_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_POPPLER\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${BUILD_DBUS_TRUE}" && test -z "${BUILD_DBUS_FALSE}"; then
+ as_fn_error $? "conditional \"BUILD_DBUS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_IJS_TRUE}" && test -z "${ENABLE_IJS_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_IJS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_GHOSTSCRIPT_TRUE}" && test -z "${ENABLE_GHOSTSCRIPT_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_GHOSTSCRIPT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_MUTOOL_TRUE}" && test -z "${ENABLE_MUTOOL_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_MUTOOL\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_FOOMATIC_TRUE}" && test -z "${ENABLE_FOOMATIC_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_FOOMATIC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_PHP_TRUE}" && test -z "${WITH_PHP_FALSE}"; then
+ as_fn_error $? "conditional \"WITH_PHP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_BRAILLE_TRUE}" && test -z "${ENABLE_BRAILLE_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_BRAILLE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by cups-filters $as_me 1.17.9, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to the package provider."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+cups-filters config.status 1.17.9
+configured by $0, generated by GNU Autoconf 2.69,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`'
+configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`'
+predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`'
+postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`'
+predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`'
+postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`'
+LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`'
+reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`'
+reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`'
+GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`'
+inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`'
+always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`'
+predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`'
+postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_import \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+lt_cv_nm_interface \
+nm_file_list_spec \
+lt_cv_truncate_bin \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib \
+compiler_lib_search_dirs \
+predep_objects \
+postdep_objects \
+predeps \
+postdeps \
+compiler_lib_search_path \
+LD_CXX \
+reload_flag_CXX \
+compiler_CXX \
+lt_prog_compiler_no_builtin_flag_CXX \
+lt_prog_compiler_pic_CXX \
+lt_prog_compiler_wl_CXX \
+lt_prog_compiler_static_CXX \
+lt_cv_prog_compiler_c_o_CXX \
+export_dynamic_flag_spec_CXX \
+whole_archive_flag_spec_CXX \
+compiler_needs_object_CXX \
+with_gnu_ld_CXX \
+allow_undefined_flag_CXX \
+no_undefined_flag_CXX \
+hardcode_libdir_flag_spec_CXX \
+hardcode_libdir_separator_CXX \
+exclude_expsyms_CXX \
+include_expsyms_CXX \
+file_list_spec_CXX \
+compiler_lib_search_dirs_CXX \
+predep_objects_CXX \
+postdep_objects_CXX \
+predeps_CXX \
+postdeps_CXX \
+compiler_lib_search_path_CXX; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+configure_time_dlsearch_path \
+configure_time_lt_sys_library_path \
+reload_cmds_CXX \
+old_archive_cmds_CXX \
+old_archive_from_new_cmds_CXX \
+old_archive_from_expsyms_cmds_CXX \
+archive_cmds_CXX \
+archive_expsym_cmds_CXX \
+module_cmds_CXX \
+module_expsym_cmds_CXX \
+export_symbols_cmds_CXX \
+prelink_cmds_CXX \
+postlink_cmds_CXX; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+
+# See if we are running on zsh, and set the options that allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ RM='$RM'
+ ofile='$ofile'
+
+
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+ "libcupsfilters.pc") CONFIG_FILES="$CONFIG_FILES libcupsfilters.pc" ;;
+ "libfontembed.pc") CONFIG_FILES="$CONFIG_FILES libfontembed.pc" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "utils/cups-browsed") CONFIG_FILES="$CONFIG_FILES utils/cups-browsed" ;;
+ "utils/cups-browsed.conf") CONFIG_FILES="$CONFIG_FILES utils/cups-browsed.conf" ;;
+ "filter/foomatic-rip/foomatic-rip.1") CONFIG_FILES="$CONFIG_FILES filter/foomatic-rip/foomatic-rip.1" ;;
+ "filter/braille/drivers/index/indexv4.sh") CONFIG_FILES="$CONFIG_FILES filter/braille/drivers/index/indexv4.sh" ;;
+ "filter/braille/drivers/index/indexv3.sh") CONFIG_FILES="$CONFIG_FILES filter/braille/drivers/index/indexv3.sh" ;;
+ "filter/braille/drivers/index/index.sh") CONFIG_FILES="$CONFIG_FILES filter/braille/drivers/index/index.sh" ;;
+ "filter/braille/drivers/index/textbrftoindexv3") CONFIG_FILES="$CONFIG_FILES filter/braille/drivers/index/textbrftoindexv3" ;;
+ "filter/braille/drivers/index/imageubrltoindexv3") CONFIG_FILES="$CONFIG_FILES filter/braille/drivers/index/imageubrltoindexv3" ;;
+ "filter/braille/drivers/index/imageubrltoindexv4") CONFIG_FILES="$CONFIG_FILES filter/braille/drivers/index/imageubrltoindexv4" ;;
+ "filter/braille/drivers/generic/brftoembosser") CONFIG_FILES="$CONFIG_FILES filter/braille/drivers/generic/brftoembosser" ;;
+ "filter/braille/filters/cups-braille.sh") CONFIG_FILES="$CONFIG_FILES filter/braille/filters/cups-braille.sh" ;;
+ "filter/braille/filters/imagetobrf") CONFIG_FILES="$CONFIG_FILES filter/braille/filters/imagetobrf" ;;
+ "filter/braille/filters/texttobrf") CONFIG_FILES="$CONFIG_FILES filter/braille/filters/texttobrf" ;;
+ "filter/braille/filters/vectortopdf") CONFIG_FILES="$CONFIG_FILES filter/braille/filters/vectortopdf" ;;
+ "filter/braille/filters/vectortobrf") CONFIG_FILES="$CONFIG_FILES filter/braille/filters/vectortobrf" ;;
+ "filter/braille/filters/musicxmltobrf") CONFIG_FILES="$CONFIG_FILES filter/braille/filters/musicxmltobrf" ;;
+ "filter/braille/filters/liblouis1.defs.gen") CONFIG_FILES="$CONFIG_FILES filter/braille/filters/liblouis1.defs.gen" ;;
+ "mime/cupsfilters.convs") CONFIG_FILES="$CONFIG_FILES mime/cupsfilters.convs" ;;
+ "executable-scripts") CONFIG_COMMANDS="$CONFIG_COMMANDS executable-scripts" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_tt"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+ } >"$ac_tmp/config.h" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$ac_tmp/config.h" "$ac_file" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error $? "could not create -" "$LINENO" 5
+ fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$_am_arg" : 'X\(//\)[^/]' \| \
+ X"$_am_arg" : 'X\(//\)$' \| \
+ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+ # Older Autoconf quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named 'Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running 'make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "$am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir=$dirpart/$fdir; as_fn_mkdir_p
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+ ;;
+ "libtool":C)
+
+ # See if we are running on zsh, and set the options that allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile=${ofile}T
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+# Generated automatically by $as_me ($PACKAGE) $VERSION
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit, 1996
+
+# Copyright (C) 2014 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.
+
+# GNU Libtool 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 2 of of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program or library that is built
+# using GNU Libtool, you may include this file under the same
+# distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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/>.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags='CXX '
+
+# Configured defaults for sys_lib_dlsearch_path munging.
+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shared archive member basename,for filename based shared library versioning on AIX.
+shared_archive_member_spec=$shared_archive_member_spec
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm into a list of symbols to manually relocate.
+global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# The name lister interface.
+nm_interface=$lt_lt_cv_nm_interface
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and where our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# Command to truncate a binary pipe.
+lt_truncate_bin=$lt_lt_cv_truncate_bin
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Detected run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path
+
+# Explicit LT_SYS_LIBRARY_PATH set during ./configure time.
+configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects
+postdep_objects=$lt_postdep_objects
+predeps=$lt_predeps
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ cat <<'_LT_EOF' >> "$cfgfile"
+
+# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
+
+# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+# string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+# string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+# "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+# VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+ case x$2 in
+ x)
+ ;;
+ *:)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
+ ;;
+ x:*)
+ eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ *::*)
+ eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+ eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
+ ;;
+ *)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ esac
+}
+
+
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+ for cc_temp in $*""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+ done
+ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+
+
+# ### END FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain=$ac_aux_dir/ltmain.sh
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+
+ cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: CXX
+
+# The linker used to build libraries.
+LD=$lt_LD_CXX
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag_CXX
+reload_cmds=$lt_reload_cmds_CXX
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_CXX
+
+# A language specific compiler.
+CC=$lt_compiler_CXX
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_CXX
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_CXX
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_CXX
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_CXX
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_CXX
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_CXX
+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_CXX
+module_expsym_cmds=$lt_module_expsym_cmds_CXX
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_CXX
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_CXX
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_CXX
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_CXX
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute_CXX
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_CXX
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic_CXX
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_CXX
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_CXX
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_CXX
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_CXX
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_CXX
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_CXX
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_CXX
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds_CXX
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_CXX
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_CXX
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects_CXX
+postdep_objects=$lt_postdep_objects_CXX
+predeps=$lt_predeps_CXX
+postdeps=$lt_postdeps_CXX
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+
+# ### END LIBTOOL TAG CONFIG: CXX
+_LT_EOF
+
+ ;;
+ "executable-scripts":C)
+ chmod +x filter/braille/filters/liblouis1.defs.gen
+ ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
+# ==============================================
+# Display final informations about configuration
+# ==============================================
+{ $as_echo "$as_me:${as_lineno-$LINENO}:
+==============================================================================
+Environment settings:
+ CFLAGS: ${CFLAGS}
+ CXXFLAGS: ${CXXFLAGS}
+ LDFLAGS: ${LDFLAGS}
+Build configuration:
+ cups-config: ${with_cups_config}
+ font directory: ${sysconfdir}/${FONTDIR}
+ foomatic: ${enable_foomatic}
+ init directory: ${INITDDIR}
+ cups dom socket: ${CUPS_DEFAULT_DOMAINSOCKET}
+ poppler: ${enable_poppler}
+ ghostscript: ${enable_ghostscript}
+ gs-path: ${with_gs_path}
+ mutool: ${enable_mutool}
+ mutool-path: ${with_mutool_path}
+ ippfind-path: ${with_ippfind_path}
+ imagefilters: ${enable_imagefilters}
+ jpeg: ${with_jpeg}
+ pdftocairo-path: ${with_pdftocairo_path}
+ pdftops: ${with_pdftops}
+ pdftops-path: ${with_pdftops_path}
+ png: ${with_png}
+ php: ${with_php}
+ php-config: ${with_php_config}
+ shell: ${with_shell}
+ test-font: ${with_test_font_path}
+ tiff: ${with_tiff}
+ avahi: ${enable_avahi}
+ dbus: ${enable_dbus}
+ browsing: ${with_browseremoteprotocols}
+ werror: ${enable_werror}
+ braille: ${enable_braille}
+ braille tables: ${TABLESDIR}
+ driverless: ${enable_driverless}
+ apple-raster: ${APPLE_RASTER_FILTER}
+ pclm: ${enable_pclm}
+ driverless auto-setup: ${enable_auto_setup_driverless}
+==============================================================================
+" >&5
+$as_echo "$as_me:
+==============================================================================
+Environment settings:
+ CFLAGS: ${CFLAGS}
+ CXXFLAGS: ${CXXFLAGS}
+ LDFLAGS: ${LDFLAGS}
+Build configuration:
+ cups-config: ${with_cups_config}
+ font directory: ${sysconfdir}/${FONTDIR}
+ foomatic: ${enable_foomatic}
+ init directory: ${INITDDIR}
+ cups dom socket: ${CUPS_DEFAULT_DOMAINSOCKET}
+ poppler: ${enable_poppler}
+ ghostscript: ${enable_ghostscript}
+ gs-path: ${with_gs_path}
+ mutool: ${enable_mutool}
+ mutool-path: ${with_mutool_path}
+ ippfind-path: ${with_ippfind_path}
+ imagefilters: ${enable_imagefilters}
+ jpeg: ${with_jpeg}
+ pdftocairo-path: ${with_pdftocairo_path}
+ pdftops: ${with_pdftops}
+ pdftops-path: ${with_pdftops_path}
+ png: ${with_png}
+ php: ${with_php}
+ php-config: ${with_php_config}
+ shell: ${with_shell}
+ test-font: ${with_test_font_path}
+ tiff: ${with_tiff}
+ avahi: ${enable_avahi}
+ dbus: ${enable_dbus}
+ browsing: ${with_browseremoteprotocols}
+ werror: ${enable_werror}
+ braille: ${enable_braille}
+ braille tables: ${TABLESDIR}
+ driverless: ${enable_driverless}
+ apple-raster: ${APPLE_RASTER_FILTER}
+ pclm: ${enable_pclm}
+ driverless auto-setup: ${enable_auto_setup_driverless}
+==============================================================================
+" >&6;}
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 000000000..520325a4f
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,907 @@
+# Process this file with autoconf to create configure.
+
+AC_PREREQ([2.65])
+
+# ====================
+# Version informations
+# ====================
+m4_define([cups_filters_version_major],[1])
+m4_define([cups_filters_version_minor],[17])
+m4_define([cups_filters_version_micro],[9])
+m4_define([cups_filters_version],[cups_filters_version_major.cups_filters_version_minor.cups_filters_version_micro])
+
+# =============
+# Automake init
+# =============
+AC_INIT([cups-filters],[cups_filters_version])
+AC_CONFIG_MACRO_DIR([m4])
+m4_include([m4/ac_define_dir.m4])
+m4_include([m4/ax_compare_version.m4])
+m4_include([m4/basic-directories.m4])
+AM_INIT_AUTOMAKE([1.11 gnu dist-xz dist-bzip2])
+AM_SILENT_RULES([yes])
+AC_LANG([C++])
+AC_CONFIG_HEADERS([config.h])
+# Extra defines for the config.h
+AH_BOTTOM([
+#ifdef HAVE_LONG_LONG
+# define CUPS_LLFMT "%lld"
+# define CUPS_LLCAST (long long)
+#else
+# define CUPS_LLFMT "%ld"
+# define CUPS_LLCAST (long)
+#endif /* HAVE_LONG_LONG */
+
+#ifdef HAVE_ARC4RANDOM
+# define CUPS_RAND() arc4random()
+# define CUPS_SRAND(v) arc4random_stir()
+#elif defined(HAVE_RANDOM)
+# define CUPS_RAND() random()
+# define CUPS_SRAND(v) srandom(v)
+#elif defined(HAVE_LRAND48)
+# define CUPS_RAND() lrand48()
+# define CUPS_SRAND(v) srand48(v)
+#else
+# define CUPS_RAND() rand()
+# define CUPS_SRAND(v) srand(v)
+#endif /* HAVE_ARC4RANDOM */
+])
+
+# ===========================
+# Find required base packages
+# ===========================
+AC_PROG_CC
+AC_PROG_CXX
+AX_CXX_COMPILE_STDCXX([11],[noext],[mandatory])
+AM_PROG_CC_C_O
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_LIBTOOL
+PKG_PROG_PKG_CONFIG([0.20])
+
+# ========================================
+# Specify the fontdir patch if not default
+# ========================================
+AC_ARG_WITH([fontdir],
+ [AS_HELP_STRING([--with-fontdir=path], [Specify path to font config directory (default: fonts/conf.d/).])],
+ [FONTDIR="$withval"],
+ [FONTDIR="fonts/conf.d"]
+)
+AC_SUBST(FONTDIR)
+
+# ================================
+# Find CUPS internals (no pc file)
+# ================================
+AC_ARG_WITH([cups-config],
+ [AS_HELP_STRING([--with-cups-config=path], [Specify path to cups-config executable.])],
+ [with_cups_config="$withval"],
+ [with_cups_config=system]
+)
+
+AS_IF([test "x$with_cups_config" != "xsystem"], [
+ CUPSCONFIG=$with_cups_config
+], [
+ AC_PATH_TOOL(CUPSCONFIG, [cups-config])
+ AS_IF([test -z "$CUPSCONFIG"], [
+ AC_MSG_ERROR([Required cups-config is missing. Please install CUPS developer packages.])
+ ])
+])
+CUPS_CFLAGS=`$CUPSCONFIG --cflags`
+CUPS_LIBS=`$CUPSCONFIG --image --libs`
+CUPS_VERSION=`$CUPSCONFIG --version`
+AC_SUBST(CUPS_CFLAGS)
+AC_SUBST(CUPS_LIBS)
+
+CUPS_DATADIR="`$CUPSCONFIG --datadir`"
+AC_DEFINE_UNQUOTED(CUPS_DATADIR, "$CUPS_DATADIR", [CUPS datadir])
+AC_SUBST(CUPS_DATADIR)
+
+CUPS_SERVERROOT="`$CUPSCONFIG --serverroot`"
+AC_DEFINE_UNQUOTED(CUPS_SERVERROOT, "$CUPS_SERVERROOT", [CUPS serverroot])
+AC_SUBST(CUPS_SERVERROOT)
+
+CUPS_FONTPATH="$CUPS_DATADIR/fonts"
+AC_DEFINE_UNQUOTED(CUPS_FONTPATH, "$CUPS_FONTPATH", [Path to CUPS fonts dir])
+AC_SUBST(CUPS_FONTPATH)
+
+CUPS_SERVERBIN="`$CUPSCONFIG --serverbin`"
+AC_DEFINE_UNQUOTED(CUPS_SERVERBIN, "$CUPS_SERVERBIN", [Path to CUPS binaries dir])
+AC_SUBST(CUPS_SERVERBIN)
+
+AX_COMPARE_VERSION([$CUPS_VERSION],[gt],[1.4], [
+ AC_DEFINE(CUPS_1_4, 1, [CUPS Version is 1.4 or newer])
+])
+
+AC_ARG_ENABLE([driverless], [AS_HELP_STRING([--enable-driverless], [enable PPD generator for driverless printing in /usr/lib/cups/driver/, for manual setup of driverless printers with printer setup tool.])],
+ [enable_driverless="$enableval"],
+ [enable_driverless=yes]
+)
+AX_COMPARE_VERSION([$CUPS_VERSION],[ge],[1.6], [
+ AM_CONDITIONAL([ENABLE_DRIVERLESS],
+ [test "x$enable_driverless" != "xno"])
+])
+
+APPLE_RASTER_FILTER=rastertopdf
+AX_COMPARE_VERSION([$CUPS_VERSION],[lt],[2.2.2], [
+ APPLE_RASTER_FILTER=urftopdf
+])
+AC_ARG_WITH([apple-raster-filter],
+ [AS_HELP_STRING([--with-apple-raster-filter=rastertopdf|urftopdf], [Select filter for Apple Raster input. Default: rastertopdf for CUPS 2.2.2+, urftopdf for older CUPS])],
+ [with_apple_raster_filter="$withval"],
+ [with_apple_raster_filter="$APPLE_RASTER_FILTER"]
+)
+AS_CASE([x$with_apple_raster_filter],
+ [xrastertopdf|xurftopdf], [APPLE_RASTER_FILTER=$with_apple_raster_filter],
+ [AC_MSG_ERROR([Unknown value of with-apple-raster-filter provided: $with_apple_raster_filter])]
+)
+AM_CONDITIONAL([ENABLE_URFTOPDF],
+ [test "x$APPLE_RASTER_FILTER" == "xurftopdf"])
+AC_SUBST(APPLE_RASTER_FILTER)
+
+AC_DEFINE(PDFTOPDF, [], [Needed for pdftopdf filter compilation])
+AC_DEFINE_DIR(BANNERTOPDF_DATADIR, "{CUPS_DATADIR}/data", [Directory where bannertopdf finds its data files (PDF templates)])
+
+AC_ARG_ENABLE([auto-setup-driverless], [AS_HELP_STRING([--enable-auto-setup-driverless], [enable automatic setup of IPP network printers with driverless printing support.])],
+ [enable_auto_setup_driverless="$enableval"],
+ [enable_auto_setup_driverless=no]
+)
+if test "x$enable_auto_setup_driverless" != "xno"; then
+ AC_DEFINE([DRIVERLESS_IPP_PRINTERS_AUTO_SETUP], [], [Auto-setup driverless IPP network printers?])
+fi
+
+AC_SEARCH_LIBS([dlopen],
+ [dl],
+ [AS_IF([test "$ac_cv_search_dlopen" != "none required"], [
+ DLOPEN_LIBS="$ac_cv_search_dlopen"
+ ])],
+ AC_MSG_ERROR([unable to find the dlopen() function])
+)
+AC_SUBST(DLOPEN_LIBS)
+
+# Transient run-time state dir of CUPS
+CUPS_STATEDIR=""
+AC_ARG_WITH(cups-rundir, [ --with-cups-rundir set transient run-time state directory of CUPS],CUPS_STATEDIR="$withval",[
+ case "$uname" in
+ Darwin*)
+ # Darwin (OS X)
+ CUPS_STATEDIR="$CUPS_SERVERROOT"
+ ;;
+ *)
+ # All others
+ CUPS_STATEDIR="$localstatedir/run/cups"
+ ;;
+ esac])
+AC_DEFINE_UNQUOTED(CUPS_STATEDIR, "$CUPS_STATEDIR", [Transient run-time state dir of CUPS])
+AC_SUBST(CUPS_STATEDIR)
+
+# Domain socket of CUPS...
+CUPS_DEFAULT_DOMAINSOCKET=""
+AC_ARG_WITH(cups-domainsocket, [ --with-cups-domainsocket set unix domain socket name used by CUPS
+],
+ default_domainsocket="$withval",
+ default_domainsocket="")
+
+if test x$enable_domainsocket != xno -a x$default_domainsocket != xno; then
+ if test "x$default_domainsocket" = x; then
+ case "$uname" in
+ Darwin*)
+ # Darwin and MaxOS X do their own thing...
+ CUPS_DEFAULT_DOMAINSOCKET="$localstatedir/run/cupsd"
+ ;;
+ *)
+ # All others use FHS standard...
+ CUPS_DEFAULT_DOMAINSOCKET="$CUPS_STATEDIR/cups.sock"
+ ;;
+ esac
+ else
+ CUPS_DEFAULT_DOMAINSOCKET="$default_domainsocket"
+ fi
+fi
+AC_DEFINE_UNQUOTED(CUPS_DEFAULT_DOMAINSOCKET, "$CUPS_DEFAULT_DOMAINSOCKET", "Domain socket of CUPS")
+AC_SUBST(CUPS_DEFAULT_DOMAINSOCKET)
+
+# ======================
+# Check system functions
+# ======================
+AC_CHECK_FUNCS(strlcat)
+AC_CHECK_FUNCS(strlcpy)
+AC_CHECK_FUNCS(sigaction)
+AC_CHECK_FUNCS(waitpid wait3)
+AC_CHECK_FUNCS(strtoll)
+AC_CHECK_FUNCS(open_memstream)
+AC_CHECK_FUNCS(getline,[],AC_SUBST([GETLINE],['bannertopdf-getline.$(OBJEXT)']))
+AC_CHECK_FUNCS(strcasestr,[],AC_SUBST([STRCASESTR],['pdftops-strcasestr.$(OBJEXT)']))
+AC_SEARCH_LIBS(pow, m)
+
+# ========================
+# Check for system headers
+# ========================
+AC_CHECK_HEADERS([stdlib.h])
+AC_CHECK_HEADERS([sys/stat.h])
+AC_CHECK_HEADERS([sys/types.h])
+AC_CHECK_HEADERS([unistd.h])
+AC_CHECK_HEADERS([zlib.h])
+AC_CHECK_HEADERS([endian.h])
+AC_CHECK_HEADERS([dirent.h])
+AC_CHECK_HEADERS([sys/ioctl.h])
+
+# =============
+# Image options
+# =============
+AC_ARG_ENABLE([imagefilters],
+ [AS_HELP_STRING([--disable-imagefilters], [Build the image filters.])],
+ [enable_imagefilters="$enableval"],
+ [enable_imagefilters=yes]
+)
+AM_CONDITIONAL([ENABLE_IMAGEFILTERS], [test "x$enable_imagefilters" != "xno"])
+
+# Libraries
+AC_ARG_WITH([jpeg],
+ [AS_HELP_STRING([--without-jpeg], [Disable jpeg support.])],
+ [with_jpeg="$withval"],
+ [with_jpeg=yes]
+)
+AS_IF([test x"$with_jpeg" != "xno"], [
+ AC_DEFINE([HAVE_LIBJPEG], [], [Defines if we provide jpeg library.])
+ AC_CHECK_HEADERS([jpeglib.h])
+ AC_SEARCH_LIBS([jpeg_destroy_decompress],
+ [jpeg],
+ LIBJPEG_LIBS="-ljpeg",
+ AC_MSG_ERROR([jpeg libraries not found.])
+ )
+ AC_SUBST(LIBJPEG_LIBS)
+])
+
+AC_ARG_WITH([png],
+ [AS_HELP_STRING([--without-png], [Disable png support.])],
+ [with_png="$withval"],
+ [with_png=yes]
+)
+AS_IF([test x"$with_png" != "xno"], [
+ PKG_CHECK_MODULES([LIBPNG], [libpng])
+ AC_DEFINE([HAVE_LIBPNG], [], [Defines if we provide png library.])
+])
+
+AC_ARG_WITH([tiff],
+ [AS_HELP_STRING([--without-tiff], [Disable tiff support.])],
+ [with_tiff="$withval"],
+ [with_tiff=yes]
+)
+AS_IF([test x"$with_tiff" != "xno"], [
+ AC_DEFINE([HAVE_LIBTIFF], [], [Defines if we provide tiff library.])
+ AC_CHECK_HEADERS([tiff.h])
+ AC_SEARCH_LIBS([TIFFReadScanline],
+ [tiff],
+ LIBJPEG_LIBS="-ltiff",
+ AC_MSG_ERROR([tiff libraries not found.])
+ )
+ AC_SUBST(LIBTIFF_LIBS)
+])
+
+# ==================================
+# Check for modules needed by utils/
+# ==================================
+
+dnl Avahi for cups-browsed
+AVAHI_LIBS=""
+AVAHI_CFLAGS=""
+AVAHI_GLIB_CFLAGS=""
+AVAHI_GLIB_LIBS=""
+
+AC_ARG_ENABLE([avahi],
+ [AS_HELP_STRING([--disable-avahi], [Disable DNS Service Discovery support using Avahi.])],
+ [enable_avahi="$enableval"],
+ [enable_avahi=yes]
+)
+AM_CONDITIONAL([ENABLE_AVAHI], [test "x$enable_avahi" != "xno"])
+
+AC_ARG_WITH(avahi-libs,
+ [AS_HELP_STRING([--with-avahi-libs], [Set directory for Avahi library.])],
+ AVAHI_LIBS="-L$withval $AVAHI_LIBS",)
+AC_ARG_WITH(avahi-includes,
+ [AS_HELP_STRING([--with-avahi-includes], [Set directory for Avahi includes])],
+ AVAHI_CFLAGS="-I$withval $AVAHI_CFLAGS",)
+
+if test "x$enable_avahi" != xno; then
+ PKG_CHECK_MODULES(AVAHI, avahi-client,
+ [AC_DEFINE(HAVE_AVAHI, [], [Define if you have the avahi library])])
+fi
+
+AC_SUBST(AVAHI_LIBS)
+AC_SUBST(AVAHI_CFLAGS)
+
+dnl
+dnl LDAP configuration stuff for CUPS.
+dnl
+dnl Copyright 2007-2011 by Apple Inc.
+dnl Copyright 2003-2006 by Easy Software Products, all rights reserved.
+dnl
+dnl These coded instructions, statements, and computer programs are the
+dnl property of Apple Inc. and are protected by Federal copyright
+dnl law. Distribution and use rights are outlined in the file "COPYING"
+dnl which should have been included with this file.
+dnl
+
+AC_ARG_ENABLE([ldap], [AS_HELP_STRING([--disable-ldap], [disable LDAP support.])],
+ [enable_ldap="$enableval"],
+ [enable_ldap=yes]
+)
+AC_ARG_WITH([ldap-libs], [AS_HELP_STRING([--with-ldap-libs], [set directory for LDAP library.])],
+ LDFLAGS="-L$withval $LDFLAGS"
+ DSOFLAGS="-L$withval $DSOFLAGS",)
+AC_ARG_WITH([ldap-includes], [AS_HELP_STRING([--with-ldap-includes], [set directory for LDAP includes.])],
+ CFLAGS="-I$withval $CFLAGS"
+ CPPFLAGS="-I$withval $CPPFLAGS",)
+
+if test x$enable_ldap != xno; then
+
+ AC_CHECK_HEADER([ldap.h], [
+ AC_SEARCH_LIBS([ldap_initialize], [ldap], [
+ AC_DEFINE([HAVE_LDAP], [], [Define if LDAP support should be enabled])
+ AC_DEFINE([HAVE_OPENLDAP], [], [If LDAP support is that of OpenLDAP])
+ AC_CHECK_LIB([ldap], [ldap_start_tls],
+ AC_DEFINE([HAVE_LDAP_SSL], [], [If LDAP has SSL/TLS support enabled]))],[
+
+ AC_CHECK_LIB([ldap], [ldap_init], [
+ AC_DEFINE([HAVE_LDAP], [], [Define if LDAP support should be enabled])
+ AC_DEFINE([HAVE_MOZILLA_LDAP], [], [If LDAP support is that of Mozilla])
+ AC_CHECK_HEADERS([ldap_ssl.h], [], [], [#include <ldap.h>])
+ AC_CHECK_LIB([ldap], [ldapssl_init],
+ AC_DEFINE([HAVE_LDAP_SSL], [], [If LDAP has SSL/TLS support enabled]))])]
+ )
+ AC_CHECK_LIB([ldap], [ldap_set_rebind_proc], AC_DEFINE([HAVE_LDAP_REBIND_PROC], [], [If libldap implements ldap_set_rebind_proc]))
+ ])
+
+fi
+
+PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.30.2])
+AC_SUBST(GLIB_CFLAGS)
+AC_SUBST(GLIB_LIBS)
+
+if test x$enable_avahi != xno; then
+ PKG_CHECK_MODULES(AVAHI_GLIB, [avahi-glib])
+fi
+
+AC_SUBST(AVAHI_GLIB_CFLAGS)
+AC_SUBST(AVAHI_GLIB_LIBS)
+
+PKG_CHECK_MODULES(GIO, [gio-2.0])
+AC_SUBST(GIO_CFLAGS)
+AC_SUBST(GIO_LIBS)
+
+PKG_CHECK_MODULES(GIO_UNIX, [gio-unix-2.0])
+AC_SUBST(GIO_UNIX_CFLAGS)
+AC_SUBST(GIO_UNIX_LIBS)
+
+AC_ARG_WITH([browseremoteprotocols],
+ [AS_HELP_STRING([--with-browseremoteprotocols=value], [Set which protocols to listen for in cups-browsed (default: dnssd cups)])],
+ [with_browseremoteprotocols="$withval"],
+ [with_browseremoteprotocols="dnssd cups"]
+)
+BROWSEREMOTEPROTOCOLS="$with_browseremoteprotocols"
+AC_SUBST(BROWSEREMOTEPROTOCOLS)
+
+dnl Setup init.d locations...
+AC_ARG_WITH(rcdir, [AS_HELP_STRING([--with-rcdir], [Set path for rc scripts])],rcdir="$withval",rcdir="")
+AC_ARG_WITH(rclevels, [AS_HELP_STRING([--with-rclevels], [Set run levels for rc scripts])],rclevels="$withval",rclevels="2 3 5")
+AC_ARG_WITH(rcstart, [AS_HELP_STRING([--with-rcstart], [Set start number for rc scripts])],rcstart="$withval",rcstart="99")
+AC_ARG_WITH(rcstop, [AS_HELP_STRING([--with-rcstop], [Set stop number for rc scripts])],rcstop="$withval",rcstop="00")
+
+INITDIR=""
+INITDDIR=""
+RCLEVELS="$rclevels"
+RCSTART="$rcstart"
+RCSTOP="$rcstop"
+
+if test x$rcdir = x; then
+ case "`uname`" in
+ FreeBSD* | OpenBSD* | MirBSD* | ekkoBSD*)
+ # FreeBSD and OpenBSD
+ ;;
+
+ Linux | GNU | GNU/k*BSD*)
+ # Linux/HURD seems to choose an init.d directory at random...
+ if test -d /sbin/init.d; then
+ # SuSE
+ INITDIR="/sbin/init.d"
+ else
+ if test -d /etc/init.d; then
+ # Others
+ INITDIR="/etc"
+ else
+ # RedHat
+ INITDIR="/etc/rc.d"
+ fi
+ fi
+ RCSTART="82"
+ RCSTOP="35"
+ ;;
+
+ NetBSD*)
+ # NetBSD
+ INITDDIR="/etc/rc.d"
+ ;;
+
+ *)
+ INITDIR="/etc"
+ ;;
+
+ esac
+elif test "x$rcdir" != xno; then
+ if test "x$rclevels" = x; then
+ INITDDIR="$rcdir"
+ else
+ INITDIR="$rcdir"
+ fi
+fi
+
+AM_CONDITIONAL([RCLINKS], [test "x$INITDIR" != "x"])
+
+if test "x${INITDIR}" != "x" -a "x${INITDDIR}" = "x"; then
+ INITDDIR="${INITDIR}/init.d"
+fi
+
+AC_SUBST(INITDIR)
+AC_SUBST(INITDDIR)
+AC_SUBST(RCLEVELS)
+AC_SUBST(RCSTART)
+AC_SUBST(RCSTOP)
+
+# ======================================
+# Check for various pdf required modules
+# ======================================
+PKG_CHECK_MODULES([LCMS], [lcms2], [lcms2=yes], [lcms2=no])
+AS_IF([test x"$lcms2" = "xno"], [
+ PKG_CHECK_MODULES([LCMS], [lcms])
+ AC_DEFINE([USE_LCMS1], [1], [Defines if use lcms1])
+])
+PKG_CHECK_MODULES([FREETYPE], [freetype2], [AC_DEFINE([HAVE_FREETYPE_H], [1], [Have FreeType2 include files])])
+PKG_CHECK_MODULES([FONTCONFIG], [fontconfig >= 2.0.0])
+PKG_CHECK_MODULES([IJS], [ijs], [have_ijs=yes], [have_ijs=no])
+PKG_CHECK_MODULES([ZLIB], [zlib])
+AC_DEFINE([HAVE_LIBZ], [], [Define that we use zlib])
+PKG_CHECK_MODULES([LIBQPDF], [libqpdf >= 3.0.2])
+
+# ===============================
+# Check for PCLm printing support
+# ===============================
+AC_ARG_ENABLE([pclm], [AS_HELP_STRING([--enable-pclm], [enable PCLm printing.])],
+ [enable_pclm="$enableval"],
+ [enable_pclm=yes]
+)
+if test "x$enable_pclm" != "xno"; then
+ # Do we have QPDF 7.0.0 or newer?
+ AC_CHECK_HEADERS([qpdf/Pl_RunLength.hh],
+ [],
+ [enable_pclm=no]
+ )
+fi
+if test "x$enable_pclm" != "xno"; then
+ AC_DEFINE([QPDF_HAVE_PCLM], [1], [QPDF has PCLm support?])
+ QPDF_NO_PCLM=
+else
+ QPDF_NO_PCLM=\#
+fi
+AC_SUBST(QPDF_NO_PCLM)
+
+
+
+# =================
+# Check for Poppler
+# =================
+AC_ARG_ENABLE(poppler, AS_HELP_STRING([--enable-poppler],[enable Poppler-based filters]),
+ enable_poppler=$enableval,enable_poppler=yes)
+AM_CONDITIONAL(ENABLE_POPPLER, test x$enable_poppler = xyes)
+if test x$enable_poppler = xyes; then
+ PKG_CHECK_MODULES([POPPLER], [poppler >= 0.18])
+ AC_CHECK_HEADER([poppler/cpp/poppler-version.h], [AC_DEFINE([HAVE_CPP_POPPLER_VERSION_H],,[Define if you have Poppler's "cpp/poppler-version.h" header file.])], [])
+fi
+
+# ===============
+# Check for D-Bus
+# ===============
+AC_ARG_ENABLE(dbus, AS_HELP_STRING([--enable-dbus],[enable DBus CMS code]),
+ enable_dbus=$enableval,enable_dbus=yes)
+AM_CONDITIONAL(BUILD_DBUS, test x$enable_dbus = xyes)
+if test x$enable_dbus = xyes; then
+ PKG_CHECK_MODULES(DBUS, dbus-1)
+fi
+
+# ===================================
+# Check for large files and long long
+# ===================================
+AC_SYS_LARGEFILE
+LARGEFILE=""
+AS_IF([test x"$enable_largefile" != "xno"], [
+ LARGEFILE="-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE"
+ AS_IF([test x"$ac_cv_sys_large_files" = "x1"], [LARGEFILE="$LARGEFILE -D_LARGE_FILES"])
+ AS_IF([test x"$ac_cv_sys_file_offset_bits" = "x64"], [LARGEFILE="$LARGEFILE -D_FILE_OFFSET_BITS=64"])
+])
+AC_SUBST(LARGEFILE)
+
+AC_CHECK_TYPE(long long, [long_long_found=yes], [long_long_found=no])
+AS_IF([test x"$long_long_found" = "xyes"], [
+ AC_DEFINE([HAVE_LONG_LONG], [], [Platform supports long long type])
+])
+
+# ================
+# Check for Mutool
+# ================
+AC_ARG_ENABLE([mutool],
+ [AS_HELP_STRING([--disable-mutool], [Disable filters using mutool.])],
+ [enable_mutool="$enableval"],
+ [enable_mutool=yes]
+)
+
+AC_ARG_WITH([mutool-path],
+ [AS_HELP_STRING([--with-mutool-path=value], [Set path to mutool binary (default: system).])],
+ [with_mutool_path="$withval"],
+ [with_mutool_path=system]
+)
+
+# ================
+# Check for pdf2ps
+# ================
+AC_ARG_ENABLE([ghostscript],
+ [AS_HELP_STRING([--disable-ghostscript], [Disable filters using Ghostscript.])],
+ [enable_ghostscript="$enableval"],
+ [enable_ghostscript=yes]
+)
+AC_ARG_ENABLE([ijs],
+ [AS_HELP_STRING([--disable-ijs], [Disable filters using IJS.])],
+ [enable_ijs="$enableval"],
+ [enable_ijs=yes]
+)
+AS_IF([test "x$enable_ijs" = "xyes" -a "x$have_ijs" != "xyes"], [
+ AC_MSG_ERROR([IJS not found, but requested.])
+])
+AM_CONDITIONAL(ENABLE_IJS, test "x$enable_ijs" = "xyes")
+AC_ARG_WITH([pdftops],
+ [AS_HELP_STRING([--with-pdftops=value], [Set which pdftops to use (gs,pdftops,pdftocairo,acroread,mupdf,hybrid).])],
+ [with_pdftops="$withval"],
+ [with_pdftops=hybrid]
+)
+AS_CASE([x$with_pdftops],
+ [xgs|xpdftops|xpdftocairo|xacroread|xmupdf|xhybrid], [],
+ [AC_MSG_ERROR([Unknown value of with-pdftops provided: $with_pdftops])]
+)
+AC_ARG_WITH([gs-path],
+ [AS_HELP_STRING([--with-gs-path=value], [Set path to ghostcript binary (default: system).])],
+ [with_gs_path="$withval"],
+ [with_gs_path=system]
+)
+AC_ARG_WITH([pdftops-path],
+ [AS_HELP_STRING([--with-pdftops-path=value], [Set path to pdftops/ghostscript binary (default: system).])],
+ [with_pdftops_path="$withval"],
+ [with_pdftops_path=system]
+)
+AC_ARG_WITH([pdftocairo-path],
+ [AS_HELP_STRING([--with-pdftocairo-path=value], [Set path to pdftocairo binary (default: system).])],
+ [with_pdftocairo_path="$withval"],
+ [with_pdftocairo_path=system]
+)
+AC_ARG_WITH([acroread-path],
+ [AS_HELP_STRING([--with-acroread-path=value], [Set path to acroread binary (default: system).])],
+ [with_acroread_path="$withval"],
+ [with_acroread_path=system]
+)
+AC_ARG_WITH([ippfind-path],
+ [AS_HELP_STRING([--with-ippfind-path=value], [Set path to ippfind binary (default: system).])],
+ [with_ippfind_path="$withval"],
+ [with_ippfind_path=system]
+)
+AC_ARG_WITH([pdftops-maxres],
+ [AS_HELP_STRING([--with-pdftops-maxres=value], [Set maximum image rendering resolution for pdftops filter (0, 75, 150, 300, 600, 1200, 2400, 4800, 90, 180, 360, 720, 1440, 2880, 5760, unlimited). Default: 1440])],
+ [with_pdftops_maxres="$withval"],
+ [with_pdftops_maxres=1440]
+)
+AS_CASE([x$with_pdftops_maxres],
+ [x0|x75|x150|x300|x600|x1200|x2400|x4800|x90|x180|x360|x720|x1440|x2880|x5760], [CUPS_PDFTOPS_MAXRES=$with_pdftops_maxres],
+ [xunlimited], [CUPS_PDFTOPS_MAXRES=0],
+ [AC_MSG_ERROR([Unknown value of with-pdftops-maxres provided: $with_pdftops])]
+)
+AC_ARG_ENABLE([gs-ps2write],
+ [AS_HELP_STRING([--disable-gs-ps2write], [Ghostscript doesn't support ps2write device.])],
+ [enable_gs_ps2write="$enableval"],
+ [enable_gs_ps2write=yes]
+)
+
+CUPS_GHOSTSCRIPT=""
+AS_IF([test "x$enable_ghostscript" != "xyes"], [
+ with_gs_path=""
+], [
+ AS_IF([test "x$with_gs_path" != "xsystem"], [
+ CUPS_GHOSTSCRIPT="$with_gs_path"
+ ], [
+ AS_IF([test "x$cross_compiling" = "xyes"], [
+ CUPS_GHOSTSCRIPT="gs"
+ ], [
+ AC_CHECK_PROG(CUPS_GHOSTSCRIPT, gs, gs)
+ ])
+ ])
+ AS_IF([test "x$CUPS_GHOSTSCRIPT" = "x"], [
+ AC_MSG_ERROR([Required gs binary is missing. Please install ghostscript-gpl package.])
+ ])
+ AC_DEFINE([HAVE_GHOSTSCRIPT], [], [Define that we provide ghostscript binary])
+ AS_IF([test x"$with_pdftops" = xgs], [AC_DEFINE_UNQUOTED([CUPS_PDFTOPS_RENDERER], [GS], [Define default renderer])])
+
+ AS_IF([test x"$enable_gs_ps2write" = "xyes"], [
+ AC_DEFINE([HAVE_GHOSTSCRIPT_PS2WRITE], [], [gs supports ps2write])
+ ])
+ AS_IF([test "x$cross_compiling" != "xyes"], [
+ AC_MSG_CHECKING(whether gs supports the ps2write device)
+ AS_IF([`$CUPS_GHOSTSCRIPT -h 2>&1 | grep -q ps2write`], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([HAVE_GHOSTSCRIPT_PS2WRITE], [], [gs supports ps2write])
+ ], [
+ AC_MSG_RESULT([no])
+ ])
+ ])
+])
+AM_CONDITIONAL(ENABLE_GHOSTSCRIPT, test "x$enable_ghostscript" = xyes)
+AC_SUBST(CUPS_GHOSTSCRIPT)
+
+CUPS_MUTOOL=""
+AS_IF([test "x$enable_mutool" != "xyes"], [
+ with_mutool_path=""
+], [
+ AS_IF([test "x$with_mutool_path" != "xsystem"], [
+ CUPS_MUTOOL="$with_mutool_path"
+ ], [
+ AS_IF([test "x$cross_compiling" = "xyes"], [
+ CUPS_MUTOOL="mutool"
+ ], [
+ AC_CHECK_PROG(CUPS_MUTOOL, mutool, mutool)
+ ])
+ ])
+ AS_IF([test "x$CUPS_MUTOOL" = "x"], [
+ AC_MSG_ERROR([Required mutool binary is missing. Please install mutool.])
+ ])
+ AS_IF([test x"$with_pdftops" = xmupdf], [AC_DEFINE_UNQUOTED([CUPS_PDFTOPS_RENDERER], [MUPDF], [Define default renderer])])
+])
+AM_CONDITIONAL(ENABLE_MUTOOL, test "x$enable_mutool" = xyes)
+AC_SUBST(CUPS_MUTOOL)
+
+AS_IF([test "x$with_pdftops_path" != "xsystem"], [
+ CUPS_PDFTOPS="$with_pdftops_path"
+], [
+ AS_IF([test "x$cross_compiling" = "xyes"], [
+ CUPS_PDFTOPS="pdftops"
+ ], [
+ AC_CHECK_PROG(CUPS_PDFTOPS, pdftops, /usr/bin/pdftops)
+ ])
+ AS_IF([test "x$CUPS_PDFTOPS" = "x"], [
+ AC_MSG_ERROR([Required pdftops is missing. Please install the pdftops utility of Poppler.])
+ ])
+])
+AS_IF([test "x$CUPS_PDFTOPS" != "x"], [
+ AC_DEFINE([HAVE_POPPLER_PDFTOPS], [], [Define that we provide poppler pdftops.])
+ AS_IF([test x"$with_pdftops" = xpdftops], [AC_DEFINE_UNQUOTED([CUPS_PDFTOPS_RENDERER], [PDFTOPS], [Define default renderer])])
+
+ AS_IF([test "x$cross_compiling" != "xyes"], [
+ AC_MSG_CHECKING([whether pdftops supports -origpagesizes])
+ AS_IF([`$CUPS_PDFTOPS -h 2>&1 | grep -q -- -origpagesizes`], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([HAVE_POPPLER_PDFTOPS_WITH_ORIGPAGESIZES], [] , [pdftops supports -origpagesizes.])
+ ], [
+ AC_MSG_RESULT([no])
+ ])
+ AC_MSG_CHECKING([whether pdftops supports -r])
+ AS_IF([`$CUPS_PDFTOPS -h 2>&1 | grep -q -- '-r '`], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([HAVE_POPPLER_PDFTOPS_WITH_RESOLUTION], [] , [pdftops supports -r argument.])
+ ], [
+ AC_MSG_RESULT([no])
+ ])
+ ])
+])
+AS_IF([test "x$with_pdftocairo_path" != "xsystem"], [
+ CUPS_PDFTOCAIRO="$with_pdftocairo_path"
+], [
+ CUPS_PDFTOCAIRO="pdftocairo"
+])
+AS_IF([test "x$CUPS_PDFTOCAIRO" != "x"], [
+ AS_IF([test x"$with_pdftops" = xpdftocairo], [AC_DEFINE_UNQUOTED([CUPS_PDFTOPS_RENDERER], [PDFTOCAIRO], [Define default renderer])])
+], [
+ AC_MSG_ERROR([Required pdftocairo is missing. Please install Poppler developer packages.])
+])
+AS_IF([test "x$with_acroread_path" != "xsystem"], [
+ CUPS_ACROREAD="$with_acroread_path"
+], [
+ CUPS_ACROREAD="acroread"
+])
+AS_IF([test "x$CUPS_ACROREAD" != "x"], [
+ AS_IF([test x"$with_pdftops" = xacroread], [AC_DEFINE_UNQUOTED([CUPS_PDFTOPS_RENDERER], [ACROREAD], [Define default renderer])])
+])
+AS_IF([test "x$with_ippfind_path" != "xsystem"], [
+ CUPS_IPPFIND="$with_ippfind_path"
+], [
+ CUPS_IPPFIND="ippfind"
+])
+
+AS_IF([test "x$CUPS_GHOSTSCRIPT" != "x" -a "x$CUPS_PDFTOPS" != "x"], [
+ AS_IF([test x"$with_pdftops" = xhybrid], [AC_DEFINE_UNQUOTED([CUPS_PDFTOPS_RENDERER], [HYBRID], [Define default renderer])])
+])
+
+AC_DEFINE_UNQUOTED([CUPS_GHOSTSCRIPT], "$CUPS_GHOSTSCRIPT", [gs binary to use])
+AC_DEFINE_UNQUOTED([CUPS_MUTOOL],"$CUPS_MUTOOL",[mutool binary to use])
+AC_DEFINE_UNQUOTED([CUPS_POPPLER_PDFTOPS], "$CUPS_PDFTOPS", [pdftops binary to use.])
+AC_DEFINE_UNQUOTED([CUPS_POPPLER_PDFTOCAIRO], "$CUPS_PDFTOCAIRO", [pdftocairo binary to use.])
+AC_DEFINE_UNQUOTED([CUPS_ACROREAD], "$CUPS_ACROREAD", [acroread binary to use.])
+AC_DEFINE_UNQUOTED([CUPS_IPPFIND], "$CUPS_IPPFIND", [ippfind binary to use.])
+AC_DEFINE_UNQUOTED([CUPS_PDFTOPS_MAX_RESOLUTION], [$CUPS_PDFTOPS_MAXRES], [max resolution used for pdftops when converting images])
+
+# ==================
+# Check for foomatic
+# ==================
+AC_ARG_ENABLE([foomatic],
+ [AS_HELP_STRING([--disable-foomatic], [Disable Foomatic-based filters.])],
+ [enable_foomatic="$enableval"],
+ [enable_foomatic=yes]
+)
+AM_CONDITIONAL([ENABLE_FOOMATIC], [test "x$enable_foomatic" = "xyes"])
+
+# =============
+# Check for php
+# =============
+# NOTE: This stuff is broken, requires internal cups headers.
+AC_ARG_WITH([php],
+ [AS_HELP_STRING([--with-php], [Determine whether to build php cups extension.])],
+ [with_php="$withval"],
+ [with_php=no]
+)
+AC_ARG_WITH([php-config],
+ [AS_HELP_STRING([--with-php-config=path], [Specify path to php-config executable.])],
+ [with_php_config="$withval"],
+ [with_php_config=system]
+)
+AM_CONDITIONAL([WITH_PHP], [test "x$with_php" = "xyes"])
+AS_IF([test x"$with_php" = "xyes"], [
+ AS_IF([test "x$with_php_config" != "xsystem"], [
+ PHPCONFIG=$with_php_config
+ ], [
+ AC_PATH_TOOL(PHPCONFIG, [php-config])
+ AS_IF([test -z "$PHPCONFIG"], [
+ AC_MSG_ERROR([Required php-config is missing. Please install PHP developer packages.])
+ ])
+ ])
+ PHPDIR="`$PHPCONFIG --extension-dir`"
+ AC_SUBST(PHPDIR)
+])
+
+# =========
+# Test ARGS
+# =========
+AC_ARG_WITH([test-font-path],
+ [AS_HELP_STRING([--with-test-font-path=value], [Set path to font used for tests (default: /usr/share/fonts/dejavu/DejaVuSans.ttf).])],
+ [with_test_font_path="$withval"],
+ [with_test_font_path="/usr/share/fonts/dejavu/DejaVuSans.ttf"]
+)
+AC_DEFINE_UNQUOTED([TESTFONT], ["$with_test_font_path"], [Path to font used in tests])
+
+# ================
+# Check for cflags
+# ================
+AC_ARG_ENABLE([werror],
+ [AS_HELP_STRING([--enable-werror], [Treat all warnings as errors, useful for development.])],
+ [enable_werror="$enableval"],
+ [enable_werror=no]
+)
+AS_IF([test x"$enable_werror" = "xyes"], [
+ CFLAGS="$CFLAGS -Werror"
+])
+AS_IF([test x"$GCC" = "xyes"], [
+ # Be tough with warnings and produce less careless code
+ CFLAGS="$CFLAGS -Wall -std=gnu11"
+ CXXFLAGS="$CXXFLAGS -Wall " # -Weffc++" # TODO: enable when it does not print 1MB of warnings
+])
+CFLAGS="$CFLAGS -D_GNU_SOURCE"
+CXXFLAGS="$CXXFLAGS -D_GNU_SOURCE"
+
+# ==========================
+# Braille embossing/liblouis
+# ==========================
+AC_ARG_ENABLE(braille, AS_HELP_STRING([--enable-braille],[enable Braille embosing filters, requires liblouis]),
+ enable_braille=$enableval,enable_braille=yes)
+AC_MSG_CHECKING(for liblouis)
+PKG_CHECK_EXISTS([liblouis], [
+ AC_MSG_RESULT(yes)
+ if test "x$enable_braille" = xyes; then
+ TABLESDIR=`$PKG_CONFIG --variable=tablesdir liblouis`
+ else
+ TABLESDIR=/usr/share/liblouis/tables
+ fi
+], [
+ AC_MSG_RESULT(no)
+ TABLESDIR=/usr/share/liblouis/tables
+])
+AM_CONDITIONAL(ENABLE_BRAILLE, test "x$enable_braille" = xyes)
+AC_SUBST(TABLESDIR)
+
+# =========================================================
+# Select a different shell instead of the default /bin/bash
+# =========================================================
+AC_ARG_WITH([shell],
+ [AS_HELP_STRING([--with-shell=path], [Specify path for a modern shell.])],
+ [with_shell="$withval"],
+ [with_shell="/bin/bash"]
+)
+AC_DEFINE_UNQUOTED([SHELL], "$with_shell", [Path for a modern shell])
+
+# =====================
+# Prepare all .in files
+# =====================
+AC_CONFIG_FILES([
+ libcupsfilters.pc
+ libfontembed.pc
+ Makefile
+ utils/cups-browsed
+ utils/cups-browsed.conf
+ filter/foomatic-rip/foomatic-rip.1
+ filter/braille/drivers/index/indexv4.sh
+ filter/braille/drivers/index/indexv3.sh
+ filter/braille/drivers/index/index.sh
+ filter/braille/drivers/index/textbrftoindexv3
+ filter/braille/drivers/index/imageubrltoindexv3
+ filter/braille/drivers/index/imageubrltoindexv4
+ filter/braille/drivers/generic/brftoembosser
+ filter/braille/filters/cups-braille.sh
+ filter/braille/filters/imagetobrf
+ filter/braille/filters/texttobrf
+ filter/braille/filters/vectortopdf
+ filter/braille/filters/vectortobrf
+ filter/braille/filters/musicxmltobrf
+ filter/braille/filters/liblouis1.defs.gen
+ mime/cupsfilters.convs
+])
+AC_CONFIG_COMMANDS([executable-scripts], [
+ chmod +x filter/braille/filters/liblouis1.defs.gen
+])
+AC_OUTPUT
+
+# ==============================================
+# Display final informations about configuration
+# ==============================================
+AC_MSG_NOTICE([
+==============================================================================
+Environment settings:
+ CFLAGS: ${CFLAGS}
+ CXXFLAGS: ${CXXFLAGS}
+ LDFLAGS: ${LDFLAGS}
+Build configuration:
+ cups-config: ${with_cups_config}
+ font directory: ${sysconfdir}/${FONTDIR}
+ foomatic: ${enable_foomatic}
+ init directory: ${INITDDIR}
+ cups dom socket: ${CUPS_DEFAULT_DOMAINSOCKET}
+ poppler: ${enable_poppler}
+ ghostscript: ${enable_ghostscript}
+ gs-path: ${with_gs_path}
+ mutool: ${enable_mutool}
+ mutool-path: ${with_mutool_path}
+ ippfind-path: ${with_ippfind_path}
+ imagefilters: ${enable_imagefilters}
+ jpeg: ${with_jpeg}
+ pdftocairo-path: ${with_pdftocairo_path}
+ pdftops: ${with_pdftops}
+ pdftops-path: ${with_pdftops_path}
+ png: ${with_png}
+ php: ${with_php}
+ php-config: ${with_php_config}
+ shell: ${with_shell}
+ test-font: ${with_test_font_path}
+ tiff: ${with_tiff}
+ avahi: ${enable_avahi}
+ dbus: ${enable_dbus}
+ browsing: ${with_browseremoteprotocols}
+ werror: ${enable_werror}
+ braille: ${enable_braille}
+ braille tables: ${TABLESDIR}
+ driverless: ${enable_driverless}
+ apple-raster: ${APPLE_RASTER_FILTER}
+ pclm: ${enable_pclm}
+ driverless auto-setup: ${enable_auto_setup_driverless}
+==============================================================================
+])
diff --git a/cupsfilters/attr.c b/cupsfilters/attr.c
new file mode 100644
index 000000000..81ca9bc62
--- /dev/null
+++ b/cupsfilters/attr.c
@@ -0,0 +1,104 @@
+/*
+ * PPD attribute lookup routine for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * cupsFindAttr() - Find a PPD attribute based on the colormodel,
+ * media, and resolution.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include <config.h>
+#include "driver.h"
+#include <string.h>
+#include <ctype.h>
+
+
+/*
+ * 'cupsFindAttr()' - Find a PPD attribute based on the colormodel,
+ * media, and resolution.
+ */
+
+ppd_attr_t * /* O - Matching attribute or NULL */
+cupsFindAttr(ppd_file_t *ppd, /* I - PPD file */
+ const char *name, /* I - Attribute name */
+ const char *colormodel, /* I - Color model */
+ const char *media, /* I - Media type */
+ const char *resolution, /* I - Resolution */
+ char *spec, /* O - Final selection string */
+ int specsize) /* I - Size of string buffer */
+{
+ ppd_attr_t *attr; /* Attribute */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (!ppd || !name || !colormodel || !media || !resolution || !spec ||
+ specsize < PPD_MAX_NAME)
+ return (NULL);
+
+ /*
+ * Look for the attribute with the following keywords:
+ *
+ * ColorModel.MediaType.Resolution
+ * ColorModel.Resolution
+ * ColorModel
+ * MediaType.Resolution
+ * MediaType
+ * Resolution
+ * ""
+ */
+
+ snprintf(spec, specsize, "%s.%s.%s", colormodel, media, resolution);
+ fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec);
+ if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL)
+ return (attr);
+
+ snprintf(spec, specsize, "%s.%s", colormodel, resolution);
+ fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec);
+ if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL)
+ return (attr);
+
+ snprintf(spec, specsize, "%s", colormodel);
+ fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec);
+ if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL)
+ return (attr);
+
+ snprintf(spec, specsize, "%s.%s", media, resolution);
+ fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec);
+ if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL)
+ return (attr);
+
+ snprintf(spec, specsize, "%s", media);
+ fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec);
+ if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL)
+ return (attr);
+
+ snprintf(spec, specsize, "%s", resolution);
+ fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec);
+ if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL)
+ return (attr);
+
+ spec[0] = '\0';
+ fprintf(stderr, "DEBUG2: Looking for \"*%s\"...\n", name);
+ if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL)
+ return (attr);
+
+ fprintf(stderr, "DEBUG2: No instance of \"*%s\" found...\n", name);
+
+ return (NULL);
+}
+
diff --git a/cupsfilters/check.c b/cupsfilters/check.c
new file mode 100644
index 000000000..c2f374dbc
--- /dev/null
+++ b/cupsfilters/check.c
@@ -0,0 +1,104 @@
+/*
+ * Byte checking routines for CUPS.
+ *
+ * Copyright 2007 by Apple Inc.
+ * Copyright 1993-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * cupsCheckBytes() - Check to see if all bytes are zero.
+ * cupsCheckValue() - Check to see if all bytes match the given value.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "driver.h"
+
+
+/*
+ * 'cupsCheckBytes()' - Check to see if all bytes are zero.
+ */
+
+int /* O - 1 if they match */
+cupsCheckBytes(const unsigned char *bytes, /* I - Bytes to check */
+ int length) /* I - Number of bytes to check */
+{
+ while (length > 7)
+ {
+ if (*bytes++)
+ return (0);
+ if (*bytes++)
+ return (0);
+ if (*bytes++)
+ return (0);
+ if (*bytes++)
+ return (0);
+ if (*bytes++)
+ return (0);
+ if (*bytes++)
+ return (0);
+ if (*bytes++)
+ return (0);
+ if (*bytes++)
+ return (0);
+
+ length -= 8;
+ }
+
+ while (length > 0)
+ if (*bytes++)
+ return (0);
+ else
+ length --;
+
+ return (1);
+}
+
+
+/*
+ * 'cupsCheckValue()' - Check to see if all bytes match the given value.
+ */
+
+int /* O - 1 if they match */
+cupsCheckValue(const unsigned char *bytes, /* I - Bytes to check */
+ int length, /* I - Number of bytes to check */
+ const unsigned char value) /* I - Value to check */
+{
+ while (length > 7)
+ {
+ if (*bytes++ != value)
+ return (0);
+ if (*bytes++ != value)
+ return (0);
+ if (*bytes++ != value)
+ return (0);
+ if (*bytes++ != value)
+ return (0);
+ if (*bytes++ != value)
+ return (0);
+ if (*bytes++ != value)
+ return (0);
+ if (*bytes++ != value)
+ return (0);
+ if (*bytes++ != value)
+ return (0);
+
+ length -= 8;
+ }
+
+ while (length > 0)
+ if (*bytes++ != value)
+ return (0);
+ else
+ length --;
+
+ return (1);
+}
+
diff --git a/cupsfilters/cmyk.c b/cupsfilters/cmyk.c
new file mode 100644
index 000000000..42766833b
--- /dev/null
+++ b/cupsfilters/cmyk.c
@@ -0,0 +1,1950 @@
+/*
+ * CMYK color separation code for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * cupsCMYKDelete() - Delete a color separation.
+ * cupsCMYKDoBlack() - Do a black separation...
+ * cupsCMYKDoCMYK() - Do a CMYK separation...
+ * cupsCMYKDoGray() - Do a grayscale separation...
+ * cupsCMYKDoRGB() - Do an sRGB separation...
+ * cupsCMYKLoad() - Load a CMYK color profile from PPD attributes.
+ * cupsCMYKNew() - Create a new CMYK color separation.
+ * cupsCMYKSetBlack() - Set the transition range for CMY to black.
+ * cupsCMYKSetCurve() - Set a color transform curve using points.
+ * cupsCMYKSetGamma() - Set a color transform curve using gamma and
+ * density.
+ * cupsCMYKSetInkLimit() - Set the limit on the amount of ink.
+ * cupsCMYKSetLtDk() - Set light/dark ink transforms.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include <config.h>
+#include "driver.h"
+#include <string.h>
+#include <ctype.h>
+
+
+/*
+ * 'cupsCMYKDelete()' - Delete a color separation.
+ */
+
+void
+cupsCMYKDelete(cups_cmyk_t *cmyk) /* I - Color separation */
+{
+ /*
+ * Range check input...
+ */
+
+ if (cmyk == NULL)
+ return;
+
+ /*
+ * Free memory used...
+ */
+
+ free(cmyk->channels[0]);
+ free(cmyk);
+}
+
+
+/*
+ * 'cupsCMYKDoBlack()' - Do a black separation...
+ */
+
+void
+cupsCMYKDoBlack(const cups_cmyk_t *cmyk,
+ /* I - Color separation */
+ const unsigned char *input,
+ /* I - Input grayscale pixels */
+ short *output,
+ /* O - Output Device-N pixels */
+ int num_pixels)
+ /* I - Number of pixels */
+{
+ int k; /* Current black value */
+ const short **channels; /* Copy of channel LUTs */
+ int ink, /* Amount of ink */
+ ink_limit; /* Ink limit from separation */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (cmyk == NULL || input == NULL || output == NULL || num_pixels <= 0)
+ return;
+
+ /*
+ * Loop through it all...
+ */
+
+ channels = (const short **)cmyk->channels;
+ ink_limit = cmyk->ink_limit;
+
+ switch (cmyk->num_channels)
+ {
+ case 1 : /* Black */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ k = *input++;
+ *output++ = channels[0][k];
+
+ num_pixels --;
+ }
+ break;
+
+ case 2 : /* Black, light black */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ k = *input++;
+ output[0] = channels[0][k];
+ output[1] = channels[1][k];
+
+ if (ink_limit)
+ {
+ ink = output[0] + output[1];
+
+ if (ink > ink_limit)
+ {
+ output[0] = ink_limit * output[0] / ink;
+ output[1] = ink_limit * output[1] / ink;
+ }
+ }
+
+ output += 2;
+ num_pixels --;
+ }
+ break;
+
+ case 3 : /* CMY */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ k = *input++;
+ output[0] = channels[0][k];
+ output[1] = channels[1][k];
+ output[2] = channels[2][k];
+
+ if (ink_limit)
+ {
+ ink = output[0] + output[1] + output[2];
+
+ if (ink > ink_limit)
+ {
+ output[0] = ink_limit * output[0] / ink;
+ output[1] = ink_limit * output[1] / ink;
+ output[2] = ink_limit * output[2] / ink;
+ }
+ }
+
+ output += 3;
+ num_pixels --;
+ }
+ break;
+
+ case 4 : /* CMYK */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ k = *input++;
+ *output++ = 0;
+ *output++ = 0;
+ *output++ = 0;
+ *output++ = channels[3][k];
+
+ num_pixels --;
+ }
+ break;
+
+ case 6 : /* CcMmYK */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ k = *input++;
+ *output++ = 0;
+ *output++ = 0;
+ *output++ = 0;
+ *output++ = 0;
+ *output++ = 0;
+ *output++ = channels[5][k];
+
+ num_pixels --;
+ }
+ break;
+
+ case 7 : /* CcMmYKk */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ k = *input++;
+ output[0] = 0;
+ output[1] = 0;
+ output[2] = 0;
+ output[3] = 0;
+ output[4] = 0;
+ output[5] = channels[5][k];
+ output[6] = channels[6][k];
+
+ if (ink_limit)
+ {
+ ink = output[5] + output[6];
+
+ if (ink > ink_limit)
+ {
+ output[5] = ink_limit * output[5] / ink;
+ output[6] = ink_limit * output[6] / ink;
+ }
+ }
+
+ output += 7;
+ num_pixels --;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'cupsCMYKDoCMYK()' - Do a CMYK separation...
+ */
+
+void
+cupsCMYKDoCMYK(const cups_cmyk_t *cmyk,
+ /* I - Color separation */
+ const unsigned char *input,
+ /* I - Input grayscale pixels */
+ short *output,
+ /* O - Output Device-N pixels */
+ int num_pixels)
+ /* I - Number of pixels */
+{
+ int c, /* Current cyan value */
+ m, /* Current magenta value */
+ y, /* Current yellow value */
+ k; /* Current black value */
+ const short **channels; /* Copy of channel LUTs */
+ int ink, /* Amount of ink */
+ ink_limit; /* Ink limit from separation */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (cmyk == NULL || input == NULL || output == NULL || num_pixels <= 0)
+ return;
+
+ /*
+ * Loop through it all...
+ */
+
+ channels = (const short **)cmyk->channels;
+ ink_limit = cmyk->ink_limit;
+
+ switch (cmyk->num_channels)
+ {
+ case 1 : /* Black */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ c = *input++;
+ m = *input++;
+ y = *input++;
+ k = *input++ + (c * 31 + m * 61 + y * 8) / 100;
+
+ if (k < 255)
+ *output++ = channels[0][k];
+ else
+ *output++ = channels[0][255];
+
+ num_pixels --;
+ }
+ break;
+
+ case 2 : /* Black, light black */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ c = *input++;
+ m = *input++;
+ y = *input++;
+ k = *input++ + (c * 31 + m * 61 + y * 8) / 100;
+
+ if (k < 255)
+ {
+ output[0] = channels[0][k];
+ output[1] = channels[1][k];
+ }
+ else
+ {
+ output[0] = channels[0][255];
+ output[1] = channels[1][255];
+ }
+
+ if (ink_limit)
+ {
+ ink = output[0] + output[1];
+
+ if (ink > ink_limit)
+ {
+ output[0] = ink_limit * output[0] / ink;
+ output[1] = ink_limit * output[1] / ink;
+ }
+ }
+
+ output += 2;
+ num_pixels --;
+ }
+ break;
+
+ case 3 : /* CMY */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ c = *input++;
+ m = *input++;
+ y = *input++;
+ k = *input++;
+ c += k;
+ m += k;
+ y += k;
+
+ if (c < 255)
+ output[0] = channels[0][c];
+ else
+ output[0] = channels[0][255];
+
+ if (m < 255)
+ output[1] = channels[1][m];
+ else
+ output[1] = channels[1][255];
+
+ if (y < 255)
+ output[2] = channels[2][y];
+ else
+ output[2] = channels[2][255];
+
+ if (ink_limit)
+ {
+ ink = output[0] + output[1] + output[2];
+
+ if (ink > ink_limit)
+ {
+ output[0] = ink_limit * output[0] / ink;
+ output[1] = ink_limit * output[1] / ink;
+ output[2] = ink_limit * output[2] / ink;
+ }
+ }
+
+ output += 3;
+ num_pixels --;
+ }
+ break;
+
+ case 4 : /* CMYK */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ c = *input++;
+ m = *input++;
+ y = *input++;
+ k = *input++;
+
+ output[0] = channels[0][c];
+ output[1] = channels[1][m];
+ output[2] = channels[2][y];
+ output[3] = channels[3][k];
+
+ if (ink_limit)
+ {
+ ink = output[0] + output[1] + output[2] + output[3];
+
+ if (ink > ink_limit)
+ {
+ output[0] = ink_limit * output[0] / ink;
+ output[1] = ink_limit * output[1] / ink;
+ output[2] = ink_limit * output[2] / ink;
+ output[3] = ink_limit * output[3] / ink;
+ }
+ }
+
+ output += 4;
+ num_pixels --;
+ }
+ break;
+
+ case 6 : /* CcMmYK */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ c = *input++;
+ m = *input++;
+ y = *input++;
+ k = *input++;
+
+ output[0] = channels[0][c];
+ output[1] = channels[1][c];
+ output[2] = channels[2][m];
+ output[3] = channels[3][m];
+ output[4] = channels[4][y];
+ output[5] = channels[5][k];
+
+ if (ink_limit)
+ {
+ ink = output[0] + output[1] + output[2] + output[3] +
+ output[4] + output[5];
+
+ if (ink > ink_limit)
+ {
+ output[0] = ink_limit * output[0] / ink;
+ output[1] = ink_limit * output[1] / ink;
+ output[2] = ink_limit * output[2] / ink;
+ output[3] = ink_limit * output[3] / ink;
+ output[4] = ink_limit * output[4] / ink;
+ output[5] = ink_limit * output[5] / ink;
+ }
+ }
+
+ output += 6;
+ num_pixels --;
+ }
+ break;
+
+ case 7 : /* CcMmYKk */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ c = *input++;
+ m = *input++;
+ y = *input++;
+ k = *input++;
+
+ output[0] = channels[0][c];
+ output[1] = channels[1][c];
+ output[2] = channels[2][m];
+ output[3] = channels[3][m];
+ output[4] = channels[4][y];
+ output[5] = channels[5][k];
+ output[6] = channels[6][k];
+
+ if (ink_limit)
+ {
+ ink = output[0] + output[1] + output[2] + output[3] +
+ output[4] + output[5] + output[6];
+
+ if (ink > ink_limit)
+ {
+ output[0] = ink_limit * output[0] / ink;
+ output[1] = ink_limit * output[1] / ink;
+ output[2] = ink_limit * output[2] / ink;
+ output[3] = ink_limit * output[3] / ink;
+ output[4] = ink_limit * output[4] / ink;
+ output[5] = ink_limit * output[5] / ink;
+ output[6] = ink_limit * output[6] / ink;
+ }
+ }
+
+ output += 7;
+ num_pixels --;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'cupsCMYKDoGray()' - Do a grayscale separation...
+ */
+
+void
+cupsCMYKDoGray(const cups_cmyk_t *cmyk,
+ /* I - Color separation */
+ const unsigned char *input,
+ /* I - Input grayscale pixels */
+ short *output,
+ /* O - Output Device-N pixels */
+ int num_pixels)
+ /* I - Number of pixels */
+{
+ int k, /* Current black value */
+ kc; /* Current black color value */
+ const short **channels; /* Copy of channel LUTs */
+ int ink, /* Amount of ink */
+ ink_limit; /* Ink limit from separation */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (cmyk == NULL || input == NULL || output == NULL || num_pixels <= 0)
+ return;
+
+ /*
+ * Loop through it all...
+ */
+
+ channels = (const short **)cmyk->channels;
+ ink_limit = cmyk->ink_limit;
+
+ switch (cmyk->num_channels)
+ {
+ case 1 : /* Black */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ k = cups_scmy_lut[*input++];
+ *output++ = channels[0][k];
+
+ num_pixels --;
+ }
+ break;
+
+ case 2 : /* Black, light black */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ k = cups_scmy_lut[*input++];
+ output[0] = channels[0][k];
+ output[1] = channels[1][k];
+
+ if (ink_limit)
+ {
+ ink = output[0] + output[1];
+
+ if (ink > ink_limit)
+ {
+ output[0] = ink_limit * output[0] / ink;
+ output[1] = ink_limit * output[1] / ink;
+ }
+ }
+
+ output += 2;
+ num_pixels --;
+ }
+ break;
+
+ case 3 : /* CMY */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ k = cups_scmy_lut[*input++];
+ output[0] = channels[0][k];
+ output[1] = channels[1][k];
+ output[2] = channels[2][k];
+
+ if (ink_limit)
+ {
+ ink = output[0] + output[1] + output[2];
+
+ if (ink > ink_limit)
+ {
+ output[0] = ink_limit * output[0] / ink;
+ output[1] = ink_limit * output[1] / ink;
+ output[2] = ink_limit * output[2] / ink;
+ }
+ }
+
+ output += 3;
+ num_pixels --;
+ }
+ break;
+
+ case 4 : /* CMYK */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ k = cups_scmy_lut[*input++];
+ kc = cmyk->color_lut[k];
+ k = cmyk->black_lut[k];
+ output[0] = channels[0][kc];
+ output[1] = channels[1][kc];
+ output[2] = channels[2][kc];
+ output[3] = channels[3][k];
+
+ if (ink_limit)
+ {
+ ink = output[0] + output[1] + output[2] + output[3];
+
+ if (ink > ink_limit)
+ {
+ output[0] = ink_limit * output[0] / ink;
+ output[1] = ink_limit * output[1] / ink;
+ output[2] = ink_limit * output[2] / ink;
+ output[3] = ink_limit * output[3] / ink;
+ }
+ }
+
+ output += 4;
+ num_pixels --;
+ }
+ break;
+
+ case 6 : /* CcMmYK */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ k = cups_scmy_lut[*input++];
+ kc = cmyk->color_lut[k];
+ k = cmyk->black_lut[k];
+ output[0] = channels[0][kc];
+ output[1] = channels[1][kc];
+ output[2] = channels[2][kc];
+ output[3] = channels[3][kc];
+ output[4] = channels[4][kc];
+ output[5] = channels[5][k];
+
+ if (ink_limit)
+ {
+ ink = output[0] + output[1] + output[2] + output[3] +
+ output[4] + output[5];
+
+ if (ink > ink_limit)
+ {
+ output[0] = ink_limit * output[0] / ink;
+ output[1] = ink_limit * output[1] / ink;
+ output[2] = ink_limit * output[2] / ink;
+ output[3] = ink_limit * output[3] / ink;
+ output[4] = ink_limit * output[4] / ink;
+ output[5] = ink_limit * output[5] / ink;
+ }
+ }
+
+ output += 6;
+ num_pixels --;
+ }
+ break;
+
+ case 7 : /* CcMmYKk */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ k = cups_scmy_lut[*input++];
+ kc = cmyk->color_lut[k];
+ k = cmyk->black_lut[k];
+ output[0] = channels[0][kc];
+ output[1] = channels[1][kc];
+ output[2] = channels[2][kc];
+ output[3] = channels[3][kc];
+ output[4] = channels[4][kc];
+ output[5] = channels[5][k];
+ output[6] = channels[6][k];
+
+ if (ink_limit)
+ {
+ ink = output[0] + output[1] + output[2] + output[3] +
+ output[4] + output[5] + output[6];
+
+ if (ink > ink_limit)
+ {
+ output[0] = ink_limit * output[0] / ink;
+ output[1] = ink_limit * output[1] / ink;
+ output[2] = ink_limit * output[2] / ink;
+ output[3] = ink_limit * output[3] / ink;
+ output[4] = ink_limit * output[4] / ink;
+ output[5] = ink_limit * output[5] / ink;
+ output[6] = ink_limit * output[6] / ink;
+ }
+ }
+
+ output += 7;
+ num_pixels --;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'cupsCMYKDoRGB()' - Do an sRGB separation...
+ */
+
+void
+cupsCMYKDoRGB(const cups_cmyk_t *cmyk,
+ /* I - Color separation */
+ const unsigned char *input,
+ /* I - Input grayscale pixels */
+ short *output,
+ /* O - Output Device-N pixels */
+ int num_pixels)
+ /* I - Number of pixels */
+{
+ int c, /* Current cyan value */
+ m, /* Current magenta value */
+ y, /* Current yellow value */
+ k, /* Current black value */
+ kc, /* Current black color value */
+ km; /* Maximum black value */
+ const short **channels; /* Copy of channel LUTs */
+ int ink, /* Amount of ink */
+ ink_limit; /* Ink limit from separation */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (cmyk == NULL || input == NULL || output == NULL || num_pixels <= 0)
+ return;
+
+ /*
+ * Loop through it all...
+ */
+
+ channels = (const short **)cmyk->channels;
+ ink_limit = cmyk->ink_limit;
+
+ switch (cmyk->num_channels)
+ {
+ case 1 : /* Black */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ c = cups_scmy_lut[*input++];
+ m = cups_scmy_lut[*input++];
+ y = cups_scmy_lut[*input++];
+ k = (c * 31 + m * 61 + y * 8) / 100;
+
+ *output++ = channels[0][k];
+
+ num_pixels --;
+ }
+ break;
+
+ case 2 : /* Black, light black */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ c = cups_scmy_lut[*input++];
+ m = cups_scmy_lut[*input++];
+ y = cups_scmy_lut[*input++];
+ k = (c * 31 + m * 61 + y * 8) / 100;
+
+ output[0] = channels[0][k];
+ output[1] = channels[1][k];
+
+ if (ink_limit)
+ {
+ ink = output[0] + output[1];
+
+ if (ink > ink_limit)
+ {
+ output[0] = ink_limit * output[0] / ink;
+ output[1] = ink_limit * output[1] / ink;
+ }
+ }
+
+ output += 2;
+ num_pixels --;
+ }
+ break;
+
+ case 3 : /* CMY */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ c = cups_scmy_lut[*input++];
+ m = cups_scmy_lut[*input++];
+ y = cups_scmy_lut[*input++];
+
+ output[0] = channels[0][c];
+ output[1] = channels[1][m];
+ output[2] = channels[2][y];
+
+ if (ink_limit)
+ {
+ ink = output[0] + output[1] + output[2];
+
+ if (ink > ink_limit)
+ {
+ output[0] = ink_limit * output[0] / ink;
+ output[1] = ink_limit * output[1] / ink;
+ output[2] = ink_limit * output[2] / ink;
+ }
+ }
+
+ output += 3;
+ num_pixels --;
+ }
+ break;
+
+ case 4 : /* CMYK */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ c = cups_scmy_lut[*input++];
+ m = cups_scmy_lut[*input++];
+ y = cups_scmy_lut[*input++];
+ k = min(c, min(m, y));
+
+ if ((km = max(c, max(m, y))) > k)
+ k = k * k * k / (km * km);
+
+ kc = cmyk->color_lut[k] - k;
+ k = cmyk->black_lut[k];
+ c += kc;
+ m += kc;
+ y += kc;
+
+ output[0] = channels[0][c];
+ output[1] = channels[1][m];
+ output[2] = channels[2][y];
+ output[3] = channels[3][k];
+
+ if (ink_limit)
+ {
+ ink = output[0] + output[1] + output[2] + output[3];
+
+ if (ink > ink_limit)
+ {
+ output[0] = ink_limit * output[0] / ink;
+ output[1] = ink_limit * output[1] / ink;
+ output[2] = ink_limit * output[2] / ink;
+ output[3] = ink_limit * output[3] / ink;
+ }
+ }
+
+ output += 4;
+ num_pixels --;
+ }
+ break;
+
+ case 6 : /* CcMmYK */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ c = cups_scmy_lut[*input++];
+ m = cups_scmy_lut[*input++];
+ y = cups_scmy_lut[*input++];
+ k = min(c, min(m, y));
+
+ if ((km = max(c, max(m, y))) > k)
+ k = k * k * k / (km * km);
+
+ kc = cmyk->color_lut[k] - k;
+ k = cmyk->black_lut[k];
+ c += kc;
+ m += kc;
+ y += kc;
+
+ output[0] = channels[0][c];
+ output[1] = channels[1][c];
+ output[2] = channels[2][m];
+ output[3] = channels[3][m];
+ output[4] = channels[4][y];
+ output[5] = channels[5][k];
+
+ if (ink_limit)
+ {
+ ink = output[0] + output[1] + output[2] + output[3] +
+ output[4] + output[5];
+
+ if (ink > ink_limit)
+ {
+ output[0] = ink_limit * output[0] / ink;
+ output[1] = ink_limit * output[1] / ink;
+ output[2] = ink_limit * output[2] / ink;
+ output[3] = ink_limit * output[3] / ink;
+ output[4] = ink_limit * output[4] / ink;
+ output[5] = ink_limit * output[5] / ink;
+ }
+ }
+
+ output += 6;
+ num_pixels --;
+ }
+ break;
+
+ case 7 : /* CcMmYKk */
+ while (num_pixels > 0)
+ {
+ /*
+ * Get the input black value and then set the corresponding color
+ * channel values...
+ */
+
+ c = cups_scmy_lut[*input++];
+ m = cups_scmy_lut[*input++];
+ y = cups_scmy_lut[*input++];
+ k = min(c, min(m, y));
+
+ if ((km = max(c, max(m, y))) > k)
+ k = k * k * k / (km * km);
+
+ kc = cmyk->color_lut[k] - k;
+ k = cmyk->black_lut[k];
+ c += kc;
+ m += kc;
+ y += kc;
+
+ output[0] = channels[0][c];
+ output[1] = channels[1][c];
+ output[2] = channels[2][m];
+ output[3] = channels[3][m];
+ output[4] = channels[4][y];
+ output[5] = channels[5][k];
+ output[6] = channels[6][k];
+
+ if (ink_limit)
+ {
+ ink = output[0] + output[1] + output[2] + output[3] +
+ output[4] + output[5] + output[6];
+
+ if (ink > ink_limit)
+ {
+ output[0] = ink_limit * output[0] / ink;
+ output[1] = ink_limit * output[1] / ink;
+ output[2] = ink_limit * output[2] / ink;
+ output[3] = ink_limit * output[3] / ink;
+ output[4] = ink_limit * output[4] / ink;
+ output[5] = ink_limit * output[5] / ink;
+ output[6] = ink_limit * output[6] / ink;
+ }
+ }
+
+ output += 7;
+ num_pixels --;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'cupsCMYKLoad()' - Load a CMYK color profile from PPD attributes.
+ */
+
+cups_cmyk_t * /* O - CMYK color separation */
+cupsCMYKLoad(ppd_file_t *ppd, /* I - PPD file */
+ const char *colormodel, /* I - ColorModel value */
+ const char *media, /* I - MediaType value */
+ const char *resolution) /* I - Resolution value */
+{
+ cups_cmyk_t *cmyk; /* CMYK color separation */
+ char spec[PPD_MAX_NAME]; /* Profile name */
+ ppd_attr_t *attr; /* Attribute from PPD file */
+ int num_channels; /* Number of color components */
+ float gamval, /* Gamma correction value */
+ density, /* Density value */
+ light, /* Light ink limit */
+ dark, /* Light ink cut-off */
+ lower, /* Start of black ink */
+ upper; /* End of color ink */
+ int num_xypoints; /* Number of X,Y points */
+ float xypoints[100 * 2], /* X,Y points */
+ *xyptr; /* Current X,Y point */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (ppd == NULL || colormodel == NULL || resolution == NULL || media == NULL)
+ return (NULL);
+
+ /*
+ * Find the following attributes:
+ *
+ * cupsAllGamma - Set default curve using gamma + density
+ * cupsAllXY - Set default curve using XY points
+ * cupsBlackGamma - Set black curve using gamma + density
+ * cupsBlackGeneration - Set black generation
+ * cupsBlackLightDark - Set black light/dark transition
+ * cupsBlackXY - Set black curve using XY points
+ * cupsCyanGamma - Set cyan curve using gamma + density
+ * cupsCyanLightDark - Set cyan light/dark transition
+ * cupsCyanXY - Set cyan curve using XY points
+ * cupsInkChannels - Set number of color channels
+ * cupsInkLimit - Set total ink limit
+ * cupsLightBlackGamma - Set light black curve using gamma + density
+ * cupsLightBlackXY - Set light black curve using XY points
+ * cupsLightCyanGamma - Set light cyan curve using gamma + density
+ * cupsLightCyanXY - Set light cyan curve using XY points
+ * cupsLightMagentaGamma - Set light magenta curve using gamma + density
+ * cupsLightMagentaXY - Set light magenta curve using XY points
+ * cupsMagentaGamma - Set magenta curve using gamma + density
+ * cupsMagentaLightDark - Set magenta light/dark transition
+ * cupsMagentaXY - Set magenta curve using XY points
+ * cupsYellowGamma - Set yellow curve using gamma + density
+ * cupsYellowXY - Set yellow curve using XY points
+ *
+ * The only required attribute is cupsInkChannels.
+ *
+ * The *XY attributes have precedence over the *Gamma attributes, and
+ * the *Light* attributes have precedence over the corresponding
+ * *LightDark* attributes.
+ */
+
+ /*
+ * Get the required cupsInkChannels attribute...
+ */
+
+ if ((attr = cupsFindAttr(ppd, "cupsInkChannels", colormodel, media,
+ resolution, spec, sizeof(spec))) == NULL)
+ return (NULL);
+
+ num_channels = atoi(attr->value);
+
+ if (num_channels < 1 || num_channels > 7 || num_channels == 5)
+ return (NULL);
+
+ if ((cmyk = cupsCMYKNew(num_channels)) == NULL)
+ return (NULL);
+
+ /*
+ * Get the optional cupsInkLimit attribute...
+ */
+
+ if ((attr = cupsFindAttr(ppd, "cupsInkLimit", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ cupsCMYKSetInkLimit(cmyk, atof(attr->value));
+
+ /*
+ * Get the optional cupsBlackGeneration attribute...
+ */
+
+ if ((attr = cupsFindAttr(ppd, "cupsBlackGeneration", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ if (sscanf(attr->value, "%f%f", &lower, &upper) == 2)
+ cupsCMYKSetBlack(cmyk, lower, upper);
+ }
+
+ /*
+ * Get the optional cupsBlackXY or cupsBlackGamma attributes...
+ */
+
+ if (num_channels != 3)
+ {
+ if ((attr = cupsFindAttr(ppd, "cupsBlackXY", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ for (num_xypoints = 0, xyptr = xypoints;
+ attr != NULL && attr->value != NULL && num_xypoints < 100;
+ attr = ppdFindNextAttr(ppd, "cupsBlackXY", spec))
+ if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+ {
+ num_xypoints ++;
+ xyptr += 2;
+ }
+
+ switch (num_channels)
+ {
+ case 1 :
+ case 2 :
+ cupsCMYKSetCurve(cmyk, 0, num_xypoints, xypoints);
+ break;
+ case 4 :
+ cupsCMYKSetCurve(cmyk, 3, num_xypoints, xypoints);
+ break;
+ case 6 :
+ case 7 :
+ cupsCMYKSetCurve(cmyk, 5, num_xypoints, xypoints);
+ break;
+ }
+ }
+ else if ((attr = cupsFindAttr(ppd, "cupsBlackGamma", colormodel,
+ media, resolution, spec,
+ sizeof(spec))) != NULL)
+ {
+ if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+ switch (num_channels)
+ {
+ case 1 :
+ case 2 :
+ cupsCMYKSetGamma(cmyk, 0, gamval, density);
+ break;
+ case 4 :
+ cupsCMYKSetGamma(cmyk, 3, gamval, density);
+ break;
+ case 6 :
+ case 7 :
+ cupsCMYKSetGamma(cmyk, 5, gamval, density);
+ break;
+ }
+ }
+ else if ((attr = cupsFindAttr(ppd, "cupsAllXY", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ for (num_xypoints = 0, xyptr = xypoints;
+ attr != NULL && attr->value != NULL && num_xypoints < 100;
+ attr = ppdFindNextAttr(ppd, "cupsAllXY", spec))
+ if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+ {
+ num_xypoints ++;
+ xyptr += 2;
+ }
+
+ switch (num_channels)
+ {
+ case 1 :
+ case 2 :
+ cupsCMYKSetCurve(cmyk, 0, num_xypoints, xypoints);
+ break;
+ case 4 :
+ cupsCMYKSetCurve(cmyk, 3, num_xypoints, xypoints);
+ break;
+ case 6 :
+ case 7 :
+ cupsCMYKSetCurve(cmyk, 5, num_xypoints, xypoints);
+ break;
+ }
+ }
+ else if ((attr = cupsFindAttr(ppd, "cupsAllGamma", colormodel,
+ media, resolution, spec,
+ sizeof(spec))) != NULL &&
+ num_channels != 3)
+ {
+ if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+ switch (num_channels)
+ {
+ case 1 :
+ case 2 :
+ cupsCMYKSetGamma(cmyk, 0, gamval, density);
+ break;
+ case 4 :
+ cupsCMYKSetGamma(cmyk, 3, gamval, density);
+ break;
+ case 6 :
+ case 7 :
+ cupsCMYKSetGamma(cmyk, 5, gamval, density);
+ break;
+ }
+ }
+ }
+
+ if (num_channels > 2)
+ {
+ /*
+ * Get the optional cupsCyanXY or cupsCyanGamma attributes...
+ */
+
+ if ((attr = cupsFindAttr(ppd, "cupsCyanXY", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ for (num_xypoints = 0, xyptr = xypoints;
+ attr != NULL && attr->value != NULL && num_xypoints < 100;
+ attr = ppdFindNextAttr(ppd, "cupsCyanXY", spec))
+ if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+ {
+ num_xypoints ++;
+ xyptr += 2;
+ }
+
+ cupsCMYKSetCurve(cmyk, 0, num_xypoints, xypoints);
+ }
+ else if ((attr = cupsFindAttr(ppd, "cupsCyanGamma", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+ cupsCMYKSetGamma(cmyk, 0, gamval, density);
+ }
+ else if ((attr = cupsFindAttr(ppd, "cupsAllXY", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ for (num_xypoints = 0, xyptr = xypoints;
+ attr != NULL && attr->value != NULL && num_xypoints < 100;
+ attr = ppdFindNextAttr(ppd, "cupsAllXY", spec))
+ if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+ {
+ num_xypoints ++;
+ xyptr += 2;
+ }
+
+ cupsCMYKSetCurve(cmyk, 0, num_xypoints, xypoints);
+ }
+ else if ((attr = cupsFindAttr(ppd, "cupsAllGamma", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+ cupsCMYKSetGamma(cmyk, 0, gamval, density);
+ }
+
+ /*
+ * Get the optional cupsMagentaXY or cupsMagentaGamma attributes...
+ */
+
+ if ((attr = cupsFindAttr(ppd, "cupsMagentaXY", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ for (num_xypoints = 0, xyptr = xypoints;
+ attr != NULL && attr->value != NULL && num_xypoints < 100;
+ attr = ppdFindNextAttr(ppd, "cupsMagentaXY", spec))
+ if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+ {
+ num_xypoints ++;
+ xyptr += 2;
+ }
+
+ switch (num_channels)
+ {
+ case 3 :
+ case 4 :
+ cupsCMYKSetCurve(cmyk, 1, num_xypoints, xypoints);
+ break;
+ case 6 :
+ case 7 :
+ cupsCMYKSetCurve(cmyk, 2, num_xypoints, xypoints);
+ break;
+ }
+ }
+ else if ((attr = cupsFindAttr(ppd, "cupsMagentaGamma", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+ switch (num_channels)
+ {
+ case 3 :
+ case 4 :
+ cupsCMYKSetGamma(cmyk, 1, gamval, density);
+ break;
+ case 6 :
+ case 7 :
+ cupsCMYKSetGamma(cmyk, 2, gamval, density);
+ break;
+ }
+ }
+ else if ((attr = cupsFindAttr(ppd, "cupsAllXY", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ for (num_xypoints = 0, xyptr = xypoints;
+ attr != NULL && attr->value != NULL && num_xypoints < 100;
+ attr = ppdFindNextAttr(ppd, "cupsAllXY", spec))
+ if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+ {
+ num_xypoints ++;
+ xyptr += 2;
+ }
+
+ switch (num_channels)
+ {
+ case 3 :
+ case 4 :
+ cupsCMYKSetCurve(cmyk, 1, num_xypoints, xypoints);
+ break;
+ case 6 :
+ case 7 :
+ cupsCMYKSetCurve(cmyk, 2, num_xypoints, xypoints);
+ break;
+ }
+ }
+ else if ((attr = cupsFindAttr(ppd, "cupsAllGamma", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+ switch (num_channels)
+ {
+ case 3 :
+ case 4 :
+ cupsCMYKSetGamma(cmyk, 1, gamval, density);
+ break;
+ case 6 :
+ case 7 :
+ cupsCMYKSetGamma(cmyk, 2, gamval, density);
+ break;
+ }
+ }
+
+ /*
+ * Get the optional cupsYellowXY or cupsYellowGamma attributes...
+ */
+
+ if ((attr = cupsFindAttr(ppd, "cupsYellowXY", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ for (num_xypoints = 0, xyptr = xypoints;
+ attr != NULL && attr->value != NULL && num_xypoints < 100;
+ attr = ppdFindNextAttr(ppd, "cupsYellowXY", spec))
+ if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+ {
+ num_xypoints ++;
+ xyptr += 2;
+ }
+
+ switch (num_channels)
+ {
+ case 3 :
+ case 4 :
+ cupsCMYKSetCurve(cmyk, 2, num_xypoints, xypoints);
+ break;
+ case 6 :
+ case 7 :
+ cupsCMYKSetCurve(cmyk, 4, num_xypoints, xypoints);
+ break;
+ }
+ }
+ else if ((attr = cupsFindAttr(ppd, "cupsYellowGamma", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+ switch (num_channels)
+ {
+ case 3 :
+ case 4 :
+ cupsCMYKSetGamma(cmyk, 2, gamval, density);
+ break;
+ case 6 :
+ case 7 :
+ cupsCMYKSetGamma(cmyk, 4, gamval, density);
+ break;
+ }
+ }
+ else if ((attr = cupsFindAttr(ppd, "cupsAllXY", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ for (num_xypoints = 0, xyptr = xypoints;
+ attr != NULL && attr->value != NULL && num_xypoints < 100;
+ attr = ppdFindNextAttr(ppd, "cupsAllXY", spec))
+ if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+ {
+ num_xypoints ++;
+ xyptr += 2;
+ }
+
+ switch (num_channels)
+ {
+ case 3 :
+ case 4 :
+ cupsCMYKSetCurve(cmyk, 2, num_xypoints, xypoints);
+ break;
+ case 6 :
+ case 7 :
+ cupsCMYKSetCurve(cmyk, 4, num_xypoints, xypoints);
+ break;
+ }
+ }
+ else if ((attr = cupsFindAttr(ppd, "cupsAllGamma", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+ switch (num_channels)
+ {
+ case 3 :
+ case 4 :
+ cupsCMYKSetGamma(cmyk, 2, gamval, density);
+ break;
+ case 6 :
+ case 7 :
+ cupsCMYKSetGamma(cmyk, 4, gamval, density);
+ break;
+ }
+ }
+ }
+
+ /*
+ * Get the optional cupsLightBlackXY, cupsLightBlackGamma, or
+ * cupsBlackLtDk attributes...
+ */
+
+ if (num_channels == 2 || num_channels == 7)
+ {
+ if ((attr = cupsFindAttr(ppd, "cupsLightBlackXY", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ for (num_xypoints = 0, xyptr = xypoints;
+ attr != NULL && attr->value != NULL && num_xypoints < 100;
+ attr = ppdFindNextAttr(ppd, "cupsLightBlackXY", spec))
+ if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+ {
+ num_xypoints ++;
+ xyptr += 2;
+ }
+
+ switch (num_channels)
+ {
+ case 2 :
+ cupsCMYKSetCurve(cmyk, 1, num_xypoints, xypoints);
+ break;
+ case 7 :
+ cupsCMYKSetCurve(cmyk, 6, num_xypoints, xypoints);
+ break;
+ }
+ }
+ else if ((attr = cupsFindAttr(ppd, "cupsLightBlackGamma", colormodel,
+ media, resolution, spec,
+ sizeof(spec))) != NULL)
+ {
+ if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+ switch (num_channels)
+ {
+ case 2 :
+ cupsCMYKSetGamma(cmyk, 1, gamval, density);
+ break;
+ case 7 :
+ cupsCMYKSetGamma(cmyk, 6, gamval, density);
+ break;
+ }
+ }
+ else if ((attr = cupsFindAttr(ppd, "cupsBlackLtDk", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ if (sscanf(attr->value, "%f%f", &light, &dark) == 2)
+ switch (num_channels)
+ {
+ case 2 :
+ cupsCMYKSetLtDk(cmyk, 0, light, dark);
+ break;
+ case 7 :
+ cupsCMYKSetLtDk(cmyk, 5, light, dark);
+ break;
+ }
+ else
+ fprintf(stderr, "ERROR: Bad cupsBlackLtDk value \"%s\"!\n",
+ attr->value);
+ }
+ else
+ fprintf(stderr, "WARNING: No light black attribute found for %s!\n",
+ spec);
+ }
+
+ if (num_channels >= 6)
+ {
+ /*
+ * Get the optional cupsLightCyanXY, cupsLightCyanGamma, or
+ * cupsCyanLtDk attributes...
+ */
+
+ if ((attr = cupsFindAttr(ppd, "cupsLightCyanXY", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ for (num_xypoints = 0, xyptr = xypoints;
+ attr != NULL && attr->value != NULL && num_xypoints < 100;
+ attr = ppdFindNextAttr(ppd, "cupsLightCyanXY", spec))
+ if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+ {
+ num_xypoints ++;
+ xyptr += 2;
+ }
+
+ cupsCMYKSetCurve(cmyk, 1, num_xypoints, xypoints);
+ }
+ else if ((attr = cupsFindAttr(ppd, "cupsLightCyanGamma", colormodel,
+ media, resolution, spec,
+ sizeof(spec))) != NULL)
+ {
+ if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+ cupsCMYKSetGamma(cmyk, 1, gamval, density);
+ }
+ else if ((attr = cupsFindAttr(ppd, "cupsCyanLtDk", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ if (sscanf(attr->value, "%f%f", &light, &dark) == 2)
+ cupsCMYKSetLtDk(cmyk, 0, light, dark);
+ else
+ fprintf(stderr, "ERROR: Bad cupsCyanLtDk value \"%s\"!\n",
+ attr->value);
+ }
+ else
+ fprintf(stderr, "WARNING: No light cyan attribute found for %s!\n",
+ spec);
+
+ /*
+ * Get the optional cupsLightMagentaXY, cupsLightMagentaGamma, or
+ * cupsMagentaLtDk attributes...
+ */
+
+ if ((attr = cupsFindAttr(ppd, "cupsLightMagentaXY", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ for (num_xypoints = 0, xyptr = xypoints;
+ attr != NULL && attr->value != NULL && num_xypoints < 100;
+ attr = ppdFindNextAttr(ppd, "cupsLightMagentaXY", spec))
+ if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+ {
+ num_xypoints ++;
+ xyptr += 2;
+ }
+
+ cupsCMYKSetCurve(cmyk, 3, num_xypoints, xypoints);
+ }
+ else if ((attr = cupsFindAttr(ppd, "cupsLightMagentaGamma", colormodel,
+ media, resolution, spec,
+ sizeof(spec))) != NULL)
+ {
+ if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+ cupsCMYKSetGamma(cmyk, 3, gamval, density);
+ }
+ else if ((attr = cupsFindAttr(ppd, "cupsMagentaLtDk", colormodel, media,
+ resolution, spec, sizeof(spec))) != NULL)
+ {
+ if (sscanf(attr->value, "%f%f", &light, &dark) == 2)
+ cupsCMYKSetLtDk(cmyk, 2, light, dark);
+ else
+ fprintf(stderr, "ERROR: Bad cupsMagentaLtDk value \"%s\"!\n",
+ attr->value);
+ }
+ else
+ fprintf(stderr, "WARNING: No light magenta attribute found for %s!\n",
+ spec);
+ }
+
+ /*
+ * Return the new profile...
+ */
+
+ return (cmyk);
+}
+
+
+/*
+ * 'cupsCMYKNew()' - Create a new CMYK color separation.
+ */
+
+cups_cmyk_t * /* O - New CMYK separation or NULL */
+cupsCMYKNew(int num_channels) /* I - Number of color components */
+{
+ cups_cmyk_t *cmyk; /* New color separation */
+ int i; /* Looping var */
+
+
+ /*
+ * Range-check the input...
+ */
+
+ if (num_channels < 1)
+ return (NULL);
+
+ /*
+ * Allocate memory for the separation...
+ */
+
+ if ((cmyk = calloc(1, sizeof(cups_cmyk_t))) == NULL)
+ return (NULL);
+
+ /*
+ * Allocate memory for the LUTs...
+ */
+
+ cmyk->num_channels = num_channels;
+
+ if ((cmyk->channels[0] = calloc(num_channels * 256, sizeof(short))) == NULL)
+ {
+ free(cmyk);
+ return (NULL);
+ }
+
+ for (i = 1; i < num_channels; i ++)
+ cmyk->channels[i] = cmyk->channels[0] + i * 256;
+
+ /*
+ * Fill in the LUTs with unity transitions...
+ */
+
+ for (i = 0; i < 256; i ++)
+ cmyk->black_lut[i] = i;
+
+ switch (num_channels)
+ {
+ case 1 : /* K */
+ case 2 : /* Kk */
+ for (i = 0; i < 256; i ++)
+ {
+ cmyk->channels[0][i] = CUPS_MAX_LUT * i / 255;
+ }
+ break;
+ case 3 : /* CMY */
+ for (i = 0; i < 256; i ++)
+ {
+ cmyk->channels[0][i] = CUPS_MAX_LUT * i / 255;
+ cmyk->channels[1][i] = CUPS_MAX_LUT * i / 255;
+ cmyk->channels[2][i] = CUPS_MAX_LUT * i / 255;
+ }
+ break;
+ case 4 : /* CMYK */
+ for (i = 0; i < 256; i ++)
+ {
+ cmyk->channels[0][i] = CUPS_MAX_LUT * i / 255;
+ cmyk->channels[1][i] = CUPS_MAX_LUT * i / 255;
+ cmyk->channels[2][i] = CUPS_MAX_LUT * i / 255;
+ cmyk->channels[3][i] = CUPS_MAX_LUT * i / 255;
+ }
+ break;
+ case 6 : /* CcMmYK */
+ case 7 : /* CcMmYKk */
+ for (i = 0; i < 256; i ++)
+ {
+ cmyk->channels[0][i] = CUPS_MAX_LUT * i / 255;
+ cmyk->channels[2][i] = CUPS_MAX_LUT * i / 255;
+ cmyk->channels[4][i] = CUPS_MAX_LUT * i / 255;
+ cmyk->channels[5][i] = CUPS_MAX_LUT * i / 255;
+ }
+ break;
+ }
+
+ /*
+ * Return the separation...
+ */
+
+ return (cmyk);
+}
+
+
+/*
+ * 'cupsCMYKSetBlack()' - Set the transition range for CMY to black.
+ */
+
+void
+cupsCMYKSetBlack(cups_cmyk_t *cmyk, /* I - CMYK color separation */
+ float lower, /* I - No black ink */
+ float upper) /* I - Only black ink */
+{
+ int i, /* Looping var */
+ delta, /* Difference between lower and upper */
+ ilower, /* Lower level from 0 to 255 */
+ iupper; /* Upper level from 0 to 255 */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (cmyk == NULL || lower < 0.0 || lower > 1.0 || upper < 0.0 || upper > 1.0 ||
+ lower > upper)
+ return;
+
+ /*
+ * Convert lower and upper to integers from 0 to 255...
+ */
+
+ ilower = (int)(255.0 * lower + 0.5);
+ iupper = (int)(255.0 * upper + 0.5);
+ delta = iupper - ilower;
+
+ /*
+ * Generate the CMY-only data...
+ */
+
+ for (i = 0; i < ilower; i ++)
+ {
+ cmyk->black_lut[i] = 0;
+ cmyk->color_lut[i] = i;
+ }
+
+ /*
+ * Then the transition data...
+ */
+
+ for (; i < iupper; i ++)
+ {
+ cmyk->black_lut[i] = iupper * (i - ilower) / delta;
+ cmyk->color_lut[i] = ilower - ilower * (i - ilower) / delta;
+ }
+
+ /*
+ * Then the K-only data...
+ */
+
+ for (; i < 256; i ++)
+ {
+ cmyk->black_lut[i] = i;
+ cmyk->color_lut[i] = 0;
+ }
+
+ fprintf(stderr, "DEBUG: cupsCMYKSetBlack(cmyk, lower=%.3f, upper=%.3f)\n", lower, upper);
+
+ for (i = 0; i < 256; i += 17)
+ fprintf(stderr, "DEBUG: %3d = %3dk + %3dc\n", i,
+ cmyk->black_lut[i], cmyk->color_lut[i]);
+}
+
+
+/*
+ * 'cupsCMYKSetCurve()' - Set a color transform curve using points.
+ */
+
+void
+cupsCMYKSetCurve(cups_cmyk_t *cmyk, /* I - CMYK color separation */
+ int channel, /* I - Color channel */
+ int num_xypoints,
+ /* I - Number of X,Y points */
+ const float *xypoints) /* I - X,Y points */
+{
+ int i; /* Looping var */
+ int xstart; /* Start position */
+ int xend; /* End position */
+ int xdelta; /* Difference in position */
+ int ystart; /* Start value */
+ int yend; /* End value */
+ int ydelta; /* Difference in value */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (cmyk == NULL || channel < 0 || channel >= cmyk->num_channels ||
+ num_xypoints < 1 || xypoints == NULL)
+ return;
+
+ /*
+ * Initialize the lookup table for the specified channel...
+ */
+
+ for (xstart = xend = 0, ystart = yend = 0;
+ num_xypoints > 0;
+ num_xypoints --, xypoints += 2, xstart = xend, ystart = yend)
+ {
+ xend = (int)(255.0 * xypoints[1] + 0.5);
+ yend = (int)(CUPS_MAX_LUT * xypoints[0] + 0.5);
+ xdelta = xend - xstart;
+ ydelta = yend - ystart;
+
+ for (i = xstart; i < xend; i ++)
+ cmyk->channels[channel][i] = ystart + ydelta * (i - xstart) / xdelta;
+ }
+
+ /*
+ * Initialize any trailing values to the maximum of the last data point...
+ */
+
+ for (i = xend; i < 256; i ++)
+ cmyk->channels[channel][i] = yend;
+
+ fprintf(stderr, "DEBUG: cupsCMYKSetXY(cmyk, channel=%d, num_xypoints=%d, "
+ "xypoints=[%.3f %.3f %.3f %.3f ...])\n", channel,
+ num_xypoints, xypoints[0], xypoints[1], xypoints[2], xypoints[3]);
+
+ for (i = 0; i < 256; i += 17)
+ fprintf(stderr, "DEBUG: %3d = %4d\n", i,
+ cmyk->channels[channel + 0][i]);
+}
+
+
+/*
+ * 'cupsCMYKSetGamma()' - Set a color transform curve using gamma and density.
+ */
+
+void
+cupsCMYKSetGamma(cups_cmyk_t *cmyk, /* I - CMYK color separation */
+ int channel, /* I - Ink channel */
+ float gamval, /* I - Gamma correction */
+ float density) /* I - Maximum density */
+{
+ int i; /* Looping var */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (cmyk == NULL || channel < 0 || channel >= cmyk->num_channels ||
+ gamval <= 0.0 || density <= 0.0 || density > 1.0)
+ return;
+
+ /*
+ * Initialize the lookup table for the specified channel...
+ */
+
+ for (i = 0; i < 256; i ++)
+ cmyk->channels[channel][i] = (int)(density * CUPS_MAX_LUT *
+ pow((float)i / 255.0, gamval) + 0.5);
+
+ fprintf(stderr, "DEBUG: cupsCMYKSetGamma(cmyk, channel=%d, gamval=%.3f, "
+ "density=%.3f)\n", channel, gamval, density);
+
+ for (i = 0; i < 256; i += 17)
+ fprintf(stderr, "DEBUG: %3d = %4d\n", i,
+ cmyk->channels[channel + 0][i]);
+}
+
+
+/*
+ * 'cupsCMYKSetInkLimit()' - Set the limit on the amount of ink.
+ */
+
+void
+cupsCMYKSetInkLimit(cups_cmyk_t *cmyk, /* I - CMYK color separation */
+ float limit) /* I - Limit of ink */
+{
+ if (!cmyk || limit < 0.0)
+ return;
+
+ cmyk->ink_limit = limit * CUPS_MAX_LUT;
+}
+
+
+/*
+ * 'cupsCMYKSetLtDk()' - Set light/dark ink transforms.
+ */
+
+void
+cupsCMYKSetLtDk(cups_cmyk_t *cmyk, /* I - CMYK color separation */
+ int channel, /* I - Dark ink channel (+1 for light) */
+ float light, /* I - Light ink only level */
+ float dark) /* I - Dark ink only level */
+{
+ int i, /* Looping var */
+ delta, /* Difference between lower and upper */
+ ilight, /* Light level from 0 to 255 */
+ idark; /* Dark level from 0 to 255 */
+ short lut[256]; /* Original LUT data */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (cmyk == NULL || light < 0.0 || light > 1.0 || dark < 0.0 || dark > 1.0 ||
+ light > dark || channel < 0 || channel > (cmyk->num_channels - 2))
+ return;
+
+ /*
+ * Convert lower and upper to integers from 0 to 255...
+ */
+
+ ilight = (int)(255.0 * light + 0.5);
+ idark = (int)(255.0 * dark + 0.5);
+ delta = idark - ilight;
+
+ /*
+ * Copy the dark ink LUT...
+ */
+
+ memcpy(lut, cmyk->channels[channel], sizeof(lut));
+
+ /*
+ * Generate the light-only data...
+ */
+
+ for (i = 0; i < ilight; i ++)
+ {
+ cmyk->channels[channel + 0][i] = 0;
+ cmyk->channels[channel + 1][i] = CUPS_MAX_LUT * i / ilight;
+ }
+
+ /*
+ * Then the transition data...
+ */
+
+ for (; i < idark; i ++)
+ {
+ cmyk->channels[channel + 0][i] = CUPS_MAX_LUT * idark * (i - ilight) /
+ delta / 255;
+ cmyk->channels[channel + 1][i] = CUPS_MAX_LUT - CUPS_MAX_LUT *
+ (i - ilight) / delta;
+ }
+
+ /*
+ * Then the K-only data...
+ */
+
+ for (; i < 256; i ++)
+ {
+ cmyk->channels[channel + 0][i] = CUPS_MAX_LUT * i / 255;
+ cmyk->channels[channel + 1][i] = 0;
+ }
+
+ fprintf(stderr, "DEBUG: cupsCMYKSetLtDk(cmyk, channel=%d, light=%.3f, "
+ "dark=%.3f)\n", channel, light, dark);
+
+ for (i = 0; i < 256; i += 17)
+ fprintf(stderr, "DEBUG: %3d = %4dlt + %4ddk\n", i,
+ cmyk->channels[channel + 0][i], cmyk->channels[channel + 1][i]);
+}
+
diff --git a/cupsfilters/colord.c b/cupsfilters/colord.c
new file mode 100644
index 000000000..ad2f55c9d
--- /dev/null
+++ b/cupsfilters/colord.c
@@ -0,0 +1,464 @@
+/*
+Copyright (c) 2011, Tim Waugh
+Copyright (c) 2011-2013, Richard Hughes
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+MIT Open Source License - http://www.opensource.org/
+
+*/
+
+
+/* Common routines for accessing the colord CMS framework */
+
+#include <cups/raster.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+#ifdef HAVE_DBUS
+ #include <dbus/dbus.h>
+#endif
+
+#include "colord.h"
+
+#define QUAL_COLORSPACE 0
+#define QUAL_MEDIA 1
+#define QUAL_RESOLUTION 2
+#define QUAL_SIZE 3
+
+char **
+colord_get_qualifier_for_ppd (ppd_file_t *ppd)
+{
+ char q_keyword[PPD_MAX_NAME];
+ char **tuple = NULL;
+ const char *q1_choice;
+ const char *q2_choice;
+ const char *q3_choice;
+ ppd_attr_t *attr;
+ ppd_attr_t *q1_attr;
+ ppd_attr_t *q2_attr;
+ ppd_attr_t *q3_attr;
+
+ /* get colorspace */
+ if ((attr = ppdFindAttr (ppd, "cupsICCQualifier1", NULL)) != NULL &&
+ attr->value && attr->value[0])
+ {
+ snprintf (q_keyword, sizeof (q_keyword), "Default%s", attr->value);
+ q1_attr = ppdFindAttr (ppd, q_keyword, NULL);
+ }
+ else if ((q1_attr = ppdFindAttr (ppd, "DefaultColorModel", NULL)) == NULL)
+ q1_attr = ppdFindAttr (ppd, "DefaultColorSpace", NULL);
+
+ if (q1_attr && q1_attr->value && q1_attr->value[0])
+ q1_choice = q1_attr->value;
+ else
+ q1_choice = "";
+
+ /* get media */
+ if ((attr = ppdFindAttr(ppd, "cupsICCQualifier2", NULL)) != NULL &&
+ attr->value && attr->value[0])
+ {
+ snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value);
+ q2_attr = ppdFindAttr(ppd, q_keyword, NULL);
+ }
+ else
+ q2_attr = ppdFindAttr(ppd, "DefaultMediaType", NULL);
+
+ if (q2_attr && q2_attr->value && q2_attr->value[0])
+ q2_choice = q2_attr->value;
+ else
+ q2_choice = "";
+
+ /* get resolution */
+ if ((attr = ppdFindAttr(ppd, "cupsICCQualifier3", NULL)) != NULL &&
+ attr->value && attr->value[0])
+ {
+ snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value);
+ q3_attr = ppdFindAttr(ppd, q_keyword, NULL);
+ }
+ else
+ q3_attr = ppdFindAttr(ppd, "DefaultResolution", NULL);
+
+ if (q3_attr && q3_attr->value && q3_attr->value[0])
+ q3_choice = q3_attr->value;
+ else
+ q3_choice = "";
+
+ /* return a NULL terminated array so we don't have to break it up later */
+ tuple = calloc(QUAL_SIZE + 1, sizeof(char*));
+ tuple[QUAL_COLORSPACE] = strdup(q1_choice);
+ tuple[QUAL_MEDIA] = strdup(q2_choice);
+ tuple[QUAL_RESOLUTION] = strdup(q3_choice);
+ return tuple;
+}
+
+#ifdef HAVE_DBUS
+
+static char *
+get_filename_for_profile_path (DBusConnection *con,
+ const char *object_path)
+{
+ char *filename = NULL;
+ const char *interface = "org.freedesktop.ColorManager.Profile";
+ const char *property = "Filename";
+ const char *tmp;
+ DBusError error;
+ DBusMessageIter args;
+ DBusMessage *message = NULL;
+ DBusMessage *reply = NULL;
+ DBusMessageIter sub;
+
+ message = dbus_message_new_method_call("org.freedesktop.ColorManager",
+ object_path,
+ "org.freedesktop.DBus.Properties",
+ "Get");
+
+ dbus_message_iter_init_append(message, &args);
+ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &interface);
+ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &property);
+
+ /* send syncronous */
+ dbus_error_init(&error);
+ fprintf(stderr, "DEBUG: Calling %s.Get(%s)\n", interface, property);
+ reply = dbus_connection_send_with_reply_and_block(con,
+ message,
+ -1,
+ &error);
+ if (reply == NULL) {
+ fprintf(stderr, "DEBUG: Failed to send: %s:%s\n",
+ error.name, error.message);
+ dbus_error_free(&error);
+ goto out;
+ }
+
+ /* get reply data */
+ dbus_message_iter_init(reply, &args);
+ if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_VARIANT) {
+ fprintf(stderr, "DEBUG: Incorrect reply type\n");
+ goto out;
+ }
+
+ dbus_message_iter_recurse(&args, &sub);
+ dbus_message_iter_get_basic(&sub, &tmp);
+ filename = strdup(tmp);
+out:
+ if (message != NULL)
+ dbus_message_unref(message);
+ if (reply != NULL)
+ dbus_message_unref(reply);
+ return filename;
+}
+
+static char *
+get_profile_for_device_path (DBusConnection *con,
+ const char *object_path,
+ const char **split)
+{
+ char **key = NULL;
+ char *profile = NULL;
+ char str[256];
+ const char *tmp;
+ DBusError error;
+ DBusMessageIter args;
+ DBusMessageIter entry;
+ DBusMessage *message = NULL;
+ DBusMessage *reply = NULL;
+ int i = 0;
+ const int max_keys = 7;
+
+ message = dbus_message_new_method_call("org.freedesktop.ColorManager",
+ object_path,
+ "org.freedesktop.ColorManager.Device",
+ "GetProfileForQualifiers");
+ dbus_message_iter_init_append(message, &args);
+
+ /* create the fallbacks */
+ key = calloc(max_keys + 1, sizeof(char*));
+
+ /* exact match */
+ i = 0;
+ snprintf(str, sizeof(str), "%s.%s.%s",
+ split[QUAL_COLORSPACE],
+ split[QUAL_MEDIA],
+ split[QUAL_RESOLUTION]);
+ key[i++] = strdup(str);
+ snprintf(str, sizeof(str), "%s.%s.*",
+ split[QUAL_COLORSPACE],
+ split[QUAL_MEDIA]);
+ key[i++] = strdup(str);
+ snprintf(str, sizeof(str), "%s.*.%s",
+ split[QUAL_COLORSPACE],
+ split[QUAL_RESOLUTION]);
+ key[i++] = strdup(str);
+ snprintf(str, sizeof(str), "%s.*.*",
+ split[QUAL_COLORSPACE]);
+ key[i++] = strdup(str);
+ key[i++] = strdup("*");
+ dbus_message_iter_open_container(&args,
+ DBUS_TYPE_ARRAY,
+ "s",
+ &entry);
+ for (i=0; key[i] != NULL; i++) {
+ dbus_message_iter_append_basic(&entry,
+ DBUS_TYPE_STRING,
+ &key[i]);
+ }
+ dbus_message_iter_close_container(&args, &entry);
+
+ /* send syncronous */
+ dbus_error_init(&error);
+ fprintf(stderr, "DEBUG: Calling GetProfileForQualifiers(%s...)\n", key[0]);
+ reply = dbus_connection_send_with_reply_and_block(con,
+ message,
+ -1,
+ &error);
+ if (reply == NULL) {
+ fprintf(stderr, "DEBUG: Failed to send: %s:%s\n",
+ error.name, error.message);
+ dbus_error_free(&error);
+ goto out;
+ }
+
+ /* get reply data */
+ dbus_message_iter_init(reply, &args);
+ if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH) {
+ fprintf(stderr, "DEBUG: Incorrect reply type\n");
+ goto out;
+ }
+ dbus_message_iter_get_basic(&args, &tmp);
+ fprintf(stderr, "DEBUG: Found profile %s\n", tmp);
+
+ /* get filename */
+ profile = get_filename_for_profile_path(con, tmp);
+
+out:
+ if (message != NULL)
+ dbus_message_unref(message);
+ if (reply != NULL)
+ dbus_message_unref(reply);
+ if (key != NULL) {
+ for (i=0; i < max_keys; i++)
+ free(key[i]);
+ free(key);
+ }
+ return profile;
+}
+
+static char *
+get_device_path_for_device_id (DBusConnection *con,
+ const char *device_id)
+{
+ char *device_path = NULL;
+ const char *device_path_tmp;
+ DBusError error;
+ DBusMessageIter args;
+ DBusMessage *message = NULL;
+ DBusMessage *reply = NULL;
+
+ message = dbus_message_new_method_call("org.freedesktop.ColorManager",
+ "/org/freedesktop/ColorManager",
+ "org.freedesktop.ColorManager",
+ "FindDeviceById");
+ dbus_message_iter_init_append(message, &args);
+ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &device_id);
+
+ /* send syncronous */
+ dbus_error_init(&error);
+ fprintf(stderr, "DEBUG: Calling FindDeviceById(%s)\n", device_id);
+ reply = dbus_connection_send_with_reply_and_block(con,
+ message,
+ -1,
+ &error);
+ if (reply == NULL) {
+ fprintf(stderr, "DEBUG: Failed to send: %s:%s\n",
+ error.name, error.message);
+ dbus_error_free(&error);
+ goto out;
+ }
+
+ /* get reply data */
+ dbus_message_iter_init(reply, &args);
+ if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH) {
+ fprintf(stderr, "DEBUG: Incorrect reply type\n");
+ goto out;
+ }
+ dbus_message_iter_get_basic(&args, &device_path_tmp);
+ fprintf(stderr, "DEBUG: Found device %s\n", device_path_tmp);
+ device_path = strdup(device_path_tmp);
+out:
+ if (message != NULL)
+ dbus_message_unref(message);
+ if (reply != NULL)
+ dbus_message_unref(reply);
+ return device_path;
+}
+
+char *
+colord_get_profile_for_device_id (const char *device_id,
+ const char **qualifier_tuple)
+{
+ DBusConnection *con = NULL;
+ char *device_path = NULL;
+ char *filename = NULL;
+
+ if (device_id == NULL) {
+ fprintf(stderr, "DEBUG: No colord device ID available\n");
+ goto out;
+ }
+
+ /* connect to system bus */
+ con = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+ if (con == NULL) {
+ // If D-Bus is not reachable, gracefully leave and ignore error
+ //fprintf(stderr, "ERROR: Failed to connect to system bus\n");
+ goto out;
+ }
+
+ /* find the device */
+ device_path = get_device_path_for_device_id (con, device_id);
+ if (device_path == NULL) {
+ fprintf(stderr, "DEBUG: Failed to get device %s\n", device_id);
+ goto out;
+ }
+
+ /* get the best profile for the device */
+ filename = get_profile_for_device_path(con, device_path, qualifier_tuple);
+ if (filename == NULL) {
+ fprintf(stderr, "DEBUG: Failed to get profile filename for %s\n", device_id);
+ goto out;
+ }
+ fprintf(stderr, "DEBUG: Use profile filename: '%s'\n", filename);
+out:
+ free(device_path);
+ if (con != NULL)
+ dbus_connection_unref(con);
+ return filename;
+}
+
+int
+get_profile_inhibitors (DBusConnection *con, const char *object_path)
+{
+ char *tmp;
+ const char *interface = "org.freedesktop.ColorManager.Device";
+ const char *property = "ProfilingInhibitors";
+ DBusError error;
+ DBusMessageIter args;
+ DBusMessageIter sub;
+ DBusMessageIter sub2;
+ DBusMessage *message = NULL;
+ DBusMessage *reply = NULL;
+ int inhibitors = 0;
+
+ message = dbus_message_new_method_call("org.freedesktop.ColorManager",
+ object_path,
+ "org.freedesktop.DBus.Properties",
+ "Get");
+
+ dbus_message_iter_init_append(message, &args);
+ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &interface);
+ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &property);
+
+ /* send syncronous */
+ dbus_error_init(&error);
+ fprintf(stderr, "DEBUG: Calling %s.Get(%s)\n", interface, property);
+ reply = dbus_connection_send_with_reply_and_block(con,
+ message,
+ -1,
+ &error);
+ if (reply == NULL) {
+ fprintf(stderr, "DEBUG: Failed to send: %s:%s\n",
+ error.name, error.message);
+ dbus_error_free(&error);
+ goto out;
+ }
+
+ /* get reply data */
+ dbus_message_iter_init(reply, &args);
+ if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_VARIANT) {
+ fprintf(stderr, "DEBUG: Incorrect reply type\n");
+ goto out;
+ }
+
+ /* count the size of the array */
+ dbus_message_iter_recurse(&args, &sub2);
+ dbus_message_iter_recurse(&sub2, &sub);
+ while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+ dbus_message_iter_get_basic(&sub, &tmp);
+ fprintf(stderr, "DEBUG: Inhibitor %s exists\n", tmp);
+ dbus_message_iter_next(&sub);
+ inhibitors++;
+ }
+out:
+ if (message != NULL)
+ dbus_message_unref(message);
+ if (reply != NULL)
+ dbus_message_unref(reply);
+ return inhibitors;
+}
+
+int
+colord_get_inhibit_for_device_id (const char *device_id)
+{
+ DBusConnection *con;
+ char *device_path = NULL;
+ int has_inhibitors = FALSE;
+
+ /* connect to system bus */
+ con = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+ if (con == NULL) {
+ // If D-Bus is not reachable, gracefully leave and ignore error
+ //fprintf(stderr, "ERROR: Failed to connect to system bus\n");
+ goto out;
+ }
+
+ /* find the device */
+ device_path = get_device_path_for_device_id (con, device_id);
+ if (device_path == NULL) {
+ fprintf(stderr, "DEBUG: Failed to get find device %s\n", device_id);
+ goto out;
+ }
+
+ /* get the best profile for the device */
+ has_inhibitors = get_profile_inhibitors(con, device_path);
+out:
+ free(device_path);
+ if (con != NULL)
+ dbus_connection_unref(con);
+ return has_inhibitors;
+}
+
+#else
+
+char *
+colord_get_profile_for_device_id (const char *device_id,
+ const char **qualifier_tuple)
+{
+ fprintf(stderr, "WARN: not compiled with DBus support\n");
+ return NULL;
+}
+
+int
+colord_get_inhibit_for_device_id (const char *device_id)
+{
+ fprintf(stderr, "WARN: not compiled with DBus support\n");
+ return 0;
+}
+
+#endif
diff --git a/cupsfilters/colord.h b/cupsfilters/colord.h
new file mode 100644
index 000000000..34d9a8016
--- /dev/null
+++ b/cupsfilters/colord.h
@@ -0,0 +1,49 @@
+/*
+Copyright (c) 2011-2013, Richard Hughes
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+MIT Open Source License - http://www.opensource.org/
+
+*/
+
+
+#ifndef _CUPS_FILTERS_COLORD_H_
+# define _CUPS_FILTERS_COLORD_H_
+
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+
+/* Common routines for accessing the colord CMS framework */
+
+#include <cups/raster.h>
+#include <cups/ppd.h>
+
+char **colord_get_qualifier_for_ppd (ppd_file_t *ppd);
+char *colord_get_profile_for_device_id (const char *device_id,
+ const char **qualifier_tuple);
+int colord_get_inhibit_for_device_id (const char *device_id);
+
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+
+#endif /* !_CUPS_FILTERS_COLORD_H_ */
diff --git a/cupsfilters/colormanager.c b/cupsfilters/colormanager.c
new file mode 100644
index 000000000..70074a313
--- /dev/null
+++ b/cupsfilters/colormanager.c
@@ -0,0 +1,355 @@
+/*
+Copyright (c) 2011-2013, Richard Hughes
+Copyright (c) 2014, Joseph Simon
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+MIT Open Source License - http://www.opensource.org/
+
+*/
+
+
+#include "colormanager.h"
+#include <cupsfilters/colord.h>
+//#include <cupsfilters/kmdevices.h>
+
+
+#define CM_MAX_FILE_LENGTH 1024
+
+
+/* Private function prototypes */
+static int _get_colord_printer_cm_status (const char *printer_name);
+static char *_get_colord_printer_id (const char *printer_name);
+static int _get_colord_profile (const char *printer_name,
+ char **profile,
+ ppd_file_t *ppd);
+static char *_get_ppd_icc_fallback (ppd_file_t *ppd,
+ char **qualifier);
+
+
+
+/* Commonly-used calibration numbers */
+
+double adobergb_wp[3] = {0.95045471, 1.0, 1.08905029};
+double sgray_wp[3] = {0.9505, 1, 1.0890};
+double adobergb_gamma[3] = {2.2, 2.2, 2.2};
+double sgray_gamma[1] = {2.2};
+double adobergb_matrix[9] = {0.60974121, 0.20527649, 0.14918518,
+ 0.31111145, 0.62567139, 0.06321716,
+ 0.01947021, 0.06086731, 0.74456787};
+double blackpoint_default[3] = {0.0, 0.0, 0.0};
+
+
+
+
+/*
+ * Public functions
+ */
+
+
+/* Get printer color management status from the system's color manager */
+int
+cmIsPrinterCmDisabled(const char *printer_name) /* dest name */
+{
+
+ int is_cm_off = 0; /* color management status flag */
+
+
+ /* Request color management status from colord */
+ is_cm_off = _get_colord_printer_cm_status(printer_name);
+
+ if (is_cm_off)
+ fprintf(stderr,"DEBUG: Color Manager: Color management disabled by OS.\n");
+
+ return is_cm_off;
+
+}
+
+
+/* Get printer ICC profile from the system's color manager */
+int
+cmGetPrinterIccProfile(const char *printer_name, /* Printer name (usually "dest" name) */
+ char **icc_profile, /* ICC Profile Path */
+ ppd_file_t *ppd) /* Optional PPD file for fallback profile */
+{
+
+ int profile_set = 0; /* 'is profile found' flag */
+
+
+ /* Request a profile from colord */
+ profile_set = _get_colord_profile(printer_name, icc_profile, ppd);
+
+ fprintf(stderr, "DEBUG: Color Manager: ICC Profile: %s\n", *icc_profile ?
+ *icc_profile : "None");
+
+ return profile_set;
+
+}
+
+
+/* Find the "cm-calibration" CUPS option */
+cm_calibration_t
+cmGetCupsColorCalibrateMode(cups_option_t *options, /* Options from CUPS */
+ int num_options) /* Options from CUPS */
+{
+
+ cm_calibration_t status; /* color management status */
+
+
+ /* Find the string in CUPS options and */
+ if (cupsGetOption(CM_CALIBRATION_STRING, num_options, options) != NULL)
+ status = CM_CALIBRATION_ENABLED;
+ else
+ status = CM_CALIBRATION_DISABLED;
+
+ fprintf(stderr, "DEBUG: Color Manager: %s\n", status ?
+ "Calibration Mode/Enabled" : "Calibration Mode/Off");
+
+ return status;
+
+}
+
+
+/* Functions to return specific calibration data */
+
+
+/* Gamma values */
+
+double *cmGammaAdobeRgb(void)
+{
+ return adobergb_gamma;
+}
+double *cmGammaSGray(void)
+{
+ return sgray_gamma;
+}
+
+
+/* Whitepoint values */
+
+double *cmWhitePointAdobeRgb(void)
+{
+ return adobergb_wp;
+}
+double *cmWhitePointSGray(void)
+{
+ return sgray_wp;
+}
+
+
+/* Adapted primaries matrix */
+
+double *cmMatrixAdobeRgb(void)
+{
+ return adobergb_matrix;
+}
+
+
+/* Blackpoint value */
+
+double *cmBlackPointDefault(void)
+{
+ return blackpoint_default;
+}
+
+
+
+
+/*
+ * Private functions
+ */
+
+
+char *
+_get_colord_printer_id(const char *printer_name) /* Dest name */
+{
+
+ if (printer_name == NULL) {
+ fprintf(stderr, "DEBUG: Color Manager: Invalid printer name.\n");
+ return 0;
+ }
+
+ /* Create printer id string for colord */
+ char* printer_id = (char*)malloc(CM_MAX_FILE_LENGTH);
+ snprintf (printer_id, CM_MAX_FILE_LENGTH, "cups-%s", printer_name);
+
+ return printer_id;
+
+}
+
+
+int
+_get_colord_printer_cm_status(const char *printer_name) /* Dest name */
+{
+
+ /* If invalid input, we leave color management alone */
+ if (printer_name == NULL) {
+ fprintf(stderr, "DEBUG: Color Manager: Invalid printer name.\n");
+ return 0;
+ } else if (!strcmp(printer_name, "(null)"))
+ return 0;
+
+ int is_printer_cm_disabled = 0; /* color management status flag */
+ char *printer_id = 0; /* colord printer id string */
+
+
+ /* Check if device is inhibited/disabled in colord */
+ printer_id = _get_colord_printer_id(printer_name);
+ is_printer_cm_disabled = colord_get_inhibit_for_device_id (printer_id);
+
+ if (printer_id != NULL)
+ free(printer_id);
+
+ return is_printer_cm_disabled;
+
+}
+
+int
+_get_colord_profile(const char *printer_name, /* Dest name */
+ char **profile, /* Requested icc profile path */
+ ppd_file_t *ppd) /* PPD file */
+{
+
+ if (printer_name == NULL || profile == 0) {
+ fprintf(stderr, "DEBUG: Color Manager: Invalid input - Unable to find profile.\n");
+ return -1;
+ }
+
+ int is_profile_set = 0; /* profile-is-found flag */
+ char **qualifier = NULL; /* color qualifier strings */
+ char *icc_profile = NULL; /* icc profile path */
+ char *printer_id = NULL; /* colord printer id */
+
+
+ /* Get color qualifier triple */
+ qualifier = colord_get_qualifier_for_ppd(ppd);
+
+ if (qualifier != NULL) {
+ printer_id = _get_colord_printer_id(printer_name);
+ /* Get profile from colord using qualifiers */
+ icc_profile = colord_get_profile_for_device_id ((const char *)printer_id,
+ (const char **)qualifier);
+ }
+
+ if (icc_profile)
+ is_profile_set = 1;
+ else if (ppd) {
+ /* Get optional fallback PPD profile */
+ icc_profile = _get_ppd_icc_fallback(ppd, qualifier);
+ if (icc_profile)
+ is_profile_set = 1;
+ }
+
+ /* If a profile is found, we give it to the caller */
+ if (is_profile_set)
+ *profile = strdup(icc_profile);
+ else
+ *profile = 0;
+
+ if (printer_id != NULL)
+ free(printer_id);
+
+ if (qualifier != NULL) {
+ for (int i=0; qualifier[i] != NULL; i++)
+ free(qualifier[i]);
+ free(qualifier);
+ }
+
+ return is_profile_set;
+
+}
+
+
+#ifndef CUPSDATA
+#define CUPSDATA "/usr/share/cups"
+#endif
+
+/* From gstoraster */
+char *
+_get_ppd_icc_fallback (ppd_file_t *ppd, char **qualifier)
+{
+ char full_path[1024];
+ char *icc_profile = NULL;
+ char qualifer_tmp[1024];
+ const char *profile_key;
+ ppd_attr_t *attr;
+
+ /* get profile attr, falling back to CUPS */
+ profile_key = "APTiogaProfile";
+ attr = ppdFindAttr(ppd, profile_key, NULL);
+ if (attr == NULL) {
+ profile_key = "cupsICCProfile";
+ attr = ppdFindAttr(ppd, profile_key, NULL);
+ }
+
+ /* create a string for a quick comparion */
+ snprintf(qualifer_tmp, sizeof(qualifer_tmp),
+ "%s.%s.%s",
+ qualifier[0],
+ qualifier[1],
+ qualifier[2]);
+
+ /* neither */
+ if (attr == NULL) {
+ fprintf(stderr, "INFO: Color Manager: no profiles specified in PPD\n");
+ goto out;
+ }
+
+ /* try to find a profile that matches the qualifier exactly */
+ for (;attr != NULL; attr = ppdFindNextAttr(ppd, profile_key, NULL)) {
+ fprintf(stderr, "INFO: Color Manager: found profile %s in PPD with qualifier '%s'\n",
+ attr->value, attr->spec);
+
+ /* invalid entry */
+ if (attr->spec == NULL || attr->value == NULL)
+ continue;
+
+ /* expand to a full path if not already specified */
+ if (attr->value[0] != '/')
+ snprintf(full_path, sizeof(full_path),
+ "%s/profiles/%s", CUPSDATA, attr->value);
+ else
+ strncpy(full_path, attr->value, sizeof(full_path));
+
+ /* check the file exists */
+ if (access(full_path, 0)) {
+ fprintf(stderr, "INFO: Color Manager: found profile %s in PPD that does not exist\n",
+ full_path);
+ continue;
+ }
+
+ /* matches the qualifier */
+ if (strcmp(qualifer_tmp, attr->spec) == 0) {
+ icc_profile = strdup(full_path);
+ goto out;
+ }
+ }
+
+ /* no match */
+ if (attr == NULL) {
+ fprintf(stderr, "INFO: Color Manager: no profiles in PPD for qualifier '%s'\n",
+ qualifer_tmp);
+ goto out;
+ }
+
+out:
+ return icc_profile;
+}
+
diff --git a/cupsfilters/colormanager.h b/cupsfilters/colormanager.h
new file mode 100644
index 000000000..dafaedca0
--- /dev/null
+++ b/cupsfilters/colormanager.h
@@ -0,0 +1,87 @@
+/*
+Copyright (c) 2014, Joseph Simon
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+MIT Open Source License - http://www.opensource.org/
+
+*/
+
+
+#ifndef _CUPS_FILTERS_COLORMANAGER_H_
+# define _CUPS_FILTERS_COLORMANAGER_H_
+
+
+/* "Color Manager" -- Color management interface for cups-filters */
+
+
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+
+
+#include <cups/raster.h>
+#include <cups/ppd.h>
+
+
+
+#define CM_CALIBRATION_STRING "cm-calibration" /* String for "Color Calibration Mode" */
+
+
+/* Enum for status of CUPS color calibration */
+typedef enum cm_calibration_e
+{
+ CM_CALIBRATION_DISABLED = 0, /* "cm-calibration" option not found */
+ CM_CALIBRATION_ENABLED = 1 /* "cm-calibration" found */
+} cm_calibration_t;
+
+
+
+/*
+ * Prototypes
+ */
+
+
+extern
+cm_calibration_t cmGetCupsColorCalibrateMode (cups_option_t *options,
+ int num_options);
+
+extern int cmGetPrinterIccProfile (const char *printer_id,
+ char **icc_profile,
+ ppd_file_t *ppd);
+
+extern int cmIsPrinterCmDisabled (const char *printer_id);
+
+extern double* cmGammaAdobeRgb (void);
+extern double* cmGammaSGray (void);
+
+extern double* cmWhitePointAdobeRgb (void);
+extern double* cmWhitePointSGray (void);
+
+extern double* cmMatrixAdobeRgb (void);
+extern double* cmBlackPointDefault (void);
+
+
+
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+
+#endif /* !_CUPS_FILTERS_COLORMANAGER_H_ */
diff --git a/cupsfilters/dither.c b/cupsfilters/dither.c
new file mode 100644
index 000000000..11c97c4ff
--- /dev/null
+++ b/cupsfilters/dither.c
@@ -0,0 +1,299 @@
+/*
+ * Dithering routines for CUPS.
+ *
+ * Copyright 2007 by Apple Inc.
+ * Copyright 1993-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * cupsDitherDelete() - Free a dithering buffer.
+ * cupsDitherLine() - Dither a line of pixels...
+ * cupsDitherNew() - Create a dithering buffer.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include <config.h>
+#include "driver.h"
+
+
+/*
+ * 'cupsDitherDelete()' - Free a dithering buffer.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+
+void
+cupsDitherDelete(cups_dither_t *d) /* I - Dithering buffer */
+{
+ if (d != NULL)
+ free(d);
+}
+
+
+/*
+ * 'cupsDitherLine()' - Dither a line of pixels...
+ */
+
+void
+cupsDitherLine(cups_dither_t *d, /* I - Dither data */
+ const cups_lut_t *lut, /* I - Lookup table */
+ const short *data, /* I - Separation data */
+ int num_channels,
+ /* I - Number of components */
+ unsigned char *p) /* O - Pixels */
+{
+ register int x, /* Horizontal position in line... */
+ pixel, /* Current adjusted pixel... */
+ e, /* Current error */
+ e0,e1,e2; /* Error values */
+ register int errval0, /* First half of error value */
+ errval1, /* Second half of error value */
+ errbase, /* Base multiplier */
+ errbase0, /* Base multiplier for large values */
+ errbase1, /* Base multiplier for small values */
+ errrange; /* Range of random multiplier */
+ register int *p0, /* Error buffer pointers... */
+ *p1;
+ static char logtable[16384]; /* Error magnitude for randomness */
+ static char loginit = 0; /* Has the table been initialized? */
+
+
+ if (!loginit)
+ {
+ /*
+ * Initialize a logarithmic table for the magnitude of randomness
+ * that is introduced.
+ */
+
+ loginit = 1;
+
+ logtable[0] = 0;
+ for (x = 1; x < 2049; x ++)
+ logtable[x] = (int)(log(x / 16.0) / log(2.0) + 1.0);
+ for (; x < 16384; x ++)
+ logtable[x] = logtable[2049];
+ }
+
+ if (d->row == 0)
+ {
+ /*
+ * Dither from left to right:
+ *
+ * e0 == p0[0]
+ * e1 e2 == p1[-1] p1[0]
+ */
+
+ p0 = d->errors + 2;
+ p1 = d->errors + 2 + d->width + 4;
+ e0 = p0[0];
+ e1 = 0;
+ e2 = 0;
+
+ /*
+ * Error diffuse each output pixel...
+ */
+
+ for (x = d->width;
+ x > 0;
+ x --, p0 ++, p1 ++, p ++, data += num_channels)
+ {
+ /*
+ * Skip blank pixels...
+ */
+
+ if (*data == 0)
+ {
+ *p = 0;
+ e0 = p0[1];
+ p1[-1] = e1;
+ e1 = e2;
+ e2 = 0;
+ continue;
+ }
+
+ /*
+ * Compute the net pixel brightness and brightness error. Set a dot
+ * if necessary...
+ */
+
+ pixel = lut[*data].intensity + e0 / 128;
+
+ if (pixel > CUPS_MAX_LUT)
+ pixel = CUPS_MAX_LUT;
+ else if (pixel < 0)
+ pixel = 0;
+
+ *p = lut[pixel].pixel;
+ e = lut[pixel].error;
+
+ /*
+ * Set the randomness factor...
+ */
+
+ if (e > 0)
+ errrange = logtable[e];
+ else
+ errrange = logtable[-e];
+
+ errbase = 8 - errrange;
+ errrange = errrange * 2 + 1;
+
+ /*
+ * Randomize the error value.
+ */
+
+ if (errrange > 1)
+ {
+ errbase0 = errbase + (CUPS_RAND() % errrange);
+ errbase1 = errbase + (CUPS_RAND() % errrange);
+ }
+ else
+ errbase0 = errbase1 = errbase;
+
+ /*
+ * X 7/16 = X e0
+ * 3/16 5/16 1/16 = e1 e2
+ */
+
+ errval0 = errbase0 * e;
+ errval1 = (16 - errbase0) * e;
+ e0 = p0[1] + 7 * errval0;
+ e1 = e2 + 5 * errval1;
+
+ errval0 = errbase1 * e;
+ errval1 = (16 - errbase1) * e;
+ e2 = errval0;
+ p1[-1] = e1 + 3 * errval1;
+ }
+ }
+ else
+ {
+ /*
+ * Dither from right to left:
+ *
+ * e0 == p0[0]
+ * e2 e1 == p1[0] p1[1]
+ */
+
+ p0 = d->errors + d->width + 1 + d->width + 4;
+ p1 = d->errors + d->width + 1;
+ p += d->width - 1;
+ data += num_channels * (d->width - 1);
+ e0 = p0[0];
+ e1 = 0;
+ e2 = 0;
+
+ /*
+ * Error diffuse each output pixel...
+ */
+
+ for (x = d->width;
+ x > 0;
+ x --, p0 --, p1 --, p --, data -= num_channels)
+ {
+ /*
+ * Skip blank pixels...
+ */
+
+ if (*data == 0)
+ {
+ *p = 0;
+ e0 = p0[-1];
+ p1[1] = e1;
+ e1 = e2;
+ e2 = 0;
+ continue;
+ }
+
+ /*
+ * Compute the net pixel brightness and brightness error. Set a dot
+ * if necessary...
+ */
+
+ pixel = lut[*data].intensity + e0 / 128;
+
+ if (pixel > CUPS_MAX_LUT)
+ pixel = CUPS_MAX_LUT;
+ else if (pixel < 0)
+ pixel = 0;
+
+ *p = lut[pixel].pixel;
+ e = lut[pixel].error;
+
+ /*
+ * Set the randomness factor...
+ */
+
+ if (e > 0)
+ errrange = logtable[e];
+ else
+ errrange = logtable[-e];
+
+ errbase = 8 - errrange;
+ errrange = errrange * 2 + 1;
+
+ /*
+ * Randomize the error value.
+ */
+
+ if (errrange > 1)
+ {
+ errbase0 = errbase + (CUPS_RAND() % errrange);
+ errbase1 = errbase + (CUPS_RAND() % errrange);
+ }
+ else
+ errbase0 = errbase1 = errbase;
+
+ /*
+ * X 7/16 = X e0
+ * 3/16 5/16 1/16 = e1 e2
+ */
+
+ errval0 = errbase0 * e;
+ errval1 = (16 - errbase0) * e;
+ e0 = p0[-1] + 7 * errval0;
+ e1 = e2 + 5 * errval1;
+
+ errval0 = errbase1 * e;
+ errval1 = (16 - errbase1) * e;
+ e2 = errval0;
+ p1[1] = e1 + 3 * errval1;
+ }
+ }
+
+ /*
+ * Update to the next row...
+ */
+
+ d->row = 1 - d->row;
+}
+
+
+/*
+ * 'cupsDitherNew()' - Create an error-diffusion dithering buffer.
+ */
+
+cups_dither_t * /* O - New state array */
+cupsDitherNew(int width) /* I - Width of output in pixels */
+{
+ cups_dither_t *d; /* New dithering buffer */
+
+
+ if ((d = (cups_dither_t *)calloc(1, sizeof(cups_dither_t) +
+ 2 * (width + 4) *
+ sizeof(int))) == NULL)
+ return (NULL);
+
+ d->width = width;
+
+ return (d);
+}
+
diff --git a/cupsfilters/driver.h b/cupsfilters/driver.h
new file mode 100644
index 000000000..112933d8e
--- /dev/null
+++ b/cupsfilters/driver.h
@@ -0,0 +1,243 @@
+/*
+ * Printer driver utilities header file for CUPS.
+ *
+ * Copyright 2007 by Apple Inc.
+ * Copyright 1993-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ */
+
+#ifndef _CUPS_FILTERS_DRIVER_H_
+# define _CUPS_FILTERS_DRIVER_H_
+
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+
+/*
+ * Include necessary headers...
+ */
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <time.h>
+# include <math.h>
+# include <cups/ppd.h>
+
+# if defined(WIN32) || defined(__EMX__)
+# include <io.h>
+# else
+# include <unistd.h>
+# include <fcntl.h>
+# endif /* WIN32 || __EMX__ */
+
+# include <cups/cups.h>
+# include <cups/raster.h>
+
+
+/*
+ * Common macros...
+ */
+
+# ifndef min
+# define min(a,b) ((a) < (b) ? (a) : (b))
+# define max(a,b) ((a) > (b) ? (a) : (b))
+# endif /* !min */
+
+
+/*
+ * Constants...
+ */
+
+#define CUPS_MAX_CHAN 15 /* Maximum number of color components */
+#define CUPS_MAX_LUT 4095 /* Maximum LUT value */
+#define CUPS_MAX_RGB 4 /* Maximum number of sRGB components */
+
+
+/*
+ * Types/structures for the various routines.
+ */
+
+typedef struct cups_lut_s /**** Lookup Table for Dithering ****/
+{
+ short intensity; /* Adjusted intensity */
+ short pixel; /* Output pixel value */
+ int error; /* Error from desired value */
+} cups_lut_t;
+
+typedef struct cups_dither_s /**** Dithering State ****/
+{
+ int width; /* Width of buffer */
+ int row; /* Current row */
+ int errors[96]; /* Error values */
+} cups_dither_t;
+
+typedef struct cups_sample_s /**** Color sample point ****/
+{
+ unsigned char rgb[3]; /* sRGB values */
+ unsigned char colors[CUPS_MAX_RGB]; /* Color values */
+} cups_sample_t;
+
+typedef struct cups_rgb_s /**** Color separation lookup table ****/
+{
+ int cube_size; /* Size of color cube (2-N) on a side */
+ int num_channels; /* Number of colors per sample */
+ unsigned char ****colors; /* 4-D array of sample values */
+ int cube_index[256]; /* Index into cube for a given sRGB value */
+ int cube_mult[256]; /* Multiplier value for a given sRGB value */
+ int cache_init; /* Are cached values initialized? */
+ unsigned char black[CUPS_MAX_RGB]; /* Cached black (sRGB = 0,0,0) */
+ unsigned char white[CUPS_MAX_RGB]; /* Cached white (sRGB = 255,255,255) */
+} cups_rgb_t;
+
+typedef struct cups_cmyk_s /**** Simple CMYK lookup table ****/
+{
+ unsigned char black_lut[256]; /* Black generation LUT */
+ unsigned char color_lut[256]; /* Color removal LUT */
+ int ink_limit; /* Ink limit */
+ int num_channels; /* Number of components */
+ short *channels[CUPS_MAX_CHAN];
+ /* Lookup tables */
+} cups_cmyk_t;
+
+
+/*
+ * Globals...
+ */
+
+extern const unsigned char
+ cups_srgb_lut[256];
+ /* sRGB gamma lookup table */
+extern const unsigned char
+ cups_scmy_lut[256];
+ /* sRGB gamma lookup table (inverted) */
+
+
+/*
+ * Prototypes...
+ */
+
+/*
+ * Attribute function...
+ */
+
+extern ppd_attr_t *cupsFindAttr(ppd_file_t *ppd, const char *name,
+ const char *colormodel,
+ const char *media,
+ const char *resolution,
+ char *spec, int specsize);
+
+/*
+ * Byte checking functions...
+ */
+
+extern int cupsCheckBytes(const unsigned char *, int);
+extern int cupsCheckValue(const unsigned char *, int,
+ const unsigned char);
+
+/*
+ * Dithering functions...
+ */
+
+extern void cupsDitherLine(cups_dither_t *d, const cups_lut_t *lut,
+ const short *data, int num_channels,
+ unsigned char *p);
+extern cups_dither_t *cupsDitherNew(int width);
+extern void cupsDitherDelete(cups_dither_t *);
+
+/*
+ * Lookup table functions for dithering...
+ */
+
+extern cups_lut_t *cupsLutNew(int num_vals, const float *vals);
+extern void cupsLutDelete(cups_lut_t *lut);
+extern cups_lut_t *cupsLutLoad(ppd_file_t *ppd,
+ const char *colormodel,
+ const char *media,
+ const char *resolution,
+ const char *ink);
+
+
+/*
+ * Bit packing functions...
+ */
+
+extern void cupsPackHorizontal(const unsigned char *,
+ unsigned char *, int,
+ const unsigned char, const int);
+extern void cupsPackHorizontal2(const unsigned char *,
+ unsigned char *, int, const int);
+extern void cupsPackHorizontalBit(const unsigned char *,
+ unsigned char *, int,
+ const unsigned char,
+ const unsigned char);
+extern void cupsPackVertical(const unsigned char *, unsigned char *,
+ int, const unsigned char, const int);
+
+/*
+ * Color separation functions...
+ */
+
+extern void cupsRGBDelete(cups_rgb_t *rgb);
+extern void cupsRGBDoGray(cups_rgb_t *rgb,
+ const unsigned char *input,
+ unsigned char *output, int num_pixels);
+extern void cupsRGBDoRGB(cups_rgb_t *rgb,
+ const unsigned char *input,
+ unsigned char *output, int num_pixels);
+extern cups_rgb_t *cupsRGBLoad(ppd_file_t *ppd,
+ const char *colormodel,
+ const char *media,
+ const char *resolution);
+extern cups_rgb_t *cupsRGBNew(int num_samples, cups_sample_t *samples,
+ int cube_size, int num_channels);
+
+/*
+ * CMYK separation functions...
+ */
+
+extern cups_cmyk_t *cupsCMYKNew(int num_channels);
+extern void cupsCMYKDelete(cups_cmyk_t *cmyk);
+extern void cupsCMYKDoBlack(const cups_cmyk_t *cmyk,
+ const unsigned char *input,
+ short *output, int num_pixels);
+extern void cupsCMYKDoCMYK(const cups_cmyk_t *cmyk,
+ const unsigned char *input,
+ short *output, int num_pixels);
+extern void cupsCMYKDoGray(const cups_cmyk_t *cmyk,
+ const unsigned char *input,
+ short *output, int num_pixels);
+extern void cupsCMYKDoRGB(const cups_cmyk_t *cmyk,
+ const unsigned char *input,
+ short *output, int num_pixels);
+extern cups_cmyk_t *cupsCMYKLoad(ppd_file_t *ppd,
+ const char *colormodel,
+ const char *media,
+ const char *resolution);
+extern void cupsCMYKSetBlack(cups_cmyk_t *cmyk,
+ float lower, float upper);
+extern void cupsCMYKSetCurve(cups_cmyk_t *cmyk, int channel,
+ int num_xypoints,
+ const float *xypoints);
+extern void cupsCMYKSetGamma(cups_cmyk_t *cmyk, int channel,
+ float gamval, float density);
+extern void cupsCMYKSetInkLimit(cups_cmyk_t *cmyk, float limit);
+extern void cupsCMYKSetLtDk(cups_cmyk_t *cmyk, int channel,
+ float light, float dark);
+
+
+/*
+ * Convenience macro for writing print data...
+ */
+
+# define cupsWritePrintData(s,n) fwrite((s), 1, (n), stdout)
+
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+
+#endif /* !_CUPS_FILTERS_DRIVER_H_ */
+
diff --git a/cupsfilters/image-bmp.c b/cupsfilters/image-bmp.c
new file mode 100644
index 000000000..4a90cd5f1
--- /dev/null
+++ b/cupsfilters/image-bmp.c
@@ -0,0 +1,537 @@
+/*
+ * BMP image routines for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2007 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * _cupsImageReadBMP() - Read a BMP image file.
+ * read_word() - Read a 16-bit unsigned integer.
+ * read_dword() - Read a 32-bit unsigned integer.
+ * read_long() - Read a 32-bit signed integer.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image-private.h"
+
+
+/*
+ * Constants for the bitmap compression...
+ */
+
+# define BI_RGB 0 /* No compression - straight BGR data */
+# define BI_RLE8 1 /* 8-bit run-length compression */
+# define BI_RLE4 2 /* 4-bit run-length compression */
+# define BI_BITFIELDS 3 /* RGB bitmap with RGB masks */
+
+
+/*
+ * Local functions...
+ */
+
+static unsigned short read_word(FILE *fp);
+static unsigned int read_dword(FILE *fp);
+static int read_long(FILE *fp);
+
+
+/*
+ * '_cupsImageReadBMP()' - Read a BMP image file.
+ */
+
+int /* O - Read status */
+_cupsImageReadBMP(
+ cups_image_t *img, /* IO - cupsImage */
+ FILE *fp, /* I - cupsImage file */
+ cups_icspace_t primary, /* I - Primary choice for colorspace */
+ cups_icspace_t secondary, /* I - Secondary choice for colorspace */
+ int saturation, /* I - Color saturation (%) */
+ int hue, /* I - Color hue (degrees) */
+ const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */
+{
+ int offset, /* Offset to bitmap data */
+ info_size, /* Size of info header */
+ planes, /* Number of planes (always 1) */
+ depth, /* Depth of image (bits) */
+ compression, /* Type of compression */
+ image_size, /* Size of image in bytes */
+ colors_used, /* Number of colors used */
+ colors_important, /* Number of important colors */
+ bpp, /* Bytes per pixel */
+ x, y, /* Looping vars */
+ color, /* Color of RLE pixel */
+ count, /* Number of times to repeat */
+ temp, /* Temporary color */
+ align; /* Alignment bytes */
+ cups_ib_t bit, /* Bit in image */
+ byte; /* Byte in image */
+ cups_ib_t *in, /* Input pixels */
+ *out, /* Output pixels */
+ *ptr; /* Pointer into pixels */
+ cups_ib_t colormap[256][4]; /* Colormap */
+
+
+ (void)secondary;
+
+ /*
+ * Get the header...
+ */
+
+ getc(fp); /* Skip "BM" sync chars */
+ getc(fp);
+ read_dword(fp); /* Skip size */
+ read_word(fp); /* Skip reserved stuff */
+ read_word(fp);
+ offset = read_dword(fp);
+
+ fprintf(stderr, "DEBUG: offset = %d\n", offset);
+
+ if (offset < 0)
+ {
+ fprintf(stderr, "DEBUG: Bad BMP offset %d\n", offset);
+ fclose(fp);
+ return (1);
+ }
+
+ /*
+ * Then the bitmap information...
+ */
+
+ info_size = read_dword(fp);
+ img->xsize = read_long(fp);
+ img->ysize = read_long(fp);
+ planes = read_word(fp);
+ depth = read_word(fp);
+ compression = read_dword(fp);
+ image_size = read_dword(fp);
+ img->xppi = read_long(fp) * 0.0254 + 0.5;
+ img->yppi = read_long(fp) * 0.0254 + 0.5;
+ colors_used = read_dword(fp);
+ colors_important = read_dword(fp);
+
+ if (img->xsize == 0 || img->xsize > CUPS_IMAGE_MAX_WIDTH ||
+ img->ysize == 0 || img->ysize > CUPS_IMAGE_MAX_HEIGHT ||
+ (depth != 1 && depth != 4 && depth != 8 && depth != 24))
+ {
+ fprintf(stderr, "DEBUG: Bad BMP dimensions %ux%ux%d\n",
+ img->xsize, img->ysize, depth);
+ fclose(fp);
+ return (1);
+ }
+
+ if (colors_used < 0 || colors_used > 256)
+ {
+ fprintf(stderr, "DEBUG: Bad BMP colormap size %d\n", colors_used);
+ fclose(fp);
+ return (1);
+ }
+
+ if (img->xppi == 0 || img->yppi == 0)
+ {
+ fprintf(stderr, "DEBUG: Bad BMP resolution %dx%d PPI.\n",
+ img->xppi, img->yppi);
+ img->xppi = img->yppi = 128;
+ }
+
+ /*
+ * Make sure the resolution info is valid...
+ */
+
+ fprintf(stderr, "info_size = %d, xsize = %d, ysize = %d, planes = %d, depth = %d\n",
+ info_size, img->xsize, img->ysize, planes, depth);
+ fprintf(stderr, "compression = %d, image_size = %d, xppi = %d, yppi = %d\n",
+ compression, image_size, img->xppi, img->yppi);
+ fprintf(stderr, "colors_used = %d, colors_important = %d\n", colors_used,
+ colors_important);
+
+ if (info_size > 40)
+ for (info_size -= 40; info_size > 0; info_size --)
+ getc(fp);
+
+ /*
+ * Get colormap...
+ */
+
+ if (colors_used == 0 && depth <= 8)
+ colors_used = 1 << depth;
+
+ if (colors_used > 0) {
+ if (fread(colormap, colors_used, 4, fp) == 0 && ferror(fp))
+ DEBUG_printf(("Error reading file!"));
+ } else
+ memset(colormap, 0, sizeof(colormap));
+
+ /*
+ * Setup image and buffers...
+ */
+
+ img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary;
+
+ cupsImageSetMaxTiles(img, 0);
+
+ bpp = cupsImageGetDepth(img);
+
+ if ((in = malloc(img->xsize * 3)) == NULL)
+ {
+ fputs("DEBUG: Unable to allocate memory!\n", stderr);
+ fclose(fp);
+ return (1);
+ }
+
+ if ((out = malloc(img->xsize * bpp)) == NULL)
+ {
+ fputs("DEBUG: Unable to allocate memory!\n", stderr);
+ free(in);
+ fclose(fp);
+ return (1);
+ }
+
+ /*
+ * Read the image data...
+ */
+
+ color = 0;
+ count = 0;
+ align = 0;
+
+ for (y = img->ysize - 1; y >= 0; y --)
+ {
+ ptr = in;
+
+ switch (depth)
+ {
+ case 1 : /* Bitmap */
+ for (x = img->xsize, bit = 128, byte = 0; x > 0; x --)
+ {
+ if (bit == 128)
+ byte = getc(fp);
+
+ if (byte & bit)
+ {
+ *ptr++ = colormap[1][2];
+ *ptr++ = colormap[1][1];
+ *ptr++ = colormap[1][0];
+ }
+ else
+ {
+ *ptr++ = colormap[0][2];
+ *ptr++ = colormap[0][1];
+ *ptr++ = colormap[0][0];
+ }
+
+ if (bit > 1)
+ bit >>= 1;
+ else
+ bit = 128;
+ }
+
+ /*
+ * Read remaining bytes to align to 32 bits...
+ */
+
+ for (temp = (img->xsize + 7) / 8; temp & 3; temp ++)
+ getc(fp);
+ break;
+
+ case 4 : /* 16-color */
+ for (x = img->xsize, bit = 0xf0, temp = 0; x > 0; x --)
+ {
+ /*
+ * Get a new count as needed...
+ */
+
+ if (compression != BI_RLE4 && count == 0)
+ {
+ count = 2;
+ color = -1;
+ }
+
+ if (count == 0)
+ {
+ while (align > 0)
+ {
+ align --;
+ getc(fp);
+ }
+
+ if ((count = getc(fp)) == 0)
+ {
+ if ((count = getc(fp)) == 0)
+ {
+ /*
+ * End of line...
+ */
+
+ x ++;
+ continue;
+ }
+ else if (count == 1)
+ {
+ /*
+ * End of image...
+ */
+
+ break;
+ }
+ else if (count == 2)
+ {
+ /*
+ * Delta...
+ */
+
+ count = getc(fp) * getc(fp) * img->xsize;
+ color = 0;
+ }
+ else
+ {
+ /*
+ * Absolute...
+ */
+
+ color = -1;
+ align = ((4 - (count & 3)) / 2) & 1;
+ }
+ }
+ else
+ color = getc(fp);
+ }
+
+ /*
+ * Get a new color as needed...
+ */
+
+ count --;
+
+ if (bit == 0xf0)
+ {
+ if (color < 0)
+ temp = getc(fp);
+ else
+ temp = color;
+
+ /*
+ * Copy the color value...
+ */
+
+ *ptr++ = colormap[temp >> 4][2];
+ *ptr++ = colormap[temp >> 4][1];
+ *ptr++ = colormap[temp >> 4][0];
+ bit = 0x0f;
+ }
+ else
+ {
+ /*
+ * Copy the color value...
+ */
+
+ *ptr++ = colormap[temp & 15][2];
+ *ptr++ = colormap[temp & 15][1];
+ *ptr++ = colormap[temp & 15][0];
+ bit = 0xf0;
+ }
+ }
+ break;
+
+ case 8 : /* 256-color */
+ for (x = img->xsize; x > 0; x --)
+ {
+ /*
+ * Get a new count as needed...
+ */
+
+ if (compression != BI_RLE8)
+ {
+ count = 1;
+ color = -1;
+ }
+
+ if (count == 0)
+ {
+ while (align > 0)
+ {
+ align --;
+ getc(fp);
+ }
+
+ if ((count = getc(fp)) == 0)
+ {
+ if ((count = getc(fp)) == 0)
+ {
+ /*
+ * End of line...
+ */
+
+ x ++;
+ continue;
+ }
+ else if (count == 1)
+ {
+ /*
+ * End of image...
+ */
+
+ break;
+ }
+ else if (count == 2)
+ {
+ /*
+ * Delta...
+ */
+
+ count = getc(fp) * getc(fp) * img->xsize;
+ color = 0;
+ }
+ else
+ {
+ /*
+ * Absolute...
+ */
+
+ color = -1;
+ align = (2 - (count & 1)) & 1;
+ }
+ }
+ else
+ color = getc(fp);
+ }
+
+ /*
+ * Get a new color as needed...
+ */
+
+ if (color < 0)
+ temp = getc(fp);
+ else
+ temp = color;
+
+ count --;
+
+ /*
+ * Copy the color value...
+ */
+
+ *ptr++ = colormap[temp][2];
+ *ptr++ = colormap[temp][1];
+ *ptr++ = colormap[temp][0];
+ }
+ break;
+
+ case 24 : /* 24-bit RGB */
+ for (x = img->xsize; x > 0; x --, ptr += 3)
+ {
+ ptr[2] = getc(fp);
+ ptr[1] = getc(fp);
+ ptr[0] = getc(fp);
+ }
+
+ /*
+ * Read remaining bytes to align to 32 bits...
+ */
+
+ for (temp = img->xsize * 3; temp & 3; temp ++)
+ getc(fp);
+ break;
+ }
+
+ if (saturation != 100 || hue != 0)
+ cupsImageRGBAdjust(in, img->xsize, saturation, hue);
+
+ switch (img->colorspace)
+ {
+ default :
+ break;
+
+ case CUPS_IMAGE_WHITE :
+ cupsImageRGBToWhite(in, out, img->xsize);
+ break;
+
+ case CUPS_IMAGE_RGB :
+ cupsImageRGBToRGB(in, out, img->xsize);
+ break;
+
+ case CUPS_IMAGE_BLACK :
+ cupsImageRGBToBlack(in, out, img->xsize);
+ break;
+
+ case CUPS_IMAGE_CMY :
+ cupsImageRGBToCMY(in, out, img->xsize);
+ break;
+
+ case CUPS_IMAGE_CMYK :
+ cupsImageRGBToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, img->xsize * bpp, lut);
+
+ _cupsImagePutRow(img, 0, y, img->xsize, out);
+ }
+
+ fclose(fp);
+ free(in);
+ free(out);
+
+ return (0);
+}
+
+
+/*
+ * 'read_word()' - Read a 16-bit unsigned integer.
+ */
+
+static unsigned short /* O - 16-bit unsigned integer */
+read_word(FILE *fp) /* I - File to read from */
+{
+ unsigned char b0, b1; /* Bytes from file */
+
+ b0 = getc(fp);
+ b1 = getc(fp);
+
+ return ((b1 << 8) | b0);
+}
+
+
+/*
+ * 'read_dword()' - Read a 32-bit unsigned integer.
+ */
+
+static unsigned int /* O - 32-bit unsigned integer */
+read_dword(FILE *fp) /* I - File to read from */
+{
+ unsigned char b0, b1, b2, b3; /* Bytes from file */
+
+ b0 = getc(fp);
+ b1 = getc(fp);
+ b2 = getc(fp);
+ b3 = getc(fp);
+
+ return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
+}
+
+
+/*
+ * 'read_long()' - Read a 32-bit signed integer.
+ */
+
+static int /* O - 32-bit signed integer */
+read_long(FILE *fp) /* I - File to read from */
+{
+ unsigned char b0, b1, b2, b3; /* Bytes from file */
+
+ b0 = getc(fp);
+ b1 = getc(fp);
+ b2 = getc(fp);
+ b3 = getc(fp);
+
+ return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
+}
+
diff --git a/cupsfilters/image-colorspace.c b/cupsfilters/image-colorspace.c
new file mode 100644
index 000000000..d5c07877a
--- /dev/null
+++ b/cupsfilters/image-colorspace.c
@@ -0,0 +1,1558 @@
+/*
+ * Colorspace conversions for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2006 by Easy Software Products.
+ *
+ * The color saturation/hue matrix stuff is provided thanks to Mr. Paul
+ * Haeberli at "http://www.sgi.com/grafica/matrix/index.html".
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * cupsImageCMYKToBlack() - Convert CMYK data to black.
+ * cupsImageCMYKToCMY() - Convert CMYK colors to CMY.
+ * cupsImageCMYKToCMYK() - Convert CMYK colors to CMYK.
+ * cupsImageCMYKToRGB() - Convert CMYK colors to device-dependent
+ * RGB.
+ * cupsImageCMYKToWhite() - Convert CMYK colors to luminance.
+ * cupsImageLut() - Adjust all pixel values with the given
+ * LUT.
+ * cupsImageRGBAdjust() - Adjust the hue and saturation of the
+ * given RGB colors.
+ * cupsImageRGBToBlack() - Convert RGB data to black.
+ * cupsImageRGBToCMY() - Convert RGB colors to CMY.
+ * cupsImageRGBToCMYK() - Convert RGB colors to CMYK.
+ * cupsImageRGBToRGB() - Convert RGB colors to device-dependent
+ * RGB.
+ * cupsImageRGBToWhite() - Convert RGB colors to luminance.
+ * cupsImageSetProfile() - Set the device color profile.
+ * cupsImageSetRasterColorSpace() - Set the destination colorspace.
+ * cupsImageWhiteToBlack() - Convert luminance colors to black.
+ * cupsImageWhiteToCMY() - Convert luminance colors to CMY.
+ * cupsImageWhiteToCMYK() - Convert luminance colors to CMYK.
+ * cupsImageWhiteToRGB() - Convert luminance data to RGB.
+ * cupsImageWhiteToWhite() - Convert luminance colors to device-
+ * dependent luminance.
+ * cielab() - Map CIE Lab transformation...
+ * huerotate() - Rotate the hue, maintaining luminance.
+ * ident() - Make an identity matrix.
+ * mult() - Multiply two matrices.
+ * rgb_to_lab() - Convert an RGB color to CIE Lab.
+ * rgb_to_xyz() - Convert an RGB color to CIE XYZ.
+ * saturate() - Make a saturation matrix.
+ * xform() - Transform a 3D point using a matrix...
+ * xrotate() - Rotate about the x (red) axis...
+ * yrotate() - Rotate about the y (green) axis...
+ * zrotate() - Rotate about the z (blue) axis...
+ * zshear() - Shear z using x and y...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image-private.h"
+
+
+/*
+ * Define some math constants that are required...
+ */
+
+#ifndef M_PI
+# define M_PI 3.14159265358979323846
+#endif /* !M_PI */
+
+#ifndef M_SQRT2
+# define M_SQRT2 1.41421356237309504880
+#endif /* !M_SQRT2 */
+
+#ifndef M_SQRT1_2
+# define M_SQRT1_2 0.70710678118654752440
+#endif /* !M_SQRT1_2 */
+
+/*
+ * CIE XYZ whitepoint...
+ */
+
+#define D65_X (0.412453 + 0.357580 + 0.180423)
+#define D65_Y (0.212671 + 0.715160 + 0.072169)
+#define D65_Z (0.019334 + 0.119193 + 0.950227)
+
+
+/*
+ * Lookup table structure...
+ */
+
+typedef int cups_clut_t[3][256];
+
+
+/*
+ * Local globals...
+ */
+
+static int cupsImageHaveProfile = 0;
+ /* Do we have a color profile? */
+static int *cupsImageDensity;
+ /* Ink/marker density LUT */
+static cups_clut_t *cupsImageMatrix;
+ /* Color transform matrix LUT */
+static cups_cspace_t cupsImageColorSpace = CUPS_CSPACE_RGB;
+ /* Destination colorspace */
+
+
+/*
+ * Local functions...
+ */
+
+static float cielab(float x, float xn);
+static void huerotate(float [3][3], float);
+static void ident(float [3][3]);
+static void mult(float [3][3], float [3][3], float [3][3]);
+static void rgb_to_lab(cups_ib_t *val);
+static void rgb_to_xyz(cups_ib_t *val);
+static void saturate(float [3][3], float);
+static void xform(float [3][3], float, float, float, float *, float *, float *);
+static void xrotate(float [3][3], float, float);
+static void yrotate(float [3][3], float, float);
+static void zrotate(float [3][3], float, float);
+static void zshear(float [3][3], float, float);
+
+
+/*
+ * 'cupsImageCMYKToBlack()' - Convert CMYK data to black.
+ */
+
+void
+cupsImageCMYKToBlack(
+ const cups_ib_t *in, /* I - Input pixels */
+ cups_ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ int k; /* Black value */
+
+
+ if (cupsImageHaveProfile)
+ while (count > 0)
+ {
+ k = (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100 + in[3];
+
+ if (k < 255)
+ *out++ = cupsImageDensity[k];
+ else
+ *out++ = cupsImageDensity[255];
+
+ in += 4;
+ count --;
+ }
+ else
+ while (count > 0)
+ {
+ k = (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100 + in[3];
+
+ if (k < 255)
+ *out++ = k;
+ else
+ *out++ = 255;
+
+ in += 4;
+ count --;
+ }
+}
+
+
+/*
+ * 'cupsImageCMYKToCMY()' - Convert CMYK colors to CMY.
+ */
+
+void
+cupsImageCMYKToCMY(
+ const cups_ib_t *in, /* I - Input pixels */
+ cups_ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ int c, m, y, k; /* CMYK values */
+ int cc, cm, cy; /* Calibrated CMY values */
+
+
+ if (cupsImageHaveProfile)
+ while (count > 0)
+ {
+ c = *in++;
+ m = *in++;
+ y = *in++;
+ k = *in++;
+
+ cc = cupsImageMatrix[0][0][c] +
+ cupsImageMatrix[0][1][m] +
+ cupsImageMatrix[0][2][y] + k;
+ cm = cupsImageMatrix[1][0][c] +
+ cupsImageMatrix[1][1][m] +
+ cupsImageMatrix[1][2][y] + k;
+ cy = cupsImageMatrix[2][0][c] +
+ cupsImageMatrix[2][1][m] +
+ cupsImageMatrix[2][2][y] + k;
+
+ if (cc < 0)
+ *out++ = 0;
+ else if (cc > 255)
+ *out++ = cupsImageDensity[255];
+ else
+ *out++ = cupsImageDensity[cc];
+
+ if (cm < 0)
+ *out++ = 0;
+ else if (cm > 255)
+ *out++ = cupsImageDensity[255];
+ else
+ *out++ = cupsImageDensity[cm];
+
+ if (cy < 0)
+ *out++ = 0;
+ else if (cy > 255)
+ *out++ = cupsImageDensity[255];
+ else
+ *out++ = cupsImageDensity[cy];
+
+ count --;
+ }
+ else
+ while (count > 0)
+ {
+ c = *in++;
+ m = *in++;
+ y = *in++;
+ k = *in++;
+
+ c += k;
+ m += k;
+ y += k;
+
+ if (c < 255)
+ *out++ = c;
+ else
+ *out++ = 255;
+
+ if (m < 255)
+ *out++ = y;
+ else
+ *out++ = 255;
+
+ if (y < 255)
+ *out++ = y;
+ else
+ *out++ = 255;
+
+ count --;
+ }
+}
+
+
+/*
+ * 'cupsImageCMYKToCMYK()' - Convert CMYK colors to CMYK.
+ */
+
+void
+cupsImageCMYKToCMYK(
+ const cups_ib_t *in, /* I - Input pixels */
+ cups_ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ int c, m, y, k; /* CMYK values */
+ int cc, cm, cy; /* Calibrated CMY values */
+
+
+ if (cupsImageHaveProfile)
+ while (count > 0)
+ {
+ c = *in++;
+ m = *in++;
+ y = *in++;
+ k = *in++;
+
+ cc = (cupsImageMatrix[0][0][c] +
+ cupsImageMatrix[0][1][m] +
+ cupsImageMatrix[0][2][y]);
+ cm = (cupsImageMatrix[1][0][c] +
+ cupsImageMatrix[1][1][m] +
+ cupsImageMatrix[1][2][y]);
+ cy = (cupsImageMatrix[2][0][c] +
+ cupsImageMatrix[2][1][m] +
+ cupsImageMatrix[2][2][y]);
+
+ if (cc < 0)
+ *out++ = 0;
+ else if (cc > 255)
+ *out++ = cupsImageDensity[255];
+ else
+ *out++ = cupsImageDensity[cc];
+
+ if (cm < 0)
+ *out++ = 0;
+ else if (cm > 255)
+ *out++ = cupsImageDensity[255];
+ else
+ *out++ = cupsImageDensity[cm];
+
+ if (cy < 0)
+ *out++ = 0;
+ else if (cy > 255)
+ *out++ = cupsImageDensity[255];
+ else
+ *out++ = cupsImageDensity[cy];
+
+ *out++ = cupsImageDensity[k];
+
+ count --;
+ }
+ else if (in != out)
+ {
+ while (count > 0)
+ {
+ *out++ = *in++;
+ *out++ = *in++;
+ *out++ = *in++;
+ *out++ = *in++;
+
+ count --;
+ }
+ }
+}
+
+
+/*
+ * 'cupsImageCMYKToRGB()' - Convert CMYK colors to device-dependent RGB.
+ */
+
+void
+cupsImageCMYKToRGB(
+ const cups_ib_t *in, /* I - Input pixels */
+ cups_ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ int c, m, y, k; /* CMYK values */
+ int cr, cg, cb; /* Calibrated RGB values */
+
+
+ if (cupsImageHaveProfile)
+ {
+ while (count > 0)
+ {
+ c = *in++;
+ m = *in++;
+ y = *in++;
+ k = *in++;
+
+ cr = cupsImageMatrix[0][0][c] +
+ cupsImageMatrix[0][1][m] +
+ cupsImageMatrix[0][2][y] + k;
+ cg = cupsImageMatrix[1][0][c] +
+ cupsImageMatrix[1][1][m] +
+ cupsImageMatrix[1][2][y] + k;
+ cb = cupsImageMatrix[2][0][c] +
+ cupsImageMatrix[2][1][m] +
+ cupsImageMatrix[2][2][y] + k;
+
+ if (cr < 0)
+ *out++ = 255;
+ else if (cr > 255)
+ *out++ = 255 - cupsImageDensity[255];
+ else
+ *out++ = 255 - cupsImageDensity[cr];
+
+ if (cg < 0)
+ *out++ = 255;
+ else if (cg > 255)
+ *out++ = 255 - cupsImageDensity[255];
+ else
+ *out++ = 255 - cupsImageDensity[cg];
+
+ if (cb < 0)
+ *out++ = 255;
+ else if (cb > 255)
+ *out++ = 255 - cupsImageDensity[255];
+ else
+ *out++ = 255 - cupsImageDensity[cb];
+
+ count --;
+ }
+ }
+ else
+ {
+ while (count > 0)
+ {
+ c = 255 - *in++;
+ m = 255 - *in++;
+ y = 255 - *in++;
+ k = *in++;
+
+ c -= k;
+ m -= k;
+ y -= k;
+
+ if (c > 0)
+ *out++ = c;
+ else
+ *out++ = 0;
+
+ if (m > 0)
+ *out++ = m;
+ else
+ *out++ = 0;
+
+ if (y > 0)
+ *out++ = y;
+ else
+ *out++ = 0;
+
+ if (cupsImageColorSpace == CUPS_CSPACE_CIELab ||
+ cupsImageColorSpace >= CUPS_CSPACE_ICC1)
+ rgb_to_lab(out - 3);
+ else if (cupsImageColorSpace == CUPS_CSPACE_CIEXYZ)
+ rgb_to_xyz(out - 3);
+
+ count --;
+ }
+ }
+}
+
+
+/*
+ * 'cupsImageCMYKToWhite()' - Convert CMYK colors to luminance.
+ */
+
+void
+cupsImageCMYKToWhite(
+ const cups_ib_t *in, /* I - Input pixels */
+ cups_ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ int w; /* White value */
+
+
+ if (cupsImageHaveProfile)
+ {
+ while (count > 0)
+ {
+ w = 255 - (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100 - in[3];
+
+ if (w > 0)
+ *out++ = cupsImageDensity[w];
+ else
+ *out++ = cupsImageDensity[0];
+
+ in += 4;
+ count --;
+ }
+ }
+ else
+ {
+ while (count > 0)
+ {
+ w = 255 - (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100 - in[3];
+
+ if (w > 0)
+ *out++ = w;
+ else
+ *out++ = 0;
+
+ in += 4;
+ count --;
+ }
+ }
+}
+
+
+/*
+ * 'cupsImageLut()' - Adjust all pixel values with the given LUT.
+ */
+
+void
+cupsImageLut(cups_ib_t *pixels, /* IO - Input/output pixels */
+ int count, /* I - Number of pixels/bytes to adjust */
+ const cups_ib_t *lut) /* I - Lookup table */
+{
+ while (count > 0)
+ {
+ *pixels = lut[*pixels];
+ pixels ++;
+ count --;
+ }
+}
+
+
+/*
+ * 'cupsImageRGBAdjust()' - Adjust the hue and saturation of the given RGB colors.
+ */
+
+void
+cupsImageRGBAdjust(cups_ib_t *pixels, /* IO - Input/output pixels */
+ int count, /* I - Number of pixels to adjust */
+ int saturation,/* I - Color saturation (%) */
+ int hue) /* I - Color hue (degrees) */
+{
+ int i, j, k; /* Looping vars */
+ float mat[3][3]; /* Color adjustment matrix */
+ static int last_sat = 100, /* Last saturation used */
+ last_hue = 0; /* Last hue used */
+ static cups_clut_t *lut = NULL; /* Lookup table for matrix */
+
+
+ if (saturation != last_sat || hue != last_hue || !lut)
+ {
+ /*
+ * Build the color adjustment matrix...
+ */
+
+ ident(mat);
+ saturate(mat, saturation * 0.01);
+ huerotate(mat, (float)hue);
+
+ /*
+ * Allocate memory for the lookup table...
+ */
+
+ if (lut == NULL)
+ lut = calloc(3, sizeof(cups_clut_t));
+
+ if (lut == NULL)
+ return;
+
+ /*
+ * Convert the matrix into a 3x3 array of lookup tables...
+ */
+
+ for (i = 0; i < 3; i ++)
+ for (j = 0; j < 3; j ++)
+ for (k = 0; k < 256; k ++)
+ lut[i][j][k] = mat[i][j] * k + 0.5;
+
+ /*
+ * Save the saturation and hue to compare later...
+ */
+
+ last_sat = saturation;
+ last_hue = hue;
+ }
+
+ /*
+ * Adjust each pixel in the given buffer.
+ */
+
+ while (count > 0)
+ {
+ i = lut[0][0][pixels[0]] +
+ lut[1][0][pixels[1]] +
+ lut[2][0][pixels[2]];
+ if (i < 0)
+ pixels[0] = 0;
+ else if (i > 255)
+ pixels[0] = 255;
+ else
+ pixels[0] = i;
+
+ i = lut[0][1][pixels[0]] +
+ lut[1][1][pixels[1]] +
+ lut[2][1][pixels[2]];
+ if (i < 0)
+ pixels[1] = 0;
+ else if (i > 255)
+ pixels[1] = 255;
+ else
+ pixels[1] = i;
+
+ i = lut[0][2][pixels[0]] +
+ lut[1][2][pixels[1]] +
+ lut[2][2][pixels[2]];
+ if (i < 0)
+ pixels[2] = 0;
+ else if (i > 255)
+ pixels[2] = 255;
+ else
+ pixels[2] = i;
+
+ count --;
+ pixels += 3;
+ }
+}
+
+
+/*
+ * 'cupsImageRGBToBlack()' - Convert RGB data to black.
+ */
+
+void
+cupsImageRGBToBlack(
+ const cups_ib_t *in, /* I - Input pixels */
+ cups_ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ if (cupsImageHaveProfile)
+ while (count > 0)
+ {
+ *out++ = cupsImageDensity[255 - (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100];
+ in += 3;
+ count --;
+ }
+ else
+ while (count > 0)
+ {
+ *out++ = 255 - (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100;
+ in += 3;
+ count --;
+ }
+}
+
+
+/*
+ * 'cupsImageRGBToCMY()' - Convert RGB colors to CMY.
+ */
+
+void
+cupsImageRGBToCMY(
+ const cups_ib_t *in, /* I - Input pixels */
+ cups_ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ int c, m, y, k; /* CMYK values */
+ int cc, cm, cy; /* Calibrated CMY values */
+
+
+ if (cupsImageHaveProfile)
+ while (count > 0)
+ {
+ c = 255 - *in++;
+ m = 255 - *in++;
+ y = 255 - *in++;
+ k = min(c, min(m, y));
+ c -= k;
+ m -= k;
+ y -= k;
+
+ cc = cupsImageMatrix[0][0][c] +
+ cupsImageMatrix[0][1][m] +
+ cupsImageMatrix[0][2][y] + k;
+ cm = cupsImageMatrix[1][0][c] +
+ cupsImageMatrix[1][1][m] +
+ cupsImageMatrix[1][2][y] + k;
+ cy = cupsImageMatrix[2][0][c] +
+ cupsImageMatrix[2][1][m] +
+ cupsImageMatrix[2][2][y] + k;
+
+ if (cc < 0)
+ *out++ = 0;
+ else if (cc > 255)
+ *out++ = cupsImageDensity[255];
+ else
+ *out++ = cupsImageDensity[cc];
+
+ if (cm < 0)
+ *out++ = 0;
+ else if (cm > 255)
+ *out++ = cupsImageDensity[255];
+ else
+ *out++ = cupsImageDensity[cm];
+
+ if (cy < 0)
+ *out++ = 0;
+ else if (cy > 255)
+ *out++ = cupsImageDensity[255];
+ else
+ *out++ = cupsImageDensity[cy];
+
+ count --;
+ }
+ else
+ while (count > 0)
+ {
+ c = 255 - in[0];
+ m = 255 - in[1];
+ y = 255 - in[2];
+ k = min(c, min(m, y));
+
+ *out++ = (255 - in[1] / 4) * (c - k) / 255 + k;
+ *out++ = (255 - in[2] / 4) * (m - k) / 255 + k;
+ *out++ = (255 - in[0] / 4) * (y - k) / 255 + k;
+ in += 3;
+ count --;
+ }
+}
+
+
+/*
+ * 'cupsImageRGBToCMYK()' - Convert RGB colors to CMYK.
+ */
+
+void
+cupsImageRGBToCMYK(
+ const cups_ib_t *in, /* I - Input pixels */
+ cups_ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ int c, m, y, k, /* CMYK values */
+ km; /* Maximum K value */
+ int cc, cm, cy; /* Calibrated CMY values */
+
+
+ if (cupsImageHaveProfile)
+ while (count > 0)
+ {
+ c = 255 - *in++;
+ m = 255 - *in++;
+ y = 255 - *in++;
+ k = min(c, min(m, y));
+
+ if ((km = max(c, max(m, y))) > k)
+ k = k * k * k / (km * km);
+
+ c -= k;
+ m -= k;
+ y -= k;
+
+ cc = (cupsImageMatrix[0][0][c] +
+ cupsImageMatrix[0][1][m] +
+ cupsImageMatrix[0][2][y]);
+ cm = (cupsImageMatrix[1][0][c] +
+ cupsImageMatrix[1][1][m] +
+ cupsImageMatrix[1][2][y]);
+ cy = (cupsImageMatrix[2][0][c] +
+ cupsImageMatrix[2][1][m] +
+ cupsImageMatrix[2][2][y]);
+
+ if (cc < 0)
+ *out++ = 0;
+ else if (cc > 255)
+ *out++ = cupsImageDensity[255];
+ else
+ *out++ = cupsImageDensity[cc];
+
+ if (cm < 0)
+ *out++ = 0;
+ else if (cm > 255)
+ *out++ = cupsImageDensity[255];
+ else
+ *out++ = cupsImageDensity[cm];
+
+ if (cy < 0)
+ *out++ = 0;
+ else if (cy > 255)
+ *out++ = cupsImageDensity[255];
+ else
+ *out++ = cupsImageDensity[cy];
+
+ *out++ = cupsImageDensity[k];
+
+ count --;
+ }
+ else
+ while (count > 0)
+ {
+ c = 255 - *in++;
+ m = 255 - *in++;
+ y = 255 - *in++;
+ k = min(c, min(m, y));
+
+ if ((km = max(c, max(m, y))) > k)
+ k = k * k * k / (km * km);
+
+ c -= k;
+ m -= k;
+ y -= k;
+
+ *out++ = c;
+ *out++ = m;
+ *out++ = y;
+ *out++ = k;
+
+ count --;
+ }
+}
+
+
+/*
+ * 'cupsImageRGBToRGB()' - Convert RGB colors to device-dependent RGB.
+ */
+
+void
+cupsImageRGBToRGB(
+ const cups_ib_t *in, /* I - Input pixels */
+ cups_ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ int c, m, y, k; /* CMYK values */
+ int cr, cg, cb; /* Calibrated RGB values */
+
+
+ if (cupsImageHaveProfile)
+ {
+ while (count > 0)
+ {
+ c = 255 - *in++;
+ m = 255 - *in++;
+ y = 255 - *in++;
+ k = min(c, min(m, y));
+ c -= k;
+ m -= k;
+ y -= k;
+
+ cr = cupsImageMatrix[0][0][c] +
+ cupsImageMatrix[0][1][m] +
+ cupsImageMatrix[0][2][y] + k;
+ cg = cupsImageMatrix[1][0][c] +
+ cupsImageMatrix[1][1][m] +
+ cupsImageMatrix[1][2][y] + k;
+ cb = cupsImageMatrix[2][0][c] +
+ cupsImageMatrix[2][1][m] +
+ cupsImageMatrix[2][2][y] + k;
+
+ if (cr < 0)
+ *out++ = 255;
+ else if (cr > 255)
+ *out++ = 255 - cupsImageDensity[255];
+ else
+ *out++ = 255 - cupsImageDensity[cr];
+
+ if (cg < 0)
+ *out++ = 255;
+ else if (cg > 255)
+ *out++ = 255 - cupsImageDensity[255];
+ else
+ *out++ = 255 - cupsImageDensity[cg];
+
+ if (cb < 0)
+ *out++ = 255;
+ else if (cb > 255)
+ *out++ = 255 - cupsImageDensity[255];
+ else
+ *out++ = 255 - cupsImageDensity[cb];
+
+ count --;
+ }
+ }
+ else
+ {
+ if (in != out)
+ memcpy(out, in, count * 3);
+
+ if (cupsImageColorSpace == CUPS_CSPACE_CIELab ||
+ cupsImageColorSpace >= CUPS_CSPACE_ICC1)
+ {
+ while (count > 0)
+ {
+ rgb_to_lab(out);
+
+ out += 3;
+ count --;
+ }
+ }
+ else if (cupsImageColorSpace == CUPS_CSPACE_CIEXYZ)
+ {
+ while (count > 0)
+ {
+ rgb_to_xyz(out);
+
+ out += 3;
+ count --;
+ }
+ }
+ }
+}
+
+
+/*
+ * 'cupsImageRGBToWhite()' - Convert RGB colors to luminance.
+ */
+
+void
+cupsImageRGBToWhite(
+ const cups_ib_t *in, /* I - Input pixels */
+ cups_ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ if (cupsImageHaveProfile)
+ {
+ while (count > 0)
+ {
+ *out++ = 255 - cupsImageDensity[255 - (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100];
+ in += 3;
+ count --;
+ }
+ }
+ else
+ {
+ while (count > 0)
+ {
+ *out++ = (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100;
+ in += 3;
+ count --;
+ }
+ }
+}
+
+
+/*
+ * 'cupsImageSetProfile()' - Set the device color profile.
+ */
+
+void
+cupsImageSetProfile(float d, /* I - Ink/marker density */
+ float g, /* I - Ink/marker gamma */
+ float matrix[3][3]) /* I - Color transform matrix */
+{
+ int i, j, k; /* Looping vars */
+ float m; /* Current matrix value */
+ int *im; /* Pointer into cupsImageMatrix */
+
+
+ /*
+ * Allocate memory for the profile data...
+ */
+
+ if (cupsImageMatrix == NULL)
+ cupsImageMatrix = calloc(3, sizeof(cups_clut_t));
+
+ if (cupsImageMatrix == NULL)
+ return;
+
+ if (cupsImageDensity == NULL)
+ cupsImageDensity = calloc(256, sizeof(int));
+
+ if (cupsImageDensity == NULL)
+ return;
+
+ /*
+ * Populate the profile lookup tables...
+ */
+
+ cupsImageHaveProfile = 1;
+
+ for (i = 0, im = cupsImageMatrix[0][0]; i < 3; i ++)
+ for (j = 0; j < 3; j ++)
+ for (k = 0, m = matrix[i][j]; k < 256; k ++)
+ *im++ = (int)(k * m + 0.5);
+
+ for (k = 0, im = cupsImageDensity; k < 256; k ++)
+ *im++ = 255.0 * d * pow((float)k / 255.0, g) + 0.5;
+}
+
+
+/*
+ * 'cupsImageSetRasterColorSpace()' - Set the destination colorspace.
+ */
+
+void
+cupsImageSetRasterColorSpace(
+ cups_cspace_t cs) /* I - Destination colorspace */
+{
+ /*
+ * Set the destination colorspace...
+ */
+
+ cupsImageColorSpace = cs;
+
+ /*
+ * Don't use color profiles in colorimetric colorspaces...
+ */
+
+ if (cs == CUPS_CSPACE_CIEXYZ ||
+ cs == CUPS_CSPACE_CIELab ||
+ cs >= CUPS_CSPACE_ICC1)
+ cupsImageHaveProfile = 0;
+}
+
+
+/*
+ * 'cupsImageWhiteToBlack()' - Convert luminance colors to black.
+ */
+
+void
+cupsImageWhiteToBlack(
+ const cups_ib_t *in, /* I - Input pixels */
+ cups_ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ if (cupsImageHaveProfile)
+ while (count > 0)
+ {
+ *out++ = cupsImageDensity[255 - *in++];
+ count --;
+ }
+ else
+ while (count > 0)
+ {
+ *out++ = 255 - *in++;
+ count --;
+ }
+}
+
+
+/*
+ * 'cupsImageWhiteToCMY()' - Convert luminance colors to CMY.
+ */
+
+void
+cupsImageWhiteToCMY(
+ const cups_ib_t *in, /* I - Input pixels */
+ cups_ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ if (cupsImageHaveProfile)
+ while (count > 0)
+ {
+ out[0] = cupsImageDensity[255 - *in++];
+ out[1] = out[0];
+ out[2] = out[0];
+ out += 3;
+ count --;
+ }
+ else
+ while (count > 0)
+ {
+ *out++ = 255 - *in;
+ *out++ = 255 - *in;
+ *out++ = 255 - *in++;
+ count --;
+ }
+}
+
+
+/*
+ * 'cupsImageWhiteToCMYK()' - Convert luminance colors to CMYK.
+ */
+
+void
+cupsImageWhiteToCMYK(
+ const cups_ib_t *in, /* I - Input pixels */
+ cups_ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ if (cupsImageHaveProfile)
+ while (count > 0)
+ {
+ *out++ = 0;
+ *out++ = 0;
+ *out++ = 0;
+ *out++ = cupsImageDensity[255 - *in++];
+ count --;
+ }
+ else
+ while (count > 0)
+ {
+ *out++ = 0;
+ *out++ = 0;
+ *out++ = 0;
+ *out++ = 255 - *in++;
+ count --;
+ }
+}
+
+
+/*
+ * 'cupsImageWhiteToRGB()' - Convert luminance data to RGB.
+ */
+
+void
+cupsImageWhiteToRGB(
+ const cups_ib_t *in, /* I - Input pixels */
+ cups_ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ if (cupsImageHaveProfile)
+ {
+ while (count > 0)
+ {
+ out[0] = 255 - cupsImageDensity[255 - *in++];
+ out[1] = out[0];
+ out[2] = out[0];
+ out += 3;
+ count --;
+ }
+ }
+ else
+ {
+ while (count > 0)
+ {
+ *out++ = *in;
+ *out++ = *in;
+ *out++ = *in++;
+
+ if (cupsImageColorSpace == CUPS_CSPACE_CIELab ||
+ cupsImageColorSpace >= CUPS_CSPACE_ICC1)
+ rgb_to_lab(out - 3);
+ else if (cupsImageColorSpace == CUPS_CSPACE_CIEXYZ)
+ rgb_to_xyz(out - 3);
+
+ count --;
+ }
+ }
+}
+
+
+/*
+ * 'cupsImageWhiteToWhite()' - Convert luminance colors to device-dependent
+ * luminance.
+ */
+
+void
+cupsImageWhiteToWhite(
+ const cups_ib_t *in, /* I - Input pixels */
+ cups_ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ if (cupsImageHaveProfile)
+ while (count > 0)
+ {
+ *out++ = 255 - cupsImageDensity[255 - *in++];
+ count --;
+ }
+ else if (in != out)
+ memcpy(out, in, count);
+}
+
+
+/*
+ * 'cielab()' - Map CIE Lab transformation...
+ */
+
+static float /* O - Adjusted color value */
+cielab(float x, /* I - Raw color value */
+ float xn) /* I - Whitepoint color value */
+{
+ float x_xn; /* Fraction of whitepoint */
+
+
+ x_xn = x / xn;
+
+ if (x_xn > 0.008856)
+ return (cbrt(x_xn));
+ else
+ return (7.787 * x_xn + 16.0 / 116.0);
+}
+
+
+/*
+ * 'huerotate()' - Rotate the hue, maintaining luminance.
+ */
+
+static void
+huerotate(float mat[3][3], /* I - Matrix to append to */
+ float rot) /* I - Hue rotation in degrees */
+{
+ float hmat[3][3]; /* Hue matrix */
+ float lx, ly, lz; /* Luminance vector */
+ float xrs, xrc; /* X rotation sine/cosine */
+ float yrs, yrc; /* Y rotation sine/cosine */
+ float zrs, zrc; /* Z rotation sine/cosine */
+ float zsx, zsy; /* Z shear x/y */
+
+
+ /*
+ * Load the identity matrix...
+ */
+
+ ident(hmat);
+
+ /*
+ * Rotate the grey vector into positive Z...
+ */
+
+ xrs = M_SQRT1_2;
+ xrc = M_SQRT1_2;
+ xrotate(hmat,xrs,xrc);
+
+ yrs = -1.0 / sqrt(3.0);
+ yrc = -M_SQRT2 * yrs;
+ yrotate(hmat,yrs,yrc);
+
+ /*
+ * Shear the space to make the luminance plane horizontal...
+ */
+
+ xform(hmat, 0.3086, 0.6094, 0.0820, &lx, &ly, &lz);
+ zsx = lx / lz;
+ zsy = ly / lz;
+ zshear(hmat, zsx, zsy);
+
+ /*
+ * Rotate the hue...
+ */
+
+ zrs = sin(rot * M_PI / 180.0);
+ zrc = cos(rot * M_PI / 180.0);
+
+ zrotate(hmat, zrs, zrc);
+
+ /*
+ * Unshear the space to put the luminance plane back...
+ */
+
+ zshear(hmat, -zsx, -zsy);
+
+ /*
+ * Rotate the grey vector back into place...
+ */
+
+ yrotate(hmat, -yrs, yrc);
+ xrotate(hmat, -xrs, xrc);
+
+ /*
+ * Append it to the current matrix...
+ */
+
+ mult(hmat, mat, mat);
+}
+
+
+/*
+ * 'ident()' - Make an identity matrix.
+ */
+
+static void
+ident(float mat[3][3]) /* I - Matrix to identify */
+{
+ mat[0][0] = 1.0;
+ mat[0][1] = 0.0;
+ mat[0][2] = 0.0;
+ mat[1][0] = 0.0;
+ mat[1][1] = 1.0;
+ mat[1][2] = 0.0;
+ mat[2][0] = 0.0;
+ mat[2][1] = 0.0;
+ mat[2][2] = 1.0;
+}
+
+
+/*
+ * 'mult()' - Multiply two matrices.
+ */
+
+static void
+mult(float a[3][3], /* I - First matrix */
+ float b[3][3], /* I - Second matrix */
+ float c[3][3]) /* I - Destination matrix */
+{
+ int x, y; /* Looping vars */
+ float temp[3][3]; /* Temporary matrix */
+
+
+ /*
+ * Multiply a and b, putting the result in temp...
+ */
+
+ for (y = 0; y < 3; y ++)
+ for (x = 0; x < 3; x ++)
+ temp[y][x] = b[y][0] * a[0][x] +
+ b[y][1] * a[1][x] +
+ b[y][2] * a[2][x];
+
+ /*
+ * Copy temp to c (that way c can be a pointer to a or b).
+ */
+
+ memcpy(c, temp, sizeof(temp));
+}
+
+
+/*
+ * 'rgb_to_lab()' - Convert an RGB color to CIE Lab.
+ */
+
+static void
+rgb_to_lab(cups_ib_t *val) /* IO - Color value */
+{
+ float r, /* Red value */
+ g, /* Green value */
+ b, /* Blue value */
+ ciex, /* CIE X value */
+ ciey, /* CIE Y value */
+ ciez, /* CIE Z value */
+ ciey_yn, /* Normalized luminance */
+ ciel, /* CIE L value */
+ ciea, /* CIE a value */
+ cieb; /* CIE b value */
+
+
+ /*
+ * Convert sRGB to linear RGB...
+ */
+
+ r = pow((val[0] / 255.0 + 0.055) / 1.055, 2.4);
+ g = pow((val[1] / 255.0 + 0.055) / 1.055, 2.4);
+ b = pow((val[2] / 255.0 + 0.055) / 1.055, 2.4);
+
+ /*
+ * Convert to CIE XYZ...
+ */
+
+ ciex = 0.412453 * r + 0.357580 * g + 0.180423 * b;
+ ciey = 0.212671 * r + 0.715160 * g + 0.072169 * b;
+ ciez = 0.019334 * r + 0.119193 * g + 0.950227 * b;
+
+ /*
+ * Normalize and convert to CIE Lab...
+ */
+
+ ciey_yn = ciey / D65_Y;
+
+ if (ciey_yn > 0.008856)
+ ciel = 116 * cbrt(ciey_yn) - 16;
+ else
+ ciel = 903.3 * ciey_yn;
+
+/*ciel = ciel;*/
+ ciea = 500 * (cielab(ciex, D65_X) - cielab(ciey, D65_Y));
+ cieb = 200 * (cielab(ciey, D65_Y) - cielab(ciez, D65_Z));
+
+ /*
+ * Scale the L value and bias the a and b values by 128 so that all
+ * numbers are from 0 to 255.
+ */
+
+ ciel = ciel * 2.55 + 0.5;
+ ciea += 128.5;
+ cieb += 128.5;
+
+ /*
+ * Output 8-bit values...
+ */
+
+ if (ciel < 0.0)
+ val[0] = 0;
+ else if (ciel < 255.0)
+ val[0] = (int)ciel;
+ else
+ val[0] = 255;
+
+ if (ciea < 0.0)
+ val[1] = 0;
+ else if (ciea < 255.0)
+ val[1] = (int)ciea;
+ else
+ val[1] = 255;
+
+ if (cieb < 0.0)
+ val[2] = 0;
+ else if (cieb < 255.0)
+ val[2] = (int)cieb;
+ else
+ val[2] = 255;
+}
+
+
+/*
+ * 'rgb_to_xyz()' - Convert an RGB color to CIE XYZ.
+ */
+
+static void
+rgb_to_xyz(cups_ib_t *val) /* IO - Color value */
+{
+ float r, /* Red value */
+ g, /* Green value */
+ b, /* Blue value */
+ ciex, /* CIE X value */
+ ciey, /* CIE Y value */
+ ciez; /* CIE Z value */
+
+
+ /*
+ * Convert sRGB to linear RGB...
+ */
+
+ r = pow((val[0] / 255.0 + 0.055) / 1.055, 2.4);
+ g = pow((val[1] / 255.0 + 0.055) / 1.055, 2.4);
+ b = pow((val[2] / 255.0 + 0.055) / 1.055, 2.4);
+
+ /*
+ * Convert to CIE XYZ...
+ */
+
+ ciex = 0.412453 * r + 0.357580 * g + 0.180423 * b;
+ ciey = 0.212671 * r + 0.715160 * g + 0.072169 * b;
+ ciez = 0.019334 * r + 0.119193 * g + 0.950227 * b;
+
+ /*
+ * Encode as 8-bit XYZ...
+ */
+
+ if (ciex < 0.0f)
+ val[0] = 0;
+ else if (ciex < 1.1f)
+ val[0] = (int)(231.8181f * ciex + 0.5);
+ else
+ val[0] = 255;
+
+ if (ciey < 0.0f)
+ val[1] = 0;
+ else if (ciey < 1.1f)
+ val[1] = (int)(231.8181f * ciey + 0.5);
+ else
+ val[1] = 255;
+
+ if (ciez < 0.0f)
+ val[2] = 0;
+ else if (ciez < 1.1f)
+ val[2] = (int)(231.8181f * ciez + 0.5);
+ else
+ val[2] = 255;
+}
+
+
+/*
+ * 'saturate()' - Make a saturation matrix.
+ */
+
+static void
+saturate(float mat[3][3], /* I - Matrix to append to */
+ float sat) /* I - Desired color saturation */
+{
+ float smat[3][3]; /* Saturation matrix */
+
+
+ smat[0][0] = (1.0 - sat) * 0.3086 + sat;
+ smat[0][1] = (1.0 - sat) * 0.3086;
+ smat[0][2] = (1.0 - sat) * 0.3086;
+ smat[1][0] = (1.0 - sat) * 0.6094;
+ smat[1][1] = (1.0 - sat) * 0.6094 + sat;
+ smat[1][2] = (1.0 - sat) * 0.6094;
+ smat[2][0] = (1.0 - sat) * 0.0820;
+ smat[2][1] = (1.0 - sat) * 0.0820;
+ smat[2][2] = (1.0 - sat) * 0.0820 + sat;
+
+ mult(smat, mat, mat);
+}
+
+
+/*
+ * 'xform()' - Transform a 3D point using a matrix...
+ */
+
+static void
+xform(float mat[3][3], /* I - Matrix */
+ float x, /* I - Input X coordinate */
+ float y, /* I - Input Y coordinate */
+ float z, /* I - Input Z coordinate */
+ float *tx, /* O - Output X coordinate */
+ float *ty, /* O - Output Y coordinate */
+ float *tz) /* O - Output Z coordinate */
+{
+ *tx = x * mat[0][0] + y * mat[1][0] + z * mat[2][0];
+ *ty = x * mat[0][1] + y * mat[1][1] + z * mat[2][1];
+ *tz = x * mat[0][2] + y * mat[1][2] + z * mat[2][2];
+}
+
+
+/*
+ * 'xrotate()' - Rotate about the x (red) axis...
+ */
+
+static void
+xrotate(float mat[3][3], /* I - Matrix */
+ float rs, /* I - Rotation angle sine */
+ float rc) /* I - Rotation angle cosine */
+{
+ float rmat[3][3]; /* I - Rotation matrix */
+
+
+ rmat[0][0] = 1.0;
+ rmat[0][1] = 0.0;
+ rmat[0][2] = 0.0;
+
+ rmat[1][0] = 0.0;
+ rmat[1][1] = rc;
+ rmat[1][2] = rs;
+
+ rmat[2][0] = 0.0;
+ rmat[2][1] = -rs;
+ rmat[2][2] = rc;
+
+ mult(rmat, mat, mat);
+}
+
+
+/*
+ * 'yrotate()' - Rotate about the y (green) axis...
+ */
+
+static void
+yrotate(float mat[3][3], /* I - Matrix */
+ float rs, /* I - Rotation angle sine */
+ float rc) /* I - Rotation angle cosine */
+{
+ float rmat[3][3]; /* I - Rotation matrix */
+
+
+ rmat[0][0] = rc;
+ rmat[0][1] = 0.0;
+ rmat[0][2] = -rs;
+
+ rmat[1][0] = 0.0;
+ rmat[1][1] = 1.0;
+ rmat[1][2] = 0.0;
+
+ rmat[2][0] = rs;
+ rmat[2][1] = 0.0;
+ rmat[2][2] = rc;
+
+ mult(rmat,mat,mat);
+}
+
+
+/*
+ * 'zrotate()' - Rotate about the z (blue) axis...
+ */
+
+static void
+zrotate(float mat[3][3], /* I - Matrix */
+ float rs, /* I - Rotation angle sine */
+ float rc) /* I - Rotation angle cosine */
+{
+ float rmat[3][3]; /* I - Rotation matrix */
+
+
+ rmat[0][0] = rc;
+ rmat[0][1] = rs;
+ rmat[0][2] = 0.0;
+
+ rmat[1][0] = -rs;
+ rmat[1][1] = rc;
+ rmat[1][2] = 0.0;
+
+ rmat[2][0] = 0.0;
+ rmat[2][1] = 0.0;
+ rmat[2][2] = 1.0;
+
+ mult(rmat,mat,mat);
+}
+
+
+/*
+ * 'zshear()' - Shear z using x and y...
+ */
+
+static void
+zshear(float mat[3][3], /* I - Matrix */
+ float dx, /* I - X shear */
+ float dy) /* I - Y shear */
+{
+ float smat[3][3]; /* Shear matrix */
+
+
+ smat[0][0] = 1.0;
+ smat[0][1] = 0.0;
+ smat[0][2] = dx;
+
+ smat[1][0] = 0.0;
+ smat[1][1] = 1.0;
+ smat[1][2] = dy;
+
+ smat[2][0] = 0.0;
+ smat[2][1] = 0.0;
+ smat[2][2] = 1.0;
+
+ mult(smat, mat, mat);
+}
+
diff --git a/cupsfilters/image-gif.c b/cupsfilters/image-gif.c
new file mode 100644
index 000000000..53cd86a52
--- /dev/null
+++ b/cupsfilters/image-gif.c
@@ -0,0 +1,689 @@
+/*
+ * GIF image routines for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2007 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * _cupsImageReadGIF() - Read a GIF image file.
+ * gif_get_block() - Read a GIF data block...
+ * gif_get_code() - Get a LZW code from the file...
+ * gif_read_cmap() - Read the colormap from a GIF file...
+ * gif_read_image() - Read a GIF image stream...
+ * gif_read_lzw() - Read a byte from the LZW stream...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image-private.h"
+
+
+/*
+ * GIF definitions...
+ */
+
+#define GIF_INTERLACE 0x40
+#define GIF_COLORMAP 0x80
+#define GIF_MAX_BITS 12
+
+typedef cups_ib_t gif_cmap_t[256][4];
+typedef short gif_table_t[4096];
+
+
+/*
+ * Local globals...
+ */
+
+static int gif_eof = 0; /* Did we hit EOF? */
+
+
+/*
+ * Local functions...
+ */
+
+static int gif_get_block(FILE *fp, unsigned char *buffer);
+static int gif_get_code (FILE *fp, int code_size, int first_time);
+static int gif_read_cmap(FILE *fp, int ncolors, gif_cmap_t cmap,
+ int *gray);
+static int gif_read_image(FILE *fp, cups_image_t *img, gif_cmap_t cmap,
+ int interlace);
+static int gif_read_lzw(FILE *fp, int first_time, int input_code_size);
+
+
+/*
+ * '_cupsImageReadGIF()' - Read a GIF image file.
+ */
+
+int /* O - Read status */
+_cupsImageReadGIF(
+ cups_image_t *img, /* IO - cupsImage */
+ FILE *fp, /* I - cupsImage file */
+ cups_icspace_t primary, /* I - Primary choice for colorspace */
+ cups_icspace_t secondary, /* I - Secondary choice for colorspace */
+ int saturation, /* I - Color saturation (%) */
+ int hue, /* I - Color hue (degrees) */
+ const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */
+{
+ unsigned char buf[1024]; /* Input buffer */
+ gif_cmap_t cmap; /* Colormap */
+ int i, /* Looping var */
+ bpp, /* Bytes per pixel */
+ gray, /* Grayscale image? */
+ ncolors, /* Bits per pixel */
+ transparent; /* Transparent color index */
+
+
+ /*
+ * GIF files are either grayscale or RGB - no CMYK...
+ */
+
+ if (primary == CUPS_IMAGE_RGB_CMYK)
+ primary = CUPS_IMAGE_RGB;
+
+ /*
+ * Read the header; we already know it is a GIF file...
+ */
+
+ if (fread(buf, 13, 1, fp) == 0 && ferror(fp))
+ DEBUG_printf(("Error reading file!"));
+
+ img->xsize = (buf[7] << 8) | buf[6];
+ img->ysize = (buf[9] << 8) | buf[8];
+ ncolors = 2 << (buf[10] & 0x07);
+ gray = primary == CUPS_IMAGE_BLACK || primary == CUPS_IMAGE_WHITE;
+
+ if (buf[10] & GIF_COLORMAP)
+ if (gif_read_cmap(fp, ncolors, cmap, &gray))
+ {
+ fclose(fp);
+ return (-1);
+ }
+
+ transparent = -1;
+
+ for (;;)
+ {
+ switch (getc(fp))
+ {
+ case ';' : /* End of image */
+ fclose(fp);
+ return (-1); /* Early end of file */
+
+ case '!' : /* Extension record */
+ buf[0] = getc(fp);
+ if (buf[0] == 0xf9) /* Graphic Control Extension */
+ {
+ gif_get_block(fp, buf);
+ if (buf[0] & 1) /* Get transparent color index */
+ transparent = buf[3];
+ }
+
+ while (gif_get_block(fp, buf) != 0);
+ break;
+
+ case ',' : /* cupsImage data */
+ if (fread(buf, 9, 1, fp) == 0 && ferror(fp))
+ DEBUG_printf(("Error reading file!"));
+
+ if (buf[8] & GIF_COLORMAP)
+ {
+ ncolors = 2 << (buf[8] & 0x07);
+ gray = primary == CUPS_IMAGE_BLACK || primary == CUPS_IMAGE_WHITE;
+
+ if (gif_read_cmap(fp, ncolors, cmap, &gray))
+ {
+ fclose(fp);
+ return (-1);
+ }
+ }
+
+ if (transparent >= 0)
+ {
+ /*
+ * Make transparent color white...
+ */
+
+ cmap[transparent][0] = 255;
+ cmap[transparent][1] = 255;
+ cmap[transparent][2] = 255;
+ }
+
+ if (gray)
+ {
+ switch (secondary)
+ {
+ case CUPS_IMAGE_CMYK :
+ for (i = ncolors - 1; i >= 0; i --)
+ cupsImageWhiteToCMYK(cmap[i], cmap[i], 1);
+ break;
+ case CUPS_IMAGE_CMY :
+ for (i = ncolors - 1; i >= 0; i --)
+ cupsImageWhiteToCMY(cmap[i], cmap[i], 1);
+ break;
+ case CUPS_IMAGE_BLACK :
+ for (i = ncolors - 1; i >= 0; i --)
+ cupsImageWhiteToBlack(cmap[i], cmap[i], 1);
+ break;
+ case CUPS_IMAGE_WHITE :
+ break;
+ case CUPS_IMAGE_RGB :
+ case CUPS_IMAGE_RGB_CMYK :
+ for (i = ncolors - 1; i >= 0; i --)
+ cupsImageWhiteToRGB(cmap[i], cmap[i], 1);
+ break;
+ }
+
+ img->colorspace = secondary;
+ }
+ else
+ {
+ if (hue != 0 || saturation != 100)
+ for (i = ncolors - 1; i >= 0; i --)
+ cupsImageRGBAdjust(cmap[i], 1, saturation, hue);
+
+ switch (primary)
+ {
+ case CUPS_IMAGE_CMYK :
+ for (i = ncolors - 1; i >= 0; i --)
+ cupsImageRGBToCMYK(cmap[i], cmap[i], 1);
+ break;
+ case CUPS_IMAGE_CMY :
+ for (i = ncolors - 1; i >= 0; i --)
+ cupsImageRGBToCMY(cmap[i], cmap[i], 1);
+ break;
+ case CUPS_IMAGE_BLACK :
+ for (i = ncolors - 1; i >= 0; i --)
+ cupsImageRGBToBlack(cmap[i], cmap[i], 1);
+ break;
+ case CUPS_IMAGE_WHITE :
+ for (i = ncolors - 1; i >= 0; i --)
+ cupsImageRGBToWhite(cmap[i], cmap[i], 1);
+ break;
+ case CUPS_IMAGE_RGB :
+ case CUPS_IMAGE_RGB_CMYK :
+ for (i = ncolors - 1; i >= 0; i --)
+ cupsImageRGBToRGB(cmap[i], cmap[i], 1);
+ break;
+ }
+
+ img->colorspace = primary;
+ }
+
+ if (lut)
+ {
+ bpp = cupsImageGetDepth(img);
+
+ for (i = ncolors - 1; i >= 0; i --)
+ cupsImageLut(cmap[i], bpp, lut);
+ }
+
+ img->xsize = (buf[5] << 8) | buf[4];
+ img->ysize = (buf[7] << 8) | buf[6];
+
+ /*
+ * Check the dimensions of the image; since the dimensions are
+ * a 16-bit integer we just need to check for 0...
+ */
+
+ if (img->xsize == 0 || img->ysize == 0)
+ {
+ fprintf(stderr, "DEBUG: Bad GIF image dimensions: %dx%d\n",
+ img->xsize, img->ysize);
+ fclose(fp);
+ return (1);
+ }
+
+ i = gif_read_image(fp, img, cmap, buf[8] & GIF_INTERLACE);
+ fclose(fp);
+ return (i);
+ }
+ }
+}
+
+
+/*
+ * 'gif_get_block()' - Read a GIF data block...
+ */
+
+static int /* O - Number characters read */
+gif_get_block(FILE *fp, /* I - File to read from */
+ unsigned char *buf) /* I - Input buffer */
+{
+ int count; /* Number of character to read */
+
+
+ /*
+ * Read the count byte followed by the data from the file...
+ */
+
+ if ((count = getc(fp)) == EOF)
+ {
+ gif_eof = 1;
+ return (-1);
+ }
+ else if (count == 0)
+ gif_eof = 1;
+ else if (fread(buf, 1, count, fp) < count)
+ {
+ gif_eof = 1;
+ return (-1);
+ }
+ else
+ gif_eof = 0;
+
+ return (count);
+}
+
+
+/*
+ * 'gif_get_code()' - Get a LZW code from the file...
+ */
+
+static int /* O - LZW code */
+gif_get_code(FILE *fp, /* I - File to read from */
+ int code_size, /* I - Size of code in bits */
+ int first_time) /* I - 1 = first time, 0 = not first time */
+{
+ unsigned i, j, /* Looping vars */
+ ret; /* Return value */
+ int count; /* Number of bytes read */
+ static unsigned char buf[280]; /* Input buffer */
+ static unsigned curbit, /* Current bit */
+ lastbit, /* Last bit in buffer */
+ done, /* Done with this buffer? */
+ last_byte; /* Last byte in buffer */
+ static const unsigned char bits[8] = /* Bit masks for codes */
+ {
+ 0x01, 0x02, 0x04, 0x08,
+ 0x10, 0x20, 0x40, 0x80
+ };
+
+
+ if (first_time)
+ {
+ /*
+ * Just initialize the input buffer...
+ */
+
+ curbit = 0;
+ lastbit = 0;
+ last_byte = 0;
+ done = 0;
+
+ return (0);
+ }
+
+ if ((curbit + code_size) >= lastbit)
+ {
+ /*
+ * Don't have enough bits to hold the code...
+ */
+
+ if (done)
+ return (-1); /* Sorry, no more... */
+
+ /*
+ * Move last two bytes to front of buffer...
+ */
+
+ if (last_byte > 1)
+ {
+ buf[0] = buf[last_byte - 2];
+ buf[1] = buf[last_byte - 1];
+ last_byte = 2;
+ }
+ else if (last_byte == 1)
+ {
+ buf[0] = buf[last_byte - 1];
+ last_byte = 1;
+ }
+
+ /*
+ * Read in another buffer...
+ */
+
+ if ((count = gif_get_block(fp, buf + last_byte)) <= 0)
+ {
+ /*
+ * Whoops, no more data!
+ */
+
+ done = 1;
+ return (-1);
+ }
+
+ /*
+ * Update buffer state...
+ */
+
+ curbit = (curbit - lastbit) + 8 * last_byte;
+ last_byte += count;
+ lastbit = last_byte * 8;
+ }
+
+ for (ret = 0, i = curbit + code_size - 1, j = code_size;
+ j > 0;
+ i --, j --)
+ ret = (ret << 1) | ((buf[i / 8] & bits[i & 7]) != 0);
+
+ curbit += code_size;
+
+ return ret;
+}
+
+
+/*
+ * 'gif_read_cmap()' - Read the colormap from a GIF file...
+ */
+
+static int /* O - -1 on error, 0 on success */
+gif_read_cmap(FILE *fp, /* I - File to read from */
+ int ncolors, /* I - Number of colors in file */
+ gif_cmap_t cmap, /* O - Colormap information */
+ int *gray) /* IO - Is the image grayscale? */
+{
+ int i; /* Looping var */
+
+
+ /*
+ * Read the colormap...
+ */
+
+ for (i = 0; i < ncolors; i ++)
+ if (fread(cmap[i], 3, 1, fp) < 1)
+ return (-1);
+
+ /*
+ * Check to see if the colormap is a grayscale ramp...
+ */
+
+ for (i = 0; i < ncolors; i ++)
+ if (cmap[i][0] != cmap[i][1] || cmap[i][1] != cmap[i][2])
+ break;
+
+ if (i == ncolors)
+ {
+ *gray = 1;
+ return (0);
+ }
+
+ /*
+ * If this needs to be a grayscale image, convert the RGB values to
+ * luminance values...
+ */
+
+ if (*gray)
+ for (i = 0; i < ncolors; i ++)
+ cmap[i][0] = (cmap[i][0] * 31 + cmap[i][1] * 61 + cmap[i][2] * 8) / 100;
+
+ return (0);
+}
+
+
+/*
+ * 'gif_read_image()' - Read a GIF image stream...
+ */
+
+static int /* I - 0 = success, -1 = failure */
+gif_read_image(FILE *fp, /* I - Input file */
+ cups_image_t *img, /* I - cupsImage pointer */
+ gif_cmap_t cmap, /* I - Colormap */
+ int interlace) /* I - Non-zero = interlaced image */
+{
+ unsigned char code_size; /* Code size */
+ cups_ib_t *pixels, /* Pixel buffer */
+ *temp; /* Current pixel */
+ int xpos, /* Current X position */
+ ypos, /* Current Y position */
+ pass; /* Current pass */
+ int pixel; /* Current pixel */
+ int bpp; /* Bytes per pixel */
+ static const int xpasses[4] = /* X interleaving */
+ { 8, 8, 4, 2 },
+ ypasses[5] = /* Y interleaving */
+ { 0, 4, 2, 1, 999999 };
+
+
+ bpp = cupsImageGetDepth(img);
+ pixels = calloc(bpp, img->xsize);
+ xpos = 0;
+ ypos = 0;
+ pass = 0;
+ code_size = getc(fp);
+
+ if (!pixels)
+ return (-1);
+
+ if (code_size > GIF_MAX_BITS || gif_read_lzw(fp, 1, code_size) < 0)
+ {
+ free(pixels);
+ return (-1);
+ }
+
+ temp = pixels;
+ while ((pixel = gif_read_lzw(fp, 0, code_size)) >= 0)
+ {
+ switch (bpp)
+ {
+ case 4 :
+ temp[3] = cmap[pixel][3];
+ case 3 :
+ temp[2] = cmap[pixel][2];
+ case 2 :
+ temp[1] = cmap[pixel][1];
+ default :
+ temp[0] = cmap[pixel][0];
+ }
+
+ xpos ++;
+ temp += bpp;
+ if (xpos == img->xsize)
+ {
+ _cupsImagePutRow(img, 0, ypos, img->xsize, pixels);
+
+ xpos = 0;
+ temp = pixels;
+
+ if (interlace)
+ {
+ ypos += xpasses[pass];
+
+ if (ypos >= img->ysize)
+ {
+ pass ++;
+
+ ypos = ypasses[pass];
+ }
+ }
+ else
+ ypos ++;
+ }
+
+ if (ypos >= img->ysize)
+ break;
+ }
+
+ free(pixels);
+
+ return (0);
+}
+
+
+/*
+ * 'gif_read_lzw()' - Read a byte from the LZW stream...
+ */
+
+static int /* I - Byte from stream */
+gif_read_lzw(FILE *fp, /* I - File to read from */
+ int first_time, /* I - 1 = first time, 0 = not first time */
+ int input_code_size) /* I - Code size in bits */
+{
+ int i, /* Looping var */
+ code, /* Current code */
+ incode; /* Input code */
+ static short fresh = 0, /* 1 = empty buffers */
+ code_size, /* Current code size */
+ set_code_size, /* Initial code size set */
+ max_code, /* Maximum code used */
+ max_code_size, /* Maximum code size */
+ firstcode, /* First code read */
+ oldcode, /* Last code read */
+ clear_code, /* Clear code for LZW input */
+ end_code, /* End code for LZW input */
+ *stack = NULL, /* Output stack */
+ *sp; /* Current stack pointer */
+ static gif_table_t *table = NULL; /* String table */
+
+
+ if (first_time)
+ {
+ /*
+ * Setup LZW state...
+ */
+
+ set_code_size = input_code_size;
+ code_size = set_code_size + 1;
+ clear_code = 1 << set_code_size;
+ end_code = clear_code + 1;
+ max_code_size = 2 * clear_code;
+ max_code = clear_code + 2;
+
+ /*
+ * Allocate memory for buffers...
+ */
+
+ if (table == NULL)
+ table = calloc(2, sizeof(gif_table_t));
+
+ if (table == NULL)
+ return (-1);
+
+ if (stack == NULL)
+ stack = calloc(8192, sizeof(short));
+
+ if (stack == NULL)
+ return (-1);
+
+ /*
+ * Initialize input buffers...
+ */
+
+ gif_get_code(fp, 0, 1);
+
+ /*
+ * Wipe the decompressor table (already mostly 0 due to the calloc above...)
+ */
+
+ fresh = 1;
+
+ for (i = 1; i < clear_code; i ++)
+ table[1][i] = i;
+
+ sp = stack;
+
+ return (0);
+ }
+ else if (fresh)
+ {
+ fresh = 0;
+
+ do
+ {
+ firstcode = oldcode = gif_get_code(fp, code_size, 0);
+ }
+ while (firstcode == clear_code);
+
+ return (firstcode & 255);
+ }
+ else if (!table)
+ return (0);
+
+ if (sp > stack)
+ return ((*--sp) & 255);
+
+ while ((code = gif_get_code(fp, code_size, 0)) >= 0)
+ {
+ if (code == clear_code)
+ {
+ /*
+ * Clear/reset the compression table...
+ */
+
+ memset(table, 0, 2 * sizeof(gif_table_t));
+ for (i = 1; i < clear_code; i ++)
+ table[1][i] = i;
+
+ code_size = set_code_size + 1;
+ max_code_size = 2 * clear_code;
+ max_code = clear_code + 2;
+
+ sp = stack;
+
+ firstcode = oldcode = gif_get_code(fp, code_size, 0);
+
+ return (firstcode & 255);
+ }
+ else if (code == end_code || code > max_code)
+ {
+ unsigned char buf[260]; /* Block buffer */
+
+ if (!gif_eof)
+ while (gif_get_block(fp, buf) > 0);
+
+ return (-2);
+ }
+
+ incode = code;
+
+ if (code == max_code)
+ {
+ if (sp < (stack + 8192))
+ *sp++ = firstcode;
+
+ code = oldcode;
+ }
+
+ while (code >= clear_code && sp < (stack + 8192))
+ {
+ *sp++ = table[1][code];
+ if (code == table[0][code])
+ return (255);
+
+ code = table[0][code];
+ }
+
+ if (sp < (stack + 8192))
+ *sp++ = firstcode = table[1][code];
+
+ code = max_code;
+
+ if (code < 4096)
+ {
+ table[0][code] = oldcode;
+ table[1][code] = firstcode;
+ max_code ++;
+
+ if (max_code >= max_code_size && max_code_size < 4096)
+ {
+ max_code_size *= 2;
+ code_size ++;
+ }
+ }
+
+ oldcode = incode;
+
+ if (sp > stack)
+ return ((*--sp) & 255);
+ }
+
+ return (code & 255);
+}
+
diff --git a/cupsfilters/image-jpeg.c b/cupsfilters/image-jpeg.c
new file mode 100644
index 000000000..81d9a9d5d
--- /dev/null
+++ b/cupsfilters/image-jpeg.c
@@ -0,0 +1,313 @@
+/*
+ * JPEG image routines for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2007 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * _cupsImageReadJPEG() - Read a JPEG image file.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image-private.h"
+
+#ifdef HAVE_LIBJPEG
+# include <jpeglib.h> /* JPEG/JFIF image definitions */
+
+
+/*
+ * '_cupsImageReadJPEG()' - Read a JPEG image file.
+ */
+
+int /* O - Read status */
+_cupsImageReadJPEG(
+ cups_image_t *img, /* IO - cupsImage */
+ FILE *fp, /* I - cupsImage file */
+ cups_icspace_t primary, /* I - Primary choice for colorspace */
+ cups_icspace_t secondary, /* I - Secondary choice for colorspace */
+ int saturation, /* I - Color saturation (%) */
+ int hue, /* I - Color hue (degrees) */
+ const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */
+{
+ struct jpeg_decompress_struct cinfo; /* Decompressor info */
+ struct jpeg_error_mgr jerr; /* Error handler info */
+ cups_ib_t *in, /* Input pixels */
+ *out; /* Output pixels */
+ jpeg_saved_marker_ptr marker; /* Pointer to marker data */
+ int psjpeg = 0; /* Non-zero if Photoshop CMYK JPEG */
+ static const char *cspaces[] =
+ { /* JPEG colorspaces... */
+ "JCS_UNKNOWN",
+ "JCS_GRAYSCALE",
+ "JCS_RGB",
+ "JCS_YCbCr",
+ "JCS_CMYK",
+ "JCS_YCCK"
+ };
+
+
+ /*
+ * Read the JPEG header...
+ */
+
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_decompress(&cinfo);
+ jpeg_save_markers(&cinfo, JPEG_APP0 + 14, 0xffff); /* Adobe JPEG */
+ jpeg_stdio_src(&cinfo, fp);
+ jpeg_read_header(&cinfo, 1);
+
+ /*
+ * Parse any Adobe APPE data embedded in the JPEG file. Since Adobe doesn't
+ * bother following standards, we have to invert the CMYK JPEG data written by
+ * Adobe apps...
+ */
+
+ for (marker = cinfo.marker_list; marker; marker = marker->next)
+ if (marker->marker == (JPEG_APP0 + 14) && marker->data_length >= 12 &&
+ !memcmp(marker->data, "Adobe", 5))
+ {
+ fputs("DEBUG: Adobe CMYK JPEG detected (inverting color values)\n",
+ stderr);
+ psjpeg = 1;
+ }
+
+ cinfo.quantize_colors = 0;
+
+ fprintf(stderr, "DEBUG: num_components = %d\n", cinfo.num_components);
+ fprintf(stderr, "DEBUG: jpeg_color_space = %s\n",
+ cspaces[cinfo.jpeg_color_space]);
+
+ if (cinfo.num_components == 1)
+ {
+ fputs("DEBUG: Converting image to grayscale...\n", stderr);
+
+ cinfo.out_color_space = JCS_GRAYSCALE;
+ cinfo.out_color_components = 1;
+ cinfo.output_components = 1;
+
+ img->colorspace = secondary;
+ }
+ else if (cinfo.num_components == 4)
+ {
+ fputs("DEBUG: Converting image to CMYK...\n", stderr);
+
+ cinfo.out_color_space = JCS_CMYK;
+ cinfo.out_color_components = 4;
+ cinfo.output_components = 4;
+
+ img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_CMYK : primary;
+ }
+ else
+ {
+ fputs("DEBUG: Converting image to RGB...\n", stderr);
+
+ cinfo.out_color_space = JCS_RGB;
+ cinfo.out_color_components = 3;
+ cinfo.output_components = 3;
+
+ img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary;
+ }
+
+ jpeg_calc_output_dimensions(&cinfo);
+
+ if (cinfo.output_width <= 0 || cinfo.output_width > CUPS_IMAGE_MAX_WIDTH ||
+ cinfo.output_height <= 0 || cinfo.output_height > CUPS_IMAGE_MAX_HEIGHT)
+ {
+ fprintf(stderr, "DEBUG: Bad JPEG dimensions %dx%d!\n",
+ cinfo.output_width, cinfo.output_height);
+
+ jpeg_destroy_decompress(&cinfo);
+
+ fclose(fp);
+ return (1);
+ }
+
+ img->xsize = cinfo.output_width;
+ img->ysize = cinfo.output_height;
+
+ if (cinfo.X_density > 0 && cinfo.Y_density > 0 && cinfo.density_unit > 0)
+ {
+ if (cinfo.density_unit == 1)
+ {
+ img->xppi = cinfo.X_density;
+ img->yppi = cinfo.Y_density;
+ }
+ else
+ {
+ img->xppi = (int)((float)cinfo.X_density * 2.54);
+ img->yppi = (int)((float)cinfo.Y_density * 2.54);
+ }
+
+ if (img->xppi == 0 || img->yppi == 0)
+ {
+ fprintf(stderr, "DEBUG: Bad JPEG image resolution %dx%d PPI.\n",
+ img->xppi, img->yppi);
+ img->xppi = img->yppi = 128;
+ }
+ }
+
+ fprintf(stderr, "DEBUG: JPEG image %dx%dx%d, %dx%d PPI\n",
+ img->xsize, img->ysize, cinfo.output_components,
+ img->xppi, img->yppi);
+
+ cupsImageSetMaxTiles(img, 0);
+
+ in = malloc(img->xsize * cinfo.output_components);
+ out = malloc(img->xsize * cupsImageGetDepth(img));
+
+ jpeg_start_decompress(&cinfo);
+
+ while (cinfo.output_scanline < cinfo.output_height)
+ {
+ jpeg_read_scanlines(&cinfo, (JSAMPROW *)&in, (JDIMENSION)1);
+
+ if (psjpeg && cinfo.output_components == 4)
+ {
+ /*
+ * Invert CMYK data from Photoshop...
+ */
+
+ cups_ib_t *ptr; /* Pointer into buffer */
+ int i; /* Looping var */
+
+
+ for (ptr = in, i = img->xsize * 4; i > 0; i --, ptr ++)
+ *ptr = 255 - *ptr;
+ }
+
+ if ((saturation != 100 || hue != 0) && cinfo.output_components == 3)
+ cupsImageRGBAdjust(in, img->xsize, saturation, hue);
+
+ if ((img->colorspace == CUPS_IMAGE_WHITE && cinfo.out_color_space == JCS_GRAYSCALE) ||
+ (img->colorspace == CUPS_IMAGE_CMYK && cinfo.out_color_space == JCS_CMYK))
+ {
+#ifdef DEBUG
+ int i, j;
+ cups_ib_t *ptr;
+
+
+ fputs("DEBUG: Direct Data...\n", stderr);
+
+ fputs("DEBUG:", stderr);
+
+ for (i = 0, ptr = in; i < img->xsize; i ++)
+ {
+ putc(' ', stderr);
+ for (j = 0; j < cinfo.output_components; j ++, ptr ++)
+ fprintf(stderr, "%02X", *ptr & 255);
+ }
+
+ putc('\n', stderr);
+#endif /* DEBUG */
+
+ if (lut)
+ cupsImageLut(in, img->xsize * cupsImageGetDepth(img), lut);
+
+ _cupsImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, in);
+ }
+ else if (cinfo.out_color_space == JCS_GRAYSCALE)
+ {
+ switch (img->colorspace)
+ {
+ default :
+ break;
+
+ case CUPS_IMAGE_BLACK :
+ cupsImageWhiteToBlack(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_RGB :
+ cupsImageWhiteToRGB(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageWhiteToCMY(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageWhiteToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, img->xsize * cupsImageGetDepth(img), lut);
+
+ _cupsImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, out);
+ }
+ else if (cinfo.out_color_space == JCS_RGB)
+ {
+ switch (img->colorspace)
+ {
+ default :
+ break;
+
+ case CUPS_IMAGE_RGB :
+ cupsImageRGBToRGB(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_WHITE :
+ cupsImageRGBToWhite(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_BLACK :
+ cupsImageRGBToBlack(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageRGBToCMY(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageRGBToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, img->xsize * cupsImageGetDepth(img), lut);
+
+ _cupsImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, out);
+ }
+ else /* JCS_CMYK */
+ {
+ fputs("DEBUG: JCS_CMYK\n", stderr);
+
+ switch (img->colorspace)
+ {
+ default :
+ break;
+
+ case CUPS_IMAGE_WHITE :
+ cupsImageCMYKToWhite(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_BLACK :
+ cupsImageCMYKToBlack(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageCMYKToCMY(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_RGB :
+ cupsImageCMYKToRGB(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, img->xsize * cupsImageGetDepth(img), lut);
+
+ _cupsImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, out);
+ }
+ }
+
+ free(in);
+ free(out);
+
+ jpeg_finish_decompress(&cinfo);
+ jpeg_destroy_decompress(&cinfo);
+
+ fclose(fp);
+
+ return (0);
+}
+#endif /* HAVE_LIBJPEG */
+
diff --git a/cupsfilters/image-photocd.c b/cupsfilters/image-photocd.c
new file mode 100644
index 000000000..9c1bb440f
--- /dev/null
+++ b/cupsfilters/image-photocd.c
@@ -0,0 +1,324 @@
+/*
+ * PhotoCD routines for CUPS.
+ *
+ * PhotoCD support is currently limited to the 768x512 base image, which
+ * is only YCC encoded. Support for the higher resolution images will
+ * require a lot of extra code...
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2006 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * _cupsImageReadPhotoCD() - Read a PhotoCD image file.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image-private.h"
+
+
+/*
+ * '_cupsImageReadPhotoCD()' - Read a PhotoCD image file.
+ */
+
+int /* O - Read status */
+_cupsImageReadPhotoCD(
+ cups_image_t *img, /* IO - cupsImage */
+ FILE *fp, /* I - cupsImage file */
+ cups_icspace_t primary, /* I - Primary choice for colorspace */
+ cups_icspace_t secondary, /* I - Secondary choice for colorspace */
+ int saturation, /* I - Color saturation (%) */
+ int hue, /* I - Color hue (degrees) */
+ const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */
+{
+ int x, y; /* Looping vars */
+ int xdir, /* X direction */
+ xstart; /* X starting point */
+ int bpp; /* Bytes per pixel */
+ int pass; /* Pass number */
+ int rotation; /* 0 for 768x512, 1 for 512x768 */
+ int temp, /* Adjusted luminance */
+ temp2, /* Red, green, and blue values */
+ cb, cr; /* Adjusted chroma values */
+ cups_ib_t *in, /* Input (YCC) pixels */
+ *iy, /* Luminance */
+ *icb, /* Blue chroma */
+ *icr, /* Red chroma */
+ *rgb, /* RGB */
+ *rgbptr, /* Pointer into RGB data */
+ *out; /* Output pixels */
+
+
+ (void)secondary;
+
+ /*
+ * Get the image orientation...
+ */
+
+ fseek(fp, 72, SEEK_SET);
+ rotation = (getc(fp) & 63) != 8;
+
+ /*
+ * Seek to the start of the base image...
+ */
+
+ fseek(fp, 0x30000, SEEK_SET);
+
+ /*
+ * Allocate and initialize...
+ */
+
+ img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary;
+ img->xppi = 128;
+ img->yppi = 128;
+
+ if (rotation)
+ {
+ img->xsize = 512;
+ img->ysize = 768;
+ }
+ else
+ {
+ img->xsize = 768;
+ img->ysize = 512;
+ }
+
+ cupsImageSetMaxTiles(img, 0);
+
+ bpp = cupsImageGetDepth(img);
+
+ if ((in = malloc(768 * 3)) == NULL)
+ {
+ fputs("DEBUG: Unable to allocate memory!\n", stderr);
+ fclose(fp);
+ return (1);
+ }
+
+ if ((out = malloc(768 * bpp)) == NULL)
+ {
+ fputs("DEBUG: Unable to allocate memory!\n", stderr);
+ fclose(fp);
+ free(in);
+ return (1);
+ }
+
+ if (bpp > 1)
+ {
+ if ((rgb = malloc(768 * 3)) == NULL)
+ {
+ fputs("DEBUG: Unable to allocate memory!\n", stderr);
+ fclose(fp);
+ free(in);
+ free(out);
+ return (1);
+ }
+ }
+ else
+ rgb = NULL;
+
+ if (rotation)
+ {
+ xstart = 767 * bpp;
+ xdir = -2 * bpp;
+ }
+ else
+ {
+ xstart = 0;
+ xdir = 0;
+ }
+
+ /*
+ * Read the image file...
+ */
+
+ for (y = 0; y < 512; y += 2)
+ {
+ /*
+ * Grab the next two scanlines:
+ *
+ * YYYYYYYYYYYYYYY...
+ * YYYYYYYYYYYYYYY...
+ * CbCbCb...CrCrCr...
+ */
+
+ if (fread(in, 1, 768 * 3, fp) < (768 * 3))
+ {
+ /*
+ * Couldn't read a row of data - return an error!
+ */
+
+ free(in);
+ free(out);
+
+ if (bpp > 1)
+ free(rgb);
+
+ return (-1);
+ }
+
+ /*
+ * Process the two scanlines...
+ */
+
+ for (pass = 0, iy = in; pass < 2; pass ++)
+ {
+ if (bpp == 1)
+ {
+ /*
+ * Just extract the luminance channel from the line and put it
+ * in the image...
+ */
+
+ if (primary == CUPS_IMAGE_BLACK)
+ {
+ if (rotation)
+ {
+ for (rgbptr = out + xstart, x = 0; x < 768; x ++)
+ *rgbptr-- = 255 - *iy++;
+
+ if (lut)
+ cupsImageLut(out, 768, lut);
+
+ _cupsImagePutCol(img, 511 - y - pass, 0, 768, out);
+ }
+ else
+ {
+ cupsImageWhiteToBlack(iy, out, 768);
+
+ if (lut)
+ cupsImageLut(out, 768, lut);
+
+ _cupsImagePutRow(img, 0, y + pass, 768, out);
+ iy += 768;
+ }
+ }
+ else if (rotation)
+ {
+ for (rgbptr = out + xstart, x = 0; x < 768; x ++)
+ *rgbptr-- = 255 - *iy++;
+
+ if (lut)
+ cupsImageLut(out, 768, lut);
+
+ _cupsImagePutCol(img, 511 - y - pass, 0, 768, out);
+ }
+ else
+ {
+ if (lut)
+ cupsImageLut(iy, 768, lut);
+
+ _cupsImagePutRow(img, 0, y + pass, 768, iy);
+ iy += 768;
+ }
+ }
+ else
+ {
+ /*
+ * Convert YCbCr to RGB... While every pixel gets a luminance
+ * value, adjacent pixels share chroma information.
+ */
+
+ cb = cr = 0.0f;
+
+ for (x = 0, rgbptr = rgb + xstart, icb = in + 1536, icr = in + 1920;
+ x < 768;
+ x ++, iy ++, rgbptr += xdir)
+ {
+ if (!(x & 1))
+ {
+ cb = (float)(*icb - 156);
+ cr = (float)(*icr - 137);
+ }
+
+ temp = 92241 * (*iy);
+
+ temp2 = (temp + 86706 * cr) / 65536;
+ if (temp2 < 0)
+ *rgbptr++ = 0;
+ else if (temp2 > 255)
+ *rgbptr++ = 255;
+ else
+ *rgbptr++ = temp2;
+
+ temp2 = (temp - 25914 * cb - 44166 * cr) / 65536;
+ if (temp2 < 0)
+ *rgbptr++ = 0;
+ else if (temp2 > 255)
+ *rgbptr++ = 255;
+ else
+ *rgbptr++ = temp2;
+
+ temp2 = (temp + 133434 * cb) / 65536;
+ if (temp2 < 0)
+ *rgbptr++ = 0;
+ else if (temp2 > 255)
+ *rgbptr++ = 255;
+ else
+ *rgbptr++ = temp2;
+
+ if (x & 1)
+ {
+ icb ++;
+ icr ++;
+ }
+ }
+
+ /*
+ * Adjust the hue and saturation if needed...
+ */
+
+ if (saturation != 100 || hue != 0)
+ cupsImageRGBAdjust(rgb, 768, saturation, hue);
+
+ /*
+ * Then convert the RGB data to the appropriate colorspace and
+ * put it in the image...
+ */
+
+ switch (img->colorspace)
+ {
+ default :
+ break;
+
+ case CUPS_IMAGE_RGB :
+ cupsImageRGBToRGB(rgb, out, 768);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageRGBToCMY(rgb, out, 768);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageRGBToCMYK(rgb, out, 768);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, 768 * bpp, lut);
+
+ if (rotation)
+ _cupsImagePutCol(img, 511 - y - pass, 0, 768, out);
+ else
+ _cupsImagePutRow(img, 0, y + pass, 768, out);
+ }
+ }
+ }
+
+ /*
+ * Free memory and return...
+ */
+
+ free(in);
+ free(out);
+ if (bpp > 1)
+ free(rgb);
+
+ return (0);
+}
+
diff --git a/cupsfilters/image-pix.c b/cupsfilters/image-pix.c
new file mode 100644
index 000000000..58551b9a9
--- /dev/null
+++ b/cupsfilters/image-pix.c
@@ -0,0 +1,231 @@
+/*
+ * Alias PIX image routines for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2007 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * _cupsImageReadPIX() - Read a PIX image file.
+ * read_short() - Read a 16-bit integer.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image-private.h"
+
+
+/*
+ * Local functions...
+ */
+
+static short read_short(FILE *fp);
+
+
+/*
+ * '_cupsImageReadPIX()' - Read a PIX image file.
+ */
+
+int /* O - Read status */
+_cupsImageReadPIX(
+ cups_image_t *img, /* IO - cupsImage */
+ FILE *fp, /* I - cupsImage file */
+ cups_icspace_t primary, /* I - Primary choice for colorspace */
+ cups_icspace_t secondary, /* I - Secondary choice for colorspace */
+ int saturation, /* I - Color saturation (%) */
+ int hue, /* I - Color hue (degrees) */
+ const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */
+{
+ short width, /* Width of image */
+ height, /* Height of image */
+ depth; /* Depth of image (bits) */
+ int count, /* Repetition count */
+ bpp, /* Bytes per pixel */
+ x, y; /* Looping vars */
+ cups_ib_t r, g, b; /* Red, green/gray, blue values */
+ cups_ib_t *in, /* Input pixels */
+ *out, /* Output pixels */
+ *ptr; /* Pointer into pixels */
+
+
+ /*
+ * Get the image dimensions and setup the image...
+ */
+
+ width = read_short(fp);
+ height = read_short(fp);
+ read_short(fp);
+ read_short(fp);
+ depth = read_short(fp);
+
+ /*
+ * Check the dimensions of the image. Since the short values used for the
+ * width and height cannot exceed CUPS_IMAGE_MAX_WIDTH or
+ * CUPS_IMAGE_MAX_HEIGHT, we just need to verify they are positive integers.
+ */
+
+ if (width <= 0 || height <= 0 ||
+ (depth != 8 && depth != 24))
+ {
+ fprintf(stderr, "DEBUG: Bad PIX image dimensions %dx%dx%d\n",
+ width, height, depth);
+ fclose(fp);
+ return (1);
+ }
+
+ if (depth == 8)
+ img->colorspace = secondary;
+ else
+ img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary;
+
+ img->xsize = width;
+ img->ysize = height;
+
+ cupsImageSetMaxTiles(img, 0);
+
+ bpp = cupsImageGetDepth(img);
+
+ if ((in = malloc(img->xsize * (depth / 8))) == NULL)
+ {
+ fputs("DEBUG: Unable to allocate memory!\n", stderr);
+ fclose(fp);
+ return (1);
+ }
+
+ if ((out = malloc(img->xsize * bpp)) == NULL)
+ {
+ fputs("DEBUG: Unable to allocate memory!\n", stderr);
+ fclose(fp);
+ free(in);
+ return (1);
+ }
+
+ /*
+ * Read the image data...
+ */
+
+ if (depth == 8)
+ {
+ for (count = 0, y = 0, g = 0; y < img->ysize; y ++)
+ {
+ if (img->colorspace == CUPS_IMAGE_WHITE)
+ ptr = out;
+ else
+ ptr = in;
+
+ for (x = img->xsize; x > 0; x --, count --)
+ {
+ if (count == 0)
+ {
+ count = getc(fp);
+ g = getc(fp);
+ }
+
+ *ptr++ = g;
+ }
+
+ if (img->colorspace != CUPS_IMAGE_WHITE)
+ switch (img->colorspace)
+ {
+ default :
+ cupsImageWhiteToRGB(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_BLACK :
+ cupsImageWhiteToBlack(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageWhiteToCMY(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageWhiteToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, img->xsize * bpp, lut);
+
+ _cupsImagePutRow(img, 0, y, img->xsize, out);
+ }
+ }
+ else
+ {
+ for (count = 0, y = 0, r = 0, g = 0, b = 0; y < img->ysize; y ++)
+ {
+ ptr = in;
+
+ for (x = img->xsize; x > 0; x --, count --)
+ {
+ if (count == 0)
+ {
+ count = getc(fp);
+ b = getc(fp);
+ g = getc(fp);
+ r = getc(fp);
+ }
+
+ *ptr++ = r;
+ *ptr++ = g;
+ *ptr++ = b;
+ }
+
+ if (saturation != 100 || hue != 0)
+ cupsImageRGBAdjust(in, img->xsize, saturation, hue);
+
+ switch (img->colorspace)
+ {
+ default :
+ break;
+
+ case CUPS_IMAGE_WHITE :
+ cupsImageRGBToWhite(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_RGB :
+ cupsImageRGBToWhite(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_BLACK :
+ cupsImageRGBToBlack(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageRGBToCMY(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageRGBToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, img->xsize * bpp, lut);
+
+ _cupsImagePutRow(img, 0, y, img->xsize, out);
+ }
+ }
+
+ fclose(fp);
+ free(in);
+ free(out);
+
+ return (0);
+}
+
+
+/*
+ * 'read_short()' - Read a 16-bit integer.
+ */
+
+static short /* O - Value from file */
+read_short(FILE *fp) /* I - File to read from */
+{
+ int ch; /* Character from file */
+
+
+ ch = getc(fp);
+ return ((ch << 8) | getc(fp));
+}
+
diff --git a/cupsfilters/image-png.c b/cupsfilters/image-png.c
new file mode 100644
index 000000000..0c5255ece
--- /dev/null
+++ b/cupsfilters/image-png.c
@@ -0,0 +1,306 @@
+/*
+ * PNG image routines for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2007 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * _cupsImageReadPNG() - Read a PNG image file.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image-private.h"
+
+#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
+# include <png.h> /* Portable Network Graphics (PNG) definitions */
+
+
+/*
+ * '_cupsImageReadPNG()' - Read a PNG image file.
+ */
+
+int /* O - Read status */
+_cupsImageReadPNG(
+ cups_image_t *img, /* IO - cupsImage */
+ FILE *fp, /* I - cupsImage file */
+ cups_icspace_t primary, /* I - Primary choice for colorspace */
+ cups_icspace_t secondary, /* I - Secondary choice for colorspace */
+ int saturation, /* I - Color saturation (%) */
+ int hue, /* I - Color hue (degrees) */
+ const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */
+{
+ int y; /* Looping var */
+ png_structp pp; /* PNG read pointer */
+ png_infop info; /* PNG info pointers */
+ png_uint_32 width, /* Width of image */
+ height; /* Height of image */
+ int bit_depth, /* Bit depth */
+ color_type, /* Color type */
+ interlace_type, /* Interlace type */
+ compression_type, /* Compression type */
+ filter_type; /* Filter type */
+ png_uint_32 xppm, /* X pixels per meter */
+ yppm; /* Y pixels per meter */
+ int bpp; /* Bytes per pixel */
+ int pass, /* Current pass */
+ passes; /* Number of passes required */
+ cups_ib_t *in, /* Input pixels */
+ *inptr, /* Pointer into pixels */
+ *out; /* Output pixels */
+ png_color_16 bg; /* Background color */
+
+
+ /*
+ * Setup the PNG data structures...
+ */
+
+ pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ info = png_create_info_struct(pp);
+
+ /*
+ * Initialize the PNG read "engine"...
+ */
+
+ png_init_io(pp, fp);
+
+ /*
+ * Get the image dimensions and load the output image...
+ */
+
+ png_read_info(pp, info);
+
+ png_get_IHDR(pp, info, &width, &height, &bit_depth, &color_type,
+ &interlace_type, &compression_type, &filter_type);
+
+ fprintf(stderr, "DEBUG: PNG image: %dx%dx%d, color_type=%x (%s%s%s)\n",
+ (int)width, (int)height, bit_depth, color_type,
+ (color_type & PNG_COLOR_MASK_COLOR) ? "RGB" : "GRAYSCALE",
+ (color_type & PNG_COLOR_MASK_ALPHA) ? "+ALPHA" : "",
+ (color_type & PNG_COLOR_MASK_PALETTE) ? "+PALETTE" : "");
+
+ if (color_type & PNG_COLOR_MASK_PALETTE)
+ png_set_expand(pp);
+ else if (bit_depth < 8)
+ {
+ png_set_packing(pp);
+ png_set_expand(pp);
+ }
+ else if (bit_depth == 16)
+ png_set_strip_16(pp);
+
+ if (color_type & PNG_COLOR_MASK_COLOR)
+ img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB :
+ primary;
+ else
+ img->colorspace = secondary;
+
+ if (width == 0 || width > CUPS_IMAGE_MAX_WIDTH ||
+ height == 0 || height > CUPS_IMAGE_MAX_HEIGHT)
+ {
+ fprintf(stderr, "DEBUG: PNG image has invalid dimensions %ux%u!\n",
+ (unsigned)width, (unsigned)height);
+ fclose(fp);
+ return (1);
+ }
+
+ img->xsize = width;
+ img->ysize = height;
+
+ if ((xppm = png_get_x_pixels_per_meter(pp, info)) != 0 &&
+ (yppm = png_get_y_pixels_per_meter(pp, info)) != 0)
+ {
+ img->xppi = (int)((float)xppm * 0.0254);
+ img->yppi = (int)((float)yppm * 0.0254);
+
+ if (img->xppi == 0 || img->yppi == 0)
+ {
+ fprintf(stderr, "DEBUG: PNG image has invalid resolution %dx%d PPI\n",
+ img->xppi, img->yppi);
+
+ img->xppi = img->yppi = 128;
+ }
+ }
+
+ cupsImageSetMaxTiles(img, 0);
+
+ passes = png_set_interlace_handling(pp);
+
+ /*
+ * Handle transparency...
+ */
+
+ if (png_get_valid(pp, info, PNG_INFO_tRNS))
+ png_set_tRNS_to_alpha(pp);
+
+ bg.red = 65535;
+ bg.green = 65535;
+ bg.blue = 65535;
+
+ png_set_background(pp, &bg, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+
+ if (passes == 1)
+ {
+ /*
+ * Load one row at a time...
+ */
+
+ if (color_type == PNG_COLOR_TYPE_GRAY ||
+ color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ in = malloc(img->xsize);
+ else
+ in = malloc(img->xsize * 3);
+ }
+ else
+ {
+ /*
+ * Interlaced images must be loaded all at once...
+ */
+
+ size_t bufsize; /* Size of buffer */
+
+
+ if (color_type == PNG_COLOR_TYPE_GRAY ||
+ color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ bufsize = img->xsize * img->ysize;
+
+ if ((bufsize / img->xsize) != img->ysize)
+ {
+ fprintf(stderr, "DEBUG: PNG image dimensions (%ux%u) too large!\n",
+ (unsigned)width, (unsigned)height);
+ fclose(fp);
+ return (1);
+ }
+ }
+ else
+ {
+ bufsize = img->xsize * img->ysize * 3;
+
+ if ((bufsize / (img->xsize * 3)) != img->ysize)
+ {
+ fprintf(stderr, "DEBUG: PNG image dimensions (%ux%u) too large!\n",
+ (unsigned)width, (unsigned)height);
+ fclose(fp);
+ return (1);
+ }
+ }
+
+ in = malloc(bufsize);
+ }
+
+ bpp = cupsImageGetDepth(img);
+ out = malloc(img->xsize * bpp);
+
+ if (!in || !out)
+ {
+ fputs("DEBUG: Unable to allocate memory for PNG image!\n", stderr);
+
+ if (in)
+ free(in);
+
+ if (out)
+ free(out);
+
+ fclose(fp);
+
+ return (1);
+ }
+
+ /*
+ * Read the image, interlacing as needed...
+ */
+
+ for (pass = 1; pass <= passes; pass ++)
+ for (inptr = in, y = 0; y < img->ysize; y ++)
+ {
+ png_read_row(pp, (png_bytep)inptr, NULL);
+
+ if (pass == passes)
+ {
+ /*
+ * Output this row...
+ */
+
+ if (color_type & PNG_COLOR_MASK_COLOR)
+ {
+ if ((saturation != 100 || hue != 0) && bpp > 1)
+ cupsImageRGBAdjust(inptr, img->xsize, saturation, hue);
+
+ switch (img->colorspace)
+ {
+ case CUPS_IMAGE_WHITE :
+ cupsImageRGBToWhite(inptr, out, img->xsize);
+ break;
+ case CUPS_IMAGE_RGB :
+ case CUPS_IMAGE_RGB_CMYK :
+ cupsImageRGBToRGB(inptr, out, img->xsize);
+ break;
+ case CUPS_IMAGE_BLACK :
+ cupsImageRGBToBlack(inptr, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageRGBToCMY(inptr, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageRGBToCMYK(inptr, out, img->xsize);
+ break;
+ }
+ }
+ else
+ {
+ switch (img->colorspace)
+ {
+ case CUPS_IMAGE_WHITE :
+ memcpy(out, inptr, img->xsize);
+ break;
+ case CUPS_IMAGE_RGB :
+ case CUPS_IMAGE_RGB_CMYK :
+ cupsImageWhiteToRGB(inptr, out, img->xsize);
+ break;
+ case CUPS_IMAGE_BLACK :
+ cupsImageWhiteToBlack(inptr, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageWhiteToCMY(inptr, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageWhiteToCMYK(inptr, out, img->xsize);
+ break;
+ }
+ }
+
+ if (lut)
+ cupsImageLut(out, img->xsize * bpp, lut);
+
+ _cupsImagePutRow(img, 0, y, img->xsize, out);
+ }
+
+ if (passes > 1)
+ {
+ if (color_type & PNG_COLOR_MASK_COLOR)
+ inptr += img->xsize * 3;
+ else
+ inptr += img->xsize;
+ }
+ }
+
+ png_read_end(pp, info);
+ png_destroy_read_struct(&pp, &info, NULL);
+
+ fclose(fp);
+ free(in);
+ free(out);
+
+ return (0);
+}
+#endif /* HAVE_LIBPNG && HAVE_LIBZ */
+
diff --git a/cupsfilters/image-pnm.c b/cupsfilters/image-pnm.c
new file mode 100644
index 000000000..e4194c733
--- /dev/null
+++ b/cupsfilters/image-pnm.c
@@ -0,0 +1,314 @@
+/*
+ * Portable Any Map file routines for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2007 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * _cupsImageReadPNM() - Read a PNM image file.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image-private.h"
+
+
+/*
+ * '_cupsImageReadPNM()' - Read a PNM image file.
+ */
+
+int /* O - Read status */
+_cupsImageReadPNM(
+ cups_image_t *img, /* IO - cupsImage */
+ FILE *fp, /* I - cupsImage file */
+ cups_icspace_t primary, /* I - Primary choice for colorspace */
+ cups_icspace_t secondary, /* I - Secondary choice for colorspace */
+ int saturation, /* I - Color saturation (%) */
+ int hue, /* I - Color hue (degrees) */
+ const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */
+{
+ int x, y; /* Looping vars */
+ int bpp; /* Bytes per pixel */
+ cups_ib_t *in, /* Input pixels */
+ *inptr, /* Current input pixel */
+ *out, /* Output pixels */
+ *outptr, /* Current output pixel */
+ bit; /* Bit in input line */
+ char line[255], /* Input line */
+ *lineptr; /* Pointer in line */
+ int format, /* Format of PNM file */
+ val, /* Pixel value */
+ maxval; /* Maximum pixel value */
+
+
+ /*
+ * Read the file header in the format:
+ *
+ * Pformat
+ * # comment1
+ * # comment2
+ * ...
+ * # commentN
+ * width
+ * height
+ * max sample
+ */
+
+ if ((lineptr = fgets(line, sizeof(line), fp)) == NULL)
+ {
+ fputs("DEBUG: Bad PNM header!\n", stderr);
+ fclose(fp);
+ return (1);
+ }
+
+ lineptr ++;
+
+ format = atoi(lineptr);
+ while (isdigit(*lineptr & 255))
+ lineptr ++;
+
+ while (lineptr != NULL && img->xsize == 0)
+ {
+ if (*lineptr == '\0' || *lineptr == '#')
+ lineptr = fgets(line, sizeof(line), fp);
+ else if (isdigit(*lineptr & 255))
+ {
+ img->xsize = atoi(lineptr);
+ while (isdigit(*lineptr & 255))
+ lineptr ++;
+ }
+ else
+ lineptr ++;
+ }
+
+ while (lineptr != NULL && img->ysize == 0)
+ {
+ if (*lineptr == '\0' || *lineptr == '#')
+ lineptr = fgets(line, sizeof(line), fp);
+ else if (isdigit(*lineptr & 255))
+ {
+ img->ysize = atoi(lineptr);
+ while (isdigit(*lineptr & 255))
+ lineptr ++;
+ }
+ else
+ lineptr ++;
+ }
+
+ if (format != 1 && format != 4)
+ {
+ maxval = 0;
+
+ while (lineptr != NULL && maxval == 0)
+ {
+ if (*lineptr == '\0' || *lineptr == '#')
+ lineptr = fgets(line, sizeof(line), fp);
+ else if (isdigit(*lineptr & 255))
+ {
+ maxval = atoi(lineptr);
+ while (isdigit(*lineptr & 255))
+ lineptr ++;
+ }
+ else
+ lineptr ++;
+ }
+ }
+ else
+ maxval = 1;
+
+ if (img->xsize == 0 || img->xsize > CUPS_IMAGE_MAX_WIDTH ||
+ img->ysize == 0 || img->ysize > CUPS_IMAGE_MAX_HEIGHT)
+ {
+ fprintf(stderr, "DEBUG: Bad PNM dimensions %dx%d!\n",
+ img->xsize, img->ysize);
+ fclose(fp);
+ return (1);
+ }
+
+ if (maxval == 0)
+ {
+ fprintf(stderr, "DEBUG: Bad PNM max value %d!\n", maxval);
+ fclose(fp);
+ return (1);
+ }
+
+ if (format == 1 || format == 2 || format == 4 || format == 5)
+ img->colorspace = secondary;
+ else
+ img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary;
+
+ cupsImageSetMaxTiles(img, 0);
+
+ bpp = cupsImageGetDepth(img);
+
+ if ((in = malloc(img->xsize * 3)) == NULL)
+ {
+ fputs("DEBUG: Unable to allocate memory!\n", stderr);
+ fclose(fp);
+ return (1);
+ }
+
+ if ((out = malloc(img->xsize * bpp)) == NULL)
+ {
+ fputs("DEBUG: Unable to allocate memory!\n", stderr);
+ fclose(fp);
+ free(in);
+ return (1);
+ }
+
+ /*
+ * Read the image file...
+ */
+
+ for (y = 0; y < img->ysize; y ++)
+ {
+ switch (format)
+ {
+ case 1 :
+ for (x = img->xsize, inptr = in; x > 0; x --, inptr ++)
+ if (fscanf(fp, "%d", &val) == 1)
+ *inptr = val ? 0 : 255;
+ break;
+
+ case 2 :
+ for (x = img->xsize, inptr = in; x > 0; x --, inptr ++)
+ if (fscanf(fp, "%d", &val) == 1)
+ *inptr = 255 * val / maxval;
+ break;
+
+ case 3 :
+ for (x = img->xsize, inptr = in; x > 0; x --, inptr += 3)
+ {
+ if (fscanf(fp, "%d", &val) == 1)
+ inptr[0] = 255 * val / maxval;
+ if (fscanf(fp, "%d", &val) == 1)
+ inptr[1] = 255 * val / maxval;
+ if (fscanf(fp, "%d", &val) == 1)
+ inptr[2] = 255 * val / maxval;
+ }
+ break;
+
+ case 4 :
+ if (fread(out, (img->xsize + 7) / 8, 1, fp) == 0 && ferror(fp))
+ DEBUG_printf(("Error reading file!"));
+ for (x = img->xsize, inptr = in, outptr = out, bit = 128;
+ x > 0;
+ x --, inptr ++)
+ {
+ if (*outptr & bit)
+ *inptr = 0;
+ else
+ *inptr = 255;
+
+ if (bit > 1)
+ bit >>= 1;
+ else
+ {
+ bit = 128;
+ outptr ++;
+ }
+ }
+ break;
+
+ case 5 :
+ if (fread(in, img->xsize, 1, fp) == 0 && ferror(fp))
+ DEBUG_printf(("Error reading file!"));
+ break;
+
+ case 6 :
+ if (fread(in, img->xsize, 3, fp) == 0 && ferror(fp))
+ DEBUG_printf(("Error reading file!"));
+ break;
+ }
+
+ switch (format)
+ {
+ case 1 :
+ case 2 :
+ case 4 :
+ case 5 :
+ if (img->colorspace == CUPS_IMAGE_WHITE)
+ {
+ if (lut)
+ cupsImageLut(in, img->xsize, lut);
+
+ _cupsImagePutRow(img, 0, y, img->xsize, in);
+ }
+ else
+ {
+ switch (img->colorspace)
+ {
+ default :
+ break;
+
+ case CUPS_IMAGE_RGB :
+ cupsImageWhiteToRGB(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_BLACK :
+ cupsImageWhiteToBlack(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageWhiteToCMY(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageWhiteToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, img->xsize * bpp, lut);
+
+ _cupsImagePutRow(img, 0, y, img->xsize, out);
+ }
+ break;
+
+ default :
+ if ((saturation != 100 || hue != 0) && bpp > 1)
+ cupsImageRGBAdjust(in, img->xsize, saturation, hue);
+
+ switch (img->colorspace)
+ {
+ default :
+ break;
+
+ case CUPS_IMAGE_WHITE :
+ cupsImageRGBToWhite(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_RGB :
+ cupsImageRGBToRGB(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_BLACK :
+ cupsImageRGBToBlack(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageRGBToCMY(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageRGBToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, img->xsize * bpp, lut);
+
+ _cupsImagePutRow(img, 0, y, img->xsize, out);
+ break;
+ }
+ }
+
+ free(in);
+ free(out);
+
+ fclose(fp);
+
+ return (0);
+}
+
diff --git a/cupsfilters/image-private.h b/cupsfilters/image-private.h
new file mode 100644
index 000000000..4975fffdf
--- /dev/null
+++ b/cupsfilters/image-private.h
@@ -0,0 +1,214 @@
+/*
+ * Private image library definitions for CUPS.
+ *
+ * Copyright 2007-2010 by Apple Inc.
+ * Copyright 1993-2006 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ */
+
+#ifndef _CUPS_IMAGE_PRIVATE_H_
+# define _CUPS_IMAGE_PRIVATE_H_
+
+/*
+ * Include necessary headers...
+ */
+
+# include <config.h>
+# include "image.h"
+# include <cups/cups.h>
+# define DEBUG_printf(x)
+# define DEBUG_puts(x)
+# include <stdlib.h>
+# include <string.h>
+# include <ctype.h>
+# ifdef WIN32
+# include <io.h>
+# else
+# include <unistd.h>
+# endif /* WIN32 */
+# include <errno.h>
+# include <math.h>
+
+
+/*
+ * Constants...
+ */
+
+# define CUPS_IMAGE_MAX_WIDTH 0x07ffffff
+ /* 2^27-1 to allow for 15-channel data */
+# define CUPS_IMAGE_MAX_HEIGHT 0x3fffffff
+ /* 2^30-1 */
+
+# define CUPS_TILE_SIZE 256 /* 256x256 pixel tiles */
+# define CUPS_TILE_MINIMUM 10 /* Minimum number of tiles */
+
+
+/*
+ * min/max/abs macros...
+ */
+
+# ifndef max
+# define max(a,b) ((a) > (b) ? (a) : (b))
+# endif /* !max */
+# ifndef min
+# define min(a,b) ((a) < (b) ? (a) : (b))
+# endif /* !min */
+# ifndef abs
+# define abs(a) ((a) < 0 ? -(a) : (a))
+# endif /* !abs */
+
+
+/*
+ * Types and structures...
+ */
+
+typedef enum cups_iztype_e /**** Image zoom type ****/
+{
+ CUPS_IZOOM_FAST, /* Use nearest-neighbor sampling */
+ CUPS_IZOOM_NORMAL, /* Use bilinear interpolation */
+ CUPS_IZOOM_BEST /* Use bicubic interpolation */
+} cups_iztype_t;
+
+struct cups_ic_s;
+
+typedef struct cups_itile_s /**** Image tile ****/
+{
+ int dirty; /* True if tile is dirty */
+ off_t pos; /* Position of tile on disk (-1 if not written) */
+ struct cups_ic_s *ic; /* Pixel data */
+} cups_itile_t;
+
+typedef struct cups_ic_s /**** Image tile cache ****/
+{
+ struct cups_ic_s *prev, /* Previous tile in cache */
+ *next; /* Next tile in cache */
+ cups_itile_t *tile; /* Tile this is attached to */
+ cups_ib_t *pixels; /* Pixel data */
+} cups_ic_t;
+
+struct cups_image_s /**** Image file data ****/
+{
+ cups_icspace_t colorspace; /* Colorspace of image */
+ unsigned xsize, /* Width of image in pixels */
+ ysize, /* Height of image in pixels */
+ xppi, /* X resolution in pixels-per-inch */
+ yppi, /* Y resolution in pixels-per-inch */
+ num_ics, /* Number of cached tiles */
+ max_ics; /* Maximum number of cached tiles */
+ cups_itile_t **tiles; /* Tiles in image */
+ cups_ic_t *first, /* First cached tile in image */
+ *last; /* Last cached tile in image */
+ int cachefile; /* Tile cache file */
+ char cachename[256]; /* Tile cache filename */
+};
+
+struct cups_izoom_s /**** Image zoom data ****/
+{
+ cups_image_t *img; /* Image to zoom */
+ cups_iztype_t type; /* Type of zooming */
+ unsigned xorig, /* X origin */
+ yorig, /* Y origin */
+ width, /* Width of input area */
+ height, /* Height of input area */
+ depth, /* Number of bytes per pixel */
+ rotated, /* Non-zero if image needs to be rotated */
+ xsize, /* Width of output image */
+ ysize, /* Height of output image */
+ xmax, /* Maximum input image X position */
+ ymax, /* Maximum input image Y position */
+ xmod, /* Threshold for Bresenheim rounding */
+ ymod; /* ... */
+ int xstep, /* Amount to step for each pixel along X */
+ xincr,
+ instep, /* Amount to step pixel pointer along X */
+ inincr,
+ ystep, /* Amount to step for each pixel along Y */
+ yincr,
+ row; /* Current row */
+ cups_ib_t *rows[2], /* Horizontally scaled pixel data */
+ *in; /* Unscaled input pixel data */
+};
+
+
+/*
+ * Prototypes...
+ */
+
+extern int _cupsImagePutCol(cups_image_t *img, int x, int y,
+ int height, const cups_ib_t *pixels);
+extern int _cupsImagePutRow(cups_image_t *img, int x, int y,
+ int width, const cups_ib_t *pixels);
+extern int _cupsImageReadBMP(cups_image_t *img, FILE *fp,
+ cups_icspace_t primary,
+ cups_icspace_t secondary,
+ int saturation, int hue,
+ const cups_ib_t *lut);
+extern int _cupsImageReadFPX(cups_image_t *img, FILE *fp,
+ cups_icspace_t primary,
+ cups_icspace_t secondary,
+ int saturation, int hue,
+ const cups_ib_t *lut);
+extern int _cupsImageReadGIF(cups_image_t *img, FILE *fp,
+ cups_icspace_t primary,
+ cups_icspace_t secondary,
+ int saturation, int hue,
+ const cups_ib_t *lut);
+extern int _cupsImageReadJPEG(cups_image_t *img, FILE *fp,
+ cups_icspace_t primary,
+ cups_icspace_t secondary,
+ int saturation, int hue,
+ const cups_ib_t *lut);
+extern int _cupsImageReadPIX(cups_image_t *img, FILE *fp,
+ cups_icspace_t primary,
+ cups_icspace_t secondary,
+ int saturation, int hue,
+ const cups_ib_t *lut);
+extern int _cupsImageReadPNG(cups_image_t *img, FILE *fp,
+ cups_icspace_t primary,
+ cups_icspace_t secondary,
+ int saturation, int hue,
+ const cups_ib_t *lut);
+extern int _cupsImageReadPNM(cups_image_t *img, FILE *fp,
+ cups_icspace_t primary,
+ cups_icspace_t secondary,
+ int saturation, int hue,
+ const cups_ib_t *lut);
+extern int _cupsImageReadPhotoCD(cups_image_t *img, FILE *fp,
+ cups_icspace_t primary,
+ cups_icspace_t secondary,
+ int saturation, int hue,
+ const cups_ib_t *lut);
+extern int _cupsImageReadSGI(cups_image_t *img, FILE *fp,
+ cups_icspace_t primary,
+ cups_icspace_t secondary,
+ int saturation, int hue,
+ const cups_ib_t *lut);
+extern int _cupsImageReadSunRaster(cups_image_t *img, FILE *fp,
+ cups_icspace_t primary,
+ cups_icspace_t secondary,
+ int saturation, int hue,
+ const cups_ib_t *lut);
+extern int _cupsImageReadTIFF(cups_image_t *img, FILE *fp,
+ cups_icspace_t primary,
+ cups_icspace_t secondary,
+ int saturation, int hue,
+ const cups_ib_t *lut);
+extern void _cupsImageZoomDelete(cups_izoom_t *z);
+extern void _cupsImageZoomFill(cups_izoom_t *z, int iy);
+extern cups_izoom_t *_cupsImageZoomNew(cups_image_t *img, int xc0, int yc0,
+ int xc1, int yc1, int xsize,
+ int ysize, int rotated,
+ cups_iztype_t type);
+
+extern int _cupsRasterExecPS(cups_page_header2_t *h,
+ int *preferred_bits,
+ const char *code);
+extern void _cupsRasterAddError(const char *f, ...);
+extern void _cupsRasterClearError(void);
+
+#endif /* !_CUPS_IMAGE_PRIVATE_H_ */
+
diff --git a/cupsfilters/image-sgi.c b/cupsfilters/image-sgi.c
new file mode 100644
index 000000000..9bdb121b2
--- /dev/null
+++ b/cupsfilters/image-sgi.c
@@ -0,0 +1,286 @@
+/*
+ * SGI image file routines for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2007 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * _cupsImageReadSGI() - Read a SGI image file.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image-private.h"
+#include "image-sgi.h"
+
+
+/*
+ * '_cupsImageReadSGI()' - Read a SGI image file.
+ */
+
+int /* O - Read status */
+_cupsImageReadSGI(
+ cups_image_t *img, /* IO - cupsImage */
+ FILE *fp, /* I - cupsImage file */
+ cups_icspace_t primary, /* I - Primary choice for colorspace */
+ cups_icspace_t secondary, /* I - Secondary choice for colorspace */
+ int saturation, /* I - Color saturation (%) */
+ int hue, /* I - Color hue (degrees) */
+ const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */
+{
+ int i, y; /* Looping vars */
+ int bpp; /* Bytes per pixel */
+ sgi_t *sgip; /* SGI image file */
+ cups_ib_t *in, /* Input pixels */
+ *inptr, /* Current input pixel */
+ *out; /* Output pixels */
+ unsigned short *rows[4], /* Row pointers for image data */
+ *red,
+ *green,
+ *blue,
+ *gray,
+ *alpha;
+
+
+ /*
+ * Setup the SGI file...
+ */
+
+ sgip = sgiOpenFile(fp, SGI_READ, 0, 0, 0, 0, 0);
+
+ /*
+ * Get the image dimensions and load the output image...
+ */
+
+ /*
+ * Check the image dimensions; since xsize and ysize are unsigned shorts,
+ * just check if they are 0 since they can't exceed CUPS_IMAGE_MAX_WIDTH or
+ * CUPS_IMAGE_MAX_HEIGHT...
+ */
+
+ if (sgip->xsize == 0 || sgip->ysize == 0 ||
+ sgip->zsize == 0 || sgip->zsize > 4)
+ {
+ fprintf(stderr, "DEBUG: Bad SGI image dimensions %ux%ux%u!\n",
+ sgip->xsize, sgip->ysize, sgip->zsize);
+ sgiClose(sgip);
+ return (1);
+ }
+
+ if (sgip->zsize < 3)
+ img->colorspace = secondary;
+ else
+ img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary;
+
+ img->xsize = sgip->xsize;
+ img->ysize = sgip->ysize;
+
+ cupsImageSetMaxTiles(img, 0);
+
+ bpp = cupsImageGetDepth(img);
+
+ if ((in = malloc(img->xsize * sgip->zsize)) == NULL)
+ {
+ fputs("DEBUG: Unable to allocate memory!\n", stderr);
+ sgiClose(sgip);
+ return (1);
+ }
+
+ if ((out = malloc(img->xsize * bpp)) == NULL)
+ {
+ fputs("DEBUG: Unable to allocate memory!\n", stderr);
+ sgiClose(sgip);
+ free(in);
+ return (1);
+ }
+
+ if ((rows[0] = calloc(img->xsize * sgip->zsize,
+ sizeof(unsigned short))) == NULL)
+ {
+ fputs("DEBUG: Unable to allocate memory!\n", stderr);
+ sgiClose(sgip);
+ free(in);
+ free(out);
+ return (1);
+ }
+
+ for (i = 1; i < sgip->zsize; i ++)
+ rows[i] = rows[0] + i * img->xsize;
+
+ /*
+ * Read the SGI image file...
+ */
+
+ for (y = 0; y < img->ysize; y ++)
+ {
+ for (i = 0; i < sgip->zsize; i ++)
+ sgiGetRow(sgip, rows[i], img->ysize - 1 - y, i);
+
+ switch (sgip->zsize)
+ {
+ case 1 :
+ if (sgip->bpp == 1)
+ for (i = img->xsize - 1, gray = rows[0], inptr = in;
+ i >= 0;
+ i --)
+ {
+ *inptr++ = *gray++;
+ }
+ else
+ for (i = img->xsize - 1, gray = rows[0], inptr = in;
+ i >= 0;
+ i --)
+ {
+ *inptr++ = (*gray++) / 256 + 128;
+ }
+ break;
+ case 2 :
+ if (sgip->bpp == 1)
+ for (i = img->xsize - 1, gray = rows[0], alpha = rows[1], inptr = in;
+ i >= 0;
+ i --)
+ {
+ *inptr++ = (*gray++) * (*alpha++) / 255;
+ }
+ else
+ for (i = img->xsize - 1, gray = rows[0], alpha = rows[1], inptr = in;
+ i >= 0;
+ i --)
+ {
+ *inptr++ = ((*gray++) / 256 + 128) * (*alpha++) / 32767;
+ }
+ break;
+ case 3 :
+ if (sgip->bpp == 1)
+ for (i = img->xsize - 1, red = rows[0], green = rows[1],
+ blue = rows[2], inptr = in;
+ i >= 0;
+ i --)
+ {
+ *inptr++ = *red++;
+ *inptr++ = *green++;
+ *inptr++ = *blue++;
+ }
+ else
+ for (i = img->xsize - 1, red = rows[0], green = rows[1],
+ blue = rows[2], inptr = in;
+ i >= 0;
+ i --)
+ {
+ *inptr++ = (*red++) / 256 + 128;
+ *inptr++ = (*green++) / 256 + 128;
+ *inptr++ = (*blue++) / 256 + 128;
+ }
+ break;
+ case 4 :
+ if (sgip->bpp == 1)
+ for (i = img->xsize - 1, red = rows[0], green = rows[1],
+ blue = rows[2], alpha = rows[3], inptr = in;
+ i >= 0;
+ i --)
+ {
+ *inptr++ = (*red++) * (*alpha) / 255;
+ *inptr++ = (*green++) * (*alpha) / 255;
+ *inptr++ = (*blue++) * (*alpha++) / 255;
+ }
+ else
+ for (i = img->xsize - 1, red = rows[0], green = rows[1],
+ blue = rows[2], alpha = rows[3], inptr = in;
+ i >= 0;
+ i --)
+ {
+ *inptr++ = ((*red++) / 256 + 128) * (*alpha) / 32767;
+ *inptr++ = ((*green++) / 256 + 128) * (*alpha) / 32767;
+ *inptr++ = ((*blue++) / 256 + 128) * (*alpha++) / 32767;
+ }
+ break;
+ }
+
+ if (sgip->zsize < 3)
+ {
+ if (img->colorspace == CUPS_IMAGE_WHITE)
+ {
+ if (lut)
+ cupsImageLut(in, img->xsize, lut);
+
+ _cupsImagePutRow(img, 0, y, img->xsize, in);
+ }
+ else
+ {
+ switch (img->colorspace)
+ {
+ default :
+ break;
+
+ case CUPS_IMAGE_RGB :
+ case CUPS_IMAGE_RGB_CMYK :
+ cupsImageWhiteToRGB(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_BLACK :
+ cupsImageWhiteToBlack(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageWhiteToCMY(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageWhiteToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, img->xsize * bpp, lut);
+
+ _cupsImagePutRow(img, 0, y, img->xsize, out);
+ }
+ }
+ else
+ {
+ if ((saturation != 100 || hue != 0) && bpp > 1)
+ cupsImageRGBAdjust(in, img->xsize, saturation, hue);
+
+ switch (img->colorspace)
+ {
+ default :
+ break;
+
+ case CUPS_IMAGE_WHITE :
+ cupsImageRGBToWhite(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_RGB :
+ cupsImageRGBToRGB(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_BLACK :
+ cupsImageRGBToBlack(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageRGBToCMY(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageRGBToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, img->xsize * bpp, lut);
+
+ _cupsImagePutRow(img, 0, y, img->xsize, out);
+ }
+ }
+
+ free(in);
+ free(out);
+ free(rows[0]);
+
+ sgiClose(sgip);
+
+ return (0);
+}
+
diff --git a/cupsfilters/image-sgi.h b/cupsfilters/image-sgi.h
new file mode 100644
index 000000000..91ea07f22
--- /dev/null
+++ b/cupsfilters/image-sgi.h
@@ -0,0 +1,78 @@
+/*
+ * SGI image file format library definitions for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ */
+
+#ifndef _SGI_H_
+# define _SGI_H_
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+
+/*
+ * Constants...
+ */
+
+# define SGI_MAGIC 474 /* Magic number in image file */
+
+# define SGI_READ 0 /* Read from an SGI image file */
+# define SGI_WRITE 1 /* Write to an SGI image file */
+
+# define SGI_COMP_NONE 0 /* No compression */
+# define SGI_COMP_RLE 1 /* Run-length encoding */
+# define SGI_COMP_ARLE 2 /* Agressive run-length encoding */
+
+
+/*
+ * Image structure...
+ */
+
+typedef struct
+{
+ FILE *file; /* Image file */
+ int mode, /* File open mode */
+ bpp, /* Bytes per pixel/channel */
+ comp; /* Compression */
+ unsigned short xsize, /* Width in pixels */
+ ysize, /* Height in pixels */
+ zsize; /* Number of channels */
+ long firstrow, /* File offset for first row */
+ nextrow, /* File offset for next row */
+ **table, /* Offset table for compression */
+ **length; /* Length table for compression */
+ unsigned short *arle_row; /* Advanced RLE compression buffer */
+ long arle_offset, /* Advanced RLE buffer offset */
+ arle_length; /* Advanced RLE buffer length */
+} sgi_t;
+
+
+/*
+ * Prototypes...
+ */
+
+extern int sgiClose(sgi_t *sgip);
+extern int sgiGetRow(sgi_t *sgip, unsigned short *row, int y, int z);
+extern sgi_t *sgiOpen(const char *filename, int mode, int comp, int bpp,
+ int xsize, int ysize, int zsize);
+extern sgi_t *sgiOpenFile(FILE *file, int mode, int comp, int bpp,
+ int xsize, int ysize, int zsize);
+extern int sgiPutRow(sgi_t *sgip, unsigned short *row, int y, int z);
+
+# ifdef __cplusplus
+}
+# endif
+#endif /* !_SGI_H_ */
+
diff --git a/cupsfilters/image-sgilib.c b/cupsfilters/image-sgilib.c
new file mode 100644
index 000000000..0b70c1345
--- /dev/null
+++ b/cupsfilters/image-sgilib.c
@@ -0,0 +1,884 @@
+/*
+ * SGI image file format library routines for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * sgiClose() - Close an SGI image file.
+ * sgiGetRow() - Get a row of image data from a file.
+ * sgiOpen() - Open an SGI image file for reading or writing.
+ * sgiOpenFile() - Open an SGI image file for reading or writing.
+ * sgiPutRow() - Put a row of image data to a file.
+ * getlong() - Get a 32-bit big-endian integer.
+ * getshort() - Get a 16-bit big-endian integer.
+ * putlong() - Put a 32-bit big-endian integer.
+ * putshort() - Put a 16-bit big-endian integer.
+ * read_rle8() - Read 8-bit RLE data.
+ * read_rle16() - Read 16-bit RLE data.
+ * write_rle8() - Write 8-bit RLE data.
+ * write_rle16() - Write 16-bit RLE data.
+ */
+
+#include "image-sgi.h"
+#include "image-private.h"
+
+
+/*
+ * Local functions...
+ */
+
+static int getlong(FILE *);
+static int getshort(FILE *);
+static int putlong(long, FILE *);
+static int putshort(unsigned short, FILE *);
+static int read_rle8(FILE *, unsigned short *, int);
+static int read_rle16(FILE *, unsigned short *, int);
+static int write_rle8(FILE *, unsigned short *, int);
+static int write_rle16(FILE *, unsigned short *, int);
+
+
+/*
+ * 'sgiClose()' - Close an SGI image file.
+ */
+
+int /* O - 0 on success, -1 on error */
+sgiClose(sgi_t *sgip) /* I - SGI image */
+{
+ int i; /* Return status */
+ long *offset; /* Looping var for offset table */
+
+
+ if (sgip == NULL)
+ return (-1);
+
+ if (sgip->mode == SGI_WRITE && sgip->comp != SGI_COMP_NONE)
+ {
+ /*
+ * Write the scanline offset table to the file...
+ */
+
+ fseek(sgip->file, 512, SEEK_SET);
+
+ for (i = sgip->ysize * sgip->zsize, offset = sgip->table[0];
+ i > 0;
+ i --, offset ++)
+ if (putlong(offset[0], sgip->file) < 0)
+ return (-1);
+
+ for (i = sgip->ysize * sgip->zsize, offset = sgip->length[0];
+ i > 0;
+ i --, offset ++)
+ if (putlong(offset[0], sgip->file) < 0)
+ return (-1);
+ }
+
+ if (sgip->table != NULL)
+ {
+ free(sgip->table[0]);
+ free(sgip->table);
+ }
+
+ if (sgip->length != NULL)
+ {
+ free(sgip->length[0]);
+ free(sgip->length);
+ }
+
+ if (sgip->comp == SGI_COMP_ARLE)
+ free(sgip->arle_row);
+
+ i = fclose(sgip->file);
+ free(sgip);
+
+ return (i);
+}
+
+
+/*
+ * 'sgiGetRow()' - Get a row of image data from a file.
+ */
+
+int /* O - 0 on success, -1 on error */
+sgiGetRow(sgi_t *sgip, /* I - SGI image */
+ unsigned short *row, /* O - Row to read */
+ int y, /* I - Line to read */
+ int z) /* I - Channel to read */
+{
+ int x; /* X coordinate */
+ long offset; /* File offset */
+
+
+ if (sgip == NULL ||
+ row == NULL ||
+ y < 0 || y >= sgip->ysize ||
+ z < 0 || z >= sgip->zsize)
+ return (-1);
+
+ switch (sgip->comp)
+ {
+ case SGI_COMP_NONE :
+ /*
+ * Seek to the image row - optimize buffering by only seeking if
+ * necessary...
+ */
+
+ offset = 512 + (y + z * sgip->ysize) * sgip->xsize * sgip->bpp;
+ if (offset != ftell(sgip->file))
+ fseek(sgip->file, offset, SEEK_SET);
+
+ if (sgip->bpp == 1)
+ {
+ for (x = sgip->xsize; x > 0; x --, row ++)
+ *row = getc(sgip->file);
+ }
+ else
+ {
+ for (x = sgip->xsize; x > 0; x --, row ++)
+ *row = getshort(sgip->file);
+ }
+ break;
+
+ case SGI_COMP_RLE :
+ offset = sgip->table[z][y];
+ if (offset != ftell(sgip->file))
+ fseek(sgip->file, offset, SEEK_SET);
+
+ if (sgip->bpp == 1)
+ return (read_rle8(sgip->file, row, sgip->xsize));
+ else
+ return (read_rle16(sgip->file, row, sgip->xsize));
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'sgiOpen()' - Open an SGI image file for reading or writing.
+ */
+
+sgi_t * /* O - New image */
+sgiOpen(const char *filename, /* I - File to open */
+ int mode, /* I - Open mode (SGI_READ or SGI_WRITE) */
+ int comp, /* I - Type of compression */
+ int bpp, /* I - Bytes per pixel */
+ int xsize, /* I - Width of image in pixels */
+ int ysize, /* I - Height of image in pixels */
+ int zsize) /* I - Number of channels */
+{
+ sgi_t *sgip; /* New SGI image file */
+ FILE *file; /* Image file pointer */
+
+
+ if (mode == SGI_READ)
+ file = fopen(filename, "rb");
+ else
+ file = fopen(filename, "wb+");
+
+ if (file == NULL)
+ return (NULL);
+
+ if ((sgip = sgiOpenFile(file, mode, comp, bpp, xsize, ysize, zsize)) == NULL)
+ fclose(file);
+
+ return (sgip);
+}
+
+
+/*
+ * 'sgiOpenFile()' - Open an SGI image file for reading or writing.
+ */
+
+sgi_t * /* O - New image */
+sgiOpenFile(FILE *file, /* I - File to open */
+ int mode, /* I - Open mode (SGI_READ or SGI_WRITE) */
+ int comp, /* I - Type of compression */
+ int bpp, /* I - Bytes per pixel */
+ int xsize, /* I - Width of image in pixels */
+ int ysize, /* I - Height of image in pixels */
+ int zsize) /* I - Number of channels */
+{
+ int i, j; /* Looping var */
+ char name[80]; /* Name of file in image header */
+ short magic; /* Magic number */
+ sgi_t *sgip; /* New image pointer */
+
+
+ if ((sgip = calloc(sizeof(sgi_t), 1)) == NULL)
+ return (NULL);
+
+ sgip->file = file;
+
+ switch (mode)
+ {
+ case SGI_READ :
+ sgip->mode = SGI_READ;
+
+ magic = getshort(sgip->file);
+ if (magic != SGI_MAGIC)
+ {
+ free(sgip);
+ return (NULL);
+ }
+
+ sgip->comp = getc(sgip->file);
+ sgip->bpp = getc(sgip->file);
+ getshort(sgip->file); /* Dimensions */
+ sgip->xsize = getshort(sgip->file);
+ sgip->ysize = getshort(sgip->file);
+ sgip->zsize = getshort(sgip->file);
+ getlong(sgip->file); /* Minimum pixel */
+ getlong(sgip->file); /* Maximum pixel */
+
+ if (sgip->comp)
+ {
+ /*
+ * This file is compressed; read the scanline tables...
+ */
+
+ fseek(sgip->file, 512, SEEK_SET);
+
+ if ((sgip->table = calloc(sgip->zsize, sizeof(long *))) == NULL)
+ {
+ free(sgip);
+ return (NULL);
+ }
+
+ if ((sgip->table[0] = calloc(sgip->ysize * sgip->zsize,
+ sizeof(long))) == NULL)
+ {
+ free(sgip->table);
+ free(sgip);
+ return (NULL);
+ }
+
+ for (i = 1; i < sgip->zsize; i ++)
+ sgip->table[i] = sgip->table[0] + i * sgip->ysize;
+
+ for (i = 0; i < sgip->zsize; i ++)
+ for (j = 0; j < sgip->ysize; j ++)
+ sgip->table[i][j] = getlong(sgip->file);
+ }
+ break;
+
+ case SGI_WRITE :
+ if (xsize < 1 ||
+ ysize < 1 ||
+ zsize < 1 ||
+ bpp < 1 || bpp > 2 ||
+ comp < SGI_COMP_NONE || comp > SGI_COMP_ARLE)
+ {
+ free(sgip);
+ return (NULL);
+ }
+
+ sgip->mode = SGI_WRITE;
+
+ putshort(SGI_MAGIC, sgip->file);
+ putc((sgip->comp = comp) != 0, sgip->file);
+ putc(sgip->bpp = bpp, sgip->file);
+ putshort(3, sgip->file); /* Dimensions */
+ putshort(sgip->xsize = xsize, sgip->file);
+ putshort(sgip->ysize = ysize, sgip->file);
+ putshort(sgip->zsize = zsize, sgip->file);
+ if (bpp == 1)
+ {
+ putlong(0, sgip->file); /* Minimum pixel */
+ putlong(255, sgip->file); /* Maximum pixel */
+ }
+ else
+ {
+ putlong(-32768, sgip->file); /* Minimum pixel */
+ putlong(32767, sgip->file); /* Maximum pixel */
+ }
+ putlong(0, sgip->file); /* Reserved */
+
+ memset(name, 0, sizeof(name));
+ fwrite(name, sizeof(name), 1, sgip->file);
+
+ for (i = 0; i < 102; i ++)
+ putlong(0, sgip->file);
+
+ switch (comp)
+ {
+ case SGI_COMP_NONE : /* No compression */
+ /*
+ * This file is uncompressed. To avoid problems with sparse files,
+ * we need to write blank pixels for the entire image...
+ */
+
+ if (bpp == 1)
+ {
+ for (i = xsize * ysize * zsize; i > 0; i --)
+ putc(0, sgip->file);
+ }
+ else
+ {
+ for (i = xsize * ysize * zsize; i > 0; i --)
+ putshort(0, sgip->file);
+ }
+ break;
+
+ case SGI_COMP_ARLE : /* Aggressive RLE */
+ sgip->arle_row = calloc(xsize, sizeof(unsigned short));
+ sgip->arle_offset = 0;
+
+ case SGI_COMP_RLE : /* Run-Length Encoding */
+ /*
+ * This file is compressed; write the (blank) scanline tables...
+ */
+
+ for (i = 2 * ysize * zsize; i > 0; i --)
+ putlong(0, sgip->file);
+
+ sgip->firstrow = ftell(sgip->file);
+ sgip->nextrow = ftell(sgip->file);
+ if ((sgip->table = calloc(sgip->zsize, sizeof(long *))) == NULL)
+ {
+ free(sgip);
+ return (NULL);
+ }
+
+ if ((sgip->table[0] = calloc(sgip->ysize * sgip->zsize,
+ sizeof(long))) == NULL)
+ {
+ free(sgip->table);
+ free(sgip);
+ return (NULL);
+ }
+
+ for (i = 1; i < sgip->zsize; i ++)
+ sgip->table[i] = sgip->table[0] + i * sgip->ysize;
+
+ if ((sgip->length = calloc(sgip->zsize, sizeof(long *))) == NULL)
+ {
+ free(sgip->table);
+ free(sgip);
+ return (NULL);
+ }
+
+ if ((sgip->length[0] = calloc(sgip->ysize * sgip->zsize,
+ sizeof(long))) == NULL)
+ {
+ free(sgip->length);
+ free(sgip->table);
+ free(sgip);
+ return (NULL);
+ }
+
+ for (i = 1; i < sgip->zsize; i ++)
+ sgip->length[i] = sgip->length[0] + i * sgip->ysize;
+ break;
+ }
+ break;
+
+ default :
+ free(sgip);
+ return (NULL);
+ }
+
+ return (sgip);
+}
+
+
+/*
+ * 'sgiPutRow()' - Put a row of image data to a file.
+ */
+
+int /* O - 0 on success, -1 on error */
+sgiPutRow(sgi_t *sgip, /* I - SGI image */
+ unsigned short *row, /* I - Row to write */
+ int y, /* I - Line to write */
+ int z) /* I - Channel to write */
+{
+ int x; /* X coordinate */
+ long offset; /* File offset */
+
+
+ if (sgip == NULL ||
+ row == NULL ||
+ y < 0 || y >= sgip->ysize ||
+ z < 0 || z >= sgip->zsize)
+ return (-1);
+
+ switch (sgip->comp)
+ {
+ case SGI_COMP_NONE :
+ /*
+ * Seek to the image row - optimize buffering by only seeking if
+ * necessary...
+ */
+
+ offset = 512 + (y + z * sgip->ysize) * sgip->xsize * sgip->bpp;
+ if (offset != ftell(sgip->file))
+ fseek(sgip->file, offset, SEEK_SET);
+
+ if (sgip->bpp == 1)
+ {
+ for (x = sgip->xsize; x > 0; x --, row ++)
+ putc(*row, sgip->file);
+ }
+ else
+ {
+ for (x = sgip->xsize; x > 0; x --, row ++)
+ putshort(*row, sgip->file);
+ }
+ break;
+
+ case SGI_COMP_ARLE :
+ if (sgip->table[z][y] != 0)
+ return (-1);
+
+ /*
+ * First check the last row written...
+ */
+
+ if (sgip->arle_offset > 0)
+ {
+ for (x = 0; x < sgip->xsize; x ++)
+ if (row[x] != sgip->arle_row[x])
+ break;
+
+ if (x == sgip->xsize)
+ {
+ sgip->table[z][y] = sgip->arle_offset;
+ sgip->length[z][y] = sgip->arle_length;
+ return (0);
+ }
+ }
+
+ /*
+ * If that didn't match, search all the previous rows...
+ */
+
+ fseek(sgip->file, sgip->firstrow, SEEK_SET);
+
+ if (sgip->bpp == 1)
+ {
+ for (;;)
+ {
+ sgip->arle_offset = ftell(sgip->file);
+ if ((sgip->arle_length = read_rle8(sgip->file, sgip->arle_row, sgip->xsize)) < 0)
+ {
+ x = 0;
+ break;
+ }
+
+ if (memcmp(row, sgip->arle_row, sgip->xsize * sizeof(unsigned short)) == 0)
+ {
+ x = sgip->xsize;
+ break;
+ }
+ }
+ }
+ else
+ {
+ for (;;)
+ {
+ sgip->arle_offset = ftell(sgip->file);
+ if ((sgip->arle_length = read_rle16(sgip->file, sgip->arle_row, sgip->xsize)) < 0)
+ {
+ x = 0;
+ break;
+ }
+
+ if (memcmp(row, sgip->arle_row, sgip->xsize * sizeof(unsigned short)) == 0)
+ {
+ x = sgip->xsize;
+ break;
+ }
+ }
+ }
+
+ if (x == sgip->xsize)
+ {
+ sgip->table[z][y] = sgip->arle_offset;
+ sgip->length[z][y] = sgip->arle_length;
+ return (0);
+ }
+ else
+ fseek(sgip->file, 0, SEEK_END); /* Clear EOF */
+
+ case SGI_COMP_RLE :
+ if (sgip->table[z][y] != 0)
+ return (-1);
+
+ offset = sgip->table[z][y] = sgip->nextrow;
+
+ if (offset != ftell(sgip->file))
+ fseek(sgip->file, offset, SEEK_SET);
+
+ if (sgip->bpp == 1)
+ x = write_rle8(sgip->file, row, sgip->xsize);
+ else
+ x = write_rle16(sgip->file, row, sgip->xsize);
+
+ if (sgip->comp == SGI_COMP_ARLE)
+ {
+ sgip->arle_offset = offset;
+ sgip->arle_length = x;
+ memcpy(sgip->arle_row, row, sgip->xsize * sizeof(unsigned short));
+ }
+
+ sgip->nextrow = ftell(sgip->file);
+ sgip->length[z][y] = x;
+
+ return (x);
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'getlong()' - Get a 32-bit big-endian integer.
+ */
+
+static int /* O - Long value */
+getlong(FILE *fp) /* I - File to read from */
+{
+ unsigned char b[4]; /* Bytes from file */
+
+
+ if (fread(b, 4, 1, fp) == 0 && ferror(fp))
+ DEBUG_printf(("Error reading file!"));
+ return ((b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]);
+}
+
+
+/*
+ * 'getshort()' - Get a 16-bit big-endian integer.
+ */
+
+static int /* O - Short value */
+getshort(FILE *fp) /* I - File to read from */
+{
+ unsigned char b[2]; /* Bytes from file */
+
+
+ if (fread(b, 2, 1, fp) == 0 && ferror(fp))
+ DEBUG_printf(("Error reading file!"));
+ return ((b[0] << 8) | b[1]);
+}
+
+
+/*
+ * 'putlong()' - Put a 32-bit big-endian integer.
+ */
+
+static int /* O - 0 on success, -1 on error */
+putlong(long n, /* I - Long to write */
+ FILE *fp) /* I - File to write to */
+{
+ if (putc(n >> 24, fp) == EOF)
+ return (EOF);
+ if (putc(n >> 16, fp) == EOF)
+ return (EOF);
+ if (putc(n >> 8, fp) == EOF)
+ return (EOF);
+ if (putc(n, fp) == EOF)
+ return (EOF);
+ else
+ return (0);
+}
+
+
+/*
+ * 'putshort()' - Put a 16-bit big-endian integer.
+ */
+
+static int /* O - 0 on success, -1 on error */
+putshort(unsigned short n, /* I - Short to write */
+ FILE *fp) /* I - File to write to */
+{
+ if (putc(n >> 8, fp) == EOF)
+ return (EOF);
+ if (putc(n, fp) == EOF)
+ return (EOF);
+ else
+ return (0);
+}
+
+
+/*
+ * 'read_rle8()' - Read 8-bit RLE data.
+ */
+
+static int /* O - Value on success, -1 on error */
+read_rle8(FILE *fp, /* I - File to read from */
+ unsigned short *row, /* O - Data */
+ int xsize) /* I - Width of data in pixels */
+{
+ int i, /* Looping var */
+ ch, /* Current character */
+ count, /* RLE count */
+ length; /* Number of bytes read... */
+
+
+ length = 0;
+
+ while (xsize > 0)
+ {
+ if ((ch = getc(fp)) == EOF)
+ return (-1);
+ length ++;
+
+ count = ch & 127;
+ if (count == 0)
+ break;
+
+ if (ch & 128)
+ {
+ for (i = 0; i < count; i ++, row ++, xsize --, length ++)
+ if (xsize > 0)
+ *row = getc(fp);
+ }
+ else
+ {
+ ch = getc(fp);
+ length ++;
+ for (i = 0; i < count && xsize > 0; i ++, row ++, xsize --)
+ *row = ch;
+ }
+ }
+
+ return (xsize > 0 ? -1 : length);
+}
+
+
+/*
+ * 'read_rle16()' - Read 16-bit RLE data.
+ */
+
+static int /* O - Value on success, -1 on error */
+read_rle16(FILE *fp, /* I - File to read from */
+ unsigned short *row, /* O - Data */
+ int xsize) /* I - Width of data in pixels */
+{
+ int i, /* Looping var */
+ ch, /* Current character */
+ count, /* RLE count */
+ length; /* Number of bytes read... */
+
+
+ length = 0;
+
+ while (xsize > 0)
+ {
+ if ((ch = getshort(fp)) == EOF)
+ return (-1);
+ length ++;
+
+ count = ch & 127;
+ if (count == 0)
+ break;
+
+ if (ch & 128)
+ {
+ for (i = 0; i < count; i ++, row ++, xsize --, length ++)
+ if (xsize > 0)
+ *row = getshort(fp);
+ }
+ else
+ {
+ ch = getshort(fp);
+ length ++;
+ for (i = 0; i < count && xsize > 0; i ++, row ++, xsize --)
+ *row = ch;
+ }
+ }
+
+ return (xsize > 0 ? -1 : length * 2);
+}
+
+
+/*
+ * 'write_rle8()' - Write 8-bit RLE data.
+ */
+
+static int /* O - Length on success, -1 on error */
+write_rle8(FILE *fp, /* I - File to write to */
+ unsigned short *row, /* I - Data */
+ int xsize) /* I - Width of data in pixels */
+{
+ int length, /* Length in bytes */
+ count, /* Number of repeating pixels */
+ i, /* Looping var */
+ x; /* Current column */
+ unsigned short *start, /* Start of current sequence */
+ repeat; /* Repeated pixel */
+
+
+ for (x = xsize, length = 0; x > 0;)
+ {
+ start = row;
+ row += 2;
+ x -= 2;
+
+ while (x > 0 && (row[-2] != row[-1] || row[-1] != row[0]))
+ {
+ row ++;
+ x --;
+ }
+
+ row -= 2;
+ x += 2;
+
+ count = row - start;
+ while (count > 0)
+ {
+ i = count > 126 ? 126 : count;
+ count -= i;
+
+ if (putc(128 | i, fp) == EOF)
+ return (-1);
+ length ++;
+
+ while (i > 0)
+ {
+ if (putc(*start, fp) == EOF)
+ return (-1);
+ start ++;
+ i --;
+ length ++;
+ }
+ }
+
+ if (x <= 0)
+ break;
+
+ start = row;
+ repeat = row[0];
+
+ row ++;
+ x --;
+
+ while (x > 0 && *row == repeat)
+ {
+ row ++;
+ x --;
+ }
+
+ count = row - start;
+ while (count > 0)
+ {
+ i = count > 126 ? 126 : count;
+ count -= i;
+
+ if (putc(i, fp) == EOF)
+ return (-1);
+ length ++;
+
+ if (putc(repeat, fp) == EOF)
+ return (-1);
+ length ++;
+ }
+ }
+
+ length ++;
+
+ if (putc(0, fp) == EOF)
+ return (-1);
+ else
+ return (length);
+}
+
+
+/*
+ * 'write_rle16()' - Write 16-bit RLE data.
+ */
+
+static int /* O - Length in words */
+write_rle16(FILE *fp, /* I - File to write to */
+ unsigned short *row, /* I - Data */
+ int xsize) /* I - Width of data in pixels */
+{
+ int length, /* Length in words */
+ count, /* Number of repeating pixels */
+ i, /* Looping var */
+ x; /* Current column */
+ unsigned short *start, /* Start of current sequence */
+ repeat; /* Repeated pixel */
+
+
+ for (x = xsize, length = 0; x > 0;)
+ {
+ start = row;
+ row += 2;
+ x -= 2;
+
+ while (x > 0 && (row[-2] != row[-1] || row[-1] != row[0]))
+ {
+ row ++;
+ x --;
+ }
+
+ row -= 2;
+ x += 2;
+
+ count = row - start;
+ while (count > 0)
+ {
+ i = count > 126 ? 126 : count;
+ count -= i;
+
+ if (putshort(128 | i, fp) == EOF)
+ return (-1);
+ length ++;
+
+ while (i > 0)
+ {
+ if (putshort(*start, fp) == EOF)
+ return (-1);
+ start ++;
+ i --;
+ length ++;
+ }
+ }
+
+ if (x <= 0)
+ break;
+
+ start = row;
+ repeat = row[0];
+
+ row ++;
+ x --;
+
+ while (x > 0 && *row == repeat)
+ {
+ row ++;
+ x --;
+ }
+
+ count = row - start;
+ while (count > 0)
+ {
+ i = count > 126 ? 126 : count;
+ count -= i;
+
+ if (putshort(i, fp) == EOF)
+ return (-1);
+ length ++;
+
+ if (putshort(repeat, fp) == EOF)
+ return (-1);
+ length ++;
+ }
+ }
+
+ length ++;
+
+ if (putshort(0, fp) == EOF)
+ return (-1);
+ else
+ return (2 * length);
+}
+
diff --git a/cupsfilters/image-sun.c b/cupsfilters/image-sun.c
new file mode 100644
index 000000000..609b194f9
--- /dev/null
+++ b/cupsfilters/image-sun.c
@@ -0,0 +1,404 @@
+/*
+ * Sun Raster image file routines for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2007 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * _cupsImageReadSunRaster() - Read a SunRaster image file.
+ * read_unsigned() - Read a 32-bit unsigned integer.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image-private.h"
+
+
+#define RAS_MAGIC 0x59a66a95
+
+ /* Sun supported ras_type's */
+#define RT_OLD 0 /* Raw pixrect image in 68000 byte order */
+#define RT_STANDARD 1 /* Raw pixrect image in 68000 byte order */
+#define RT_BYTE_ENCODED 2 /* Run-length compression of bytes */
+#define RT_FORMAT_RGB 3 /* XRGB or RGB instead of XBGR or BGR */
+#define RT_EXPERIMENTAL 0xffff /* Reserved for testing */
+
+ /* Sun registered ras_maptype's */
+#define RMT_RAW 2
+ /* Sun supported ras_maptype's */
+#define RMT_NONE 0 /* ras_maplength is expected to be 0 */
+#define RMT_EQUAL_RGB 1 /* red[ras_maplength/3],green[],blue[] */
+
+#define RAS_RLE 0x80
+
+/*
+ * NOTES:
+ * Each line of the image is rounded out to a multiple of 16 bits.
+ * This corresponds to the rounding convention used by the memory pixrect
+ * package (/usr/include/pixrect/memvar.h) of the SunWindows system.
+ * The ras_encoding field (always set to 0 by Sun's supported software)
+ * was renamed to ras_length in release 2.0. As a result, rasterfiles
+ * of type 0 generated by the old software claim to have 0 length; for
+ * compatibility, code reading rasterfiles must be prepared to compute the
+ * true length from the width, height, and depth fields.
+ */
+
+/*
+ * Local functions...
+ */
+
+static unsigned read_unsigned(FILE *fp);
+
+
+/*
+ * '_cupsImageReadSunRaster()' - Read a SunRaster image file.
+ */
+
+int /* O - Read status */
+_cupsImageReadSunRaster(
+ cups_image_t *img, /* IO - cupsImage */
+ FILE *fp, /* I - cupsImage file */
+ cups_icspace_t primary, /* I - Primary choice for colorspace */
+ cups_icspace_t secondary, /* I - Secondary choice for colorspace */
+ int saturation, /* I - Color saturation (%) */
+ int hue, /* I - Color hue (degrees) */
+ const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */
+{
+ int i, x, y,
+ bpp, /* Bytes per pixel */
+ scanwidth,
+ run_count,
+ run_value;
+ cups_ib_t *in,
+ *out,
+ *scanline,
+ *scanptr,
+ *p,
+ bit;
+ unsigned ras_depth, /* depth (1, 8, or 24 bits) of pixel */
+ ras_type, /* type of file; see RT_* below */
+ ras_maplength; /* length (bytes) of following map */
+ unsigned char cmap[3][256]; /* colormap */
+
+
+ /*
+ * Read the header; we already know that this is a raster file (cupsImageOpen
+ * checks this) so we don't need to check the magic number again.
+ */
+
+ fputs("DEBUG: Reading Sun Raster image...\n", stderr);
+
+ read_unsigned(fp); /* Skip magic */
+ img->xsize = read_unsigned(fp);
+ img->ysize = read_unsigned(fp);
+ ras_depth = read_unsigned(fp);
+ /* ras_length */read_unsigned(fp);
+ ras_type = read_unsigned(fp);
+ /* ras_maptype*/read_unsigned(fp);
+ ras_maplength = read_unsigned(fp);
+
+ fprintf(stderr, "DEBUG: ras_width=%d, ras_height=%d, ras_depth=%d, ras_type=%d, ras_maplength=%d\n",
+ img->xsize, img->ysize, ras_depth, ras_type, ras_maplength);
+
+ if (ras_maplength > 768 ||
+ img->xsize == 0 || img->xsize > CUPS_IMAGE_MAX_WIDTH ||
+ img->ysize == 0 || img->ysize > CUPS_IMAGE_MAX_HEIGHT ||
+ ras_depth == 0 || ras_depth > 32)
+ {
+ fputs("DEBUG: Raster image cannot be loaded!\n", stderr);
+ return (1);
+ }
+
+ if (ras_maplength > 0)
+ {
+ memset(cmap[0], 255, sizeof(cmap[0]));
+ memset(cmap[1], 0, sizeof(cmap[1]));
+ memset(cmap[2], 0, sizeof(cmap[2]));
+
+ if (fread(cmap[0], 1, ras_maplength / 3, fp) == 0 && ferror(fp))
+ DEBUG_printf(("Error reading file!"));
+ if (fread(cmap[1], 1, ras_maplength / 3, fp) == 0 && ferror(fp))
+ DEBUG_printf(("Error reading file!"));
+ if (fread(cmap[2], 1, ras_maplength / 3, fp) == 0 && ferror(fp))
+ DEBUG_printf(("Error reading file!"));
+ }
+
+ /*
+ * Compute the width of each line and allocate memory as needed...
+ */
+
+ scanwidth = (img->xsize * ras_depth + 7) / 8;
+ if (scanwidth & 1)
+ scanwidth ++;
+
+ if (ras_depth < 24 && ras_maplength == 0)
+ {
+ img->colorspace = secondary;
+ in = malloc(img->xsize + 1);
+ }
+ else
+ {
+ img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary;
+ in = malloc(img->xsize * 3 + 1);
+ }
+
+ if (!in)
+ {
+ fputs("DEBUG: Unable to allocate memory!\n", stderr);
+ fclose(fp);
+ return (1);
+ }
+
+ bpp = cupsImageGetDepth(img);
+
+ if ((out = malloc(img->xsize * bpp)) == NULL)
+ {
+ fputs("DEBUG: Unable to allocate memory!\n", stderr);
+ fclose(fp);
+ free(in);
+ return (1);
+ }
+
+ if ((scanline = malloc(scanwidth)) == NULL)
+ {
+ fputs("DEBUG: Unable to allocate memory!\n", stderr);
+ fclose(fp);
+ free(in);
+ free(out);
+ return (1);
+ }
+
+ run_count = 0;
+ run_value = 0;
+
+ fprintf(stderr, "DEBUG: bpp=%d, scanwidth=%d\n", bpp, scanwidth);
+
+ for (y = 0; y < img->ysize; y ++)
+ {
+ if ((ras_depth != 8 && ras_depth != 24) || ras_maplength > 0)
+ p = scanline;
+ else
+ p = in;
+
+ if (ras_type != RT_BYTE_ENCODED)
+ {
+ if (fread(p, scanwidth, 1, fp) == 0 && ferror(fp))
+ DEBUG_printf(("Error reading file!"));
+ }
+ else
+ {
+ for (i = scanwidth; i > 0; i --, p ++)
+ {
+ if (run_count > 0)
+ {
+ *p = run_value;
+ run_count --;
+ }
+ else
+ {
+ run_value = getc(fp);
+
+ if (run_value == RAS_RLE)
+ {
+ run_count = getc(fp);
+ if (run_count == 0)
+ *p = RAS_RLE;
+ else
+ run_value = *p = getc(fp);
+ }
+ else
+ *p = run_value;
+ }
+ }
+ }
+
+ if (ras_depth == 1 && ras_maplength == 0)
+ {
+ /*
+ * 1-bit B&W image...
+ */
+
+ for (x = img->xsize, bit = 128, scanptr = scanline, p = in;
+ x > 0;
+ x --, p ++)
+ {
+ if (*scanptr & bit)
+ *p = 255;
+ else
+ *p = 0;
+
+ if (bit > 1)
+ bit >>= 1;
+ else
+ {
+ bit = 128;
+ scanptr ++;
+ }
+ }
+ }
+ else if (ras_depth == 1)
+ {
+ /*
+ * 1-bit colormapped image...
+ */
+
+ for (x = img->xsize, bit = 128, scanptr = scanline, p = in;
+ x > 0;
+ x --)
+ {
+ if (*scanptr & bit)
+ {
+ *p++ = cmap[0][1];
+ *p++ = cmap[1][1];
+ *p++ = cmap[2][1];
+ }
+ else
+ {
+ *p++ = cmap[0][0];
+ *p++ = cmap[1][0];
+ *p++ = cmap[2][0];
+ }
+
+ if (bit > 1)
+ bit >>= 1;
+ else
+ {
+ bit = 128;
+ scanptr ++;
+ }
+ }
+ }
+ else if (ras_depth == 8 && ras_maplength > 0)
+ {
+ /*
+ * 8-bit colormapped image.
+ */
+
+ for (x = img->xsize, scanptr = scanline, p = in;
+ x > 0;
+ x --)
+ {
+ *p++ = cmap[0][*scanptr];
+ *p++ = cmap[1][*scanptr];
+ *p++ = cmap[2][*scanptr++];
+ }
+ }
+ else if (ras_depth == 24 && ras_type != RT_FORMAT_RGB)
+ {
+ /*
+ * Convert BGR to RGB...
+ */
+
+ for (x = img->xsize, scanptr = scanline, p = in;
+ x > 0;
+ x --, scanptr += 3)
+ {
+ *p++ = scanptr[2];
+ *p++ = scanptr[1];
+ *p++ = scanptr[0];
+ }
+ }
+
+ if (ras_depth <= 8 && ras_maplength == 0)
+ {
+ if (img->colorspace == CUPS_IMAGE_WHITE)
+ {
+ if (lut)
+ cupsImageLut(in, img->xsize, lut);
+
+ _cupsImagePutRow(img, 0, y, img->xsize, in);
+ }
+ else
+ {
+ switch (img->colorspace)
+ {
+ default :
+ break;
+
+ case CUPS_IMAGE_RGB :
+ cupsImageWhiteToRGB(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_BLACK :
+ cupsImageWhiteToBlack(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageWhiteToCMY(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageWhiteToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, img->xsize * bpp, lut);
+
+ _cupsImagePutRow(img, 0, y, img->xsize, out);
+ }
+ }
+ else
+ {
+ if ((saturation != 100 || hue != 0) && bpp > 1)
+ cupsImageRGBAdjust(in, img->xsize, saturation, hue);
+
+ switch (img->colorspace)
+ {
+ default :
+ break;
+
+ case CUPS_IMAGE_WHITE :
+ cupsImageRGBToWhite(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_BLACK :
+ cupsImageRGBToBlack(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageRGBToCMY(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageRGBToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, img->xsize * bpp, lut);
+
+ _cupsImagePutRow(img, 0, y, img->xsize, out);
+ }
+ }
+
+ free(scanline);
+ free(in);
+ free(out);
+
+ fclose(fp);
+
+ return (0);
+}
+
+
+/*
+ * 'read_unsigned()' - Read a 32-bit unsigned integer.
+ */
+
+static unsigned /* O - Integer from file */
+read_unsigned(FILE *fp) /* I - File to read from */
+{
+ unsigned v; /* Integer from file */
+
+
+ v = getc(fp);
+ v = (v << 8) | getc(fp);
+ v = (v << 8) | getc(fp);
+ v = (v << 8) | getc(fp);
+
+ return (v);
+}
+
diff --git a/cupsfilters/image-tiff.c b/cupsfilters/image-tiff.c
new file mode 100644
index 000000000..4fd875663
--- /dev/null
+++ b/cupsfilters/image-tiff.c
@@ -0,0 +1,1711 @@
+/*
+ * TIFF file routines for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2007 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * _cupsImageReadTIFF() - Read a TIFF image file.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image-private.h"
+
+#ifdef HAVE_LIBTIFF
+# include <tiff.h> /* TIFF image definitions */
+# include <tiffio.h>
+# include <unistd.h>
+
+
+/*
+ * '_cupsImageReadTIFF()' - Read a TIFF image file.
+ */
+
+int /* O - Read status */
+_cupsImageReadTIFF(
+ cups_image_t *img, /* IO - cupsImage */
+ FILE *fp, /* I - cupsImage file */
+ cups_icspace_t primary, /* I - Primary choice for colorspace */
+ cups_icspace_t secondary, /* I - Secondary choice for colorspace */
+ int saturation, /* I - Color saturation (%) */
+ int hue, /* I - Color hue (degrees) */
+ const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */
+{
+ TIFF *tif; /* TIFF file */
+ uint32 width, height; /* Size of image */
+ uint16 photometric, /* Colorspace */
+ compression, /* Type of compression */
+ orientation, /* Orientation */
+ resunit, /* Units for resolution */
+ samples, /* Number of samples/pixel */
+ bits, /* Number of bits/pixel */
+ inkset, /* Ink set for color separations */
+ numinks; /* Number of inks in set */
+ float xres, /* Horizontal resolution */
+ yres; /* Vertical resolution */
+ uint16 *redcmap, /* Red colormap information */
+ *greencmap, /* Green colormap information */
+ *bluecmap; /* Blue colormap information */
+ int c, /* Color index */
+ num_colors, /* Number of colors */
+ bpp, /* Bytes per pixel */
+ x, y, /* Current x & y */
+ row, /* Current row in image */
+ xstart, ystart, /* Starting x & y */
+ xdir, ydir, /* X & y direction */
+ xcount, ycount, /* X & Y counters */
+ pstep, /* Pixel step (= bpp or -2 * bpp) */
+ scanwidth, /* Width of scanline */
+ r, g, b, k, /* Red, green, blue, and black values */
+ alpha; /* cupsImage includes alpha? */
+ cups_ib_t *in, /* Input buffer */
+ *out, /* Output buffer */
+ *p, /* Pointer into buffer */
+ *scanline, /* Scanline buffer */
+ *scanptr, /* Pointer into scanline buffer */
+ bit, /* Current bit */
+ pixel, /* Current pixel */
+ zero, /* Zero value (bitmaps) */
+ one; /* One value (bitmaps) */
+
+
+ /*
+ * Open the TIFF file and get the required parameters...
+ */
+
+ lseek(fileno(fp), 0, SEEK_SET); /* Work around "feature" in some stdio's */
+
+ if ((tif = TIFFFdOpen(fileno(fp), "", "r")) == NULL)
+ {
+ fputs("DEBUG: TIFFFdOpen() failed!\n", stderr);
+ fclose(fp);
+ return (-1);
+ }
+
+ if (!TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width))
+ {
+ fputs("DEBUG: No image width tag in the file!\n", stderr);
+ TIFFClose(tif);
+ fclose(fp);
+ return (-1);
+ }
+
+ if (!TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height))
+ {
+ fputs("DEBUG: No image height tag in the file!\n", stderr);
+ TIFFClose(tif);
+ fclose(fp);
+ return (-1);
+ }
+
+ if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric))
+ {
+ fputs("DEBUG: No photometric tag in the file!\n", stderr);
+ TIFFClose(tif);
+ fclose(fp);
+ return (-1);
+ }
+
+ if (!TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression))
+ {
+ fputs("DEBUG: No compression tag in the file!\n", stderr);
+ TIFFClose(tif);
+ fclose(fp);
+ return (-1);
+ }
+
+ if (!TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samples))
+ samples = 1;
+
+ if (!TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bits))
+ bits = 1;
+
+ /*
+ * Get the image orientation...
+ */
+
+ if (!TIFFGetField(tif, TIFFTAG_ORIENTATION, &orientation))
+ orientation = 0;
+
+ /*
+ * Get the image resolution...
+ */
+
+ if (TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres) &&
+ TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres) &&
+ TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &resunit))
+ {
+ if (resunit == RESUNIT_INCH)
+ {
+ img->xppi = xres;
+ img->yppi = yres;
+ }
+ else if (resunit == RESUNIT_CENTIMETER)
+ {
+ img->xppi = xres * 2.54;
+ img->yppi = yres * 2.54;
+ }
+ else
+ {
+ img->xppi = 128;
+ img->yppi = 128;
+ }
+
+ if (img->xppi == 0 || img->yppi == 0)
+ {
+ fputs("DEBUG: Bad TIFF resolution.\n", stderr);
+ img->xppi = img->yppi = 128;
+ }
+
+ fprintf(stderr, "DEBUG: TIFF resolution = %fx%f, units=%d\n",
+ xres, yres, resunit);
+ fprintf(stderr, "DEBUG: Stored resolution = %dx%d PPI\n",
+ img->xppi, img->yppi);
+ }
+
+ /*
+ * See if the image has an alpha channel...
+ */
+
+ if (samples == 2 || (samples == 4 && photometric == PHOTOMETRIC_RGB))
+ alpha = 1;
+ else
+ alpha = 0;
+
+ /*
+ * Check the size of the image...
+ */
+
+ if (width == 0 || width > CUPS_IMAGE_MAX_WIDTH ||
+ height == 0 || height > CUPS_IMAGE_MAX_HEIGHT ||
+ (bits != 1 && bits != 2 && bits != 4 && bits != 8) ||
+ samples < 1 || samples > 4)
+ {
+ fprintf(stderr, "DEBUG: Bad TIFF dimensions %ux%ux%ux%u!\n",
+ (unsigned)width, (unsigned)height, (unsigned)bits,
+ (unsigned)samples);
+ TIFFClose(tif);
+ fclose(fp);
+ return (1);
+ }
+
+ /*
+ * Setup the image size and colorspace...
+ */
+
+ img->xsize = width;
+ img->ysize = height;
+ if (photometric == PHOTOMETRIC_MINISBLACK ||
+ photometric == PHOTOMETRIC_MINISWHITE)
+ img->colorspace = secondary;
+ else if (photometric == PHOTOMETRIC_SEPARATED && primary == CUPS_IMAGE_RGB_CMYK)
+ img->colorspace = CUPS_IMAGE_CMYK;
+ else if (primary == CUPS_IMAGE_RGB_CMYK)
+ img->colorspace = CUPS_IMAGE_RGB;
+ else
+ img->colorspace = primary;
+
+ fprintf(stderr, "DEBUG: img->colorspace = %d\n", img->colorspace);
+
+ bpp = cupsImageGetDepth(img);
+
+ cupsImageSetMaxTiles(img, 0);
+
+ /*
+ * Set the X & Y start and direction according to the image orientation...
+ */
+
+ switch (orientation)
+ {
+ case ORIENTATION_TOPRIGHT :
+ fputs("DEBUG: orientation = top-right\n", stderr);
+ break;
+ case ORIENTATION_RIGHTTOP :
+ fputs("DEBUG: orientation = right-top\n", stderr);
+ break;
+ default :
+ case ORIENTATION_TOPLEFT :
+ fputs("DEBUG: orientation = top-left\n", stderr);
+ break;
+ case ORIENTATION_LEFTTOP :
+ fputs("DEBUG: orientation = left-top\n", stderr);
+ break;
+ case ORIENTATION_BOTLEFT :
+ fputs("DEBUG: orientation = bottom-left\n", stderr);
+ break;
+ case ORIENTATION_LEFTBOT :
+ fputs("DEBUG: orientation = left-bottom\n", stderr);
+ break;
+ case ORIENTATION_BOTRIGHT :
+ fputs("DEBUG: orientation = bottom-right\n", stderr);
+ break;
+ case ORIENTATION_RIGHTBOT :
+ fputs("DEBUG: orientation = right-bottom\n", stderr);
+ break;
+ }
+
+ switch (orientation)
+ {
+ case ORIENTATION_TOPRIGHT :
+ case ORIENTATION_RIGHTTOP :
+ xstart = img->xsize - 1;
+ xdir = -1;
+ ystart = 0;
+ ydir = 1;
+ break;
+ default :
+ case ORIENTATION_TOPLEFT :
+ case ORIENTATION_LEFTTOP :
+ xstart = 0;
+ xdir = 1;
+ ystart = 0;
+ ydir = 1;
+ break;
+ case ORIENTATION_BOTLEFT :
+ case ORIENTATION_LEFTBOT :
+ xstart = 0;
+ xdir = 1;
+ ystart = img->ysize - 1;
+ ydir = -1;
+ break;
+ case ORIENTATION_BOTRIGHT :
+ case ORIENTATION_RIGHTBOT :
+ xstart = img->xsize - 1;
+ xdir = -1;
+ ystart = img->ysize - 1;
+ ydir = -1;
+ break;
+ }
+
+ /*
+ * Allocate a scanline buffer...
+ */
+
+ scanwidth = TIFFScanlineSize(tif);
+ scanline = _TIFFmalloc(scanwidth);
+
+ /*
+ * Allocate input and output buffers...
+ */
+
+ if (orientation < ORIENTATION_LEFTTOP)
+ {
+ if (samples > 1 || photometric == PHOTOMETRIC_PALETTE)
+ pstep = xdir * 3;
+ else
+ pstep = xdir;
+
+ in = malloc(img->xsize * 3 + 3);
+ out = malloc(img->xsize * bpp);
+ }
+ else
+ {
+ if (samples > 1 || photometric == PHOTOMETRIC_PALETTE)
+ pstep = ydir * 3;
+ else
+ pstep = ydir;
+
+ in = malloc(img->ysize * 3 + 3);
+ out = malloc(img->ysize * bpp);
+ }
+
+ /*
+ * Read the image. This is greatly complicated by the fact that TIFF
+ * supports literally hundreds of different colorspaces and orientations,
+ * each which must be handled separately...
+ */
+
+ fprintf(stderr, "DEBUG: photometric = %d\n", photometric);
+ fprintf(stderr, "DEBUG: compression = %d\n", compression);
+
+ switch (photometric)
+ {
+ case PHOTOMETRIC_MINISWHITE :
+ case PHOTOMETRIC_MINISBLACK :
+ if (photometric == PHOTOMETRIC_MINISWHITE)
+ {
+ zero = 255;
+ one = 0;
+ }
+ else
+ {
+ zero = 0;
+ one = 255;
+ }
+
+ if (orientation < ORIENTATION_LEFTTOP)
+ {
+ /*
+ * Row major order...
+ */
+
+ for (y = ystart, ycount = img->ysize, row = 0;
+ ycount > 0;
+ ycount --, y += ydir, row ++)
+ {
+ if (bits == 1)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline, p = in + xstart, bit = 128;
+ xcount > 0;
+ xcount --, p += pstep)
+ {
+ if (*scanptr & bit)
+ *p = one;
+ else
+ *p = zero;
+
+ if (bit > 1)
+ bit >>= 1;
+ else
+ {
+ bit = 128;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 2)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline, p = in + xstart, bit = 0xc0;
+ xcount > 0;
+ xcount --, p += pstep)
+ {
+ pixel = *scanptr & bit;
+ while (pixel > 3)
+ pixel >>= 2;
+ *p = (255 * pixel / 3) ^ zero;
+
+ if (bit > 3)
+ bit >>= 2;
+ else
+ {
+ bit = 0xc0;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 4)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline, p = in + xstart, bit = 0xf0;
+ xcount > 0;
+ xcount --, p += pstep)
+ {
+ if (bit == 0xf0)
+ {
+ *p = (255 * ((*scanptr & 0xf0) >> 4) / 15) ^ zero;
+ bit = 0x0f;
+ }
+ else
+ {
+ *p = (255 * (*scanptr & 0x0f) / 15) ^ zero;
+ bit = 0xf0;
+ scanptr ++;
+ }
+ }
+ }
+ else if (xdir < 0 || zero || alpha)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+
+ if (alpha)
+ {
+ if (zero)
+ {
+ for (xcount = img->xsize, p = in + xstart, scanptr = scanline;
+ xcount > 0;
+ xcount --, p += pstep, scanptr += 2)
+ *p = (scanptr[1] * (255 - scanptr[0]) +
+ (255 - scanptr[1]) * 255) / 255;
+ }
+ else
+ {
+ for (xcount = img->xsize, p = in + xstart, scanptr = scanline;
+ xcount > 0;
+ xcount --, p += pstep, scanptr += 2)
+ *p = (scanptr[1] * scanptr[0] +
+ (255 - scanptr[1]) * 255) / 255;
+ }
+ }
+ else
+ {
+ if (zero)
+ {
+ for (xcount = img->xsize, p = in + xstart, scanptr = scanline;
+ xcount > 0;
+ xcount --, p += pstep, scanptr ++)
+ *p = 255 - *scanptr;
+ }
+ else
+ {
+ for (xcount = img->xsize, p = in + xstart, scanptr = scanline;
+ xcount > 0;
+ xcount --, p += pstep, scanptr ++)
+ *p = *scanptr;
+ }
+ }
+ }
+ else
+ TIFFReadScanline(tif, in, row, 0);
+
+ if (img->colorspace == CUPS_IMAGE_WHITE)
+ {
+ if (lut)
+ cupsImageLut(in, img->xsize, lut);
+
+ _cupsImagePutRow(img, 0, y, img->xsize, in);
+ }
+ else
+ {
+ switch (img->colorspace)
+ {
+ default :
+ break;
+
+ case CUPS_IMAGE_RGB :
+ cupsImageWhiteToRGB(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_BLACK :
+ cupsImageWhiteToBlack(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageWhiteToCMY(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageWhiteToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, img->xsize * bpp, lut);
+
+ _cupsImagePutRow(img, 0, y, img->xsize, out);
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Column major order...
+ */
+
+ for (x = xstart, xcount = img->xsize, row = 0;
+ xcount > 0;
+ xcount --, x += xdir, row ++)
+ {
+ if (bits == 1)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline, p = in + ystart, bit = 128;
+ ycount > 0;
+ ycount --, p += ydir)
+ {
+ if (*scanptr & bit)
+ *p = one;
+ else
+ *p = zero;
+
+ if (bit > 1)
+ bit >>= 1;
+ else
+ {
+ bit = 128;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 2)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline, p = in + ystart, bit = 0xc0;
+ ycount > 0;
+ ycount --, p += ydir)
+ {
+ pixel = *scanptr & 0xc0;
+ while (pixel > 3)
+ pixel >>= 2;
+
+ *p = (255 * pixel / 3) ^ zero;
+
+ if (bit > 3)
+ bit >>= 2;
+ else
+ {
+ bit = 0xc0;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 4)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline, p = in + ystart, bit = 0xf0;
+ ycount > 0;
+ ycount --, p += ydir)
+ {
+ if (bit == 0xf0)
+ {
+ *p = (255 * ((*scanptr & 0xf0) >> 4) / 15) ^ zero;
+ bit = 0x0f;
+ }
+ else
+ {
+ *p = (255 * (*scanptr & 0x0f) / 15) ^ zero;
+ bit = 0xf0;
+ scanptr ++;
+ }
+ }
+ }
+ else if (ydir < 0 || zero || alpha)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+
+ if (alpha)
+ {
+ if (zero)
+ {
+ for (ycount = img->ysize, p = in + ystart, scanptr = scanline;
+ ycount > 0;
+ ycount --, p += ydir, scanptr += 2)
+ *p = (scanptr[1] * (255 - scanptr[0]) +
+ (255 - scanptr[1]) * 255) / 255;
+ }
+ else
+ {
+ for (ycount = img->ysize, p = in + ystart, scanptr = scanline;
+ ycount > 0;
+ ycount --, p += ydir, scanptr += 2)
+ *p = (scanptr[1] * scanptr[0] +
+ (255 - scanptr[1]) * 255) / 255;
+ }
+ }
+ else
+ {
+ if (zero)
+ {
+ for (ycount = img->ysize, p = in + ystart, scanptr = scanline;
+ ycount > 0;
+ ycount --, p += ydir, scanptr ++)
+ *p = 255 - *scanptr;
+ }
+ else
+ {
+ for (ycount = img->ysize, p = in + ystart, scanptr = scanline;
+ ycount > 0;
+ ycount --, p += ydir, scanptr ++)
+ *p = *scanptr;
+ }
+ }
+ }
+ else
+ TIFFReadScanline(tif, in, row, 0);
+
+ if (img->colorspace == CUPS_IMAGE_WHITE)
+ {
+ if (lut)
+ cupsImageLut(in, img->ysize, lut);
+
+ _cupsImagePutCol(img, x, 0, img->ysize, in);
+ }
+ else
+ {
+ switch (img->colorspace)
+ {
+ default :
+ break;
+
+ case CUPS_IMAGE_RGB :
+ cupsImageWhiteToRGB(in, out, img->ysize);
+ break;
+ case CUPS_IMAGE_BLACK :
+ cupsImageWhiteToBlack(in, out, img->ysize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageWhiteToCMY(in, out, img->ysize);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageWhiteToCMYK(in, out, img->ysize);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, img->ysize * bpp, lut);
+
+ _cupsImagePutCol(img, x, 0, img->ysize, out);
+ }
+ }
+ }
+ break;
+
+ case PHOTOMETRIC_PALETTE :
+ if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &redcmap, &greencmap, &bluecmap))
+ {
+ _TIFFfree(scanline);
+ free(in);
+ free(out);
+
+ TIFFClose(tif);
+ fputs("DEBUG: No colormap tag in the file!\n", stderr);
+ fclose(fp);
+ return (-1);
+ }
+
+ num_colors = 1 << bits;
+
+ for (c = 0; c < num_colors; c ++)
+ {
+ redcmap[c] >>= 8;
+ greencmap[c] >>= 8;
+ bluecmap[c] >>= 8;
+ }
+
+ if (orientation < ORIENTATION_LEFTTOP)
+ {
+ /*
+ * Row major order...
+ */
+
+ for (y = ystart, ycount = img->ysize, row = 0;
+ ycount > 0;
+ ycount --, y += ydir, row ++)
+ {
+ if (bits == 1)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline,
+ p = in + xstart * 3, bit = 128;
+ xcount > 0;
+ xcount --, p += pstep)
+ {
+ if (*scanptr & bit)
+ {
+ p[0] = redcmap[1];
+ p[1] = greencmap[1];
+ p[2] = bluecmap[1];
+ }
+ else
+ {
+ p[0] = redcmap[0];
+ p[1] = greencmap[0];
+ p[2] = bluecmap[0];
+ }
+
+ if (bit > 1)
+ bit >>= 1;
+ else
+ {
+ bit = 128;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 2)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline,
+ p = in + xstart * 3, bit = 0xc0;
+ xcount > 0;
+ xcount --, p += pstep)
+ {
+ pixel = *scanptr & bit;
+ while (pixel > 3)
+ pixel >>= 2;
+
+ p[0] = redcmap[pixel];
+ p[1] = greencmap[pixel];
+ p[2] = bluecmap[pixel];
+
+ if (bit > 3)
+ bit >>= 2;
+ else
+ {
+ bit = 0xc0;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 4)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline,
+ p = in + 3 * xstart, bit = 0xf0;
+ xcount > 0;
+ xcount --, p += pstep)
+ {
+ if (bit == 0xf0)
+ {
+ pixel = (*scanptr & 0xf0) >> 4;
+ p[0] = redcmap[pixel];
+ p[1] = greencmap[pixel];
+ p[2] = bluecmap[pixel];
+ bit = 0x0f;
+ }
+ else
+ {
+ pixel = *scanptr++ & 0x0f;
+ p[0] = redcmap[pixel];
+ p[1] = greencmap[pixel];
+ p[2] = bluecmap[pixel];
+ bit = 0xf0;
+ }
+ }
+ }
+ else
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+
+ for (xcount = img->xsize, p = in + 3 * xstart, scanptr = scanline;
+ xcount > 0;
+ xcount --, p += pstep)
+ {
+ p[0] = redcmap[*scanptr];
+ p[1] = greencmap[*scanptr];
+ p[2] = bluecmap[*scanptr++];
+ }
+ }
+
+ switch (img->colorspace)
+ {
+ default :
+ break;
+
+ case CUPS_IMAGE_WHITE :
+ cupsImageRGBToWhite(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_RGB :
+ cupsImageRGBToRGB(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_BLACK :
+ cupsImageRGBToBlack(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageRGBToCMY(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageRGBToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, img->xsize * bpp, lut);
+
+ _cupsImagePutRow(img, 0, y, img->xsize, out);
+ }
+ }
+ else
+ {
+ /*
+ * Column major order...
+ */
+
+ for (x = xstart, xcount = img->xsize, row = 0;
+ xcount > 0;
+ xcount --, x += xdir, row ++)
+ {
+ if (bits == 1)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline,
+ p = in + 3 * ystart, bit = 128;
+ ycount > 0;
+ ycount --, p += ydir)
+ {
+ if (*scanptr & bit)
+ {
+ p[0] = redcmap[1];
+ p[1] = greencmap[1];
+ p[2] = bluecmap[1];
+ }
+ else
+ {
+ p[0] = redcmap[0];
+ p[1] = greencmap[0];
+ p[2] = bluecmap[0];
+ }
+
+ if (bit > 1)
+ bit >>= 1;
+ else
+ {
+ bit = 128;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 2)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline,
+ p = in + 3 * ystart, bit = 0xc0;
+ ycount > 0;
+ ycount --, p += ydir)
+ {
+ pixel = *scanptr & 0xc0;
+ while (pixel > 3)
+ pixel >>= 2;
+
+ p[0] = redcmap[pixel];
+ p[1] = greencmap[pixel];
+ p[2] = bluecmap[pixel];
+
+ if (bit > 3)
+ bit >>= 2;
+ else
+ {
+ bit = 0xc0;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 4)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline,
+ p = in + 3 * ystart, bit = 0xf0;
+ ycount > 0;
+ ycount --, p += ydir)
+ {
+ if (bit == 0xf0)
+ {
+ pixel = (*scanptr & 0xf0) >> 4;
+ p[0] = redcmap[pixel];
+ p[1] = greencmap[pixel];
+ p[2] = bluecmap[pixel];
+ bit = 0x0f;
+ }
+ else
+ {
+ pixel = *scanptr++ & 0x0f;
+ p[0] = redcmap[pixel];
+ p[1] = greencmap[pixel];
+ p[2] = bluecmap[pixel];
+ bit = 0xf0;
+ }
+ }
+ }
+ else
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+
+ for (ycount = img->ysize, p = in + 3 * ystart, scanptr = scanline;
+ ycount > 0;
+ ycount --, p += ydir)
+ {
+ p[0] = redcmap[*scanptr];
+ p[1] = greencmap[*scanptr];
+ p[2] = bluecmap[*scanptr++];
+ }
+ }
+
+ switch (img->colorspace)
+ {
+ default :
+ break;
+
+ case CUPS_IMAGE_WHITE :
+ cupsImageRGBToWhite(in, out, img->ysize);
+ break;
+ case CUPS_IMAGE_RGB :
+ cupsImageRGBToRGB(in, out, img->ysize);
+ break;
+ case CUPS_IMAGE_BLACK :
+ cupsImageRGBToBlack(in, out, img->ysize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageRGBToCMY(in, out, img->ysize);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageRGBToCMYK(in, out, img->ysize);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, img->ysize * bpp, lut);
+
+ _cupsImagePutCol(img, x, 0, img->ysize, out);
+ }
+ }
+ break;
+
+ case PHOTOMETRIC_RGB :
+ if (orientation < ORIENTATION_LEFTTOP)
+ {
+ /*
+ * Row major order...
+ */
+
+ for (y = ystart, ycount = img->ysize, row = 0;
+ ycount > 0;
+ ycount --, y += ydir, row ++)
+ {
+ if (bits == 1)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3, bit = 0xf0;
+ xcount > 0;
+ xcount --, p += pstep)
+ {
+ if (*scanptr & bit & 0x88)
+ p[0] = 255;
+ else
+ p[0] = 0;
+
+ if (*scanptr & bit & 0x44)
+ p[1] = 255;
+ else
+ p[1] = 0;
+
+ if (*scanptr & bit & 0x22)
+ p[2] = 255;
+ else
+ p[2] = 0;
+
+ if (bit == 0xf0)
+ bit = 0x0f;
+ else
+ {
+ bit = 0xf0;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 2)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3;
+ xcount > 0;
+ xcount --, p += pstep, scanptr ++)
+ {
+ pixel = *scanptr >> 2;
+ p[0] = 255 * (pixel & 3) / 3;
+ pixel >>= 2;
+ p[1] = 255 * (pixel & 3) / 3;
+ pixel >>= 2;
+ p[2] = 255 * (pixel & 3) / 3;
+ }
+ }
+ else if (bits == 4)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3;
+ xcount > 0;
+ xcount -= 2, p += 2 * pstep, scanptr += 3)
+ {
+ pixel = scanptr[0];
+ p[1] = 255 * (pixel & 15) / 15;
+ pixel >>= 4;
+ p[0] = 255 * (pixel & 15) / 15;
+ pixel = scanptr[1];
+ p[2] = 255 * ((pixel >> 4) & 15) / 15;
+
+ if (xcount > 1)
+ {
+ p[pstep + 0] = 255 * (pixel & 15) / 15;
+ pixel = scanptr[2];
+ p[pstep + 2] = 255 * (pixel & 15) / 15;
+ pixel >>= 4;
+ p[pstep + 1] = 255 * (pixel & 15) / 15;
+ }
+ }
+ }
+ else if (xdir < 0 || alpha)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+
+ if (alpha)
+ {
+ for (xcount = img->xsize, p = in + xstart * 3, scanptr = scanline;
+ xcount > 0;
+ xcount --, p += pstep, scanptr += 4)
+ {
+ p[0] = (scanptr[0] * scanptr[3] + 255 * (255 - scanptr[3])) / 255;
+ p[1] = (scanptr[1] * scanptr[3] + 255 * (255 - scanptr[3])) / 255;
+ p[2] = (scanptr[2] * scanptr[3] + 255 * (255 - scanptr[3])) / 255;
+ }
+ }
+ else
+ {
+ for (xcount = img->xsize, p = in + xstart * 3, scanptr = scanline;
+ xcount > 0;
+ xcount --, p += pstep, scanptr += 3)
+ {
+ p[0] = scanptr[0];
+ p[1] = scanptr[1];
+ p[2] = scanptr[2];
+ }
+ }
+ }
+ else
+ TIFFReadScanline(tif, in, row, 0);
+
+ if ((saturation != 100 || hue != 0) && bpp > 1)
+ cupsImageRGBAdjust(in, img->xsize, saturation, hue);
+
+ switch (img->colorspace)
+ {
+ default :
+ break;
+
+ case CUPS_IMAGE_WHITE :
+ cupsImageRGBToWhite(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_RGB :
+ cupsImageRGBToRGB(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_BLACK :
+ cupsImageRGBToBlack(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageRGBToCMY(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageRGBToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, img->xsize * bpp, lut);
+
+ _cupsImagePutRow(img, 0, y, img->xsize, out);
+ }
+ }
+ else
+ {
+ /*
+ * Column major order...
+ */
+
+ for (x = xstart, xcount = img->xsize, row = 0;
+ xcount > 0;
+ xcount --, x += xdir, row ++)
+ {
+ if (bits == 1)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline, p = in + ystart * 3, bit = 0xf0;
+ ycount > 0;
+ ycount --, p += pstep)
+ {
+ if (*scanptr & bit & 0x88)
+ p[0] = 255;
+ else
+ p[0] = 0;
+
+ if (*scanptr & bit & 0x44)
+ p[1] = 255;
+ else
+ p[1] = 0;
+
+ if (*scanptr & bit & 0x22)
+ p[2] = 255;
+ else
+ p[2] = 0;
+
+ if (bit == 0xf0)
+ bit = 0x0f;
+ else
+ {
+ bit = 0xf0;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 2)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline, p = in + ystart * 3;
+ ycount > 0;
+ ycount --, p += pstep, scanptr ++)
+ {
+ pixel = *scanptr >> 2;
+ p[0] = 255 * (pixel & 3) / 3;
+ pixel >>= 2;
+ p[1] = 255 * (pixel & 3) / 3;
+ pixel >>= 2;
+ p[2] = 255 * (pixel & 3) / 3;
+ }
+ }
+ else if (bits == 4)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline, p = in + ystart * 3;
+ ycount > 0;
+ ycount -= 2, p += 2 * pstep, scanptr += 3)
+ {
+ pixel = scanptr[0];
+ p[1] = 255 * (pixel & 15) / 15;
+ pixel >>= 4;
+ p[0] = 255 * (pixel & 15) / 15;
+ pixel = scanptr[1];
+ p[2] = 255 * ((pixel >> 4) & 15) / 15;
+
+ if (ycount > 1)
+ {
+ p[pstep + 0] = 255 * (pixel & 15) / 15;
+ pixel = scanptr[2];
+ p[pstep + 2] = 255 * (pixel & 15) / 15;
+ pixel >>= 4;
+ p[pstep + 1] = 255 * (pixel & 15) / 15;
+ }
+ }
+ }
+ else if (ydir < 0 || alpha)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+
+ if (alpha)
+ {
+ for (ycount = img->ysize, p = in + ystart * 3, scanptr = scanline;
+ ycount > 0;
+ ycount --, p += pstep, scanptr += 4)
+ {
+ p[0] = (scanptr[0] * scanptr[3] + 255 * (255 - scanptr[3])) / 255;
+ p[1] = (scanptr[1] * scanptr[3] + 255 * (255 - scanptr[3])) / 255;
+ p[2] = (scanptr[2] * scanptr[3] + 255 * (255 - scanptr[3])) / 255;
+ }
+ }
+ else
+ {
+ for (ycount = img->ysize, p = in + ystart * 3, scanptr = scanline;
+ ycount > 0;
+ ycount --, p += pstep, scanptr += 3)
+ {
+ p[0] = scanptr[0];
+ p[1] = scanptr[1];
+ p[2] = scanptr[2];
+ }
+ }
+ }
+ else
+ TIFFReadScanline(tif, in, row, 0);
+
+ if ((saturation != 100 || hue != 0) && bpp > 1)
+ cupsImageRGBAdjust(in, img->ysize, saturation, hue);
+
+ switch (img->colorspace)
+ {
+ default :
+ break;
+
+ case CUPS_IMAGE_WHITE :
+ cupsImageRGBToWhite(in, out, img->ysize);
+ break;
+ case CUPS_IMAGE_RGB :
+ cupsImageRGBToRGB(in, out, img->ysize);
+ break;
+ case CUPS_IMAGE_BLACK :
+ cupsImageRGBToBlack(in, out, img->ysize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageRGBToCMY(in, out, img->ysize);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageRGBToCMYK(in, out, img->ysize);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, img->ysize * bpp, lut);
+
+ _cupsImagePutCol(img, x, 0, img->ysize, out);
+ }
+ }
+ break;
+
+ case PHOTOMETRIC_SEPARATED :
+ inkset = INKSET_CMYK;
+ numinks = 4;
+
+#ifdef TIFFTAG_NUMBEROFINKS
+ if (!TIFFGetField(tif, TIFFTAG_INKSET, &inkset) &&
+ !TIFFGetField(tif, TIFFTAG_NUMBEROFINKS, &numinks))
+#else
+ if (!TIFFGetField(tif, TIFFTAG_INKSET, &inkset))
+#endif /* TIFFTAG_NUMBEROFINKS */
+ {
+ fputs("WARNING: No inkset or number-of-inks tag in the file!\n", stderr);
+ }
+
+ if (inkset == INKSET_CMYK || numinks == 4)
+ {
+ if (orientation < ORIENTATION_LEFTTOP)
+ {
+ /*
+ * Row major order...
+ */
+
+ for (y = ystart, ycount = img->ysize, row = 0;
+ ycount > 0;
+ ycount --, y += ydir, row ++)
+ {
+ if (bits == 1)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3, bit = 0xf0;
+ xcount > 0;
+ xcount --, p += pstep)
+ {
+ if (*scanptr & bit & 0x11)
+ {
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+ }
+ else
+ {
+ if (*scanptr & bit & 0x88)
+ p[0] = 0;
+ else
+ p[0] = 255;
+
+ if (*scanptr & bit & 0x44)
+ p[1] = 0;
+ else
+ p[1] = 255;
+
+ if (*scanptr & bit & 0x22)
+ p[2] = 0;
+ else
+ p[2] = 255;
+ }
+
+ if (bit == 0xf0)
+ bit = 0x0f;
+ else
+ {
+ bit = 0xf0;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 2)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3;
+ xcount > 0;
+ xcount --, p += pstep, scanptr ++)
+ {
+ pixel = *scanptr;
+ k = 255 * (pixel & 3) / 3;
+ if (k == 255)
+ {
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+ }
+ else
+ {
+ pixel >>= 2;
+ b = 255 - 255 * (pixel & 3) / 3 - k;
+ if (b < 0)
+ p[2] = 0;
+ else if (b < 256)
+ p[2] = b;
+ else
+ p[2] = 255;
+
+ pixel >>= 2;
+ g = 255 - 255 * (pixel & 3) / 3 - k;
+ if (g < 0)
+ p[1] = 0;
+ else if (g < 256)
+ p[1] = g;
+ else
+ p[1] = 255;
+
+ pixel >>= 2;
+ r = 255 - 255 * (pixel & 3) / 3 - k;
+ if (r < 0)
+ p[0] = 0;
+ else if (r < 256)
+ p[0] = r;
+ else
+ p[0] = 255;
+ }
+ }
+ }
+ else if (bits == 4)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3;
+ xcount > 0;
+ xcount --, p += pstep, scanptr += 2)
+ {
+ pixel = scanptr[1];
+ k = 255 * (pixel & 15) / 15;
+ if (k == 255)
+ {
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+ }
+ else
+ {
+ pixel >>= 4;
+ b = 255 - 255 * (pixel & 15) / 15 - k;
+ if (b < 0)
+ p[2] = 0;
+ else if (b < 256)
+ p[2] = b;
+ else
+ p[2] = 255;
+
+ pixel = scanptr[0];
+ g = 255 - 255 * (pixel & 15) / 15 - k;
+ if (g < 0)
+ p[1] = 0;
+ else if (g < 256)
+ p[1] = g;
+ else
+ p[1] = 255;
+
+ pixel >>= 4;
+ r = 255 - 255 * (pixel & 15) / 15 - k;
+ if (r < 0)
+ p[0] = 0;
+ else if (r < 256)
+ p[0] = r;
+ else
+ p[0] = 255;
+ }
+ }
+ }
+ else if (img->colorspace == CUPS_IMAGE_CMYK)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ _cupsImagePutRow(img, 0, y, img->xsize, scanline);
+ }
+ else
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+
+ for (xcount = img->xsize, p = in + xstart * 3, scanptr = scanline;
+ xcount > 0;
+ xcount --, p += pstep, scanptr += 4)
+ {
+ k = scanptr[3];
+ if (k == 255)
+ {
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+ }
+ else
+ {
+ r = 255 - scanptr[0] - k;
+ if (r < 0)
+ p[0] = 0;
+ else if (r < 256)
+ p[0] = r;
+ else
+ p[0] = 255;
+
+ g = 255 - scanptr[1] - k;
+ if (g < 0)
+ p[1] = 0;
+ else if (g < 256)
+ p[1] = g;
+ else
+ p[1] = 255;
+
+ b = 255 - scanptr[2] - k;
+ if (b < 0)
+ p[2] = 0;
+ else if (b < 256)
+ p[2] = b;
+ else
+ p[2] = 255;
+ }
+ }
+ }
+
+ if ((saturation != 100 || hue != 0) && bpp > 1)
+ cupsImageRGBAdjust(in, img->xsize, saturation, hue);
+
+ switch (img->colorspace)
+ {
+ default :
+ break;
+
+ case CUPS_IMAGE_WHITE :
+ cupsImageRGBToWhite(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_RGB :
+ cupsImageRGBToRGB(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_BLACK :
+ cupsImageRGBToBlack(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageRGBToCMY(in, out, img->xsize);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageRGBToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, img->xsize * 3, lut);
+
+ _cupsImagePutRow(img, 0, y, img->xsize, out);
+ }
+ }
+ else
+ {
+ /*
+ * Column major order...
+ */
+
+ for (x = xstart, xcount = img->xsize, row = 0;
+ xcount > 0;
+ xcount --, x += xdir, row ++)
+ {
+ if (bits == 1)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline, p = in + xstart * 3, bit = 0xf0;
+ ycount > 0;
+ ycount --, p += pstep)
+ {
+ if (*scanptr & bit & 0x11)
+ {
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+ }
+ else
+ {
+ if (*scanptr & bit & 0x88)
+ p[0] = 0;
+ else
+ p[0] = 255;
+
+ if (*scanptr & bit & 0x44)
+ p[1] = 0;
+ else
+ p[1] = 255;
+
+ if (*scanptr & bit & 0x22)
+ p[2] = 0;
+ else
+ p[2] = 255;
+ }
+
+ if (bit == 0xf0)
+ bit = 0x0f;
+ else
+ {
+ bit = 0xf0;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 2)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline, p = in + xstart * 3;
+ ycount > 0;
+ ycount --, p += pstep, scanptr ++)
+ {
+ pixel = *scanptr;
+ k = 255 * (pixel & 3) / 3;
+ if (k == 255)
+ {
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+ }
+ else
+ {
+ pixel >>= 2;
+ b = 255 - 255 * (pixel & 3) / 3 - k;
+ if (b < 0)
+ p[2] = 0;
+ else if (b < 256)
+ p[2] = b;
+ else
+ p[2] = 255;
+
+ pixel >>= 2;
+ g = 255 - 255 * (pixel & 3) / 3 - k;
+ if (g < 0)
+ p[1] = 0;
+ else if (g < 256)
+ p[1] = g;
+ else
+ p[1] = 255;
+
+ pixel >>= 2;
+ r = 255 - 255 * (pixel & 3) / 3 - k;
+ if (r < 0)
+ p[0] = 0;
+ else if (r < 256)
+ p[0] = r;
+ else
+ p[0] = 255;
+ }
+ }
+ }
+ else if (bits == 4)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline, p = in + xstart * 3;
+ ycount > 0;
+ ycount --, p += pstep, scanptr += 2)
+ {
+ pixel = scanptr[1];
+ k = 255 * (pixel & 15) / 15;
+ if (k == 255)
+ {
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+ }
+ else
+ {
+ pixel >>= 4;
+ b = 255 - 255 * (pixel & 15) / 15 - k;
+ if (b < 0)
+ p[2] = 0;
+ else if (b < 256)
+ p[2] = b;
+ else
+ p[2] = 255;
+
+ pixel = scanptr[0];
+ g = 255 - 255 * (pixel & 15) / 15 - k;
+ if (g < 0)
+ p[1] = 0;
+ else if (g < 256)
+ p[1] = g;
+ else
+ p[1] = 255;
+
+ pixel >>= 4;
+ r = 255 - 255 * (pixel & 15) / 15 - k;
+ if (r < 0)
+ p[0] = 0;
+ else if (r < 256)
+ p[0] = r;
+ else
+ p[0] = 255;
+ }
+ }
+ }
+ else if (img->colorspace == CUPS_IMAGE_CMYK)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ _cupsImagePutCol(img, x, 0, img->ysize, scanline);
+ }
+ else
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+
+ for (ycount = img->ysize, p = in + xstart * 3, scanptr = scanline;
+ ycount > 0;
+ ycount --, p += pstep, scanptr += 4)
+ {
+ k = scanptr[3];
+ if (k == 255)
+ {
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+ }
+ else
+ {
+ r = 255 - scanptr[0] - k;
+ if (r < 0)
+ p[0] = 0;
+ else if (r < 256)
+ p[0] = r;
+ else
+ p[0] = 255;
+
+ g = 255 - scanptr[1] - k;
+ if (g < 0)
+ p[1] = 0;
+ else if (g < 256)
+ p[1] = g;
+ else
+ p[1] = 255;
+
+ b = 255 - scanptr[2] - k;
+ if (b < 0)
+ p[2] = 0;
+ else if (b < 256)
+ p[2] = b;
+ else
+ p[2] = 255;
+ }
+ }
+ }
+
+ if ((saturation != 100 || hue != 0) && bpp > 1)
+ cupsImageRGBAdjust(in, img->ysize, saturation, hue);
+
+ switch (img->colorspace)
+ {
+ default :
+ break;
+
+ case CUPS_IMAGE_WHITE :
+ cupsImageRGBToWhite(in, out, img->ysize);
+ break;
+ case CUPS_IMAGE_RGB :
+ cupsImageRGBToRGB(in, out, img->ysize);
+ break;
+ case CUPS_IMAGE_BLACK :
+ cupsImageRGBToBlack(in, out, img->ysize);
+ break;
+ case CUPS_IMAGE_CMY :
+ cupsImageRGBToCMY(in, out, img->ysize);
+ break;
+ case CUPS_IMAGE_CMYK :
+ cupsImageRGBToCMYK(in, out, img->ysize);
+ break;
+ }
+
+ if (lut)
+ cupsImageLut(out, img->ysize * bpp, lut);
+
+ _cupsImagePutCol(img, x, 0, img->ysize, out);
+ }
+ }
+
+ break;
+ }
+
+ default :
+ _TIFFfree(scanline);
+ free(in);
+ free(out);
+
+ TIFFClose(tif);
+ fputs("DEBUG: Unknown TIFF photometric value!\n", stderr);
+ return (-1);
+ }
+
+ /*
+ * Free temporary buffers, close the TIFF file, and return.
+ */
+
+ _TIFFfree(scanline);
+ free(in);
+ free(out);
+
+ TIFFClose(tif);
+ return (0);
+}
+#endif /* HAVE_LIBTIFF */
+
diff --git a/cupsfilters/image-zoom.c b/cupsfilters/image-zoom.c
new file mode 100644
index 000000000..5896665f6
--- /dev/null
+++ b/cupsfilters/image-zoom.c
@@ -0,0 +1,352 @@
+/*
+ * cupsImage zoom routines for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2006 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * _cupsImageZoomDelete() - Free a zoom record...
+ * _cupsImageZoomFill() - Fill a zoom record...
+ * _cupsImageZoomNew() - Allocate a pixel zoom record...
+ * zoom_bilinear() - Fill a zoom record with image data utilizing
+ * bilinear interpolation.
+ * zoom_nearest() - Fill a zoom record quickly using nearest-neighbor
+ * sampling.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image-private.h"
+
+
+/*
+ * Local functions...
+ */
+
+static void zoom_bilinear(cups_izoom_t *z, int iy);
+static void zoom_nearest(cups_izoom_t *z, int iy);
+
+
+/*
+ * '_cupsImageZoomDelete()' - Free a zoom record...
+ */
+
+void
+_cupsImageZoomDelete(cups_izoom_t *z) /* I - Zoom record to free */
+{
+ free(z->rows[0]);
+ free(z->rows[1]);
+ free(z->in);
+ free(z);
+}
+
+
+/*
+ * '_cupsImageZoomFill()' - Fill a zoom record with image data utilizing bilinear
+ * interpolation.
+ */
+
+void
+_cupsImageZoomFill(cups_izoom_t *z, /* I - Zoom record to fill */
+ int iy) /* I - Zoom image row */
+{
+ switch (z->type)
+ {
+ case CUPS_IZOOM_FAST :
+ zoom_nearest(z, iy);
+ break;
+
+ default :
+ zoom_bilinear(z, iy);
+ break;
+ }
+}
+
+
+/*
+ * '_cupsImageZoomNew()' - Allocate a pixel zoom record...
+ */
+
+cups_izoom_t *
+_cupsImageZoomNew(
+ cups_image_t *img, /* I - cupsImage to zoom */
+ int xc0, /* I - Upper-lefthand corner */
+ int yc0, /* I - ... */
+ int xc1, /* I - Lower-righthand corner */
+ int yc1, /* I - ... */
+ int xsize, /* I - Final width of image */
+ int ysize, /* I - Final height of image */
+ int rotated, /* I - Non-zero if image is rotated 90 degs */
+ cups_iztype_t type) /* I - Zoom type */
+{
+ cups_izoom_t *z; /* New zoom record */
+ int flip; /* Flip on X axis? */
+
+
+ if (xsize > CUPS_IMAGE_MAX_WIDTH ||
+ ysize > CUPS_IMAGE_MAX_HEIGHT ||
+ (xc1 - xc0) > CUPS_IMAGE_MAX_WIDTH ||
+ (yc1 - yc0) > CUPS_IMAGE_MAX_HEIGHT)
+ return (NULL); /* Protect against integer overflow */
+
+ if ((z = (cups_izoom_t *)calloc(1, sizeof(cups_izoom_t))) == NULL)
+ return (NULL);
+
+ z->img = img;
+ z->row = 0;
+ z->depth = cupsImageGetDepth(img);
+ z->rotated = rotated;
+ z->type = type;
+
+ if (xsize < 0)
+ {
+ flip = 1;
+ xsize = -xsize;
+ }
+ else
+ {
+ flip = 0;
+ }
+
+ if (rotated)
+ {
+ z->xorig = xc1;
+ z->yorig = yc0;
+ z->width = yc1 - yc0 + 1;
+ z->height = xc1 - xc0 + 1;
+ z->xsize = xsize;
+ z->ysize = ysize;
+ z->xmod = z->width % z->xsize;
+ z->xstep = z->width / z->xsize;
+ z->xincr = 1;
+ z->ymod = z->height % z->ysize;
+ z->ystep = z->height / z->ysize;
+ z->yincr = 1;
+ z->instep = z->xstep * z->depth;
+ z->inincr = /* z->xincr * */ z->depth; /* z->xincr is always 1 */
+
+ if (z->width < img->ysize)
+ z->xmax = z->width;
+ else
+ z->xmax = z->width - 1;
+
+ if (z->height < img->xsize)
+ z->ymax = z->height;
+ else
+ z->ymax = z->height - 1;
+ }
+ else
+ {
+ z->xorig = xc0;
+ z->yorig = yc0;
+ z->width = xc1 - xc0 + 1;
+ z->height = yc1 - yc0 + 1;
+ z->xsize = xsize;
+ z->ysize = ysize;
+ z->xmod = z->width % z->xsize;
+ z->xstep = z->width / z->xsize;
+ z->xincr = 1;
+ z->ymod = z->height % z->ysize;
+ z->ystep = z->height / z->ysize;
+ z->yincr = 1;
+ z->instep = z->xstep * z->depth;
+ z->inincr = /* z->xincr * */ z->depth; /* z->xincr is always 1 */
+
+ if (z->width < img->xsize)
+ z->xmax = z->width;
+ else
+ z->xmax = z->width - 1;
+
+ if (z->height < img->ysize)
+ z->ymax = z->height;
+ else
+ z->ymax = z->height - 1;
+ }
+
+ if (flip)
+ {
+ z->instep = -z->instep;
+ z->inincr = -z->inincr;
+ }
+
+ if ((z->rows[0] = (cups_ib_t *)malloc(z->xsize * z->depth)) == NULL)
+ {
+ free(z);
+ return (NULL);
+ }
+
+ if ((z->rows[1] = (cups_ib_t *)malloc(z->xsize * z->depth)) == NULL)
+ {
+ free(z->rows[0]);
+ free(z);
+ return (NULL);
+ }
+
+ if ((z->in = (cups_ib_t *)malloc(z->width * z->depth)) == NULL)
+ {
+ free(z->rows[0]);
+ free(z->rows[1]);
+ free(z);
+ return (NULL);
+ }
+
+ return (z);
+}
+
+
+/*
+ * 'zoom_bilinear()' - Fill a zoom record with image data utilizing bilinear
+ * interpolation.
+ */
+
+static void
+zoom_bilinear(cups_izoom_t *z, /* I - Zoom record to fill */
+ int iy) /* I - Zoom image row */
+{
+ cups_ib_t *r, /* Row pointer */
+ *inptr; /* Pixel pointer */
+ int xerr0, /* X error counter */
+ xerr1; /* ... */
+ int ix,
+ x,
+ count,
+ z_depth,
+ z_xstep,
+ z_xincr,
+ z_instep,
+ z_inincr,
+ z_xmax,
+ z_xmod,
+ z_xsize;
+
+
+ if (iy > z->ymax)
+ iy = z->ymax;
+
+ z->row ^= 1;
+
+ z_depth = z->depth;
+ z_xsize = z->xsize;
+ z_xmax = z->xmax;
+ z_xmod = z->xmod;
+ z_xstep = z->xstep;
+ z_xincr = z->xincr;
+ z_instep = z->instep;
+ z_inincr = z->inincr;
+
+ if (z->rotated)
+ cupsImageGetCol(z->img, z->xorig - iy, z->yorig, z->width, z->in);
+ else
+ cupsImageGetRow(z->img, z->xorig, z->yorig + iy, z->width, z->in);
+
+ if (z_inincr < 0)
+ inptr = z->in + (z->width - 1) * z_depth;
+ else
+ inptr = z->in;
+
+ for (x = z_xsize, xerr0 = z_xsize, xerr1 = 0, ix = 0, r = z->rows[z->row];
+ x > 0;
+ x --)
+ {
+ if (ix < z_xmax)
+ {
+ for (count = 0; count < z_depth; count ++)
+ *r++ = (inptr[count] * xerr0 + inptr[z_depth + count] * xerr1) / z_xsize;
+ }
+ else
+ {
+ for (count = 0; count < z_depth; count ++)
+ *r++ = inptr[count];
+ }
+
+ ix += z_xstep;
+ inptr += z_instep;
+ xerr0 -= z_xmod;
+ xerr1 += z_xmod;
+
+ if (xerr0 <= 0)
+ {
+ xerr0 += z_xsize;
+ xerr1 -= z_xsize;
+ ix += z_xincr;
+ inptr += z_inincr;
+ }
+ }
+}
+
+
+/*
+ * 'zoom_nearest()' - Fill a zoom record quickly using nearest-neighbor
+ * sampling.
+ */
+
+static void
+zoom_nearest(cups_izoom_t *z, /* I - Zoom record to fill */
+ int iy) /* I - Zoom image row */
+{
+ cups_ib_t *r, /* Row pointer */
+ *inptr; /* Pixel pointer */
+ int xerr0; /* X error counter */
+ int ix,
+ x,
+ count,
+ z_depth,
+ z_xstep,
+ z_xincr,
+ z_instep,
+ z_inincr,
+ z_xmod,
+ z_xsize;
+
+
+ if (iy > z->ymax)
+ iy = z->ymax;
+
+ z->row ^= 1;
+
+ z_depth = z->depth;
+ z_xsize = z->xsize;
+ z_xmod = z->xmod;
+ z_xstep = z->xstep;
+ z_xincr = z->xincr;
+ z_instep = z->instep;
+ z_inincr = z->inincr;
+
+ if (z->rotated)
+ cupsImageGetCol(z->img, z->xorig - iy, z->yorig, z->width, z->in);
+ else
+ cupsImageGetRow(z->img, z->xorig, z->yorig + iy, z->width, z->in);
+
+ if (z_inincr < 0)
+ inptr = z->in + (z->width - 1) * z_depth;
+ else
+ inptr = z->in;
+
+ for (x = z_xsize, xerr0 = z_xsize, ix = 0, r = z->rows[z->row];
+ x > 0;
+ x --)
+ {
+ for (count = 0; count < z_depth; count ++)
+ *r++ = inptr[count];
+
+ ix += z_xstep;
+ inptr += z_instep;
+ xerr0 -= z_xmod;
+
+ if (xerr0 <= 0)
+ {
+ xerr0 += z_xsize;
+ ix += z_xincr;
+ inptr += z_inincr;
+ }
+ }
+}
+
diff --git a/cupsfilters/image.c b/cupsfilters/image.c
new file mode 100644
index 000000000..736c7fea7
--- /dev/null
+++ b/cupsfilters/image.c
@@ -0,0 +1,809 @@
+/*
+ * Base image support for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * cupsImageClose() - Close an image file.
+ * cupsImageGetCol() - Get a column of pixels from an image.
+ * cupsImageGetColorSpace() - Get the image colorspace.
+ * cupsImageGetDepth() - Get the number of bytes per pixel.
+ * cupsImageGetHeight() - Get the height of an image.
+ * cupsImageGetRow() - Get a row of pixels from an image.
+ * cupsImageGetWidth() - Get the width of an image.
+ * cupsImageGetXPPI() - Get the horizontal resolution of an image.
+ * cupsImageGetYPPI() - Get the vertical resolution of an image.
+ * cupsImageOpen() - Open an image file and read it into memory.
+ * _cupsImagePutCol() - Put a column of pixels to an image.
+ * _cupsImagePutRow() - Put a row of pixels to an image.
+ * cupsImageSetMaxTiles() - Set the maximum number of tiles to cache.
+ * flush_tile() - Flush the least-recently-used tile in the cache.
+ * get_tile() - Get a cached tile.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image-private.h"
+
+
+/*
+ * Local functions...
+ */
+
+static void flush_tile(cups_image_t *img);
+static cups_ib_t *get_tile(cups_image_t *img, int x, int y);
+
+
+/*
+ * 'cupsImageClose()' - Close an image file.
+ */
+
+void
+cupsImageClose(cups_image_t *img) /* I - Image to close */
+{
+ cups_ic_t *current, /* Current cached tile */
+ *next; /* Next cached tile */
+
+
+ /*
+ * Wipe the tile cache file (if any)...
+ */
+
+ if (img->cachefile >= 0)
+ {
+ DEBUG_printf(("Closing/removing swap file \"%s\"...\n", img->cachename));
+
+ close(img->cachefile);
+ unlink(img->cachename);
+ }
+
+ /*
+ * Free the image cache...
+ */
+
+ DEBUG_puts("Freeing memory...");
+
+ for (current = img->first, next = NULL; current != NULL; current = next)
+ {
+ DEBUG_printf(("Freeing cache (%p, next = %p)...\n", current, next));
+
+ next = current->next;
+ free(current);
+ }
+
+ /*
+ * Free the rest of memory...
+ */
+
+ if (img->tiles != NULL)
+ {
+ DEBUG_printf(("Freeing tiles (%p)...\n", img->tiles[0]));
+
+ free(img->tiles[0]);
+
+ DEBUG_printf(("Freeing tile pointers (%p)...\n", img->tiles));
+
+ free(img->tiles);
+ }
+
+ free(img);
+}
+
+
+/*
+ * 'cupsImageGetCol()' - Get a column of pixels from an image.
+ */
+
+int /* O - -1 on error, 0 on success */
+cupsImageGetCol(cups_image_t *img, /* I - Image */
+ int x, /* I - Column */
+ int y, /* I - Start row */
+ int height, /* I - Column height */
+ cups_ib_t *pixels) /* O - Pixel data */
+{
+ int bpp, /* Bytes per pixel */
+ twidth, /* Tile width */
+ count; /* Number of pixels to get */
+ const cups_ib_t *ib; /* Pointer into tile */
+
+
+ if (img == NULL || x < 0 || x >= img->xsize || y >= img->ysize)
+ return (-1);
+
+ if (y < 0)
+ {
+ height += y;
+ y = 0;
+ }
+
+ if ((y + height) > img->ysize)
+ height = img->ysize - y;
+
+ if (height < 1)
+ return (-1);
+
+ bpp = cupsImageGetDepth(img);
+ twidth = bpp * (CUPS_TILE_SIZE - 1);
+
+ while (height > 0)
+ {
+ ib = get_tile(img, x, y);
+
+ if (ib == NULL)
+ return (-1);
+
+ count = CUPS_TILE_SIZE - (y & (CUPS_TILE_SIZE - 1));
+ if (count > height)
+ count = height;
+
+ y += count;
+ height -= count;
+
+ for (; count > 0; count --, ib += twidth)
+ switch (bpp)
+ {
+ case 4 :
+ *pixels++ = *ib++;
+ case 3 :
+ *pixels++ = *ib++;
+ *pixels++ = *ib++;
+ case 1 :
+ *pixels++ = *ib++;
+ break;
+ }
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'cupsImageGetColorSpace()' - Get the image colorspace.
+ */
+
+cups_icspace_t /* O - Colorspace */
+cupsImageGetColorSpace(
+ cups_image_t *img) /* I - Image */
+{
+ return (img->colorspace);
+}
+
+
+/*
+ * 'cupsImageGetDepth()' - Get the number of bytes per pixel.
+ */
+
+int /* O - Bytes per pixel */
+cupsImageGetDepth(cups_image_t *img) /* I - Image */
+{
+ return (abs(img->colorspace));
+}
+
+
+/*
+ * 'cupsImageGetHeight()' - Get the height of an image.
+ */
+
+unsigned /* O - Height in pixels */
+cupsImageGetHeight(cups_image_t *img) /* I - Image */
+{
+ return (img->ysize);
+}
+
+
+/*
+ * 'cupsImageGetRow()' - Get a row of pixels from an image.
+ */
+
+int /* O - -1 on error, 0 on success */
+cupsImageGetRow(cups_image_t *img, /* I - Image */
+ int x, /* I - Start column */
+ int y, /* I - Row */
+ int width, /* I - Width of row */
+ cups_ib_t *pixels) /* O - Pixel data */
+{
+ int bpp, /* Bytes per pixel */
+ count; /* Number of pixels to get */
+ const cups_ib_t *ib; /* Pointer to pixels */
+
+
+ if (img == NULL || y < 0 || y >= img->ysize || x >= img->xsize)
+ return (-1);
+
+ if (x < 0)
+ {
+ width += x;
+ x = 0;
+ }
+
+ if ((x + width) > img->xsize)
+ width = img->xsize - x;
+
+ if (width < 1)
+ return (-1);
+
+ bpp = img->colorspace < 0 ? -img->colorspace : img->colorspace;
+
+ while (width > 0)
+ {
+ ib = get_tile(img, x, y);
+
+ if (ib == NULL)
+ return (-1);
+
+ count = CUPS_TILE_SIZE - (x & (CUPS_TILE_SIZE - 1));
+ if (count > width)
+ count = width;
+ memcpy(pixels, ib, count * bpp);
+ pixels += count * bpp;
+ x += count;
+ width -= count;
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'cupsImageGetWidth()' - Get the width of an image.
+ */
+
+unsigned /* O - Width in pixels */
+cupsImageGetWidth(cups_image_t *img) /* I - Image */
+{
+ return (img->xsize);
+}
+
+
+/*
+ * 'cupsImageGetXPPI()' - Get the horizontal resolution of an image.
+ */
+
+unsigned /* O - Horizontal PPI */
+cupsImageGetXPPI(cups_image_t *img) /* I - Image */
+{
+ return (img->xppi);
+}
+
+
+/*
+ * 'cupsImageGetYPPI()' - Get the vertical resolution of an image.
+ */
+
+unsigned /* O - Vertical PPI */
+cupsImageGetYPPI(cups_image_t *img) /* I - Image */
+{
+ return (img->yppi);
+}
+
+
+/*
+ * 'cupsImageOpen()' - Open an image file and read it into memory.
+ */
+
+cups_image_t * /* O - New image */
+cupsImageOpen(
+ const char *filename, /* I - Filename of image */
+ cups_icspace_t primary, /* I - Primary colorspace needed */
+ cups_icspace_t secondary, /* I - Secondary colorspace if primary no good */
+ int saturation, /* I - Color saturation level */
+ int hue, /* I - Color hue adjustment */
+ const cups_ib_t *lut) /* I - RGB gamma/brightness LUT */
+{
+ FILE *fp; /* File pointer */
+ unsigned char header[16], /* First 16 bytes of file */
+ header2[16]; /* Bytes 2048-2064 (PhotoCD) */
+ cups_image_t *img; /* New image buffer */
+ int status; /* Status of load... */
+
+
+ DEBUG_printf(("cupsImageOpen(\"%s\", %d, %d, %d, %d, %p)\n",
+ filename ? filename : "(null)", primary, secondary,
+ saturation, hue, lut));
+
+ /*
+ * Figure out the file type...
+ */
+
+ if ((fp = fopen(filename, "r")) == NULL)
+ return (NULL);
+
+ if (fread(header, 1, sizeof(header), fp) == 0)
+ {
+ fclose(fp);
+ return (NULL);
+ }
+
+ fseek(fp, 2048, SEEK_SET);
+ memset(header2, 0, sizeof(header2));
+ if (fread(header2, 1, sizeof(header2), fp) == 0 && ferror(fp))
+ DEBUG_printf(("Error reading file!"));
+ fseek(fp, 0, SEEK_SET);
+
+ /*
+ * Allocate memory...
+ */
+
+ img = calloc(sizeof(cups_image_t), 1);
+
+ if (img == NULL)
+ {
+ fclose(fp);
+ return (NULL);
+ }
+
+ /*
+ * Load the image as appropriate...
+ */
+
+ img->cachefile = -1;
+ img->max_ics = CUPS_TILE_MINIMUM;
+ img->xppi = 128;
+ img->yppi = 128;
+
+ if (!memcmp(header, "GIF87a", 6) || !memcmp(header, "GIF89a", 6))
+ status = _cupsImageReadGIF(img, fp, primary, secondary, saturation, hue,
+ lut);
+ else if (!memcmp(header, "BM", 2))
+ status = _cupsImageReadBMP(img, fp, primary, secondary, saturation, hue,
+ lut);
+ else if (header[0] == 0x01 && header[1] == 0xda)
+ status = _cupsImageReadSGI(img, fp, primary, secondary, saturation, hue,
+ lut);
+ else if (header[0] == 0x59 && header[1] == 0xa6 &&
+ header[2] == 0x6a && header[3] == 0x95)
+ status = _cupsImageReadSunRaster(img, fp, primary, secondary, saturation,
+ hue, lut);
+ else if (header[0] == 'P' && header[1] >= '1' && header[1] <= '6')
+ status = _cupsImageReadPNM(img, fp, primary, secondary, saturation, hue,
+ lut);
+ else if (!memcmp(header2, "PCD_IPI", 7))
+ status = _cupsImageReadPhotoCD(img, fp, primary, secondary, saturation,
+ hue, lut);
+ else if (!memcmp(header + 8, "\000\010", 2) ||
+ !memcmp(header + 8, "\000\030", 2))
+ status = _cupsImageReadPIX(img, fp, primary, secondary, saturation, hue,
+ lut);
+#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
+ else if (!memcmp(header, "\211PNG", 4))
+ status = _cupsImageReadPNG(img, fp, primary, secondary, saturation, hue,
+ lut);
+#endif /* HAVE_LIBPNG && HAVE_LIBZ */
+#ifdef HAVE_LIBJPEG
+ else if (!memcmp(header, "\377\330\377", 3) && /* Start-of-Image */
+ header[3] >= 0xe0 && header[3] <= 0xef) /* APPn */
+ status = _cupsImageReadJPEG(img, fp, primary, secondary, saturation, hue,
+ lut);
+#endif /* HAVE_LIBJPEG */
+#ifdef HAVE_LIBTIFF
+ else if (!memcmp(header, "MM\000\052", 4) ||
+ !memcmp(header, "II\052\000", 4))
+ status = _cupsImageReadTIFF(img, fp, primary, secondary, saturation, hue,
+ lut);
+#endif /* HAVE_LIBTIFF */
+ else
+ {
+ fclose(fp);
+ status = -1;
+ }
+
+ if (status)
+ {
+ free(img);
+ return (NULL);
+ }
+ else
+ return (img);
+}
+
+
+/*
+ * '_cupsImagePutCol()' - Put a column of pixels to an image.
+ */
+
+int /* O - -1 on error, 0 on success */
+_cupsImagePutCol(
+ cups_image_t *img, /* I - Image */
+ int x, /* I - Column */
+ int y, /* I - Start row */
+ int height, /* I - Column height */
+ const cups_ib_t *pixels) /* I - Pixels to put */
+{
+ int bpp, /* Bytes per pixel */
+ twidth, /* Width of tile */
+ count; /* Number of pixels to put */
+ int tilex, /* Column within tile */
+ tiley; /* Row within tile */
+ cups_ib_t *ib; /* Pointer to pixels in tile */
+
+
+ if (img == NULL || x < 0 || x >= img->xsize || y >= img->ysize)
+ return (-1);
+
+ if (y < 0)
+ {
+ height += y;
+ y = 0;
+ }
+
+ if ((y + height) > img->ysize)
+ height = img->ysize - y;
+
+ if (height < 1)
+ return (-1);
+
+ bpp = cupsImageGetDepth(img);
+ twidth = bpp * (CUPS_TILE_SIZE - 1);
+ tilex = x / CUPS_TILE_SIZE;
+ tiley = y / CUPS_TILE_SIZE;
+
+ while (height > 0)
+ {
+ ib = get_tile(img, x, y);
+
+ if (ib == NULL)
+ return (-1);
+
+ img->tiles[tiley][tilex].dirty = 1;
+ tiley ++;
+
+ count = CUPS_TILE_SIZE - (y & (CUPS_TILE_SIZE - 1));
+ if (count > height)
+ count = height;
+
+ y += count;
+ height -= count;
+
+ for (; count > 0; count --, ib += twidth)
+ switch (bpp)
+ {
+ case 4 :
+ *ib++ = *pixels++;
+ case 3 :
+ *ib++ = *pixels++;
+ *ib++ = *pixels++;
+ case 1 :
+ *ib++ = *pixels++;
+ break;
+ }
+ }
+
+ return (0);
+}
+
+
+/*
+ * '_cupsImagePutRow()' - Put a row of pixels to an image.
+ */
+
+int /* O - -1 on error, 0 on success */
+_cupsImagePutRow(
+ cups_image_t *img, /* I - Image */
+ int x, /* I - Start column */
+ int y, /* I - Row */
+ int width, /* I - Row width */
+ const cups_ib_t *pixels) /* I - Pixel data */
+{
+ int bpp, /* Bytes per pixel */
+ count; /* Number of pixels to put */
+ int tilex, /* Column within tile */
+ tiley; /* Row within tile */
+ cups_ib_t *ib; /* Pointer to pixels in tile */
+
+
+ if (img == NULL || y < 0 || y >= img->ysize || x >= img->xsize)
+ return (-1);
+
+ if (x < 0)
+ {
+ width += x;
+ x = 0;
+ }
+
+ if ((x + width) > img->xsize)
+ width = img->xsize - x;
+
+ if (width < 1)
+ return (-1);
+
+ bpp = img->colorspace < 0 ? -img->colorspace : img->colorspace;
+ tilex = x / CUPS_TILE_SIZE;
+ tiley = y / CUPS_TILE_SIZE;
+
+ while (width > 0)
+ {
+ ib = get_tile(img, x, y);
+
+ if (ib == NULL)
+ return (-1);
+
+ img->tiles[tiley][tilex].dirty = 1;
+
+ count = CUPS_TILE_SIZE - (x & (CUPS_TILE_SIZE - 1));
+ if (count > width)
+ count = width;
+ memcpy(ib, pixels, count * bpp);
+ pixels += count * bpp;
+ x += count;
+ width -= count;
+ tilex ++;
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'cupsImageSetMaxTiles()' - Set the maximum number of tiles to cache.
+ *
+ * If the "max_tiles" argument is 0 then the maximum number of tiles is
+ * computed from the image size or the RIP_CACHE environment variable.
+ */
+
+void
+cupsImageSetMaxTiles(
+ cups_image_t *img, /* I - Image to set */
+ int max_tiles) /* I - Number of tiles to cache */
+{
+ int cache_size, /* Size of tile cache in bytes */
+ min_tiles, /* Minimum number of tiles to cache */
+ max_size; /* Maximum cache size in bytes */
+ char *cache_env, /* Cache size environment variable */
+ cache_units[255]; /* Cache size units */
+
+
+ min_tiles = max(CUPS_TILE_MINIMUM,
+ 1 + max((img->xsize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE,
+ (img->ysize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE));
+
+ if (max_tiles == 0)
+ max_tiles = ((img->xsize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE) *
+ ((img->ysize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE);
+
+ cache_size = max_tiles * CUPS_TILE_SIZE * CUPS_TILE_SIZE *
+ cupsImageGetDepth(img);
+
+ if ((cache_env = getenv("RIP_MAX_CACHE")) != NULL)
+ {
+ switch (sscanf(cache_env, "%d%254s", &max_size, cache_units))
+ {
+ case 0 :
+ max_size = 32 * 1024 * 1024;
+ break;
+ case 1 :
+ max_size *= 4 * CUPS_TILE_SIZE * CUPS_TILE_SIZE;
+ break;
+ case 2 :
+ if (tolower(cache_units[0] & 255) == 'g')
+ max_size *= 1024 * 1024 * 1024;
+ else if (tolower(cache_units[0] & 255) == 'm')
+ max_size *= 1024 * 1024;
+ else if (tolower(cache_units[0] & 255) == 'k')
+ max_size *= 1024;
+ else if (tolower(cache_units[0] & 255) == 't')
+ max_size *= 4 * CUPS_TILE_SIZE * CUPS_TILE_SIZE;
+ break;
+ }
+ }
+ else
+ max_size = 32 * 1024 * 1024;
+
+ if (cache_size > max_size)
+ max_tiles = max_size / CUPS_TILE_SIZE / CUPS_TILE_SIZE /
+ cupsImageGetDepth(img);
+
+ if (max_tiles < min_tiles)
+ max_tiles = min_tiles;
+
+ img->max_ics = max_tiles;
+
+ DEBUG_printf(("max_ics=%d...\n", img->max_ics));
+}
+
+
+/*
+ * 'flush_tile()' - Flush the least-recently-used tile in the cache.
+ */
+
+static void
+flush_tile(cups_image_t *img) /* I - Image */
+{
+ int bpp; /* Bytes per pixel */
+ cups_itile_t *tile; /* Pointer to tile */
+
+
+ bpp = cupsImageGetDepth(img);
+ tile = img->first->tile;
+
+ if (!tile->dirty)
+ {
+ tile->ic = NULL;
+ return;
+ }
+
+ if (img->cachefile < 0)
+ {
+ if ((img->cachefile = cupsTempFd(img->cachename,
+ sizeof(img->cachename))) < 0)
+ {
+ tile->ic = NULL;
+ tile->dirty = 0;
+ return;
+ }
+
+ DEBUG_printf(("Created swap file \"%s\"...\n", img->cachename));
+ }
+
+ if (tile->pos >= 0)
+ {
+ if (lseek(img->cachefile, tile->pos, SEEK_SET) != tile->pos)
+ {
+ tile->ic = NULL;
+ tile->dirty = 0;
+ return;
+ }
+ }
+ else
+ {
+ if ((tile->pos = lseek(img->cachefile, 0, SEEK_END)) < 0)
+ {
+ tile->ic = NULL;
+ tile->dirty = 0;
+ return;
+ }
+ }
+
+ if (write(img->cachefile, tile->ic->pixels,
+ bpp * CUPS_TILE_SIZE * CUPS_TILE_SIZE) == -1)
+ DEBUG_printf(("Error writing cache tile!"));
+
+ tile->ic = NULL;
+ tile->dirty = 0;
+}
+
+
+/*
+ * 'get_tile()' - Get a cached tile.
+ */
+
+static cups_ib_t * /* O - Pointer to tile or NULL */
+get_tile(cups_image_t *img, /* I - Image */
+ int x, /* I - Column in image */
+ int y) /* I - Row in image */
+{
+ int bpp, /* Bytes per pixel */
+ tilex, /* Column within tile */
+ tiley, /* Row within tile */
+ xtiles, /* Number of tiles horizontally */
+ ytiles; /* Number of tiles vertically */
+ cups_ic_t *ic; /* Cache pointer */
+ cups_itile_t *tile; /* Tile pointer */
+
+
+ if (img->tiles == NULL)
+ {
+ xtiles = (img->xsize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE;
+ ytiles = (img->ysize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE;
+
+ DEBUG_printf(("Creating tile array (%dx%d)\n", xtiles, ytiles));
+
+ if ((img->tiles = calloc(sizeof(cups_itile_t *), ytiles)) == NULL)
+ return (NULL);
+
+ if ((tile = calloc(xtiles * sizeof(cups_itile_t), ytiles)) == NULL)
+ return (NULL);
+
+ for (tiley = 0; tiley < ytiles; tiley ++)
+ {
+ img->tiles[tiley] = tile;
+ for (tilex = xtiles; tilex > 0; tilex --, tile ++)
+ tile->pos = -1;
+ }
+ }
+
+ bpp = cupsImageGetDepth(img);
+ tilex = x / CUPS_TILE_SIZE;
+ tiley = y / CUPS_TILE_SIZE;
+ tile = img->tiles[tiley] + tilex;
+ x &= (CUPS_TILE_SIZE - 1);
+ y &= (CUPS_TILE_SIZE - 1);
+
+ if ((ic = tile->ic) == NULL)
+ {
+ if (img->num_ics < img->max_ics)
+ {
+ if ((ic = calloc(sizeof(cups_ic_t) +
+ bpp * CUPS_TILE_SIZE * CUPS_TILE_SIZE, 1)) == NULL)
+ {
+ if (img->num_ics == 0)
+ return (NULL);
+
+ flush_tile(img);
+ ic = img->first;
+ }
+ else
+ {
+ ic->pixels = ((cups_ib_t *)ic) + sizeof(cups_ic_t);
+
+ img->num_ics ++;
+
+ DEBUG_printf(("Allocated cache tile %d (%p)...\n", img->num_ics, ic));
+ }
+ }
+ else
+ {
+ DEBUG_printf(("Flushing old cache tile (%p)...\n", img->first));
+
+ flush_tile(img);
+ ic = img->first;
+ }
+
+ ic->tile = tile;
+ tile->ic = ic;
+
+ if (tile->pos >= 0)
+ {
+ DEBUG_printf(("Loading cache tile from file position " CUPS_LLFMT "...\n",
+ CUPS_LLCAST tile->pos));
+
+ lseek(img->cachefile, tile->pos, SEEK_SET);
+ if (read(img->cachefile, ic->pixels,
+ bpp * CUPS_TILE_SIZE * CUPS_TILE_SIZE) == -1)
+ DEBUG_printf(("Error reading cache tile!"));
+ }
+ else
+ {
+ DEBUG_puts("Clearing cache tile...");
+
+ memset(ic->pixels, 0, bpp * CUPS_TILE_SIZE * CUPS_TILE_SIZE);
+ }
+ }
+
+ if (ic == img->first)
+ {
+ if (ic->next != NULL)
+ ic->next->prev = NULL;
+
+ img->first = ic->next;
+ ic->next = NULL;
+ ic->prev = NULL;
+ }
+ else if (img->first == NULL)
+ img->first = ic;
+
+ if (ic != img->last)
+ {
+ /*
+ * Remove the cache entry from the list...
+ */
+
+ if (ic->prev != NULL)
+ ic->prev->next = ic->next;
+ if (ic->next != NULL)
+ ic->next->prev = ic->prev;
+
+ /*
+ * And add it to the end...
+ */
+
+ if (img->last != NULL)
+ img->last->next = ic;
+
+ ic->prev = img->last;
+ img->last = ic;
+ }
+
+ ic->next = NULL;
+
+ return (ic->pixels + bpp * (y * CUPS_TILE_SIZE + x));
+}
+
diff --git a/cupsfilters/image.h b/cupsfilters/image.h
new file mode 100644
index 000000000..3c7e48078
--- /dev/null
+++ b/cupsfilters/image.h
@@ -0,0 +1,122 @@
+/*
+ * Image library definitions for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2006 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ */
+
+#ifndef _CUPS_FILTERS_IMAGE_H_
+# define _CUPS_FILTERS_IMAGE_H_
+
+/*
+ * Include necessary headers...
+ */
+
+# include <stdio.h>
+# include <cups/raster.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+
+/*
+ * Constants...
+ */
+
+typedef enum cups_icspace_e /**** Image colorspaces ****/
+{
+ CUPS_IMAGE_CMYK = -4, /* Cyan, magenta, yellow, and black */
+ CUPS_IMAGE_CMY = -3, /* Cyan, magenta, and yellow */
+ CUPS_IMAGE_BLACK = -1, /* Black */
+ CUPS_IMAGE_WHITE = 1, /* White (luminance) */
+ CUPS_IMAGE_RGB = 3, /* Red, green, and blue */
+ CUPS_IMAGE_RGB_CMYK = 4 /* Use RGB or CMYK */
+} cups_icspace_t;
+
+
+/*
+ * Types and structures...
+ */
+
+typedef unsigned char cups_ib_t; /**** Image byte ****/
+
+struct cups_image_s;
+typedef struct cups_image_s cups_image_t;
+ /**** Image file data ****/
+
+struct cups_izoom_s;
+typedef struct cups_izoom_s cups_izoom_t;
+ /**** Image zoom data ****/
+
+
+/*
+ * Prototypes...
+ */
+
+extern void cupsImageClose(cups_image_t *img) _CUPS_API_1_2;
+extern void cupsImageCMYKToBlack(const cups_ib_t *in,
+ cups_ib_t *out, int count) _CUPS_API_1_2;
+extern void cupsImageCMYKToCMY(const cups_ib_t *in,
+ cups_ib_t *out, int count) _CUPS_API_1_2;
+extern void cupsImageCMYKToCMYK(const cups_ib_t *in,
+ cups_ib_t *out, int count) _CUPS_API_1_2;
+extern void cupsImageCMYKToRGB(const cups_ib_t *in,
+ cups_ib_t *out, int count) _CUPS_API_1_2;
+extern void cupsImageCMYKToWhite(const cups_ib_t *in,
+ cups_ib_t *out, int count) _CUPS_API_1_2;
+extern int cupsImageGetCol(cups_image_t *img, int x, int y,
+ int height, cups_ib_t *pixels) _CUPS_API_1_2;
+extern cups_icspace_t cupsImageGetColorSpace(cups_image_t *img) _CUPS_API_1_2;
+extern int cupsImageGetDepth(cups_image_t *img) _CUPS_API_1_2;
+extern unsigned cupsImageGetHeight(cups_image_t *img) _CUPS_API_1_2;
+extern int cupsImageGetRow(cups_image_t *img, int x, int y,
+ int width, cups_ib_t *pixels) _CUPS_API_1_2;
+extern unsigned cupsImageGetWidth(cups_image_t *img) _CUPS_API_1_2;
+extern unsigned cupsImageGetXPPI(cups_image_t *img) _CUPS_API_1_2;
+extern unsigned cupsImageGetYPPI(cups_image_t *img) _CUPS_API_1_2;
+extern void cupsImageLut(cups_ib_t *pixels, int count,
+ const cups_ib_t *lut) _CUPS_API_1_2;
+extern cups_image_t *cupsImageOpen(const char *filename,
+ cups_icspace_t primary,
+ cups_icspace_t secondary,
+ int saturation, int hue,
+ const cups_ib_t *lut) _CUPS_API_1_2;
+extern void cupsImageRGBAdjust(cups_ib_t *pixels, int count,
+ int saturation, int hue) _CUPS_API_1_2;
+extern void cupsImageRGBToBlack(const cups_ib_t *in,
+ cups_ib_t *out, int count) _CUPS_API_1_2;
+extern void cupsImageRGBToCMY(const cups_ib_t *in,
+ cups_ib_t *out, int count) _CUPS_API_1_2;
+extern void cupsImageRGBToCMYK(const cups_ib_t *in,
+ cups_ib_t *out, int count) _CUPS_API_1_2;
+extern void cupsImageRGBToRGB(const cups_ib_t *in,
+ cups_ib_t *out, int count) _CUPS_API_1_2;
+extern void cupsImageRGBToWhite(const cups_ib_t *in,
+ cups_ib_t *out, int count) _CUPS_API_1_2;
+extern void cupsImageSetMaxTiles(cups_image_t *img, int max_tiles) _CUPS_API_1_2;
+extern void cupsImageSetProfile(float d, float g,
+ float matrix[3][3]) _CUPS_API_1_2;
+extern void cupsImageSetRasterColorSpace(cups_cspace_t cs) _CUPS_API_1_2;
+extern void cupsImageWhiteToBlack(const cups_ib_t *in,
+ cups_ib_t *out, int count) _CUPS_API_1_2;
+extern void cupsImageWhiteToCMY(const cups_ib_t *in,
+ cups_ib_t *out, int count) _CUPS_API_1_2;
+extern void cupsImageWhiteToCMYK(const cups_ib_t *in,
+ cups_ib_t *out, int count) _CUPS_API_1_2;
+extern void cupsImageWhiteToRGB(const cups_ib_t *in,
+ cups_ib_t *out, int count) _CUPS_API_1_2;
+extern void cupsImageWhiteToWhite(const cups_ib_t *in,
+ cups_ib_t *out, int count) _CUPS_API_1_2;
+
+
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+
+#endif /* !_CUPS_FILTERS_IMAGE_H_ */
+
diff --git a/cupsfilters/image.pgm b/cupsfilters/image.pgm
new file mode 100644
index 000000000..c0b7a22f7
--- /dev/null
+++ b/cupsfilters/image.pgm
Binary files differ
diff --git a/cupsfilters/image.ppm b/cupsfilters/image.ppm
new file mode 100644
index 000000000..3823fe48b
--- /dev/null
+++ b/cupsfilters/image.ppm
Binary files differ
diff --git a/cupsfilters/lut.c b/cupsfilters/lut.c
new file mode 100644
index 000000000..7539ee257
--- /dev/null
+++ b/cupsfilters/lut.c
@@ -0,0 +1,195 @@
+/*
+ * Lookup table routines for CUPS.
+ *
+ * Copyright 2007 by Apple Inc.
+ * Copyright 1993-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * cupsLutDelete() - Free the memory used by a lookup table.
+ * cupsLutLoad() - Load a LUT from a PPD file.
+ * cupsLutNew() - Make a lookup table from a list of pixel values.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "driver.h"
+#include <math.h>
+
+
+/*
+ * 'cupsLutDelete()' - Free the memory used by a lookup table.
+ */
+
+void
+cupsLutDelete(cups_lut_t *lut) /* I - Lookup table to free */
+{
+ if (lut != NULL)
+ free(lut);
+}
+
+
+/*
+ * 'cupsLutLoad()' - Load a LUT from a PPD file.
+ */
+
+cups_lut_t * /* O - New lookup table */
+cupsLutLoad(ppd_file_t *ppd, /* I - PPD file */
+ const char *colormodel, /* I - Color model */
+ const char *media, /* I - Media type */
+ const char *resolution, /* I - Resolution */
+ const char *ink) /* I - Ink name */
+{
+ char name[PPD_MAX_NAME], /* Attribute name */
+ spec[PPD_MAX_NAME]; /* Attribute spec */
+ ppd_attr_t *attr; /* Attribute */
+ int nvals; /* Number of values */
+ float vals[4]; /* Values */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (!ppd || !colormodel || !media || !resolution || !ink)
+ return (NULL);
+
+ /*
+ * Try to find the LUT values...
+ */
+
+ snprintf(name, sizeof(name), "cups%sDither", ink);
+
+ if ((attr = cupsFindAttr(ppd, name, colormodel, media, resolution, spec,
+ sizeof(spec))) == NULL)
+ attr = cupsFindAttr(ppd, "cupsAllDither", colormodel, media,
+ resolution, spec, sizeof(spec));
+
+ if (!attr)
+ return (NULL);
+
+ vals[0] = 0.0;
+ vals[1] = 0.0;
+ vals[2] = 0.0;
+ vals[3] = 0.0;
+ nvals = sscanf(attr->value, "%f%f%f", vals + 1, vals + 2, vals + 3) + 1;
+
+ fprintf(stderr, "DEBUG: Loaded LUT %s from PPD with values [%.3f %.3f %.3f %.3f]\n",
+ name, vals[0], vals[1], vals[2], vals[3]);
+
+ return (cupsLutNew(nvals, vals));
+}
+
+
+/*
+ * 'cupsLutNew()' - Make a lookup table from a list of pixel values.
+ *
+ * Returns a pointer to the lookup table on success, NULL on failure.
+ */
+
+cups_lut_t * /* O - New lookup table */
+cupsLutNew(int num_values, /* I - Number of values */
+ const float *values) /* I - Lookup table values */
+{
+ int pixel; /* Pixel value */
+ cups_lut_t *lut; /* Lookup table */
+ int start, /* Start value */
+ end, /* End value */
+ maxval; /* Maximum value */
+
+
+ /*
+ * Range check...
+ */
+
+ if (!num_values || !values)
+ return (NULL);
+
+ /*
+ * Allocate memory for the lookup table...
+ */
+
+ if ((lut = (cups_lut_t *)calloc((CUPS_MAX_LUT + 1),
+ sizeof(cups_lut_t))) == NULL)
+ return (NULL);
+
+ /*
+ * Generate the dither lookup table. The pixel values are roughly
+ * defined by a piecewise linear curve that has an intensity value
+ * at each output pixel. This isn't perfectly accurate, but it's
+ * close enough for jazz.
+ */
+
+ maxval = CUPS_MAX_LUT / values[num_values - 1];
+
+ for (start = 0; start <= CUPS_MAX_LUT; start ++)
+ lut[start].intensity = start * maxval / CUPS_MAX_LUT;
+
+ for (pixel = 0; pixel < num_values; pixel ++)
+ {
+ /*
+ * Select start and end values for this pixel...
+ */
+
+ if (pixel == 0)
+ start = 0;
+ else
+ start = (int)(0.5 * maxval * (values[pixel - 1] +
+ values[pixel])) + 1;
+
+ if (start < 0)
+ start = 0;
+ else if (start > CUPS_MAX_LUT)
+ start = CUPS_MAX_LUT;
+
+ if (pixel == (num_values - 1))
+ end = CUPS_MAX_LUT;
+ else
+ end = (int)(0.5 * maxval * (values[pixel] + values[pixel + 1]));
+
+ if (end < 0)
+ end = 0;
+ else if (end > CUPS_MAX_LUT)
+ end = CUPS_MAX_LUT;
+
+ if (start == end)
+ break;
+
+ /*
+ * Generate lookup values and errors for each pixel.
+ */
+
+ while (start <= end)
+ {
+ lut[start].pixel = pixel;
+ if (start == 0)
+ lut[0].error = 0;
+ else
+ lut[start].error = start - maxval * values[pixel];
+
+ start ++;
+ }
+ }
+
+ /*
+ * Show the lookup table...
+ */
+
+ for (start = 0; start <= CUPS_MAX_LUT; start += CUPS_MAX_LUT / 15)
+ fprintf(stderr, "DEBUG: %d = %d/%d/%d\n", start, lut[start].intensity,
+ lut[start].pixel, lut[start].error);
+
+ /*
+ * Return the lookup table...
+ */
+
+ return (lut);
+}
+
diff --git a/cupsfilters/pack.c b/cupsfilters/pack.c
new file mode 100644
index 000000000..3ac1a07d6
--- /dev/null
+++ b/cupsfilters/pack.c
@@ -0,0 +1,300 @@
+/*
+ * Bit packing routines for CUPS.
+ *
+ * Copyright 2007 by Apple Inc.
+ * Copyright 1993-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * cupsPackHorizontal() - Pack pixels horizontally...
+ * cupsPackHorizontal2() - Pack 2-bit pixels horizontally...
+ * cupsPackHorizontalBit() - Pack pixels horizontally by bit...
+ * cupsPackVertical() - Pack pixels vertically...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "driver.h"
+
+
+/*
+ * 'cupsPackHorizontal()' - Pack pixels horizontally...
+ */
+
+void
+cupsPackHorizontal(const unsigned char *ipixels,/* I - Input pixels */
+ unsigned char *obytes, /* O - Output bytes */
+ int width, /* I - Number of pixels */
+ const unsigned char clearto, /* I - Initial value of bytes */
+ const int step) /* I - Step value between pixels */
+{
+ register unsigned char b; /* Current byte */
+
+
+ /*
+ * Do whole bytes first...
+ */
+
+ while (width > 7)
+ {
+ b = clearto;
+
+ if (*ipixels)
+ b ^= 0x80;
+ ipixels += step;
+ if (*ipixels)
+ b ^= 0x40;
+ ipixels += step;
+ if (*ipixels)
+ b ^= 0x20;
+ ipixels += step;
+ if (*ipixels)
+ b ^= 0x10;
+ ipixels += step;
+ if (*ipixels)
+ b ^= 0x08;
+ ipixels += step;
+ if (*ipixels)
+ b ^= 0x04;
+ ipixels += step;
+ if (*ipixels)
+ b ^= 0x02;
+ ipixels += step;
+ if (*ipixels)
+ b ^= 0x01;
+ ipixels += step;
+
+ *obytes++ = b;
+
+ width -= 8;
+ }
+
+ /*
+ * Then do the last N bytes (N < 8)...
+ */
+
+ b = clearto;
+
+ switch (width)
+ {
+ case 7 :
+ if (ipixels[6 * step])
+ b ^= 0x02;
+ case 6 :
+ if (ipixels[5 * step])
+ b ^= 0x04;
+ case 5 :
+ if (ipixels[4 * step])
+ b ^= 0x08;
+ case 4 :
+ if (ipixels[3 * step])
+ b ^= 0x10;
+ case 3 :
+ if (ipixels[2 * step])
+ b ^= 0x20;
+ case 2 :
+ if (ipixels[1 * step])
+ b ^= 0x40;
+ case 1 :
+ if (ipixels[0])
+ b ^= 0x80;
+ *obytes = b;
+ break;
+ }
+}
+
+
+/*
+ * 'cupsPackHorizontal2()' - Pack 2-bit pixels horizontally...
+ */
+
+void
+cupsPackHorizontal2(const unsigned char *ipixels, /* I - Input pixels */
+ unsigned char *obytes, /* O - Output bytes */
+ int width, /* I - Number of pixels */
+ const int step) /* I - Stepping value */
+{
+ register unsigned char b; /* Current byte */
+
+
+ /*
+ * Do whole bytes first...
+ */
+
+ while (width > 3)
+ {
+ b = *ipixels;
+ ipixels += step;
+ b = (b << 2) | *ipixels;
+ ipixels += step;
+ b = (b << 2) | *ipixels;
+ ipixels += step;
+ b = (b << 2) | *ipixels;
+ ipixels += step;
+
+ *obytes++ = b;
+
+ width -= 4;
+ }
+
+ /*
+ * Then do the last N bytes (N < 4)...
+ */
+
+ b = 0;
+
+ switch (width)
+ {
+ case 3 :
+ b = ipixels[2 * step];
+ case 2 :
+ b = (b << 2) | ipixels[step];
+ case 1 :
+ b = (b << 2) | ipixels[0];
+ *obytes = b << (8 - 2 * width);
+ break;
+ }
+}
+
+
+/*
+ * 'cupsPackHorizontalBit()' - Pack pixels horizontally by bit...
+ */
+
+void
+cupsPackHorizontalBit(const unsigned char *ipixels, /* I - Input pixels */
+ unsigned char *obytes, /* O - Output bytes */
+ int width, /* I - Number of pixels */
+ const unsigned char clearto, /* I - Initial value of bytes */
+ const unsigned char bit) /* I - Bit to check */
+{
+ register unsigned char b; /* Current byte */
+
+
+ /*
+ * Do whole bytes first...
+ */
+
+ while (width > 7)
+ {
+ b = clearto;
+
+ if (*ipixels++ & bit)
+ b ^= 0x80;
+ if (*ipixels++ & bit)
+ b ^= 0x40;
+ if (*ipixels++ & bit)
+ b ^= 0x20;
+ if (*ipixels++ & bit)
+ b ^= 0x10;
+ if (*ipixels++ & bit)
+ b ^= 0x08;
+ if (*ipixels++ & bit)
+ b ^= 0x04;
+ if (*ipixels++ & bit)
+ b ^= 0x02;
+ if (*ipixels++ & bit)
+ b ^= 0x01;
+
+ *obytes++ = b;
+
+ width -= 8;
+ }
+
+ /*
+ * Then do the last N bytes (N < 8)...
+ */
+
+ b = clearto;
+
+ switch (width)
+ {
+ case 7 :
+ if (ipixels[6] & bit)
+ b ^= 0x02;
+ case 6 :
+ if (ipixels[5] & bit)
+ b ^= 0x04;
+ case 5 :
+ if (ipixels[4] & bit)
+ b ^= 0x08;
+ case 4 :
+ if (ipixels[3] & bit)
+ b ^= 0x10;
+ case 3 :
+ if (ipixels[2] & bit)
+ b ^= 0x20;
+ case 2 :
+ if (ipixels[1] & bit)
+ b ^= 0x40;
+ case 1 :
+ if (ipixels[0] & bit)
+ b ^= 0x80;
+ *obytes = b;
+ break;
+ }
+}
+
+
+/*
+ * 'cupsPackVertical()' - Pack pixels vertically...
+ */
+
+void
+cupsPackVertical(const unsigned char *ipixels, /* I - Input pixels */
+ unsigned char *obytes, /* O - Output bytes */
+ int width, /* I - Number of input pixels */
+ const unsigned char bit, /* I - Output bit */
+ const int step) /* I - Number of bytes between columns */
+{
+ /*
+ * Loop through the entire array...
+ */
+
+ while (width > 7)
+ {
+ if (*ipixels++)
+ *obytes ^= bit;
+ obytes += step;
+ if (*ipixels++)
+ *obytes ^= bit;
+ obytes += step;
+ if (*ipixels++)
+ *obytes ^= bit;
+ obytes += step;
+ if (*ipixels++)
+ *obytes ^= bit;
+ obytes += step;
+ if (*ipixels++)
+ *obytes ^= bit;
+ obytes += step;
+ if (*ipixels++)
+ *obytes ^= bit;
+ obytes += step;
+ if (*ipixels++)
+ *obytes ^= bit;
+ obytes += step;
+ if (*ipixels++)
+ *obytes ^= bit;
+ obytes += step;
+
+ width -= 8;
+ }
+
+ while (width > 0)
+ {
+ if (*ipixels++)
+ *obytes ^= bit;
+
+ obytes += step;
+ width --;
+ }
+}
+
diff --git a/cupsfilters/ppdgenerator.c b/cupsfilters/ppdgenerator.c
new file mode 100644
index 000000000..d4a6903e2
--- /dev/null
+++ b/cupsfilters/ppdgenerator.c
@@ -0,0 +1,2256 @@
+/*
+ * PWG Raster/Apple Raster/PCLm/PDF/IPP legacy PPD generator
+ *
+ * Copyright 2016 by Till Kamppeter.
+ * Copyright 2017 by Sahil Arora.
+ *
+ * The PPD generator is based on the PPD generator for the CUPS
+ * "lpadmin -m everywhere" functionality in the cups/ppd-cache.c
+ * file. The copyright of this file is:
+ *
+ * Copyright 2010-2016 by Apple Inc.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * ppdCreateFromIPP() - Create a PPD file based on the result of an
+ * get-printer-attributes IPP request
+ */
+
+#include <config.h>
+#include <cups/cups.h>
+#if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 5)
+#define HAVE_CUPS_1_6 1
+#endif
+#if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 6)
+#define HAVE_CUPS_1_7 1
+#endif
+
+/*
+ * Include necessary headers.
+ */
+
+#include <errno.h>
+#include "driver.h"
+#include <string.h>
+#include <ctype.h>
+#ifdef HAVE_CUPS_1_7
+#include <cups/pwg.h>
+#endif /* HAVE_CUPS_1_7 */
+
+#ifdef HAVE_CUPS_1_6
+/* The following code uses a lot of CUPS >= 1.6 specific stuff.
+ It needed for create_local_queue() in cups-browsed
+ to set up local queues for non-CUPS printer broadcasts
+ that is disabled in create_local_queue() for older CUPS <= 1.5.4.
+ Accordingly the following code is also disabled here for CUPS < 1.6. */
+
+/*
+ * The code below is borrowed from the CUPS 2.2.x upstream repository
+ * (via patches attached to https://www.cups.org/str.php?L4258). This
+ * allows for automatic PPD generation already with CUPS versions older
+ * than CUPS 2.2.x. We have also an additional test and development
+ * platform for this code. Taken from cups/ppd-cache.c,
+ * cups/string-private.h, cups/string.c.
+ *
+ * The advantage of PPD generation instead of working with System V
+ * interface scripts is that the print dialogs of the clients do not
+ * need to ask the printer for its options via IPP. So we have access
+ * to the options with the current PPD-based dialogs and can even share
+ * the automatically created print queue to other CUPS-based machines
+ * without problems.
+ */
+
+
+typedef struct _pwg_finishings_s /**** PWG finishings mapping data ****/
+{
+ ipp_finishings_t value; /* finishings value */
+ int num_options; /* Number of options to apply */
+ cups_option_t *options; /* Options to apply */
+} _pwg_finishings_t;
+
+char ppdgenerator_msg[1024];
+
+#define _PWG_EQUIVALENT(x, y) (abs((x)-(y)) < 2)
+
+static void pwg_ppdize_name(const char *ipp, char *name, size_t namesize);
+static void pwg_ppdize_resolution(ipp_attribute_t *attr, int element, int *xres, int *yres, char *name, size_t namesize);
+
+/*
+ * '_cupsSetError()' - Set the last PPD generator status-message.
+ *
+ * This function replaces the original _cupsSetError() of the private
+ * API of the CUPS library. The #define and the renamed function prevent
+ * from the linker using the original function of the CUPS library instead
+ * of this replacement function.
+ */
+
+#define _cupsSetError(x, y, z) _CFcupsSetError(x, y, z)
+
+void
+_CFcupsSetError(ipp_status_t status, /* I - IPP status code
+ (for compatibility, ignored) */
+ const char *message, /* I - status-message value */
+ int localize) /* I - Localize the message?
+ (for compatibility, ignored) */
+{
+ (void)status;
+ (void)localize;
+
+ if (!message && errno)
+ message = strerror(errno);
+
+ if (message)
+ snprintf(ppdgenerator_msg, sizeof(ppdgenerator_msg), "%s", message);
+}
+
+int /* O - 1 on match, 0 otherwise */
+_cups_isalnum(int ch) /* I - Character to test */
+{
+ return ((ch >= '0' && ch <= '9') ||
+ (ch >= 'A' && ch <= 'Z') ||
+ (ch >= 'a' && ch <= 'z'));
+}
+
+int /* O - 1 on match, 0 otherwise */
+_cups_isalpha(int ch) /* I - Character to test */
+{
+ return ((ch >= 'A' && ch <= 'Z') ||
+ (ch >= 'a' && ch <= 'z'));
+}
+
+int /* O - 1 on match, 0 otherwise */
+_cups_islower(int ch) /* I - Character to test */
+{
+ return (ch >= 'a' && ch <= 'z');
+}
+
+int /* O - 1 on match, 0 otherwise */
+_cups_isspace(int ch) /* I - Character to test */
+{
+ return (ch == ' ' || ch == '\f' || ch == '\n' || ch == '\r' || ch == '\t' ||
+ ch == '\v');
+}
+
+int /* O - 1 on match, 0 otherwise */
+_cups_isupper(int ch) /* I - Character to test */
+{
+ return (ch >= 'A' && ch <= 'Z');
+}
+
+int /* O - Converted character */
+_cups_tolower(int ch) /* I - Character to convert */
+{
+ return (_cups_isupper(ch) ? ch - 'A' + 'a' : ch);
+}
+
+int /* O - Converted character */
+_cups_toupper(int ch) /* I - Character to convert */
+{
+ return (_cups_islower(ch) ? ch - 'a' + 'A' : ch);
+}
+
+#ifndef HAVE_STRLCPY
+/*
+ * '_cups_strlcpy()' - Safely copy two strings.
+ */
+
+size_t /* O - Length of string */
+strlcpy(char *dst, /* O - Destination string */
+ const char *src, /* I - Source string */
+ size_t size) /* I - Size of destination string buffer */
+{
+ size_t srclen; /* Length of source string */
+
+
+ /*
+ * Figure out how much room is needed...
+ */
+
+ size --;
+
+ srclen = strlen(src);
+
+ /*
+ * Copy the appropriate amount...
+ */
+
+ if (srclen > size)
+ srclen = size;
+
+ memmove(dst, src, srclen);
+ dst[srclen] = '\0';
+
+ return (srclen);
+}
+#endif /* !HAVE_STRLCPY */
+
+/*
+ * '_cupsStrFormatd()' - Format a floating-point number.
+ */
+
+char * /* O - Pointer to end of string */
+_cupsStrFormatd(char *buf, /* I - String */
+ char *bufend, /* I - End of string buffer */
+ double number, /* I - Number to format */
+ struct lconv *loc) /* I - Locale data */
+{
+ char *bufptr, /* Pointer into buffer */
+ temp[1024], /* Temporary string */
+ *tempdec, /* Pointer to decimal point */
+ *tempptr; /* Pointer into temporary string */
+ const char *dec; /* Decimal point */
+ int declen; /* Length of decimal point */
+
+
+ /*
+ * Format the number using the "%.12f" format and then eliminate
+ * unnecessary trailing 0's.
+ */
+
+ snprintf(temp, sizeof(temp), "%.12f", number);
+ for (tempptr = temp + strlen(temp) - 1;
+ tempptr > temp && *tempptr == '0';
+ *tempptr-- = '\0');
+
+ /*
+ * Next, find the decimal point...
+ */
+
+ if (loc && loc->decimal_point)
+ {
+ dec = loc->decimal_point;
+ declen = (int)strlen(dec);
+ }
+ else
+ {
+ dec = ".";
+ declen = 1;
+ }
+
+ if (declen == 1)
+ tempdec = strchr(temp, *dec);
+ else
+ tempdec = strstr(temp, dec);
+
+ /*
+ * Copy everything up to the decimal point...
+ */
+
+ if (tempdec)
+ {
+ for (tempptr = temp, bufptr = buf;
+ tempptr < tempdec && bufptr < bufend;
+ *bufptr++ = *tempptr++);
+
+ tempptr += declen;
+
+ if (*tempptr && bufptr < bufend)
+ {
+ *bufptr++ = '.';
+
+ while (*tempptr && bufptr < bufend)
+ *bufptr++ = *tempptr++;
+ }
+
+ *bufptr = '\0';
+ }
+ else
+ {
+ strlcpy(buf, temp, (size_t)(bufend - buf + 1));
+ bufptr = buf + strlen(buf);
+ }
+
+ return (bufptr);
+}
+
+
+/*
+ * '_cups_strcasecmp()' - Do a case-insensitive comparison.
+ */
+
+int /* O - Result of comparison (-1, 0, or 1) */
+_cups_strcasecmp(const char *s, /* I - First string */
+ const char *t) /* I - Second string */
+{
+ while (*s != '\0' && *t != '\0')
+ {
+ if (_cups_tolower(*s) < _cups_tolower(*t))
+ return (-1);
+ else if (_cups_tolower(*s) > _cups_tolower(*t))
+ return (1);
+
+ s ++;
+ t ++;
+ }
+
+ if (*s == '\0' && *t == '\0')
+ return (0);
+ else if (*s != '\0')
+ return (1);
+ else
+ return (-1);
+}
+
+/*
+ * '_cups_strncasecmp()' - Do a case-insensitive comparison on up to N chars.
+ */
+
+int /* O - Result of comparison (-1, 0, or 1) */
+_cups_strncasecmp(const char *s, /* I - First string */
+ const char *t, /* I - Second string */
+ size_t n) /* I - Maximum number of characters to compare */
+{
+ while (*s != '\0' && *t != '\0' && n > 0)
+ {
+ if (_cups_tolower(*s) < _cups_tolower(*t))
+ return (-1);
+ else if (_cups_tolower(*s) > _cups_tolower(*t))
+ return (1);
+
+ s ++;
+ t ++;
+ n --;
+ }
+
+ if (n == 0)
+ return (0);
+ else if (*s == '\0' && *t == '\0')
+ return (0);
+ else if (*s != '\0')
+ return (1);
+ else
+ return (-1);
+}
+
+/*
+ * '_()' - Simplify copying the ppdCreateFromIPP() function from CUPS,
+ * as we do not do translations of UI strings in cups-browsed
+ */
+
+#define _(s) s
+
+/*
+ * '_cupsLangString()' - Simplify copying the ppdCreateFromIPP() function
+ * from CUPS, as we do not do translations of UI strings
+ * in cups-browsed
+ */
+
+const char *
+_cupsLangString(cups_lang_t *l, const char *s)
+{
+ return s;
+}
+
+/* Data structure for resolution (X x Y dpi) */
+typedef struct res_s {
+ int x, y;
+} res_t;
+
+int
+compare_resolutions(void *resolution_a, void *resolution_b,
+ void *user_data)
+{
+ res_t *res_a = (res_t *)resolution_a;
+ res_t *res_b = (res_t *)resolution_b;
+ int i, a, b;
+
+ /* Compare the pixels per square inch */
+ a = res_a->x * res_a->y;
+ b = res_b->x * res_b->y;
+ i = (a > b) - (a < b);
+ if (i) return i;
+
+ /* Compare how much the pixel shape deviates from a square, the
+ more, the worse */
+ a = 100 * res_a->y / res_a->x;
+ if (a > 100) a = 10000 / a;
+ b = 100 * res_b->y / res_b->x;
+ if (b > 100) b = 10000 / b;
+ return (a > b) - (a < b);
+}
+
+void *
+copy_resolution(void *resolution, void *user_data)
+{
+ res_t *res = (res_t *)resolution;
+ res_t *copy;
+
+ copy = (res_t *)calloc(1, sizeof(res_t));
+ if (copy) {
+ copy->x = res->x;
+ copy->y = res->y;
+ }
+
+ return copy;
+}
+
+void
+free_resolution(void *resolution, void *user_data)
+{
+ res_t *res = (res_t *)resolution;
+
+ if (res) free(res);
+}
+
+cups_array_t *
+resolutionArrayNew()
+{
+ return cupsArrayNew3(compare_resolutions, NULL, NULL, 0,
+ copy_resolution, free_resolution);
+}
+
+res_t *
+resolutionNew(int x, int y)
+{
+ res_t *res = (res_t *)calloc(1, sizeof(res_t));
+ if (res) {
+ res->x = x;
+ res->y = y;
+ }
+ return res;
+}
+
+/* Read a single resolution from an IPP attribute, take care of
+ obviously wrong entries (printer firmware bugs), ignoring
+ resolutions of less than 75 dpi in at least one dimension and
+ fixing Brother's "600x2dpi" resolutions. */
+res_t *
+ippResolutionToRes(ipp_attribute_t *attr, int index)
+{
+ res_t *res = NULL;
+ int x = 0, y = 0;
+
+ if (attr) {
+ ipp_tag_t tag = ippGetValueTag(attr);
+ int count = ippGetCount(attr);
+
+ if (tag == IPP_TAG_RESOLUTION && index < count) {
+ pwg_ppdize_resolution(attr, index, &x, &y, NULL, 0);
+ if (y == 2) y = x; /* Brother quirk ("600x2dpi") */
+ if (x >= 75 && y >= 75)
+ res = resolutionNew(x, y);
+ }
+ }
+
+ return res;
+}
+
+cups_array_t *
+ippResolutionListToArray(ipp_attribute_t *attr)
+{
+ cups_array_t *res_array = NULL;
+ res_t *res;
+ int i;
+
+ if (attr) {
+ ipp_tag_t tag = ippGetValueTag(attr);
+ int count = ippGetCount(attr);
+
+ if (tag == IPP_TAG_RESOLUTION && count > 0) {
+ res_array = resolutionArrayNew();
+ if (res_array) {
+ for (i = 0; i < count; i ++)
+ if ((res = ippResolutionToRes(attr, i)) != NULL &&
+ cupsArrayFind(res_array, res) == NULL)
+ cupsArrayAdd(res_array, res);
+ }
+ if (cupsArrayCount(res_array) == 0) {
+ cupsArrayDelete(res_array);
+ res_array = NULL;
+ }
+ }
+ }
+
+ return res_array;
+}
+
+/* Build up an array of common resolutions and most desirable default
+ resolution from multiple arrays of resolutions with an optional
+ default resolution.
+ Call this function with each resolution array you find as "new", and
+ in "current" an array of the common resolutions will be built up.
+ You do not need to create an empty array for "current" before
+ starting. Initialize it with NULL.
+ "current_default" holds the default resolution of the array "current".
+ It will get replaced by "new_default" if "current_default" is either
+ NULL or a resolution which is not in "current" any more.
+ "new" and "new_default" will be deleted/freed and set to NULL after
+ each, successful or unsuccssful operation.
+ Note that when calling this function the addresses of the pointers
+ to the resolution arrays and default resolutions have to be given
+ (call by reference) as all will get modified by the function. */
+
+int /* 1 on success, 0 on failure */
+joinResolutionArrays(cups_array_t **current, cups_array_t **new,
+ res_t **current_default, res_t **new_default)
+{
+ res_t *res;
+ int retval;
+
+ if (current == NULL || new == NULL || *new == NULL ||
+ cupsArrayCount(*new) == 0) {
+ retval = 0;
+ goto finish;
+ }
+
+ if (*current == NULL) {
+ /* We are adding the very first resolution array, simply make it
+ our common resolutions array */
+ *current = *new;
+ if (current_default) {
+ if (*current_default)
+ free(*current_default);
+ *current_default = (new_default ? *new_default : NULL);
+ }
+ return 1;
+ } else if (cupsArrayCount(*current) == 0) {
+ retval = 1;
+ goto finish;
+ }
+
+ /* Dry run: Check whether the two array have at least one resolution
+ in common, if not, do not touch the original array */
+ for (res = cupsArrayFirst(*current);
+ res; res = cupsArrayNext(*current))
+ if (cupsArrayFind(*new, res))
+ break;
+
+ if (res) {
+ /* Reduce the original array to the resolutions which are in both
+ the original and the new array, at least one resolution will
+ remain. */
+ for (res = cupsArrayFirst(*current);
+ res; res = cupsArrayNext(*current))
+ if (!cupsArrayFind(*new, res))
+ cupsArrayRemove(*current, res);
+ if (current_default) {
+ /* Replace the current default by the new one if the current default
+ is not in the array any more or if it is NULL. If the new default
+ is not in the list or NULL in such a case, set the current default
+ to NULL */
+ if (*current_default && !cupsArrayFind(*current, *current_default)) {
+ free(*current_default);
+ *current_default = NULL;
+ }
+ if (*current_default == NULL && new_default && *new_default &&
+ cupsArrayFind(*current, *new_default))
+ *current_default = copy_resolution(*new_default, NULL);
+ }
+ retval = 1;
+ } else
+ retval = 0;
+
+ finish:
+ if (new && *new) {
+ cupsArrayDelete(*new);
+ *new = NULL;
+ }
+ if (new_default && *new_default) {
+ free(*new_default);
+ *new_default = NULL;
+ }
+ return retval;
+}
+
+/*
+ * 'ppdCreateFromIPP()' - Create a PPD file describing the capabilities
+ * of an IPP printer.
+ */
+
+char * /* O - PPD filename or NULL on error */
+ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
+ size_t bufsize, /* I - Size of filename buffer */
+ ipp_t *response, /* I - Get-Printer-Attributes response */
+ const char *make_model,/* I - Make and model from DNS-SD */
+ const char *pdl, /* I - List of PDLs from DNS-SD */
+ int color, /* I - Color printer? (from DNS-SD) */
+ int duplex) /* I - Duplex printer? (from DNS-SD) */
+{
+ cups_file_t *fp; /* PPD file */
+ cups_array_t *sizes; /* Media sizes we've added */
+ ipp_attribute_t *attr, /* xxx-supported */
+ *defattr, /* xxx-default */
+ *quality, /* print-quality-supported */
+ *x_dim, *y_dim; /* Media dimensions */
+ ipp_t *media_size; /* Media size collection */
+ char make[256], /* Make and model */
+ *model, /* Model name */
+ ppdname[PPD_MAX_NAME];
+ /* PPD keyword */
+ int i, j, /* Looping vars */
+ count = 0, /* Number of values */
+ bottom, /* Largest bottom margin */
+ left, /* Largest left margin */
+ right, /* Largest right margin */
+ top, /* Largest top margin */
+ is_apple = 0, /* Does the printer support Apple
+ Raster? */
+ is_pwg = 0, /* Does the printer support PWG
+ Raster? */
+ is_pclm = 0, /* Does the printer support PCLm? */
+ is_pdf = 0; /* Does the printer support PDF? */
+ pwg_media_t *pwg; /* PWG media size */
+ int xres, yres; /* Resolution values */
+ cups_array_t *common_res, /* Common resolutions of all PDLs */
+ *current_res, /* Resolutions of current PDL */
+ *pdl_list; /* List of PDLs */
+ res_t *common_def, /* Common default resolution */
+ *current_def, /* Default resolution of current PDL */
+ *min_res, /* Minimum common resolution */
+ *max_res; /* Maximum common resolution */
+ cups_lang_t *lang = cupsLangDefault();
+ /* Localization info */
+ struct lconv *loc = localeconv();
+ /* Locale data */
+ static const char * const finishings[][2] =
+ { /* Finishings strings */
+ { "bale", _("Bale") },
+ { "bind", _("Bind") },
+ { "bind-bottom", _("Bind (Reverse Landscape)") },
+ { "bind-left", _("Bind (Portrait)") },
+ { "bind-right", _("Bind (Reverse Portrait)") },
+ { "bind-top", _("Bind (Landscape)") },
+ { "booklet-maker", _("Booklet Maker") },
+ { "coat", _("Coat") },
+ { "cover", _("Cover") },
+ { "edge-stitch", _("Staple Edge") },
+ { "edge-stitch-bottom", _("Staple Edge (Reverse Landscape)") },
+ { "edge-stitch-left", _("Staple Edge (Portrait)") },
+ { "edge-stitch-right", _("Staple Edge (Reverse Portrait)") },
+ { "edge-stitch-top", _("Staple Edge (Landscape)") },
+ { "fold", _("Fold") },
+ { "fold-accordian", _("Accordian Fold") },
+ { "fold-double-gate", _("Double Gate Fold") },
+ { "fold-engineering-z", _("Engineering Z Fold") },
+ { "fold-gate", _("Gate Fold") },
+ { "fold-half", _("Half Fold") },
+ { "fold-half-z", _("Half Z Fold") },
+ { "fold-left-gate", _("Left Gate Fold") },
+ { "fold-letter", _("Letter Fold") },
+ { "fold-parallel", _("Parallel Fold") },
+ { "fold-poster", _("Poster Fold") },
+ { "fold-right-gate", _("Right Gate Fold") },
+ { "fold-z", _("Z Fold") },
+ { "jog-offset", _("Jog") },
+ { "laminate", _("Laminate") },
+ { "punch", _("Punch") },
+ { "punch-bottom-left", _("Single Punch (Reverse Landscape)") },
+ { "punch-bottom-right", _("Single Punch (Reverse Portrait)") },
+ { "punch-double-bottom", _("2-Hole Punch (Reverse Portrait)") },
+ { "punch-double-left", _("2-Hole Punch (Reverse Landscape)") },
+ { "punch-double-right", _("2-Hole Punch (Landscape)") },
+ { "punch-double-top", _("2-Hole Punch (Portrait)") },
+ { "punch-quad-bottom", _("4-Hole Punch (Reverse Landscape)") },
+ { "punch-quad-left", _("4-Hole Punch (Portrait)") },
+ { "punch-quad-right", _("4-Hole Punch (Reverse Portrait)") },
+ { "punch-quad-top", _("4-Hole Punch (Landscape)") },
+ { "punch-top-left", _("Single Punch (Portrait)") },
+ { "punch-top-right", _("Single Punch (Landscape)") },
+ { "punch-triple-bottom", _("3-Hole Punch (Reverse Landscape)") },
+ { "punch-triple-left", _("3-Hole Punch (Portrait)") },
+ { "punch-triple-right", _("3-Hole Punch (Reverse Portrait)") },
+ { "punch-triple-top", _("3-Hole Punch (Landscape)") },
+ { "punch-multiple-bottom", _("Multi-Hole Punch (Reverse Landscape)") },
+ { "punch-multiple-left", _("Multi-Hole Punch (Portrait)") },
+ { "punch-multiple-right", _("Multi-Hole Punch (Reverse Portrait)") },
+ { "punch-multiple-top", _("Multi-Hole Punch (Landscape)") },
+ { "saddle-stitch", _("Saddle Stitch") },
+ { "staple", _("Staple") },
+ { "staple-bottom-left", _("Single Staple (Reverse Landscape)") },
+ { "staple-bottom-right", _("Single Staple (Reverse Portrait)") },
+ { "staple-dual-bottom", _("Double Staple (Reverse Landscape)") },
+ { "staple-dual-left", _("Double Staple (Portrait)") },
+ { "staple-dual-right", _("Double Staple (Reverse Portrait)") },
+ { "staple-dual-top", _("Double Staple (Landscape)") },
+ { "staple-top-left", _("Single Staple (Portrait)") },
+ { "staple-top-right", _("Single Staple (Landscape)") },
+ { "staple-triple-bottom", _("Triple Staple (Reverse Landscape)") },
+ { "staple-triple-left", _("Triple Staple (Portrait)") },
+ { "staple-triple-right", _("Triple Staple (Reverse Portrait)") },
+ { "staple-triple-top", _("Triple Staple (Landscape)") },
+ { "trim", _("Cut Media") }
+ };
+ char filter_path[1024];
+ /* Path to filter executable */
+ const char *cups_serverbin;/* CUPS_SERVERBIN environment
+ variable */
+
+ /*
+ * Range check input...
+ */
+
+ if (buffer)
+ *buffer = '\0';
+
+ if (!buffer || bufsize < 1)
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
+ return (NULL);
+ }
+
+ if (!response)
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No IPP attributes."), 1);
+ return (NULL);
+ }
+
+ /*
+ * Open a temporary file for the PPD...
+ */
+
+ if ((fp = cupsTempFile2(buffer, (int)bufsize)) == NULL)
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
+ return (NULL);
+ }
+
+ /*
+ * Standard stuff for PPD file...
+ */
+
+ cupsFilePuts(fp, "*PPD-Adobe: \"4.3\"\n");
+ cupsFilePuts(fp, "*FormatVersion: \"4.3\"\n");
+ cupsFilePrintf(fp, "*FileVersion: \"%d.%d\"\n", CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR);
+ cupsFilePuts(fp, "*LanguageVersion: English\n");
+ cupsFilePuts(fp, "*LanguageEncoding: ISOLatin1\n");
+ cupsFilePuts(fp, "*PSVersion: \"(3010.000) 0\"\n");
+ cupsFilePuts(fp, "*LanguageLevel: \"3\"\n");
+ cupsFilePuts(fp, "*FileSystem: False\n");
+ cupsFilePuts(fp, "*PCFileName: \"ippeve.ppd\"\n");
+
+ if ((attr = ippFindAttribute(response, "printer-make-and-model", IPP_TAG_TEXT)) != NULL)
+ strlcpy(make, ippGetString(attr, 0, NULL), sizeof(make));
+ else if (make_model && make_model[0] != '\0')
+ strlcpy(make, make_model, sizeof(make));
+ else
+ strlcpy(make, "Unknown Printer", sizeof(make));
+
+ if (!_cups_strncasecmp(make, "Hewlett Packard ", 16) ||
+ !_cups_strncasecmp(make, "Hewlett-Packard ", 16))
+ {
+ model = make + 16;
+ strlcpy(make, "HP", sizeof(make));
+ }
+ else if ((model = strchr(make, ' ')) != NULL)
+ *model++ = '\0';
+ else
+ model = make;
+
+ cupsFilePrintf(fp, "*Manufacturer: \"%s\"\n", make);
+ cupsFilePrintf(fp, "*ModelName: \"%s %s\"\n", make, model);
+ cupsFilePrintf(fp, "*Product: \"(%s %s)\"\n", make, model);
+ cupsFilePrintf(fp, "*NickName: \"%s %s, driverless, cups-filters %s\"\n", make, model,
+ VERSION);
+ cupsFilePrintf(fp, "*ShortNickName: \"%s %s\"\n", make, model);
+
+ if (((attr = ippFindAttribute(response, "color-supported", IPP_TAG_BOOLEAN)) != NULL && ippGetBoolean(attr, 0)) || color)
+ cupsFilePuts(fp, "*ColorDevice: True\n");
+ else
+ cupsFilePuts(fp, "*ColorDevice: False\n");
+
+ cupsFilePrintf(fp, "*cupsVersion: %d.%d\n", CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR);
+ cupsFilePuts(fp, "*cupsSNMPSupplies: False\n");
+ cupsFilePuts(fp, "*cupsLanguages: \"en\"\n");
+
+ /*
+ * PDLs and common resolutions ...
+ */
+
+ common_res = NULL;
+ current_res = NULL;
+ common_def = NULL;
+ current_def = NULL;
+ min_res = NULL;
+ max_res = NULL;
+ /* Put all available PDls into a simple case-insensitevely searchable
+ sorted string list */
+ if ((pdl_list = cupsArrayNew3((cups_array_func_t)strcasecmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ goto bad_ppd;
+ int formatfound = 0;
+
+ if (((attr = ippFindAttribute(response, "document-format-supported", IPP_TAG_MIMETYPE)) != NULL) || (pdl && pdl[0] != '\0'))
+ {
+ const char *format = pdl;
+ i = 0;
+ count = ippGetCount(attr);
+ while ((attr && i < count) || /* Go through formats in attribute */
+ (!attr && pdl && pdl[0] != '\0' && format[0] != '\0'))
+ /* Go through formats in pdl string (from DNS-SD record) */
+ {
+ /* Pick next format from attribute */
+ if (attr) format = ippGetString(attr, i, NULL);
+ /* Add format to list of supported PDLs, skip duplicates */
+ if (!cupsArrayFind(pdl_list, (void *)format))
+ cupsArrayAdd(pdl_list, (void *)format);
+ if (attr)
+ /* Next format in attribute */
+ i ++;
+ else {
+ /* Find the next format in the string pdl, if there is none left,
+ go to the terminating zero */
+ while (!isspace(*format) && *format != ',' && *format != '\0')
+ format ++;
+ while ((isspace(*format) || *format == ',') && *format != '\0')
+ format ++;
+ }
+ }
+ }
+
+ /* Check for each CUPS/cups-filters-supported PDL, starting with the
+ most desirable going to the least desirable. If a PDL requires a
+ certain set of resolutions (the raster-based PDLs), find the
+ resolutions and find out which are the common resolutions of all
+ supported PDLs. Choose the default resolution from the most
+ desirable of all resolution-requiring PDLs if it is common in all
+ of them. Skip a resolution-requiring PDL if its resolution list
+ attrinbute is missing or contains only broken entries. Use the
+ general resolution list and default resolution of the printer
+ only if it does not support any resolution-requiring PDL. Use 300
+ dpi if there is no resolution info at all in the attributes. */
+ if (cupsArrayFind(pdl_list, "application/pdf")) {
+ cupsFilePuts(fp, "*cupsFilter2: \"application/vnd.cups-pdf application/pdf 0 -\"\n");
+ formatfound = 1;
+ is_pdf = 1;
+ }
+ if (cupsArrayFind(pdl_list, "image/pwg-raster")) {
+ if ((attr = ippFindAttribute(response, "pwg-raster-document-resolution-supported", IPP_TAG_RESOLUTION)) != NULL) {
+ current_def = NULL;
+ if ((current_res = ippResolutionListToArray(attr)) != NULL &&
+ joinResolutionArrays(&common_res, &current_res, &common_def,
+ &current_def)) {
+ cupsFilePuts(fp, "*cupsFilter2: \"image/pwg-raster image/pwg-raster 0 -\"\n");
+ formatfound = 1;
+ is_pwg = 1;
+ }
+ }
+ }
+#ifdef CUPS_RASTER_HAVE_APPLERASTER
+ if (cupsArrayFind(pdl_list, "image/urf")) {
+ if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL) {
+ int lowdpi = 0, hidpi = 0; /* Lower and higher resolution */
+ for (i = 0, count = ippGetCount(attr); i < count; i ++) {
+ const char *rs = ippGetString(attr, i, NULL); /* RS value */
+ if (_cups_strncasecmp(rs, "RS", 2))
+ continue;
+ lowdpi = atoi(rs + 2);
+ if ((rs = strrchr(rs, '-')) != NULL)
+ hidpi = atoi(rs + 1);
+ else
+ hidpi = lowdpi;
+ break;
+ }
+ if (lowdpi == 0) {
+ /* Invalid "urf-supported" value... */
+ goto bad_ppd;
+ } else {
+ if ((current_res = resolutionArrayNew()) != NULL) {
+ if ((current_def = resolutionNew(lowdpi, lowdpi)) != NULL)
+ cupsArrayAdd(current_res, current_def);
+ if (hidpi != lowdpi &&
+ (current_def = resolutionNew(hidpi, hidpi)) != NULL)
+ cupsArrayAdd(current_res, current_def);
+ current_def = NULL;
+ if (cupsArrayCount(current_res) > 0 &&
+ joinResolutionArrays(&common_res, &current_res, &common_def,
+ &current_def)) {
+ cupsFilePuts(fp, "*cupsFilter2: \"image/urf image/urf 100 -\"\n");
+ formatfound = 1;
+ is_apple = 1;
+ }
+ }
+ }
+ }
+ }
+#endif
+#ifdef QPDF_HAVE_PCLM
+ if (cupsArrayFind(pdl_list, "application/PCLm")) {
+ if ((attr = ippFindAttribute(response, "pclm-source-resolution-supported", IPP_TAG_RESOLUTION)) != NULL) {
+ if ((defattr = ippFindAttribute(response, "pclm-source-resolution-default", IPP_TAG_RESOLUTION)) != NULL)
+ current_def = ippResolutionToRes(defattr, 0);
+ else
+ current_def = NULL;
+ if ((current_res = ippResolutionListToArray(attr)) != NULL &&
+ joinResolutionArrays(&common_res, &current_res, &common_def,
+ &current_def)) {
+ cupsFilePuts(fp, "*cupsFilter2: \"application/PCLm application/PCLm 200 -\"\n");
+ formatfound = 1;
+ is_pclm = 1;
+ }
+ }
+ }
+#endif
+ if (cupsArrayFind(pdl_list, "application/vnd.hp-pclxl")) {
+ /* Check whether the gstopxl filter is installed,
+ otherwise ignore the PCL-XL support of the printer */
+ if ((cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL)
+ cups_serverbin = CUPS_SERVERBIN;
+ snprintf(filter_path, sizeof(filter_path), "%s/filter/gstopxl",
+ cups_serverbin);
+ if (access(filter_path, X_OK) == 0) {
+ /* We put a high cost factor here as if a printer supports also
+ another format, like PWG or Apple Raster, we prefer it, as some
+ PCL-XL printers have bugs in their PCL-XL interpreters */
+ cupsFilePrintf(fp, "*cupsFilter2: \"application/vnd.cups-pdf application/vnd.hp-pclxl 300 gstopxl\"\n");
+ formatfound = 1;
+ }
+ }
+ if (cupsArrayFind(pdl_list, "application/postscript")) {
+ /* We put a high cost factor here as if a printer supports also
+ another format, like PWG or Apple Raster, we prefer it, as many
+ PostScript printers have bugs in their PostScript interpreters */
+ cupsFilePuts(fp, "*cupsFilter2: \"application/vnd.cups-postscript application/postscript 500 -\"\n");
+ formatfound = 1;
+ }
+ if (cupsArrayFind(pdl_list, "application/vnd.hp-pcl")) {
+ /* We put a high cost factor here as if a printer supports also
+ another format, like PWG or Apple Raster, we prefer it, as there
+ are some printers, like HP inkjets which report to accept PCL
+ but do not support PCL 5c/e or PCL-XL */
+ cupsFilePrintf(fp, "*cupsFilter2: \"application/vnd.cups-raster application/vnd.hp-pcl 700 rastertopclx\"\n");
+ formatfound = 1;
+ }
+ if (cupsArrayFind(pdl_list, "image/jpeg"))
+ cupsFilePuts(fp, "*cupsFilter2: \"image/jpeg image/jpeg 0 -\"\n");
+ if (cupsArrayFind(pdl_list, "image/png"))
+ cupsFilePuts(fp, "*cupsFilter2: \"image/png image/png 0 -\"\n");
+ cupsArrayDelete(pdl_list);
+ if (formatfound == 0)
+ goto bad_ppd;
+
+ /* No resolution requirements by any of the supported PDLs?
+ Use "printer-resolution-supported" attribute */
+ if (common_res == NULL) {
+ if ((attr = ippFindAttribute(response, "printer-resolution-supported", IPP_TAG_RESOLUTION)) != NULL) {
+ if ((defattr = ippFindAttribute(response, "printer-resolution-default", IPP_TAG_RESOLUTION)) != NULL)
+ current_def = ippResolutionToRes(defattr, 0);
+ else
+ current_def = NULL;
+ if ((current_res = ippResolutionListToArray(attr)) != NULL)
+ joinResolutionArrays(&common_res, &current_res, &common_def,
+ &current_def);
+ }
+ }
+ /* Still no resolution found? Default to 300 dpi */
+ if (common_res == NULL) {
+ if ((common_res = resolutionArrayNew()) != NULL) {
+ if ((current_def = resolutionNew(300, 300)) != NULL)
+ cupsArrayAdd(common_res, current_def);
+ current_def = NULL;
+ } else
+ goto bad_ppd;
+ }
+ /* No default resolution determined yet */
+ if (common_def == NULL) {
+ if ((defattr = ippFindAttribute(response, "printer-resolution-default", IPP_TAG_RESOLUTION)) != NULL) {
+ common_def = ippResolutionToRes(defattr, 0);
+ if (!cupsArrayFind(common_res, common_def)) {
+ free(common_def);
+ common_def = NULL;
+ }
+ }
+ if (common_def == NULL) {
+ count = cupsArrayCount(common_res);
+ common_def = copy_resolution(cupsArrayIndex(common_res, count / 2), NULL);
+ }
+ }
+ /* Get minimum and maximum resolution */
+ min_res = copy_resolution(cupsArrayFirst(common_res), NULL);
+ max_res = copy_resolution(cupsArrayLast(common_res), NULL);
+ cupsArrayDelete(common_res);
+
+#ifdef QPDF_HAVE_PCLM
+ /*
+ * Generically check for PCLm attributes in IPP response
+ * and ppdize them one by one
+ */
+
+ if (is_pclm)
+ {
+ attr = ippFirstAttribute(response); /* first attribute */
+ while (attr) /* loop through all the attributes */
+ {
+ if (_cups_strncasecmp(ippGetName(attr), "pclm", 4) == 0)
+ {
+ pwg_ppdize_name(ippGetName(attr), ppdname, sizeof(ppdname));
+ cupsFilePrintf(fp, "*cups%s: ", ppdname);
+ ipp_tag_t tag = ippGetValueTag(attr);
+ count = ippGetCount(attr);
+
+ if (tag == IPP_TAG_RESOLUTION) /* ppdize values of type resolution */
+ {
+ if ((current_res = ippResolutionListToArray(attr)) != NULL)
+ {
+ count = cupsArrayCount(current_res);
+ if (count > 1)
+ cupsFilePuts(fp, "\"");
+ for (i = 0, current_def = cupsArrayFirst(current_res);
+ current_def;
+ i ++, current_def = cupsArrayNext(current_res))
+ {
+ int x = current_def->x;
+ int y = current_def->y;
+ if (x == y)
+ cupsFilePrintf(fp, "%ddpi", x);
+ else
+ cupsFilePrintf(fp, "%dx%ddpi", x, y);
+ if (i < count - 1)
+ cupsFilePuts(fp, ",");
+ }
+ if (count > 1)
+ cupsFilePuts(fp, "\"");
+ cupsFilePuts(fp, "\n");
+ }
+ else
+ cupsFilePuts(fp, "\"\"\n");
+ cupsArrayDelete(current_res);
+ }
+ else
+ {
+ ippAttributeString(attr, ppdname, sizeof(ppdname));
+ if (count > 1 || /* quotes around multi-valued and string
+ attributes */
+ tag == IPP_TAG_STRING ||
+ tag == IPP_TAG_TEXT ||
+ tag == IPP_TAG_TEXTLANG)
+ cupsFilePrintf(fp, "\"%s\"\n", ppdname);
+ else
+ cupsFilePrintf(fp, "%s\n", ppdname);
+ }
+ }
+ attr = ippNextAttribute(response);
+ }
+ }
+#endif
+
+ /*
+ * PageSize/PageRegion/ImageableArea/PaperDimension
+ */
+
+ if ((attr = ippFindAttribute(response, "media-bottom-margin-supported", IPP_TAG_INTEGER)) != NULL)
+ {
+ for (i = 1, bottom = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
+ if (ippGetInteger(attr, i) > bottom)
+ bottom = ippGetInteger(attr, i);
+ }
+ else
+ bottom = 1270;
+
+ if ((attr = ippFindAttribute(response, "media-left-margin-supported", IPP_TAG_INTEGER)) != NULL)
+ {
+ for (i = 1, left = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
+ if (ippGetInteger(attr, i) > left)
+ left = ippGetInteger(attr, i);
+ }
+ else
+ left = 635;
+
+ if ((attr = ippFindAttribute(response, "media-right-margin-supported", IPP_TAG_INTEGER)) != NULL)
+ {
+ for (i = 1, right = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
+ if (ippGetInteger(attr, i) > right)
+ right = ippGetInteger(attr, i);
+ }
+ else
+ right = 635;
+
+ if ((attr = ippFindAttribute(response, "media-top-margin-supported", IPP_TAG_INTEGER)) != NULL)
+ {
+ for (i = 1, top = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
+ if (ippGetInteger(attr, i) > top)
+ top = ippGetInteger(attr, i);
+ }
+ else
+ top = 1270;
+
+ if ((defattr = ippFindAttribute(response, "media-col-default", IPP_TAG_BEGIN_COLLECTION)) != NULL)
+ {
+ if ((attr = ippFindAttribute(ippGetCollection(defattr, 0), "media-size", IPP_TAG_BEGIN_COLLECTION)) != NULL)
+ {
+ media_size = ippGetCollection(attr, 0);
+ x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_INTEGER);
+ y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_INTEGER);
+
+ if (x_dim && y_dim && (pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0))) != NULL)
+ strlcpy(ppdname, pwg->ppd, sizeof(ppdname));
+ else
+ strlcpy(ppdname, "Unknown", sizeof(ppdname));
+ }
+ else
+ strlcpy(ppdname, "Unknown", sizeof(ppdname));
+ }
+ else if ((pwg = pwgMediaForPWG(ippGetString(ippFindAttribute(response, "media-default", IPP_TAG_ZERO), 0, NULL))) != NULL)
+ strlcpy(ppdname, pwg->ppd, sizeof(ppdname));
+ else
+ strlcpy(ppdname, "Unknown", sizeof(ppdname));
+
+ if ((attr = ippFindAttribute(response, "media-size-supported", IPP_TAG_BEGIN_COLLECTION)) == NULL)
+ attr = ippFindAttribute(response, "media-supported", IPP_TAG_ZERO);
+ if (attr && ippGetCount(attr) > 0)
+ {
+ cupsFilePrintf(fp, "*OpenUI *PageSize: PickOne\n"
+ "*OrderDependency: 10 AnySetup *PageSize\n"
+ "*DefaultPageSize: %s\n", ppdname);
+
+ sizes = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
+
+ for (i = 0, count = ippGetCount(attr); i < count; i ++)
+ {
+ if (ippGetValueTag(attr) == IPP_TAG_BEGIN_COLLECTION)
+ {
+ media_size = ippGetCollection(attr, i);
+ x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_INTEGER);
+ y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_INTEGER);
+
+ pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0));
+ }
+ else
+ pwg = pwgMediaForPWG(ippGetString(attr, i, NULL));
+
+ if (pwg)
+ {
+ char twidth[256], /* Width string */
+ tlength[256]; /* Length string */
+
+ if (cupsArrayFind(sizes, (void *)pwg->ppd))
+ {
+ cupsFilePrintf(fp, "*%% warning: Duplicate size '%s' reported by printer.\n",
+ pwg->ppd);
+ continue;
+ }
+
+ if (!pwg->ppd || pwg->width <= 0 || pwg->length <= 0) {
+ cupsFilePrintf(fp, "*%% warning: Invalid size '%s' (%dx%d pt, %.1fx%.1f inches, %.1fx%.1f cm) reported by printer.\n",
+ (pwg->ppd ? pwg->ppd : "NO SIZE NAME"),
+ (int)(pwg->width * 72.0 / 2540.0),
+ (int)(pwg->length * 72.0 / 2540.0),
+ pwg->width / 2540.0,
+ pwg->length / 2540.0,
+ pwg->width / 1000.0,
+ pwg->length / 1000.0);
+ continue;
+ }
+
+ cupsArrayAdd(sizes, (void *)pwg->ppd);
+
+ _cupsStrFormatd(twidth, twidth + sizeof(twidth), pwg->width * 72.0 / 2540.0, loc);
+ _cupsStrFormatd(tlength, tlength + sizeof(tlength), pwg->length * 72.0 / 2540.0, loc);
+
+ cupsFilePrintf(fp, "*PageSize %s: \"<</PageSize[%s %s]>>setpagedevice\"\n", pwg->ppd, twidth, tlength);
+ }
+ }
+ cupsFilePuts(fp, "*CloseUI: *PageSize\n");
+
+ cupsArrayDelete(sizes);
+ sizes = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
+
+ cupsFilePrintf(fp, "*OpenUI *PageRegion: PickOne\n"
+ "*OrderDependency: 10 AnySetup *PageRegion\n"
+ "*DefaultPageRegion: %s\n", ppdname);
+ for (i = 0, count = ippGetCount(attr); i < count; i ++)
+ {
+ if (ippGetValueTag(attr) == IPP_TAG_BEGIN_COLLECTION)
+ {
+ media_size = ippGetCollection(attr, i);
+ x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_INTEGER);
+ y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_INTEGER);
+
+ pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0));
+ }
+ else
+ pwg = pwgMediaForPWG(ippGetString(attr, i, NULL));
+
+ if (pwg)
+ {
+ char twidth[256], /* Width string */
+ tlength[256]; /* Length string */
+
+ if (cupsArrayFind(sizes, (void *)pwg->ppd))
+ continue;
+
+ if (!pwg->ppd || pwg->width <= 0 || pwg->length <= 0)
+ continue;
+
+ cupsArrayAdd(sizes, (void *)pwg->ppd);
+
+ _cupsStrFormatd(twidth, twidth + sizeof(twidth), pwg->width * 72.0 / 2540.0, loc);
+ _cupsStrFormatd(tlength, tlength + sizeof(tlength), pwg->length * 72.0 / 2540.0, loc);
+
+ cupsFilePrintf(fp, "*PageRegion %s: \"<</PageSize[%s %s]>>setpagedevice\"\n", pwg->ppd, twidth, tlength);
+ }
+ }
+ cupsFilePuts(fp, "*CloseUI: *PageRegion\n");
+
+ cupsArrayDelete(sizes);
+ sizes = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
+
+ cupsFilePrintf(fp, "*DefaultImageableArea: %s\n"
+ "*DefaultPaperDimension: %s\n", ppdname, ppdname);
+ for (i = 0, count = ippGetCount(attr); i < count; i ++)
+ {
+ if (ippGetValueTag(attr) == IPP_TAG_BEGIN_COLLECTION)
+ {
+ media_size = ippGetCollection(attr, i);
+ x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_INTEGER);
+ y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_INTEGER);
+
+ pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0));
+ }
+ else
+ pwg = pwgMediaForPWG(ippGetString(attr, i, NULL));
+
+ if (pwg)
+ {
+ char tleft[256], /* Left string */
+ tbottom[256], /* Bottom string */
+ tright[256], /* Right string */
+ ttop[256], /* Top string */
+ twidth[256], /* Width string */
+ tlength[256]; /* Length string */
+
+ if (cupsArrayFind(sizes, (void *)pwg->ppd))
+ continue;
+
+ if (!pwg->ppd || pwg->width <= 0 || pwg->length <= 0)
+ continue;
+
+ cupsArrayAdd(sizes, (void *)pwg->ppd);
+
+ _cupsStrFormatd(tleft, tleft + sizeof(tleft), left * 72.0 / 2540.0, loc);
+ _cupsStrFormatd(tbottom, tbottom + sizeof(tbottom), bottom * 72.0 / 2540.0, loc);
+ _cupsStrFormatd(tright, tright + sizeof(tright), (pwg->width - right) * 72.0 / 2540.0, loc);
+ _cupsStrFormatd(ttop, ttop + sizeof(ttop), (pwg->length - top) * 72.0 / 2540.0, loc);
+ _cupsStrFormatd(twidth, twidth + sizeof(twidth), pwg->width * 72.0 / 2540.0, loc);
+ _cupsStrFormatd(tlength, tlength + sizeof(tlength), pwg->length * 72.0 / 2540.0, loc);
+
+ cupsFilePrintf(fp, "*ImageableArea %s: \"%s %s %s %s\"\n", pwg->ppd, tleft, tbottom, tright, ttop);
+ cupsFilePrintf(fp, "*PaperDimension %s: \"%s %s\"\n", pwg->ppd, twidth, tlength);
+ }
+ }
+ cupsArrayDelete(sizes);
+ } else {
+ cupsFilePrintf(fp,
+ "*%% Printer did not supply page size info via IPP, using defaults\n"
+ "*OpenUI *PageSize: PickOne\n"
+ "*OrderDependency: 10 AnySetup *PageSize\n"
+ "*DefaultPageSize: Letter\n"
+ "*PageSize Letter/US Letter: \"<</PageSize[612 792]>>setpagedevice\"\n"
+ "*PageSize Legal/US Legal: \"<</PageSize[612 1008]>>setpagedevice\"\n"
+ "*PageSize Executive/Executive: \"<</PageSize[522 756]>>setpagedevice\"\n"
+ "*PageSize Tabloid/Tabloid: \"<</PageSize[792 1224]>>setpagedevice\"\n"
+ "*PageSize A3/A3: \"<</PageSize[842 1191]>>setpagedevice\"\n"
+ "*PageSize A4/A4: \"<</PageSize[595 842]>>setpagedevice\"\n"
+ "*PageSize A5/A5: \"<</PageSize[420 595]>>setpagedevice\"\n"
+ "*PageSize B5/JIS B5: \"<</PageSize[516 729]>>setpagedevice\"\n"
+ "*PageSize EnvISOB5/Envelope B5: \"<</PageSize[499 709]>>setpagedevice\"\n"
+ "*PageSize Env10/Envelope #10 : \"<</PageSize[297 684]>>setpagedevice\"\n"
+ "*PageSize EnvC5/Envelope C5: \"<</PageSize[459 649]>>setpagedevice\"\n"
+ "*PageSize EnvDL/Envelope DL: \"<</PageSize[312 624]>>setpagedevice\"\n"
+ "*PageSize EnvMonarch/Envelope Monarch: \"<</PageSize[279 540]>>setpagedevice\"\n"
+ "*CloseUI: *PageSize\n"
+ "*OpenUI *PageRegion: PickOne\n"
+ "*OrderDependency: 10 AnySetup *PageRegion\n"
+ "*DefaultPageRegion: Letter\n"
+ "*PageRegion Letter/US Letter: \"<</PageSize[612 792]>>setpagedevice\"\n"
+ "*PageRegion Legal/US Legal: \"<</PageSize[612 1008]>>setpagedevice\"\n"
+ "*PageRegion Executive/Executive: \"<</PageSize[522 756]>>setpagedevice\"\n"
+ "*PageRegion Tabloid/Tabloid: \"<</PageSize[792 1224]>>setpagedevice\"\n"
+ "*PageRegion A3/A3: \"<</PageSize[842 1191]>>setpagedevice\"\n"
+ "*PageRegion A4/A4: \"<</PageSize[595 842]>>setpagedevice\"\n"
+ "*PageRegion A5/A5: \"<</PageSize[420 595]>>setpagedevice\"\n"
+ "*PageRegion B5/JIS B5: \"<</PageSize[516 729]>>setpagedevice\"\n"
+ "*PageRegion EnvISOB5/Envelope B5: \"<</PageSize[499 709]>>setpagedevice\"\n"
+ "*PageRegion Env10/Envelope #10 : \"<</PageSize[297 684]>>setpagedevice\"\n"
+ "*PageRegion EnvC5/Envelope C5: \"<</PageSize[459 649]>>setpagedevice\"\n"
+ "*PageRegion EnvDL/Envelope DL: \"<</PageSize[312 624]>>setpagedevice\"\n"
+ "*PageRegion EnvMonarch/Envelope Monarch: \"<</PageSize[279 540]>>setpagedevice\"\n"
+ "*CloseUI: *PageSize\n"
+ "*DefaultImageableArea: Letter\n"
+ "*ImageableArea Letter/US Letter: \"18 12 594 780\"\n"
+ "*ImageableArea Legal/US Legal: \"18 12 594 996\"\n"
+ "*ImageableArea Executive/Executive: \"18 12 504 744\"\n"
+ "*ImageableArea Tabloid/Tabloid: \"18 12 774 1212\"\n"
+ "*ImageableArea A3/A3: \"18 12 824 1179\"\n"
+ "*ImageableArea A4/A4: \"18 12 577 830\"\n"
+ "*ImageableArea A5/A5: \"18 12 402 583\"\n"
+ "*ImageableArea B5/JIS B5: \"18 12 498 717\"\n"
+ "*ImageableArea EnvISOB5/Envelope B5: \"18 12 481 697\"\n"
+ "*ImageableArea Env10/Envelope #10 : \"18 12 279 672\"\n"
+ "*ImageableArea EnvC5/Envelope C5: \"18 12 441 637\"\n"
+ "*ImageableArea EnvDL/Envelope DL: \"18 12 294 612\"\n"
+ "*ImageableArea EnvMonarch/Envelope Monarch: \"18 12 261 528\"\n"
+ "*DefaultPaperDimension: Letter\n"
+ "*PaperDimension Letter/US Letter: \"612 792\"\n"
+ "*PaperDimension Legal/US Legal: \"612 1008\"\n"
+ "*PaperDimension Executive/Executive: \"522 756\"\n"
+ "*PaperDimension Tabloid/Tabloid: \"792 1224\"\n"
+ "*PaperDimension A3/A3: \"842 1191\"\n"
+ "*PaperDimension A4/A4: \"595 842\"\n"
+ "*PaperDimension A5/A5: \"420 595\"\n"
+ "*PaperDimension B5/JIS B5: \"516 729\"\n"
+ "*PaperDimension EnvISOB5/Envelope B5: \"499 709\"\n"
+ "*PaperDimension Env10/Envelope #10 : \"297 684\"\n"
+ "*PaperDimension EnvC5/Envelope C5: \"459 649\"\n"
+ "*PaperDimension EnvDL/Envelope DL: \"312 624\"\n"
+ "*PaperDimension EnvMonarch/Envelope Monarch: \"279 540\"\n");
+ }
+
+ /*
+ * InputSlot...
+ */
+
+ if ((attr = ippFindAttribute(ippGetCollection(defattr, 0), "media-source", IPP_TAG_KEYWORD)) != NULL)
+ pwg_ppdize_name(ippGetString(attr, 0, NULL), ppdname, sizeof(ppdname));
+ else
+ strlcpy(ppdname, "Unknown", sizeof(ppdname));
+
+ if ((attr = ippFindAttribute(response, "media-source-supported", IPP_TAG_KEYWORD)) != NULL && (count = ippGetCount(attr)) > 1)
+ {
+ static const char * const sources[][2] =
+ { /* "media-source" strings */
+ { "Auto", _("Automatic") },
+ { "Main", _("Main") },
+ { "Alternate", _("Alternate") },
+ { "LargeCapacity", _("Large Capacity") },
+ { "Manual", _("Manual") },
+ { "Envelope", _("Envelope") },
+ { "Disc", _("Disc") },
+ { "Photo", _("Photo") },
+ { "Hagaki", _("Hagaki") },
+ { "MainRoll", _("Main Roll") },
+ { "AlternateRoll", _("Alternate Roll") },
+ { "Top", _("Top") },
+ { "Middle", _("Middle") },
+ { "Bottom", _("Bottom") },
+ { "Side", _("Side") },
+ { "Left", _("Left") },
+ { "Right", _("Right") },
+ { "Center", _("Center") },
+ { "Rear", _("Rear") },
+ { "ByPassTray", _("Multipurpose") },
+ { "Tray1", _("Tray 1") },
+ { "Tray2", _("Tray 2") },
+ { "Tray3", _("Tray 3") },
+ { "Tray4", _("Tray 4") },
+ { "Tray5", _("Tray 5") },
+ { "Tray6", _("Tray 6") },
+ { "Tray7", _("Tray 7") },
+ { "Tray8", _("Tray 8") },
+ { "Tray9", _("Tray 9") },
+ { "Tray10", _("Tray 10") },
+ { "Tray11", _("Tray 11") },
+ { "Tray12", _("Tray 12") },
+ { "Tray13", _("Tray 13") },
+ { "Tray14", _("Tray 14") },
+ { "Tray15", _("Tray 15") },
+ { "Tray16", _("Tray 16") },
+ { "Tray17", _("Tray 17") },
+ { "Tray18", _("Tray 18") },
+ { "Tray19", _("Tray 19") },
+ { "Tray20", _("Tray 20") },
+ { "Roll1", _("Roll 1") },
+ { "Roll2", _("Roll 2") },
+ { "Roll3", _("Roll 3") },
+ { "Roll4", _("Roll 4") },
+ { "Roll5", _("Roll 5") },
+ { "Roll6", _("Roll 6") },
+ { "Roll7", _("Roll 7") },
+ { "Roll8", _("Roll 8") },
+ { "Roll9", _("Roll 9") },
+ { "Roll10", _("Roll 10") }
+ };
+
+ cupsFilePrintf(fp, "*OpenUI *InputSlot: PickOne\n"
+ "*OrderDependency: 10 AnySetup *InputSlot\n"
+ "*DefaultInputSlot: %s\n", ppdname);
+ for (i = 0, count = ippGetCount(attr); i < count; i ++)
+ {
+ pwg_ppdize_name(ippGetString(attr, i, NULL), ppdname, sizeof(ppdname));
+
+ for (j = 0; j < (int)(sizeof(sources) / sizeof(sources[0])); j ++)
+ if (!strcmp(sources[j][0], ppdname))
+ {
+ cupsFilePrintf(fp, "*InputSlot %s/%s: \"<</MediaPosition %d>>setpagedevice\"\n", ppdname, _cupsLangString(lang, sources[j][1]), j);
+ break;
+ }
+ }
+ cupsFilePuts(fp, "*CloseUI: *InputSlot\n");
+ }
+
+ /*
+ * MediaType...
+ */
+
+ if ((attr = ippFindAttribute(ippGetCollection(defattr, 0), "media-type", IPP_TAG_KEYWORD)) != NULL)
+ pwg_ppdize_name(ippGetString(attr, 0, NULL), ppdname, sizeof(ppdname));
+ else
+ strlcpy(ppdname, "Unknown", sizeof(ppdname));
+
+ if ((attr = ippFindAttribute(response, "media-type-supported", IPP_TAG_KEYWORD)) != NULL && (count = ippGetCount(attr)) > 1)
+ {
+ static const char * const media_types[][2] =
+ { /* "media-type" strings */
+ { "aluminum", _("Aluminum") },
+ { "auto", _("Automatic") },
+ { "back-print-film", _("Back Print Film") },
+ { "cardboard", _("Cardboard") },
+ { "cardstock", _("Cardstock") },
+ { "cd", _("CD") },
+ { "com.hp.advanced-photo", _("Advanced Photo Paper") }, /* HP */
+ { "com.hp.brochure-glossy", _("Glossy Brochure Paper") }, /* HP */
+ { "com.hp.brochure-matte", _("Matte Brochure Paper") }, /* HP */
+ { "com.hp.cover-matte", _("Matte Cover Paper") }, /* HP */
+ { "com.hp.ecosmart-lite", _("Office Recycled Paper") }, /* HP */
+ { "com.hp.everyday-glossy", _("Everyday Glossy Photo Paper") }, /* HP */
+ { "com.hp.everyday-matte", _("Everyday Matte Paper") }, /* HP */
+ { "com.hp.extra-heavy", _("Extra Heavyweight Paper") }, /* HP */
+ { "com.hp.intermediate", _("Multipurpose Paper") }, /* HP */
+ { "com.hp.mid-weight", _("Mid-Weight Paper") }, /* HP */
+ { "com.hp.premium-inkjet", _("Premium Inkjet Paper") }, /* HP */
+ { "com.hp.premium-photo", _("Premium Photo Glossy Paper") }, /* HP */
+ { "com.hp.premium-presentation-matte", _("Premium Presentation Matte Paper") }, /* HP */
+ { "continuous", _("Continuous") },
+ { "continuous-long", _("Continuous Long") },
+ { "continuous-short", _("Continuous Short") },
+ { "disc", _("Optical Disc") },
+ { "disc-glossy", _("Glossy Optical Disc") },
+ { "disc-high-gloss", _("High Gloss Optical Disc") },
+ { "disc-matte", _("Matte Optical Disc") },
+ { "disc-satin", _("Satin Optical Disc") },
+ { "disc-semi-gloss", _("Semi-Gloss Optical Disc") },
+ { "double-wall", _("Double Wall Cardboard") },
+ { "dry-film", _("Dry Film") },
+ { "dvd", _("DVD") },
+ { "embossing-foil", _("Embossing Foil") },
+ { "end-board", _("End Board") },
+ { "envelope", _("Envelope") },
+ { "envelope-archival", _("Archival Envelope") },
+ { "envelope-bond", _("Bond Envelope") },
+ { "envelope-coated", _("Coated Envelope") },
+ { "envelope-cotton", _("Cotton Envelope") },
+ { "envelope-fine", _("Fine Envelope") },
+ { "envelope-heavyweight", _("Heavyweight Envelope") },
+ { "envelope-inkjet", _("Inkjet Envelope") },
+ { "envelope-lightweight", _("Lightweight Envelope") },
+ { "envelope-plain", _("Plain Envelope") },
+ { "envelope-preprinted", _("Preprinted Envelope") },
+ { "envelope-window", _("Windowed Envelope") },
+ { "fabric", _("Fabric") },
+ { "fabric-archival", _("Archival Fabric") },
+ { "fabric-glossy", _("Glossy Fabric") },
+ { "fabric-high-gloss", _("High Gloss Fabric") },
+ { "fabric-matte", _("Matte Fabric") },
+ { "fabric-semi-gloss", _("Semi-Gloss Fabric") },
+ { "fabric-waterproof", _("Waterproof Fabric") },
+ { "film", _("Film") },
+ { "flexo-base", _("Flexo Base") },
+ { "flexo-photo-polymer", _("Flexo Photo Polymer") },
+ { "flute", _("Flute") },
+ { "foil", _("Foil") },
+ { "full-cut-tabs", _("Full Cut Tabs") },
+ { "glass", _("Glass") },
+ { "glass-colored", _("Glass Colored") },
+ { "glass-opaque", _("Glass Opaque") },
+ { "glass-surfaced", _("Glass Surfaced") },
+ { "glass-textured", _("Glass Textured") },
+ { "gravure-cylinder", _("Gravure Cylinder") },
+ { "image-setter-paper", _("Image Setter Paper") },
+ { "imaging-cylinder", _("Imaging Cylinder") },
+ { "jp.co.canon_photo-paper-plus-glossy-ii", _("Photo Paper Plus Glossy II") }, /* Canon */
+ { "jp.co.canon_photo-paper-pro-platinum", _("Photo Paper Pro Platinum") }, /* Canon */
+ { "jp.co.canon-photo-paper-plus-glossy-ii", _("Photo Paper Plus Glossy II") }, /* Canon */
+ { "jp.co.canon-photo-paper-pro-platinum", _("Photo Paper Pro Platinum") }, /* Canon */
+ { "labels", _("Labels") },
+ { "labels-colored", _("Colored Labels") },
+ { "labels-glossy", _("Glossy Labels") },
+ { "labels-high-gloss", _("High Gloss Labels") },
+ { "labels-inkjet", _("Inkjet Labels") },
+ { "labels-matte", _("Matte Labels") },
+ { "labels-permanent", _("Permanent Labels") },
+ { "labels-satin", _("Satin Labels") },
+ { "labels-security", _("Security Labels") },
+ { "labels-semi-gloss", _("Semi-Gloss Labels") },
+ { "laminating-foil", _("Laminating Foil") },
+ { "letterhead", _("Letterhead") },
+ { "metal", _("Metal") },
+ { "metal-glossy", _("Metal Glossy") },
+ { "metal-high-gloss", _("Metal High Gloss") },
+ { "metal-matte", _("Metal Matte") },
+ { "metal-satin", _("Metal Satin") },
+ { "metal-semi-gloss", _("Metal Semi Gloss") },
+ { "mounting-tape", _("Mounting Tape") },
+ { "multi-layer", _("Multi Layer") },
+ { "multi-part-form", _("Multi Part Form") },
+ { "other", _("Other") },
+ { "paper", _("Paper") },
+ { "photo", _("Photo Paper") }, /* HP mis-spelling */
+ { "photographic", _("Photo Paper") },
+ { "photographic-archival", _("Archival Photo Paper") },
+ { "photographic-film", _("Photo Film") },
+ { "photographic-glossy", _("Glossy Photo Paper") },
+ { "photographic-high-gloss", _("High Gloss Photo Paper") },
+ { "photographic-matte", _("Matte Photo Paper") },
+ { "photographic-satin", _("Satin Photo Paper") },
+ { "photographic-semi-gloss", _("Semi-Gloss Photo Paper") },
+ { "plastic", _("Plastic") },
+ { "plastic-archival", _("Plastic Archival") },
+ { "plastic-colored", _("Plastic Colored") },
+ { "plastic-glossy", _("Plastic Glossy") },
+ { "plastic-high-gloss", _("Plastic High Gloss") },
+ { "plastic-matte", _("Plastic Matte") },
+ { "plastic-satin", _("Plastic Satin") },
+ { "plastic-semi-gloss", _("Plastic Semi Gloss") },
+ { "plate", _("Plate") },
+ { "polyester", _("Polyester") },
+ { "pre-cut-tabs", _("Pre Cut Tabs") },
+ { "roll", _("Roll") },
+ { "screen", _("Screen") },
+ { "screen-paged", _("Screen Paged") },
+ { "self-adhesive", _("Self Adhesive") },
+ { "self-adhesive-film", _("Self Adhesive Film") },
+ { "shrink-foil", _("Shrink Foil") },
+ { "single-face", _("Single Face") },
+ { "single-wall", _("Single Wall Cardboard") },
+ { "sleeve", _("Sleeve") },
+ { "stationery", _("Plain Paper") },
+ { "stationery-archival", _("Archival Paper") },
+ { "stationery-coated", _("Coated Paper") },
+ { "stationery-cotton", _("Cotton Paper") },
+ { "stationery-fine", _("Vellum Paper") },
+ { "stationery-heavyweight", _("Heavyweight Paper") },
+ { "stationery-heavyweight-coated", _("Heavyweight Coated Paper") },
+ { "stationery-inkjet", _("Inkjet Paper") },
+ { "stationery-letterhead", _("Letterhead") },
+ { "stationery-lightweight", _("Lightweight Paper") },
+ { "stationery-preprinted", _("Preprinted Paper") },
+ { "stationery-prepunched", _("Punched Paper") },
+ { "tab-stock", _("Tab Stock") },
+ { "tractor", _("Tractor") },
+ { "transfer", _("Transfer") },
+ { "transparency", _("Transparency") },
+ { "triple-wall", _("Triple Wall Cardboard") },
+ { "wet-film", _("Wet Film") }
+ };
+
+ cupsFilePrintf(fp, "*OpenUI *MediaType: PickOne\n"
+ "*OrderDependency: 10 AnySetup *MediaType\n"
+ "*DefaultMediaType: %s\n", ppdname);
+ for (i = 0; i < count; i ++)
+ {
+ const char *keyword = ippGetString(attr, i, NULL);
+
+ pwg_ppdize_name(keyword, ppdname, sizeof(ppdname));
+
+ for (j = 0; j < (int)(sizeof(media_types) / sizeof(media_types[0])); j ++)
+ if (!strcmp(keyword, media_types[j][0]))
+ break;
+
+ if (j < (int)(sizeof(media_types) / sizeof(media_types[0])))
+ cupsFilePrintf(fp, "*MediaType %s/%s: \"<</MediaType(%s)>>setpagedevice\"\n", ppdname, _cupsLangString(lang, media_types[j][1]), ppdname);
+ else
+ cupsFilePrintf(fp, "*MediaType %s/%s: \"<</MediaType(%s)>>setpagedevice\"\n", ppdname, keyword, ppdname);
+ }
+ cupsFilePuts(fp, "*CloseUI: *MediaType\n");
+ }
+
+ /*
+ * ColorModel...
+ */
+
+ if ((attr = ippFindAttribute(response, "pwg-raster-document-type-supported", IPP_TAG_KEYWORD)) == NULL)
+ if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) == NULL)
+ if ((attr = ippFindAttribute(response, "print-color-mode-supported", IPP_TAG_KEYWORD)) == NULL)
+ attr = ippFindAttribute(response, "output-mode-supported", IPP_TAG_KEYWORD);
+
+ if (attr && ippGetCount(attr) > 0)
+ {
+ const char *default_color = NULL; /* Default */
+
+ for (i = 0, count = ippGetCount(attr); i < count; i ++)
+ {
+ const char *keyword = ippGetString(attr, i, NULL);
+ /* Keyword for color/bit depth */
+
+ if (!strcasecmp(keyword, "black_1") || !strcmp(keyword, "bi-level") || !strcmp(keyword, "process-bi-level"))
+ {
+ if (!default_color)
+ cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
+ "*OrderDependency: 10 AnySetup *ColorModel\n", _cupsLangString(lang, _("Color Mode")));
+
+ cupsFilePrintf(fp, "*ColorModel FastGray/%s: \"<</cupsColorSpace 3/cupsBitsPerColor 1/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n", _cupsLangString(lang, _("Fast Grayscale")));
+
+ if (!default_color)
+ default_color = "FastGray";
+ }
+ else if (!strcasecmp(keyword, "sgray_8") || !strcmp(keyword, "W8") || !strcmp(keyword, "monochrome") || !strcmp(keyword, "process-monochrome"))
+ {
+ if (!default_color)
+ cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
+ "*OrderDependency: 10 AnySetup *ColorModel\n", _cupsLangString(lang, _("Color Mode")));
+
+ cupsFilePrintf(fp, "*ColorModel Gray/%s: \"<</cupsColorSpace 18/cupsBitsPerColor 8/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n", _cupsLangString(lang, _("Grayscale")));
+
+ if (!default_color || !strcmp(default_color, "FastGray"))
+ default_color = "Gray";
+ }
+ else if (!strcasecmp(keyword, "srgb_8") || !strcmp(keyword, "SRGB24") || !strcmp(keyword, "color"))
+ {
+ if (!default_color)
+ cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
+ "*OrderDependency: 10 AnySetup *ColorModel\n", _cupsLangString(lang, _("Color Mode")));
+
+ cupsFilePrintf(fp, "*ColorModel RGB/%s: \"<</cupsColorSpace 19/cupsBitsPerColor 8/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n", _cupsLangString(lang, _("Color")));
+
+ default_color = "RGB";
+ }
+ else if (!strcasecmp(keyword, "adobe-rgb_16") || !strcmp(keyword, "ADOBERGB48"))
+ {
+ if (!default_color)
+ cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
+ "*OrderDependency: 10 AnySetup *ColorModel\n", _cupsLangString(lang, _("Color Mode")));
+
+ cupsFilePrintf(fp, "*ColorModel AdobeRGB/%s: \"<</cupsColorSpace 20/cupsBitsPerColor 16/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n", _cupsLangString(lang, _("Deep Color")));
+
+ if (!default_color)
+ default_color = "AdobeRGB";
+ }
+ }
+
+ if (default_color)
+ {
+ cupsFilePrintf(fp, "*DefaultColorModel: %s\n", default_color);
+ cupsFilePuts(fp, "*CloseUI: *ColorModel\n");
+ }
+ } else {
+ cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
+ "*OrderDependency: 10 AnySetup *ColorModel\n", _cupsLangString(lang, _("Color Mode")));
+ cupsFilePrintf(fp, "*DefaultColorModel: Gray\n");
+ cupsFilePuts(fp, "*ColorModel FastGray/Fast Grayscale: \"<</cupsColorSpace 3/cupsBitsPerColor 1/cupsColorOrder 0/cupsCompression 0/ProcessColorModel /DeviceGray>>setpagedevice\"\n");
+ cupsFilePuts(fp, "*ColorModel Gray/Grayscale: \"<</cupsColorSpace 18/cupsBitsPerColor 8/cupsColorOrder 0/cupsCompression 0/ProcessColorModel /DeviceGray>>setpagedevice\"\n");
+ if (color) {
+ /* Color printer according to DNS-SD (or unknown) */
+ cupsFilePuts(fp, "*ColorModel RGB/Color: \"<</cupsColorSpace 19/cupsBitsPerColor 8/cupsColorOrder 0/cupsCompression 0/ProcessColorModel /DeviceRGB>>setpagedevice\"\n");
+ }
+ cupsFilePuts(fp, "*CloseUI: *ColorModel\n");
+ }
+
+ /*
+ * Duplex...
+ */
+
+ if (((attr = ippFindAttribute(response, "sides-supported",
+ IPP_TAG_KEYWORD)) != NULL &&
+ ippContainsString(attr, "two-sided-long-edge")) ||
+ (attr == NULL && duplex))
+ {
+ cupsFilePrintf(fp, "*OpenUI *Duplex/%s: PickOne\n"
+ "*OrderDependency: 10 AnySetup *Duplex\n"
+ "*DefaultDuplex: None\n"
+ "*Duplex None/%s: \"<</Duplex false>>setpagedevice\"\n"
+ "*Duplex DuplexNoTumble/%s: \"<</Duplex true/Tumble false>>setpagedevice\"\n"
+ "*Duplex DuplexTumble/%s: \"<</Duplex true/Tumble true>>setpagedevice\"\n"
+ "*CloseUI: *Duplex\n", _cupsLangString(lang, _("2-Sided Printing")), _cupsLangString(lang, _("Off (1-Sided)")), _cupsLangString(lang, _("Long-Edge (Portrait)")), _cupsLangString(lang, _("Short-Edge (Landscape)")));
+
+ if ((attr = ippFindAttribute(response, "pwg-raster-document-sheet-back", IPP_TAG_KEYWORD)) != NULL)
+ {
+ const char *keyword = ippGetString(attr, 0, NULL);
+ /* Keyword value */
+
+ if (!strcmp(keyword, "flipped"))
+ cupsFilePuts(fp, "*cupsBackSide: Flipped\n");
+ else if (!strcmp(keyword, "manual-tumble"))
+ cupsFilePuts(fp, "*cupsBackSide: ManualTumble\n");
+ else if (!strcmp(keyword, "normal"))
+ cupsFilePuts(fp, "*cupsBackSide: Normal\n");
+ else
+ cupsFilePuts(fp, "*cupsBackSide: Rotated\n");
+ }
+ else if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL)
+ {
+ for (i = 0, count = ippGetCount(attr); i < count; i ++)
+ {
+ const char *dm = ippGetString(attr, i, NULL);
+ /* DM value */
+
+ if (!_cups_strcasecmp(dm, "DM1"))
+ {
+ cupsFilePuts(fp, "*cupsBackSide: Normal\n");
+ break;
+ }
+ else if (!_cups_strcasecmp(dm, "DM2"))
+ {
+ cupsFilePuts(fp, "*cupsBackSide: Flipped\n");
+ break;
+ }
+ else if (!_cups_strcasecmp(dm, "DM3"))
+ {
+ cupsFilePuts(fp, "*cupsBackSide: Rotated\n");
+ break;
+ }
+ else if (!_cups_strcasecmp(dm, "DM4"))
+ {
+ cupsFilePuts(fp, "*cupsBackSide: ManualTumble\n");
+ break;
+ }
+ }
+ }
+ }
+
+ /*
+ * Output bin...
+ */
+
+ if ((attr = ippFindAttribute(response, "output-bin-default", IPP_TAG_ZERO)) != NULL)
+ pwg_ppdize_name(ippGetString(attr, 0, NULL), ppdname, sizeof(ppdname));
+ else
+ strlcpy(ppdname, "Unknown", sizeof(ppdname));
+
+ if ((attr = ippFindAttribute(response, "output-bin-supported", IPP_TAG_ZERO)) != NULL && (count = ippGetCount(attr)) > 1)
+ {
+ static const char * const output_bins[][2] =
+ { /* "output-bin" strings */
+ { "auto", _("Automatic") },
+ { "bottom", _("Bottom Tray") },
+ { "center", _("Center Tray") },
+ { "face-down", _("Face Down") },
+ { "face-up", _("Face Up") },
+ { "large-capacity", _("Large Capacity Tray") },
+ { "left", _("Left Tray") },
+ { "mailbox-1", _("Mailbox 1") },
+ { "mailbox-2", _("Mailbox 2") },
+ { "mailbox-3", _("Mailbox 3") },
+ { "mailbox-4", _("Mailbox 4") },
+ { "mailbox-5", _("Mailbox 5") },
+ { "mailbox-6", _("Mailbox 6") },
+ { "mailbox-7", _("Mailbox 7") },
+ { "mailbox-8", _("Mailbox 8") },
+ { "mailbox-9", _("Mailbox 9") },
+ { "mailbox-10", _("Mailbox 10") },
+ { "middle", _("Middle") },
+ { "my-mailbox", _("My Mailbox") },
+ { "rear", _("Rear Tray") },
+ { "right", _("Right Tray") },
+ { "side", _("Side Tray") },
+ { "stacker-1", _("Stacker 1") },
+ { "stacker-2", _("Stacker 2") },
+ { "stacker-3", _("Stacker 3") },
+ { "stacker-4", _("Stacker 4") },
+ { "stacker-5", _("Stacker 5") },
+ { "stacker-6", _("Stacker 6") },
+ { "stacker-7", _("Stacker 7") },
+ { "stacker-8", _("Stacker 8") },
+ { "stacker-9", _("Stacker 9") },
+ { "stacker-10", _("Stacker 10") },
+ { "top", _("Top Tray") },
+ { "tray-1", _("Tray 1") },
+ { "tray-2", _("Tray 2") },
+ { "tray-3", _("Tray 3") },
+ { "tray-4", _("Tray 4") },
+ { "tray-5", _("Tray 5") },
+ { "tray-6", _("Tray 6") },
+ { "tray-7", _("Tray 7") },
+ { "tray-8", _("Tray 8") },
+ { "tray-9", _("Tray 9") },
+ { "tray-10", _("Tray 10") }
+ };
+
+ cupsFilePrintf(fp, "*OpenUI *OutputBin: PickOne\n"
+ "*OrderDependency: 10 AnySetup *OutputBin\n"
+ "*DefaultOutputBin: %s\n", ppdname);
+ for (i = 0; i < (int)(sizeof(output_bins) / sizeof(output_bins[0])); i ++)
+ {
+ if (!ippContainsString(attr, output_bins[i][0]))
+ continue;
+
+ pwg_ppdize_name(output_bins[i][0], ppdname, sizeof(ppdname));
+
+ cupsFilePrintf(fp, "*OutputBin %s/%s: \"\"\n", ppdname, _cupsLangString(lang, output_bins[i][1]));
+ }
+ cupsFilePuts(fp, "*CloseUI: *OutputBin\n");
+ }
+
+ /*
+ * Finishing options...
+ *
+ * Eventually need to re-add support for finishings-col-database, however
+ * it is difficult to map arbitrary finishing-template values to PPD options
+ * and have the right constraints apply (e.g. stapling vs. folding vs.
+ * punching, etc.)
+ */
+
+ if ((attr = ippFindAttribute(response, "finishings-supported", IPP_TAG_ENUM)) != NULL)
+ {
+ const char *name; /* String name */
+ int value; /* Enum value */
+ cups_array_t *names; /* Names we've added */
+
+ count = ippGetCount(attr);
+ names = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
+
+ /*
+ * Staple/Bind/Stitch
+ */
+
+ for (i = 0; i < count; i ++)
+ {
+ value = ippGetInteger(attr, i);
+ name = ippEnumString("finishings", value);
+
+ if (!strncmp(name, "staple-", 7) || !strncmp(name, "bind-", 5) || !strncmp(name, "edge-stitch-", 12) || !strcmp(name, "saddle-stitch"))
+ break;
+ }
+
+ if (i < count)
+ {
+ cupsFilePrintf(fp, "*OpenUI *StapleLocation/%s: PickOne\n", _cupsLangString(lang, _("Staple")));
+ cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *StapleLocation\n");
+ cupsFilePuts(fp, "*DefaultStapleLocation: None\n");
+ cupsFilePrintf(fp, "*StapleLocation None/%s: \"\"\n", _cupsLangString(lang, _("None")));
+
+ for (; i < count; i ++)
+ {
+ value = ippGetInteger(attr, i);
+ name = ippEnumString("finishings", value);
+
+ if (strncmp(name, "staple-", 7) && strncmp(name, "bind-", 5) && strncmp(name, "edge-stitch-", 12) && strcmp(name, "saddle-stitch"))
+ continue;
+
+ if (cupsArrayFind(names, (char *)name))
+ continue; /* Already did this finishing template */
+
+ cupsArrayAdd(names, (char *)name);
+
+ for (j = 0; j < (int)(sizeof(finishings) / sizeof(finishings[0])); j ++)
+ {
+ if (!strcmp(finishings[j][0], name))
+ {
+ cupsFilePrintf(fp, "*StapleLocation %s/%s: \"\"\n", name, _cupsLangString(lang, finishings[j][1]));
+ cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*StapleLocation %s\"\n", value, name, name);
+ break;
+ }
+ }
+ }
+
+ cupsFilePuts(fp, "*CloseUI: *StapleLocation\n");
+ }
+
+ /*
+ * Fold
+ */
+
+ for (i = 0; i < count; i ++)
+ {
+ value = ippGetInteger(attr, i);
+ name = ippEnumString("finishings", value);
+
+ if (!strncmp(name, "fold-", 5))
+ break;
+ }
+
+ if (i < count)
+ {
+ cupsFilePrintf(fp, "*OpenUI *FoldType/%s: PickOne\n", _cupsLangString(lang, _("Fold")));
+ cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *FoldType\n");
+ cupsFilePuts(fp, "*DefaultFoldType: None\n");
+ cupsFilePrintf(fp, "*FoldType None/%s: \"\"\n", _cupsLangString(lang, _("None")));
+
+ for (; i < count; i ++)
+ {
+ value = ippGetInteger(attr, i);
+ name = ippEnumString("finishings", value);
+
+ if (strncmp(name, "fold-", 5))
+ continue;
+
+ if (cupsArrayFind(names, (char *)name))
+ continue; /* Already did this finishing template */
+
+ cupsArrayAdd(names, (char *)name);
+
+ for (j = 0; j < (int)(sizeof(finishings) / sizeof(finishings[0])); j ++)
+ {
+ if (!strcmp(finishings[j][0], name))
+ {
+ cupsFilePrintf(fp, "*FoldType %s/%s: \"\"\n", name, _cupsLangString(lang, finishings[j][1]));
+ cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*FoldType %s\"\n", value, name, name);
+ break;
+ }
+ }
+ }
+
+ cupsFilePuts(fp, "*CloseUI: *FoldType\n");
+ }
+
+ /*
+ * Punch
+ */
+
+ for (i = 0; i < count; i ++)
+ {
+ value = ippGetInteger(attr, i);
+ name = ippEnumString("finishings", value);
+
+ if (!strncmp(name, "punch-", 6))
+ break;
+ }
+
+ if (i < count)
+ {
+ cupsFilePrintf(fp, "*OpenUI *PunchMedia/%s: PickOne\n", _cupsLangString(lang, _("Punch")));
+ cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *PunchMedia\n");
+ cupsFilePuts(fp, "*DefaultPunchMedia: None\n");
+ cupsFilePrintf(fp, "*PunchMedia None/%s: \"\"\n", _cupsLangString(lang, _("None")));
+
+ for (i = 0; i < count; i ++)
+ {
+ value = ippGetInteger(attr, i);
+ name = ippEnumString("finishings", value);
+
+ if (strncmp(name, "punch-", 6))
+ continue;
+
+ if (cupsArrayFind(names, (char *)name))
+ continue; /* Already did this finishing template */
+
+ cupsArrayAdd(names, (char *)name);
+
+ for (j = 0; j < (int)(sizeof(finishings) / sizeof(finishings[0])); j ++)
+ {
+ if (!strcmp(finishings[j][0], name))
+ {
+ cupsFilePrintf(fp, "*PunchMedia %s/%s: \"\"\n", name, _cupsLangString(lang, finishings[j][1]));
+ cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*PunchMedia %s\"\n", value, name, name);
+ break;
+ }
+ }
+ }
+
+ cupsFilePuts(fp, "*CloseUI: *PunchMedia\n");
+ }
+
+ /*
+ * Booklet
+ */
+
+ if (ippContainsInteger(attr, IPP_FINISHINGS_BOOKLET_MAKER))
+ {
+ cupsFilePrintf(fp, "*OpenUI *Booklet/%s: Boolean\n", _cupsLangString(lang, _("Booklet")));
+ cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *Booklet\n");
+ cupsFilePuts(fp, "*DefaultBooklet: False\n");
+ cupsFilePuts(fp, "*Booklet False: \"\"\n");
+ cupsFilePuts(fp, "*Booklet True: \"\"\n");
+ cupsFilePrintf(fp, "*cupsIPPFinishings %d/booklet-maker: \"*Booklet True\"\n", IPP_FINISHINGS_BOOKLET_MAKER);
+ cupsFilePuts(fp, "*CloseUI: *Booklet\n");
+ }
+
+ cupsArrayDelete(names);
+ }
+
+ /*
+ * DefaultResolution...
+ */
+
+ xres = common_def->x;
+ yres = common_def->y;
+ if (xres == yres)
+ cupsFilePrintf(fp, "*DefaultResolution: %ddpi\n", xres);
+ else
+ cupsFilePrintf(fp, "*DefaultResolution: %dx%ddpi\n", xres, yres);
+
+ /*
+ * cupsPrintQuality...
+ */
+
+ if ((quality =
+ ippFindAttribute(response, "print-quality-supported",
+ IPP_TAG_ENUM)) != NULL)
+ {
+ cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality/%s: PickOne\n"
+ "*OrderDependency: 10 AnySetup *cupsPrintQuality\n"
+ "*DefaultcupsPrintQuality: %d\n",
+ _cupsLangString(lang, _("Print Quality")),
+ IPP_QUALITY_NORMAL);
+ if (ippContainsInteger(quality, IPP_QUALITY_DRAFT))
+ cupsFilePrintf(fp, "*cupsPrintQuality %d/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", IPP_QUALITY_DRAFT, _cupsLangString(lang, _("Draft")),
+ min_res->x, min_res->y);
+ cupsFilePrintf(fp, "*cupsPrintQuality %d/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", IPP_QUALITY_NORMAL, _cupsLangString(lang, _("Normal")),
+ common_def->x, common_def->y);
+ if (ippContainsInteger(quality, IPP_QUALITY_HIGH))
+ cupsFilePrintf(fp, "*cupsPrintQuality %d/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", IPP_QUALITY_HIGH, _cupsLangString(lang, _("High")),
+ max_res->x, max_res->y);
+ cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n");
+ }
+
+ /*
+ * Close up and return...
+ */
+
+ free(common_def);
+ free(min_res);
+ free(max_res);
+
+ snprintf(ppdgenerator_msg, sizeof(ppdgenerator_msg),
+ "%s PPD generated.",
+ (is_pdf ? "PDF" :
+ (is_pwg ? "PWG Raster" :
+ (is_apple ? "Apple Raster" :
+ (is_pclm ? "PCLm" :
+ "Legacy IPP printer")))));
+
+ cupsFileClose(fp);
+
+ return (buffer);
+
+ /*
+ * If we get here then there was a problem creating the PPD...
+ */
+
+ bad_ppd:
+
+ if (common_res) cupsArrayDelete(common_res);
+ if (common_def) free(common_def);
+ if (min_res) free(min_res);
+ if (max_res) free(max_res);
+
+ cupsFileClose(fp);
+ unlink(buffer);
+ *buffer = '\0';
+
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Printer does not support required IPP attributes or document formats."), 1);
+
+ return (NULL);
+}
+
+
+/*
+ * '_pwgInputSlotForSource()' - Get the InputSlot name for the given PWG
+ * media-source.
+ */
+
+const char * /* O - InputSlot name */
+_pwgInputSlotForSource(
+ const char *media_source, /* I - PWG media-source */
+ char *name, /* I - Name buffer */
+ size_t namesize) /* I - Size of name buffer */
+{
+ /*
+ * Range check input...
+ */
+
+ if (!media_source || !name || namesize < PPD_MAX_NAME)
+ return (NULL);
+
+ if (_cups_strcasecmp(media_source, "main"))
+ strlcpy(name, "Cassette", namesize);
+ else if (_cups_strcasecmp(media_source, "alternate"))
+ strlcpy(name, "Multipurpose", namesize);
+ else if (_cups_strcasecmp(media_source, "large-capacity"))
+ strlcpy(name, "LargeCapacity", namesize);
+ else if (_cups_strcasecmp(media_source, "bottom"))
+ strlcpy(name, "Lower", namesize);
+ else if (_cups_strcasecmp(media_source, "middle"))
+ strlcpy(name, "Middle", namesize);
+ else if (_cups_strcasecmp(media_source, "top"))
+ strlcpy(name, "Upper", namesize);
+ else if (_cups_strcasecmp(media_source, "rear"))
+ strlcpy(name, "Rear", namesize);
+ else if (_cups_strcasecmp(media_source, "side"))
+ strlcpy(name, "Side", namesize);
+ else if (_cups_strcasecmp(media_source, "envelope"))
+ strlcpy(name, "Envelope", namesize);
+ else if (_cups_strcasecmp(media_source, "main-roll"))
+ strlcpy(name, "Roll", namesize);
+ else if (_cups_strcasecmp(media_source, "alternate-roll"))
+ strlcpy(name, "Roll2", namesize);
+ else
+ pwg_ppdize_name(media_source, name, namesize);
+
+ return (name);
+}
+
+
+/*
+ * '_pwgMediaTypeForType()' - Get the MediaType name for the given PWG
+ * media-type.
+ */
+
+const char * /* O - MediaType name */
+_pwgMediaTypeForType(
+ const char *media_type, /* I - PWG media-type */
+ char *name, /* I - Name buffer */
+ size_t namesize) /* I - Size of name buffer */
+{
+ /*
+ * Range check input...
+ */
+
+ if (!media_type || !name || namesize < PPD_MAX_NAME)
+ return (NULL);
+
+ if (_cups_strcasecmp(media_type, "auto"))
+ strlcpy(name, "Auto", namesize);
+ else if (_cups_strcasecmp(media_type, "cardstock"))
+ strlcpy(name, "Cardstock", namesize);
+ else if (_cups_strcasecmp(media_type, "envelope"))
+ strlcpy(name, "Envelope", namesize);
+ else if (_cups_strcasecmp(media_type, "photographic-glossy"))
+ strlcpy(name, "Glossy", namesize);
+ else if (_cups_strcasecmp(media_type, "photographic-high-gloss"))
+ strlcpy(name, "HighGloss", namesize);
+ else if (_cups_strcasecmp(media_type, "photographic-matte"))
+ strlcpy(name, "Matte", namesize);
+ else if (_cups_strcasecmp(media_type, "stationery"))
+ strlcpy(name, "Plain", namesize);
+ else if (_cups_strcasecmp(media_type, "stationery-coated"))
+ strlcpy(name, "Coated", namesize);
+ else if (_cups_strcasecmp(media_type, "stationery-inkjet"))
+ strlcpy(name, "Inkjet", namesize);
+ else if (_cups_strcasecmp(media_type, "stationery-letterhead"))
+ strlcpy(name, "Letterhead", namesize);
+ else if (_cups_strcasecmp(media_type, "stationery-preprinted"))
+ strlcpy(name, "Preprinted", namesize);
+ else if (_cups_strcasecmp(media_type, "transparency"))
+ strlcpy(name, "Transparency", namesize);
+ else
+ pwg_ppdize_name(media_type, name, namesize);
+
+ return (name);
+}
+
+
+/*
+ * '_pwgPageSizeForMedia()' - Get the PageSize name for the given media.
+ */
+
+const char * /* O - PageSize name */
+_pwgPageSizeForMedia(
+ pwg_media_t *media, /* I - Media */
+ char *name, /* I - PageSize name buffer */
+ size_t namesize) /* I - Size of name buffer */
+{
+ const char *sizeptr, /* Pointer to size in PWG name */
+ *dimptr; /* Pointer to dimensions in PWG name */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (!media || !name || namesize < PPD_MAX_NAME)
+ return (NULL);
+
+ /*
+ * Copy or generate a PageSize name...
+ */
+
+ if (media->ppd)
+ {
+ /*
+ * Use a standard Adobe name...
+ */
+
+ strlcpy(name, media->ppd, namesize);
+ }
+ else if (!media->pwg || !strncmp(media->pwg, "custom_", 7) ||
+ (sizeptr = strchr(media->pwg, '_')) == NULL ||
+ (dimptr = strchr(sizeptr + 1, '_')) == NULL ||
+ (size_t)(dimptr - sizeptr) > namesize)
+ {
+ /*
+ * Use a name of the form "wNNNhNNN"...
+ */
+
+ snprintf(name, namesize, "w%dh%d", (int)PWG_TO_POINTS(media->width),
+ (int)PWG_TO_POINTS(media->length));
+ }
+ else
+ {
+ /*
+ * Copy the size name from class_sizename_dimensions...
+ */
+
+ memcpy(name, sizeptr + 1, (size_t)(dimptr - sizeptr - 1));
+ name[dimptr - sizeptr - 1] = '\0';
+ }
+
+ return (name);
+}
+
+
+/*
+ * 'pwg_ppdize_name()' - Convert an IPP keyword to a PPD keyword.
+ */
+
+static void
+pwg_ppdize_name(const char *ipp, /* I - IPP keyword */
+ char *name, /* I - Name buffer */
+ size_t namesize) /* I - Size of name buffer */
+{
+ char *ptr, /* Pointer into name buffer */
+ *end; /* End of name buffer */
+
+
+ *name = (char)toupper(*ipp++);
+
+ for (ptr = name + 1, end = name + namesize - 1; *ipp && ptr < end;)
+ {
+ if (*ipp == '-' && _cups_isalpha(ipp[1]))
+ {
+ ipp ++;
+ *ptr++ = (char)toupper(*ipp++ & 255);
+ }
+ else
+ *ptr++ = *ipp++;
+ }
+
+ *ptr = '\0';
+}
+
+
+
+/*
+ * 'pwg_ppdize_resolution()' - Convert PWG resolution values to PPD values.
+ */
+
+static void
+pwg_ppdize_resolution(
+ ipp_attribute_t *attr, /* I - Attribute to convert */
+ int element, /* I - Element to convert */
+ int *xres, /* O - X resolution in DPI */
+ int *yres, /* O - Y resolution in DPI */
+ char *name, /* I - Name buffer */
+ size_t namesize) /* I - Size of name buffer */
+{
+ ipp_res_t units; /* Units for resolution */
+
+
+ *xres = ippGetResolution(attr, element, yres, &units);
+
+ if (units == IPP_RES_PER_CM)
+ {
+ *xres = (int)(*xres * 2.54);
+ *yres = (int)(*yres * 2.54);
+ }
+
+ if (name && namesize > 4)
+ {
+ if (*xres == *yres)
+ snprintf(name, namesize, "%ddpi", *xres);
+ else
+ snprintf(name, namesize, "%dx%ddpi", *xres, *yres);
+ }
+}
+#endif /* HAVE_CUPS_1_6 */
+
+/*
+ * End
+ */
diff --git a/cupsfilters/ppdgenerator.h b/cupsfilters/ppdgenerator.h
new file mode 100644
index 000000000..4bf642e2e
--- /dev/null
+++ b/cupsfilters/ppdgenerator.h
@@ -0,0 +1,72 @@
+/*
+ * IPP Everywhere/Apple Raster/IPP legacy PPD generator header file
+ *
+ * Copyright 2016 by Till Kamppeter.
+ *
+ * The PPD generator is based on the PPD generator for the CUPS
+ * "lpadmin -m everywhere" functionality in the cups/ppd-cache.c
+ * file. The copyright of this file is:
+ *
+ * Copyright 2010-2016 by Apple Inc.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ */
+
+#ifndef _CUPS_FILTERS_PPDGENERATOR_H_
+# define _CUPS_FILTERS_PPDGENERATOR_H_
+
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+
+/*
+ * Include necessary headers...
+ */
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <time.h>
+# include <math.h>
+
+# if defined(WIN32) || defined(__EMX__)
+# include <io.h>
+# else
+# include <unistd.h>
+# include <fcntl.h>
+# endif /* WIN32 || __EMX__ */
+
+# include <cups/cups.h>
+# include <cups/raster.h>
+
+#include <config.h>
+#include <cups/cups.h>
+#if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 5)
+#define HAVE_CUPS_1_6 1
+#endif
+
+/*
+ * Prototypes...
+ */
+
+#ifdef HAVE_CUPS_1_6
+
+extern char ppdgenerator_msg[1024];
+
+char *ppdCreateFromIPP(char *buffer, size_t bufsize,
+ ipp_t *response, const char *make_model,
+ const char *pdl, int color, int duplex);
+#endif /* HAVE_CUPS_1_6 */
+
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+
+#endif /* !_CUPS_FILTERS_PPDGENERATOR_H_ */
+
+/*
+ * End
+ */
+
diff --git a/cupsfilters/raster.c b/cupsfilters/raster.c
new file mode 100644
index 000000000..8203690d4
--- /dev/null
+++ b/cupsfilters/raster.c
@@ -0,0 +1,1088 @@
+/*
+ * Function to apply IPP options to a CUPS/PWG Raster header.
+ *
+ * Copyright 2013 by Till Kamppeter.
+ *
+ * Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * cupsRasterParseIPPOptions() - Parse IPP options from the command line
+ * and apply them to the CUPS Raster header.
+ */
+
+#include <config.h>
+#include <cups/cups.h>
+#if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 6)
+#define HAVE_CUPS_1_7 1
+#endif
+
+/*
+ * Include necessary headers.
+ */
+
+#include "driver.h"
+#include <string.h>
+#include <ctype.h>
+#ifdef HAVE_CUPS_1_7
+#include <cups/pwg.h>
+#endif /* HAVE_CUPS_1_7 */
+
+/*
+ * '_strlcpy()' - Safely copy two strings.
+ */
+
+size_t /* O - Length of string */
+_strlcpy(char *dst, /* O - Destination string */
+ const char *src, /* I - Source string */
+ size_t size) /* I - Size of destination string buffer */
+{
+ size_t srclen; /* Length of source string */
+
+
+ /*
+ * Figure out how much room is needed...
+ */
+
+ size --;
+
+ srclen = strlen(src);
+
+ /*
+ * Copy the appropriate amount...
+ */
+
+ if (srclen > size)
+ srclen = size;
+
+ memcpy(dst, src, srclen);
+ dst[srclen] = '\0';
+
+ return (srclen);
+}
+
+/*
+ * 'cupsRasterParseIPPOptions()' - Parse IPP options from the command line
+ * and apply them to the CUPS Raster header.
+ */
+
+int /* O - -1 on error, 0 on success */
+cupsRasterParseIPPOptions(cups_page_header2_t *h, /* I - Raster header */
+ int num_options, /* I - Number of options */
+ cups_option_t *options, /* I - Options */
+ int pwg_raster, /* I - 1 if PWG Raster */
+ int set_defaults) /* I - If 1, se default values
+ for all fields for which
+ we did not get an option */
+{
+#ifdef HAVE_CUPS_1_7
+ int i; /* Looping var */
+ char *ptr, /* Pointer into string */
+ s[255]; /* Temporary string */
+ const char *val, /* Pointer into value */
+ *media, /* media option */
+ *page_size, /* PageSize option */
+ *media_source, /* Media source */
+ *media_type; /* Media type */
+ pwg_media_t *size_found; /* page size found for given name */
+ float size; /* page size dimension */
+
+ /*
+ * Range check input...
+ */
+
+ if (!h)
+ return (-1);
+
+ /*
+ * Check if the supplied "media" option is a comma-separated list of any
+ * combination of page size ("media"), media source ("media-position"),
+ * and media type ("media-type") and if so, put these list elements into
+ * their dedicated options.
+ */
+
+ page_size = NULL;
+ media_source = NULL;
+ media_type = NULL;
+ if ((media = cupsGetOption("media", num_options, options)) != NULL)
+ {
+ /*
+ * Loop through the option string, separating it at commas and marking each
+ * individual option as long as the corresponding PPD option (PageSize,
+ * InputSlot, etc.) is not also set.
+ *
+ * For PageSize, we also check for an empty option value since some versions
+ * of MacOS X use it to specify auto-selection of the media based solely on
+ * the size.
+ */
+
+ for (val = media; *val;)
+ {
+ /*
+ * Extract the sub-option from the string...
+ */
+
+ for (ptr = s; *val && *val != ',' && (ptr - s) < (sizeof(s) - 1);)
+ *ptr++ = *val++;
+ *ptr++ = '\0';
+
+ if (*val == ',')
+ val ++;
+
+ /*
+ * Identify it...
+ */
+
+ size_found = NULL;
+ if ((size_found = pwgMediaForPWG(s)) == NULL)
+ if ((size_found = pwgMediaForPPD(s)) == NULL)
+ if ((size_found = pwgMediaForPPD(s)) == NULL)
+ {
+ if (strcasestr(s, "tray") ||
+ strcasestr(s, "feed") ||
+ strcasestr(s, "capacity") ||
+ strcasestr(s, "upper") ||
+ strcasestr(s, "top") ||
+ strcasestr(s, "middle") ||
+ strcasestr(s, "lower") ||
+ strcasestr(s, "bottom") ||
+ strcasestr(s, "left") ||
+ strcasestr(s, "right") ||
+ strcasestr(s, "side") ||
+ strcasestr(s, "main"))
+ media_source = strdup(s);
+ else
+ media_type = strdup(s);
+ }
+ if (size_found)
+ page_size = strdup(size_found->pwg);
+ }
+ }
+
+ if (pwg_raster)
+ strcpy(h->MediaClass, "PwgRaster");
+ else if ((val = cupsGetOption("media-class", num_options, options)) != NULL ||
+ (val = cupsGetOption("MediaClass", num_options, options)) != NULL)
+ _strlcpy(h->MediaClass, val, sizeof(h->MediaClass));
+ else if (set_defaults)
+ strcpy(h->MediaClass, "");
+
+ if ((val = cupsGetOption("media-color", num_options, options)) != NULL ||
+ (val = cupsGetOption("MediaColor", num_options, options)) != NULL)
+ _strlcpy(h->MediaColor, val, sizeof(h->MediaColor));
+ else if (set_defaults)
+ h->MediaColor[0] = '\0';
+
+ if ((val = cupsGetOption("media-type", num_options, options)) != NULL ||
+ (val = cupsGetOption("MediaType", num_options, options)) != NULL ||
+ (val = media_type) != NULL)
+ _strlcpy(h->MediaType, val, sizeof(h->MediaType));
+ else if (set_defaults)
+ h->MediaType[0] = '\0';
+
+ if ((val = cupsGetOption("print-content-optimize", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("output-type", num_options, options)) != NULL ||
+ (val = cupsGetOption("OutputType", num_options, options)) != NULL)
+ {
+ if (!strcasecmp(val, "automatic"))
+ _strlcpy(h->OutputType, "Automatic",
+ sizeof(h->OutputType));
+ else if (!strcasecmp(val, "graphics"))
+ _strlcpy(h->OutputType, "Graphics", sizeof(h->OutputType));
+ else if (!strcasecmp(val, "photo"))
+ _strlcpy(h->OutputType, "Photo", sizeof(h->OutputType));
+ else if (!strcasecmp(val, "text"))
+ _strlcpy(h->OutputType, "Text", sizeof(h->OutputType));
+ else if (!strcasecmp(val, "text-and-graphics") ||
+ !strcasecmp(val, "TextAndGraphics"))
+ _strlcpy(h->OutputType, "TextAndGraphics",
+ sizeof(h->OutputType));
+ else if (pwg_raster)
+ fprintf(stderr, "DEBUG: Unsupported print-content-type \"%s\".\n", val);
+ else
+ _strlcpy(h->OutputType, val, sizeof(h->OutputType));
+ }
+ else if (set_defaults)
+ _strlcpy(h->OutputType, "Automatic", sizeof(h->OutputType));
+
+ if (pwg_raster)
+ {
+ /* Set "reserved" fields to 0 */
+ h->AdvanceDistance = 0;
+ h->AdvanceMedia = CUPS_ADVANCE_NONE;
+ h->Collate = CUPS_FALSE;
+ }
+ else
+ {
+ /* TODO - Support for advance distance and advance media */
+ if (set_defaults)
+ {
+ h->AdvanceDistance = 0;
+ h->AdvanceMedia = CUPS_ADVANCE_NONE;
+ }
+ if ((val = cupsGetOption("Collate", num_options, options)) != NULL &&
+ (!strcasecmp(val, "true") || !strcasecmp(val, "on") ||
+ !strcasecmp(val, "yes")))
+ h->Collate = CUPS_TRUE;
+ else if ((val = cupsGetOption("Collate", num_options, options)) != NULL &&
+ (!strcasecmp(val, "false") || !strcasecmp(val, "off") ||
+ !strcasecmp(val, "no")))
+ h->Collate = CUPS_FALSE;
+ else if (set_defaults)
+ h->Collate = CUPS_FALSE;
+ }
+
+ if (set_defaults)
+ h->CutMedia = CUPS_CUT_NONE;
+
+ if (set_defaults)
+ h->Tumble = CUPS_FALSE;
+ if ((val = cupsGetOption("sides", num_options, options)) != NULL ||
+ (val = cupsGetOption("Duplex", num_options, options)) != NULL)
+ {
+ if (!strcasecmp(val, "None") || !strcasecmp(val, "Off") ||
+ !strcasecmp(val, "False") || !strcasecmp(val, "No") ||
+ !strcasecmp(val, "one-sided") || !strcasecmp(val, "OneSided"))
+ h->Duplex = CUPS_FALSE;
+ else if (!strcasecmp(val, "On") ||
+ !strcasecmp(val, "True") || !strcasecmp(val, "Yes") ||
+ !strncasecmp(val, "two-sided", 9) ||
+ !strncasecmp(val, "TwoSided", 8) ||
+ !strncasecmp(val, "Duplex", 6))
+ {
+ h->Duplex = CUPS_TRUE;
+ if (!strncasecmp(val, "DuplexTumble", 12))
+ h->Tumble = CUPS_TRUE;
+ if (!strncasecmp(val, "DuplexNoTumble", 12))
+ h->Tumble = CUPS_FALSE;
+ }
+ else if (set_defaults)
+ h->Duplex = CUPS_FALSE;
+ }
+ else if (set_defaults)
+ h->Duplex = CUPS_FALSE;
+
+ if ((val = cupsGetOption("printer-resolution", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("Resolution", num_options, options)) != NULL)
+ {
+ int xres, /* X resolution */
+ yres; /* Y resolution */
+ char *ptr; /* Pointer into value */
+
+ xres = yres = strtol(val, (char **)&ptr, 10);
+ if (ptr > val && xres > 0)
+ {
+ if (*ptr == 'x')
+ yres = strtol(ptr + 1, (char **)&ptr, 10);
+ }
+
+ if (ptr <= val || xres <= 0 || yres <= 0 || !ptr ||
+ (*ptr != '\0' &&
+ strcasecmp(ptr, "dpi") &&
+ strcasecmp(ptr, "dpc") &&
+ strcasecmp(ptr, "dpcm")))
+ {
+ fprintf(stderr, "DEBUG: Bad resolution value \"%s\".\n", val);
+ if (set_defaults)
+ {
+ h->HWResolution[0] = 600;
+ h->HWResolution[1] = 600;
+ }
+ }
+ else
+ {
+ if (!strcasecmp(ptr, "dpc") ||
+ !strcasecmp(ptr, "dpcm"))
+ {
+ xres = xres * 254 / 100;
+ yres = yres * 254 / 100;
+ }
+ h->HWResolution[0] = xres;
+ h->HWResolution[1] = yres;
+ }
+ }
+ else if (set_defaults)
+ {
+ h->HWResolution[0] = 600;
+ h->HWResolution[1] = 600;
+ }
+
+ if (set_defaults)
+ {
+ /* TODO - Support for insert sheets */
+ h->InsertSheet = CUPS_FALSE;
+ }
+
+ if (set_defaults)
+ {
+ /* TODO - Support for jog */
+ h->Jog = CUPS_JOG_NONE;
+ }
+
+ if ((val = cupsGetOption("feed-orientation", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("feed-direction", num_options, options)) != NULL ||
+ (val = cupsGetOption("LeadingEdge", num_options, options)) != NULL)
+ {
+ if (!strcasecmp(val, "ShortEdgeFirst"))
+ h->LeadingEdge = CUPS_EDGE_TOP;
+ else if (!strcasecmp(val, "LongEdgeFirst"))
+ h->LeadingEdge = CUPS_EDGE_RIGHT;
+ else
+ fprintf(stderr, "DEBUG: Unsupported feed-orientation \"%s\".\n", val);
+ }
+ else if (set_defaults)
+ h->LeadingEdge = CUPS_EDGE_TOP;
+
+ if (pwg_raster || set_defaults)
+ {
+ /* TODO - Support for manual feed */
+ h->ManualFeed = CUPS_FALSE;
+ }
+
+ if ((val = cupsGetOption("media-position", num_options, options)) != NULL ||
+ (val = cupsGetOption("MediaPosition", num_options, options)) != NULL ||
+ (val = cupsGetOption("media-source", num_options, options)) != NULL ||
+ (val = cupsGetOption("MediaSource", num_options, options)) != NULL ||
+ (val = cupsGetOption("InputSlot", num_options, options)) != NULL ||
+ (val = media_source) != NULL)
+ {
+ if (!strncasecmp(val, "Auto", 4) ||
+ !strncasecmp(val, "Default", 7))
+ h->MediaPosition = 0;
+ else if (!strcasecmp(val, "Main"))
+ h->MediaPosition = 1;
+ else if (!strcasecmp(val, "Alternate"))
+ h->MediaPosition = 2;
+ else if (!strcasecmp(val, "LargeCapacity"))
+ h->MediaPosition = 3;
+ else if (!strcasecmp(val, "Manual"))
+ h->MediaPosition = 4;
+ else if (!strcasecmp(val, "Envelope"))
+ h->MediaPosition = 5;
+ else if (!strcasecmp(val, "Disc"))
+ h->MediaPosition = 6;
+ else if (!strcasecmp(val, "Photo"))
+ h->MediaPosition = 7;
+ else if (!strcasecmp(val, "Hagaki"))
+ h->MediaPosition = 8;
+ else if (!strcasecmp(val, "MainRoll"))
+ h->MediaPosition = 9;
+ else if (!strcasecmp(val, "AlternateRoll"))
+ h->MediaPosition = 10;
+ else if (!strcasecmp(val, "Top"))
+ h->MediaPosition = 11;
+ else if (!strcasecmp(val, "Middle"))
+ h->MediaPosition = 12;
+ else if (!strcasecmp(val, "Bottom"))
+ h->MediaPosition = 13;
+ else if (!strcasecmp(val, "Side"))
+ h->MediaPosition = 14;
+ else if (!strcasecmp(val, "Left"))
+ h->MediaPosition = 15;
+ else if (!strcasecmp(val, "Right"))
+ h->MediaPosition = 16;
+ else if (!strcasecmp(val, "Center"))
+ h->MediaPosition = 17;
+ else if (!strcasecmp(val, "Rear"))
+ h->MediaPosition = 18;
+ else if (!strcasecmp(val, "ByPassTray"))
+ h->MediaPosition = 19;
+ else if (!strcasecmp(val, "Tray1"))
+ h->MediaPosition = 20;
+ else if (!strcasecmp(val, "Tray2"))
+ h->MediaPosition = 21;
+ else if (!strcasecmp(val, "Tray3"))
+ h->MediaPosition = 22;
+ else if (!strcasecmp(val, "Tray4"))
+ h->MediaPosition = 23;
+ else if (!strcasecmp(val, "Tray5"))
+ h->MediaPosition = 24;
+ else if (!strcasecmp(val, "Tray6"))
+ h->MediaPosition = 25;
+ else if (!strcasecmp(val, "Tray7"))
+ h->MediaPosition = 26;
+ else if (!strcasecmp(val, "Tray8"))
+ h->MediaPosition = 27;
+ else if (!strcasecmp(val, "Tray9"))
+ h->MediaPosition = 28;
+ else if (!strcasecmp(val, "Tray10"))
+ h->MediaPosition = 29;
+ else if (!strcasecmp(val, "Tray11"))
+ h->MediaPosition = 30;
+ else if (!strcasecmp(val, "Tray12"))
+ h->MediaPosition = 31;
+ else if (!strcasecmp(val, "Tray13"))
+ h->MediaPosition = 32;
+ else if (!strcasecmp(val, "Tray14"))
+ h->MediaPosition = 33;
+ else if (!strcasecmp(val, "Tray15"))
+ h->MediaPosition = 34;
+ else if (!strcasecmp(val, "Tray16"))
+ h->MediaPosition = 35;
+ else if (!strcasecmp(val, "Tray17"))
+ h->MediaPosition = 36;
+ else if (!strcasecmp(val, "Tray18"))
+ h->MediaPosition = 37;
+ else if (!strcasecmp(val, "Tray19"))
+ h->MediaPosition = 38;
+ else if (!strcasecmp(val, "Tray20"))
+ h->MediaPosition = 39;
+ else if (!strcasecmp(val, "Roll1"))
+ h->MediaPosition = 40;
+ else if (!strcasecmp(val, "Roll2"))
+ h->MediaPosition = 41;
+ else if (!strcasecmp(val, "Roll3"))
+ h->MediaPosition = 42;
+ else if (!strcasecmp(val, "Roll4"))
+ h->MediaPosition = 43;
+ else if (!strcasecmp(val, "Roll5"))
+ h->MediaPosition = 44;
+ else if (!strcasecmp(val, "Roll6"))
+ h->MediaPosition = 45;
+ else if (!strcasecmp(val, "Roll7"))
+ h->MediaPosition = 46;
+ else if (!strcasecmp(val, "Roll8"))
+ h->MediaPosition = 47;
+ else if (!strcasecmp(val, "Roll9"))
+ h->MediaPosition = 48;
+ else if (!strcasecmp(val, "Roll10"))
+ h->MediaPosition = 49;
+ else
+ fprintf(stderr, "DEBUG: Unsupported media source \"%s\".\n", val);
+ }
+ else if (set_defaults)
+ h->MediaPosition = 0; /* Auto */
+
+ if ((val = cupsGetOption("media-weight", num_options, options)) != NULL ||
+ (val = cupsGetOption("MediaWeight", num_options, options)) != NULL ||
+ (val = cupsGetOption("media-weight-metric", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("MediaWeightMetric", num_options, options)) != NULL)
+ h->MediaWeight = atol(val);
+ else if (set_defaults)
+ h->MediaWeight = 0;
+
+ if (pwg_raster)
+ {
+ /* Set "reserved" fields to 0 */
+ h->MirrorPrint = CUPS_FALSE;
+ h->NegativePrint = CUPS_FALSE;
+ }
+ else
+ {
+ if ((val = cupsGetOption("mirror-print", num_options, options)) != NULL ||
+ (val = cupsGetOption("MirrorPrint", num_options, options)) != NULL)
+ {
+ if (!strcasecmp(val, "true") || !strcasecmp(val, "on") ||
+ !strcasecmp(val, "yes"))
+ h->MirrorPrint = CUPS_TRUE;
+ else if (!strcasecmp(val, "false") ||
+ !strcasecmp(val, "off") ||
+ !strcasecmp(val, "no"))
+ h->MirrorPrint = CUPS_FALSE;
+ else if (set_defaults)
+ h->MirrorPrint = CUPS_FALSE;
+ }
+ if ((val = cupsGetOption("negative-print", num_options, options)) != NULL ||
+ (val = cupsGetOption("NegativePrint", num_options, options)) != NULL)
+ {
+ if (!strcasecmp(val, "true") || !strcasecmp(val, "on") ||
+ !strcasecmp(val, "yes"))
+ h->NegativePrint = CUPS_TRUE;
+ else if (!strcasecmp(val, "false") ||
+ !strcasecmp(val, "off") ||
+ !strcasecmp(val, "no"))
+ h->NegativePrint = CUPS_FALSE;
+ else if (set_defaults)
+ h->NegativePrint = CUPS_FALSE;
+ }
+ }
+
+ if ((val = cupsGetOption("copies", num_options, options)) != NULL ||
+ (val = cupsGetOption("Copies", num_options, options)) != NULL ||
+ (val = cupsGetOption("num-copies", num_options, options)) != NULL ||
+ (val = cupsGetOption("NumCopies", num_options, options)) != NULL)
+ h->NumCopies = atol(val);
+ else if (set_defaults)
+ h->NumCopies = 1; /* 0 = Printer default */
+
+ if ((val = cupsGetOption("orientation-requested", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("OrientationRequested", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("Orientation", num_options, options)) != NULL)
+ {
+ if (!strcasecmp(val, "Portrait") ||
+ !strcasecmp(val, "3"))
+ h->Orientation = CUPS_ORIENT_0;
+ else if (!strcasecmp(val, "Landscape") ||
+ !strcasecmp(val, "4"))
+ h->Orientation = CUPS_ORIENT_90;
+ else if (!strcasecmp(val, "reverse-portrait") ||
+ !strcasecmp(val, "ReversePortrait") ||
+ !strcasecmp(val, "5"))
+ h->Orientation = CUPS_ORIENT_180;
+ else if (!strcasecmp(val, "reverse-landscape") ||
+ !strcasecmp(val, "ReverseLandscape") ||
+ !strcasecmp(val, "6"))
+ h->Orientation = CUPS_ORIENT_270;
+ else
+ fprintf(stderr, "DEBUG: Unsupported Orientation \"%s\".\n", val);
+ }
+ else if (set_defaults)
+ h->Orientation = CUPS_ORIENT_0;
+
+ if (pwg_raster)
+ {
+ /* Set "reserved" fields to 0 */
+ h->OutputFaceUp = CUPS_FALSE;
+ }
+ else
+ {
+ if ((val = cupsGetOption("OutputFaceUp", num_options, options)) != NULL ||
+ (val = cupsGetOption("output-face-up", num_options, options)) != NULL)
+ {
+ if (!strcasecmp(val, "true") || !strcasecmp(val, "on") ||
+ !strcasecmp(val, "yes"))
+ h->OutputFaceUp = CUPS_TRUE;
+ else if (!strcasecmp(val, "false") ||
+ !strcasecmp(val, "off") ||
+ !strcasecmp(val, "no"))
+ h->OutputFaceUp = CUPS_FALSE;
+ else if (set_defaults)
+ h->OutputFaceUp = CUPS_FALSE;
+ }
+ }
+
+ if ((val = cupsGetOption("media-size", num_options, options)) != NULL ||
+ (val = cupsGetOption("MediaSize", num_options, options)) != NULL ||
+ (val = cupsGetOption("page-size", num_options, options)) != NULL ||
+ (val = cupsGetOption("PageSize", num_options, options)) != NULL ||
+ (val = page_size) != NULL)
+ {
+ size_found = NULL;
+ if ((size_found = pwgMediaForPWG(val)) == NULL)
+ if ((size_found = pwgMediaForPPD(val)) == NULL)
+ size_found = pwgMediaForLegacy(val);
+ if (size_found != NULL)
+ {
+ h->PageSize[0] = size_found->width * 72 / 2540;
+ h->PageSize[1] = size_found->length * 72 / 2540;
+ _strlcpy(h->cupsPageSizeName, size_found->pwg,
+ sizeof(h->cupsPageSizeName));
+ if (pwg_raster)
+ {
+ h->cupsPageSize[0] = 0.0;
+ h->cupsPageSize[1] = 0.0;
+ }
+ else
+ {
+ h->cupsPageSize[0] = size_found->width * 72.0 / 2540.0;
+ h->cupsPageSize[1] = size_found->length * 72.0 / 2540.0;
+ }
+ }
+ else
+ fprintf(stderr, "DEBUG: Unsupported page size %s.\n", val);
+ }
+ else if (set_defaults)
+ {
+ /* TODO: Automatic A4/Letter, like in scheduler/conf.c in CUPS. */
+ h->PageSize[0] = 612;
+ h->PageSize[1] = 792;
+ _strlcpy(h->cupsPageSizeName, "na_letter_8.5x11in",
+ sizeof(h->cupsPageSizeName));
+ if (pwg_raster)
+ {
+ h->cupsPageSize[0] = 0.0;
+ h->cupsPageSize[1] = 0.0;
+ }
+ }
+ else if (pwg_raster)
+ {
+ h->cupsPageSize[0] = 0.0;
+ h->cupsPageSize[1] = 0.0;
+ }
+
+ if (pwg_raster)
+ {
+ /* Set "reserved" fields to 0 */
+ h->Margins[0] = 0;
+ h->Margins[1] = 0;
+ h->ImagingBoundingBox[0] = 0;
+ h->ImagingBoundingBox[1] = 0;
+ h->ImagingBoundingBox[2] = 0;
+ h->ImagingBoundingBox[3] = 0;
+ h->cupsImagingBBox[0] = 0.0;
+ h->cupsImagingBBox[1] = 0.0;
+ h->cupsImagingBBox[2] = 0.0;
+ h->cupsImagingBBox[3] = 0.0;
+ }
+ else
+ {
+ if ((val = cupsGetOption("media-left-margin", num_options, options))
+ != NULL)
+ {
+ size = atol(val) * 72.0 / 2540.0;
+ h->Margins[0] = (int)size;
+ h->ImagingBoundingBox[0] = (int)size;
+ h->cupsImagingBBox[0] = size;
+ }
+ else if (set_defaults)
+ {
+ h->Margins[0] = 0;
+ h->ImagingBoundingBox[0] = 0;
+ h->cupsImagingBBox[0] = 0.0;
+ }
+ if ((val = cupsGetOption("media-bottom-margin", num_options, options))
+ != NULL)
+ {
+ size = atol(val) * 72.0 / 2540.0;
+ h->Margins[1] = (int)size;
+ h->ImagingBoundingBox[1] = (int)size;
+ h->cupsImagingBBox[1] = size;
+ }
+ else if (set_defaults)
+ {
+ h->Margins[1] = 0;
+ h->ImagingBoundingBox[1] = 0;
+ h->cupsImagingBBox[1] = 0.0;
+ }
+ if ((val = cupsGetOption("media-right-margin", num_options, options))
+ != NULL)
+ {
+ size = atol(val) * 72.0 / 2540.0;
+ h->ImagingBoundingBox[2] = h->PageSize[0] - (int)size;
+ h->cupsImagingBBox[2] = h->cupsPageSize[0] - size;
+ }
+ else if (set_defaults)
+ {
+ h->ImagingBoundingBox[2] = h->PageSize[0];
+ h->cupsImagingBBox[2] = h->cupsPageSize[0];
+ }
+ if ((val = cupsGetOption("media-top-margin", num_options, options))
+ != NULL)
+ {
+ size = atol(val) * 72.0 / 2540.0;
+ h->ImagingBoundingBox[3] = h->PageSize[1] - (int)size;
+ h->cupsImagingBBox[3] = h->cupsPageSize[1] - size;
+ }
+ else if (set_defaults)
+ {
+ h->ImagingBoundingBox[3] = h->PageSize[1];
+ h->cupsImagingBBox[3] = h->cupsPageSize[1];
+ }
+ }
+
+ if (pwg_raster)
+ {
+ /* Set "reserved" fields to 0 */
+ h->Separations = CUPS_FALSE;
+ h->TraySwitch = CUPS_FALSE;
+ }
+ else
+ {
+ if ((val = cupsGetOption("separations", num_options, options)) != NULL ||
+ (val = cupsGetOption("Separations", num_options, options)) != NULL)
+ {
+ if (!strcasecmp(val, "true") || !strcasecmp(val, "on") ||
+ !strcasecmp(val, "yes"))
+ h->Separations = CUPS_TRUE;
+ else if (!strcasecmp(val, "false") ||
+ !strcasecmp(val, "off") ||
+ !strcasecmp(val, "no"))
+ h->Separations = CUPS_FALSE;
+ else if (set_defaults)
+ h->Separations = CUPS_FALSE;
+ }
+ if ((val = cupsGetOption("tray-switch", num_options, options)) != NULL ||
+ (val = cupsGetOption("TraySwitch", num_options, options)) != NULL)
+ {
+ if (!strcasecmp(val, "true") || !strcasecmp(val, "on") ||
+ !strcasecmp(val, "yes"))
+ h->TraySwitch = CUPS_TRUE;
+ else if (!strcasecmp(val, "false") ||
+ !strcasecmp(val, "off") ||
+ !strcasecmp(val, "no"))
+ h->TraySwitch = CUPS_FALSE;
+ else if (set_defaults)
+ h->TraySwitch = CUPS_FALSE;
+ }
+ }
+
+ if ((val = cupsGetOption("sides", num_options, options)) != NULL ||
+ (val = cupsGetOption("Tumble", num_options, options)) != NULL)
+ {
+ if (!strcasecmp(val, "None") || !strcasecmp(val, "Off") ||
+ !strcasecmp(val, "False") || !strcasecmp(val, "No") ||
+ !strcasecmp(val, "one-sided") || !strcasecmp(val, "OneSided") ||
+ !strcasecmp(val, "two-sided-long-edge") ||
+ !strcasecmp(val, "TwoSidedLongEdge") ||
+ !strcasecmp(val, "DuplexNoTumble"))
+ h->Tumble = CUPS_FALSE;
+ else if (!strcasecmp(val, "On") ||
+ !strcasecmp(val, "True") || !strcasecmp(val, "Yes") ||
+ !strcasecmp(val, "two-sided-short-edge") ||
+ !strcasecmp(val, "TwoSidedShortEdge") ||
+ !strcasecmp(val, "DuplexTumble"))
+ h->Tumble = CUPS_TRUE;
+ }
+
+ h->cupsWidth = h->HWResolution[0] * h->PageSize[0] / 72;
+ h->cupsHeight = h->HWResolution[1] * h->PageSize[1] / 72;
+
+ if (pwg_raster || set_defaults)
+ {
+ /* TODO - Support for MediaType number */
+ h->cupsMediaType = 0;
+ }
+
+ if ((val = cupsGetOption("pwg-raster-document-type", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("PwgRasterDocumentType", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("print-color-mode", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("PrintColorMode", num_options, options)) != NULL ||
+ (val = cupsGetOption("color-space", num_options, options)) != NULL ||
+ (val = cupsGetOption("ColorSpace", num_options, options)) != NULL ||
+ (val = cupsGetOption("color-model", num_options, options)) != NULL ||
+ (val = cupsGetOption("ColorModel", num_options, options)) != NULL)
+ {
+ int bitspercolor, /* Bits per color */
+ bitsperpixel, /* Bits per pixel */
+ colorspace, /* CUPS/PWG raster color space */
+ numcolors; /* Number of colorants */
+ const char *ptr; /* Pointer into value */
+
+ ptr = NULL;
+ numcolors = 0;
+ bitspercolor = 8;
+ if (!strncasecmp(val, "AdobeRgb", 8))
+ {
+ if (*(val + 8) == '_' || *(val + 8) == '-')
+ ptr = val + 9;
+ colorspace = 20;
+ numcolors = 3;
+ }
+ else if (!strncasecmp(val, "Black", 5))
+ {
+ if (*(val + 5) == '_' || *(val + 5) == '-')
+ ptr = val + 6;
+ bitspercolor = 1;
+ colorspace = 3;
+ numcolors = 1;
+ }
+ else if (!strncasecmp(val, "Cmyk", 4))
+ {
+ if (*(val + 4) == '_' || *(val + 4) == '-')
+ ptr = val + 5;
+ colorspace = 6;
+ numcolors = 4;
+ }
+ else if (!strncasecmp(val, "Device", 6))
+ {
+ ptr = val + 6;
+ numcolors = strtol(ptr, (char **)&ptr, 10);
+ if (*ptr == '_' || *ptr == '-')
+ {
+ ptr ++;
+ colorspace = 47 + numcolors;
+ }
+ else
+ {
+ numcolors = 0;
+ ptr = NULL;
+ }
+ }
+ else if (!strncasecmp(val, "Sgray", 5))
+ {
+ if (*(val + 5) == '_' || *(val + 5) == '-')
+ ptr = val + 6;
+ colorspace = 18;
+ numcolors = 1;
+ }
+ else if (!strncasecmp(val, "Srgb", 4))
+ {
+ if (*(val + 4) == '_' || *(val + 4) == '-')
+ ptr = val + 5;
+ colorspace = 19;
+ numcolors = 3;
+ }
+ else if (!strncasecmp(val, "Rgb", 3))
+ {
+ if (*(val + 3) == '_' || *(val + 3) == '-')
+ ptr = val + 4;
+ colorspace = 1;
+ numcolors = 3;
+ }
+ if (numcolors > 0)
+ {
+ if (ptr)
+ bitspercolor = strtol(ptr, (char **)&ptr, 10);
+ bitsperpixel = bitspercolor * numcolors;
+ /* In 1-bit-per-color RGB modes we add a forth bit to each pixel
+ to align the pixels with bytes */
+ if (bitsperpixel == 3 &&
+ strcasestr(val, "Rgb"))
+ bitsperpixel = 4;
+ h->cupsBitsPerColor = bitspercolor;
+ h->cupsBitsPerPixel = bitsperpixel;
+ h->cupsColorSpace = colorspace;
+ h->cupsNumColors = numcolors;
+ }
+ else
+ {
+ fprintf(stderr, "DEBUG: Bad color space value \"%s\".\n", val);
+ if (set_defaults)
+ {
+ h->cupsBitsPerColor = 1;
+ h->cupsBitsPerPixel = 1;
+ h->cupsColorSpace = 3;
+ h->cupsNumColors = 1;
+ }
+ }
+ }
+ else if (set_defaults)
+ {
+ h->cupsBitsPerColor = 1;
+ h->cupsBitsPerPixel = 1;
+ h->cupsColorSpace = 3;
+ h->cupsNumColors = 1;
+ }
+
+ h->cupsBytesPerLine = (h->cupsWidth * h->cupsBitsPerPixel + 7) / 8;
+
+ if (pwg_raster || set_defaults)
+ {
+ /* TODO - Support for color orders 1 (banded) and 2 (planar) */
+ h->cupsColorOrder = 0;
+ }
+
+ if (pwg_raster || set_defaults)
+ {
+ /* TODO - Support for these parameters */
+ h->cupsCompression = 0;
+ h->cupsRowCount = 0;
+ h->cupsRowFeed = 0;
+ h->cupsRowStep = 0;
+ }
+
+ if (pwg_raster || set_defaults)
+ {
+ /* TODO - Support for cupsBorderlessScalingFactor */
+ h->cupsBorderlessScalingFactor = 0.0;
+ }
+
+ if (pwg_raster || set_defaults)
+ {
+ /* TODO - Support for custom values in CUPS Raster mode */
+ for (i = 0; i < 16; i ++)
+ {
+ h->cupsInteger[i] = 0;
+ h->cupsReal[i] = 0.0;
+ memset(h->cupsString[i], 0, 64);
+ }
+ }
+
+ if (pwg_raster)
+ {
+
+ if ((val = cupsGetOption("job-impressions", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("JobImpressions", num_options, options)) != NULL ||
+ (val = cupsGetOption("Impressions", num_options, options)) != NULL)
+ {
+ int impressions = atoi(val);
+ if (impressions >= 0)
+ h->cupsInteger[0] = impressions;
+ }
+
+ if ((val = cupsGetOption("pwg-raster-document-sheet-back", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("PwgRasterDocumentSheetBack", num_options,
+ options)) != NULL)
+ {
+ /* Set CrossFeedTransform and FeedTransform */
+ if (h->Duplex == CUPS_FALSE)
+ {
+ h->cupsInteger[1] = 1;
+ h->cupsInteger[2] = 1;
+ }
+ else if (h->Duplex == CUPS_TRUE)
+ {
+ if (h->Tumble == CUPS_FALSE)
+ {
+ if (!strcasecmp(val, "Flipped"))
+ {
+ h->cupsInteger[1] = 1;
+ h->cupsInteger[2] = -1;
+ }
+ else if (!strncasecmp(val, "Manual", 6))
+ {
+ h->cupsInteger[1] = 1;
+ h->cupsInteger[2] = 1;
+ }
+ else if (!strcasecmp(val, "Normal"))
+ {
+ h->cupsInteger[1] = 1;
+ h->cupsInteger[2] = 1;
+ }
+ else if (!strcasecmp(val, "Rotated"))
+ {
+ h->cupsInteger[1] = -1;
+ h->cupsInteger[2] = -1;
+ }
+ else
+ {
+ h->cupsInteger[1] = 1;
+ h->cupsInteger[2] = 1;
+ }
+ }
+ else
+ {
+ if (!strcasecmp(val, "Flipped"))
+ {
+ h->cupsInteger[1] = -1;
+ h->cupsInteger[2] = 1;
+ }
+ else if (!strncasecmp(val, "Manual", 6))
+ {
+ h->cupsInteger[1] = -1;
+ h->cupsInteger[2] = -1;
+ }
+ else if (!strcasecmp(val, "Normal"))
+ {
+ h->cupsInteger[1] = 1;
+ h->cupsInteger[2] = 1;
+ }
+ else if (!strcasecmp(val, "Rotated"))
+ {
+ h->cupsInteger[1] = 1;
+ h->cupsInteger[2] = 1;
+ }
+ else
+ {
+ h->cupsInteger[1] = 1;
+ h->cupsInteger[2] = 1;
+ }
+ }
+ }
+ else
+ {
+ h->cupsInteger[1] = 1;
+ h->cupsInteger[2] = 1;
+ }
+ }
+ else
+ {
+ h->cupsInteger[1] = 1;
+ h->cupsInteger[2] = 1;
+ }
+
+ /* TODO - Support for ImageBoxLeft, ImageBoxTop, ImageBoxRight, and
+ ImageBoxBottom (h->cupsInteger[3..6]), leave on 0 for now */
+
+ if ((val = cupsGetOption("alternate-primary", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("AlternatePrimary", num_options,
+ options)) != NULL)
+ {
+ int alternateprimary = atoi(val); /* SRGB value for black
+ pixels */
+ h->cupsInteger[7] = alternateprimary;
+ }
+
+ if ((val = cupsGetOption("print-quality", num_options, options)) != NULL ||
+ (val = cupsGetOption("PrintQuality", num_options, options)) != NULL ||
+ (val = cupsGetOption("Quality", num_options, options)) != NULL)
+ {
+ int quality = atoi(val); /* print-quality value */
+
+ if (!quality ||
+ (quality >= IPP_QUALITY_DRAFT && quality <= IPP_QUALITY_HIGH))
+ h->cupsInteger[8] = quality;
+ else
+ fprintf(stderr, "DEBUG: Unsupported print-quality %d.\n", quality);
+ }
+
+ /* Leave "reserved" fields (h->cupsInteger[9..13]) on 0 */
+
+ if ((val = cupsGetOption("vendor-identifier", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("VendorIdentifier", num_options,
+ options)) != NULL)
+ {
+ int vendorid = atoi(val); /* USB ID of manufacturer */
+ h->cupsInteger[14] = vendorid;
+ }
+
+ if ((val = cupsGetOption("vendor-length", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("VendorLength", num_options,
+ options)) != NULL)
+ {
+ int vendorlength = atoi(val); /* How many bytes of vendor
+ data? */
+ if (vendorlength <= 1088)
+ {
+ h->cupsInteger[15] = vendorlength;
+ if ((val = cupsGetOption("vendor-data", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("VendorData", num_options,
+ options)) != NULL)
+ /* TODO - How to enter binary data here? */
+ _strlcpy((char *)&(h->cupsReal[0]), val, 1088);
+ }
+ }
+ }
+
+ if (pwg_raster || set_defaults)
+ {
+ /* Set "reserved" fields to 0 */
+ memset(h->cupsMarkerType, 0, 64);
+ }
+
+ if ((val = cupsGetOption("print-rendering-intent", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("PrintRenderingIntent", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("RenderingIntent", num_options,
+ options)) != NULL)
+ {
+ if (!strcmp(val, "absolute"))
+ _strlcpy(h->cupsRenderingIntent, "Absolute",
+ sizeof(h->cupsRenderingIntent));
+ else if (!strcmp(val, "automatic"))
+ _strlcpy(h->cupsRenderingIntent, "Automatic",
+ sizeof(h->cupsRenderingIntent));
+ else if (!strcmp(val, "perceptual"))
+ _strlcpy(h->cupsRenderingIntent, "Perceptual",
+ sizeof(h->cupsRenderingIntent));
+ else if (!strcmp(val, "relative"))
+ _strlcpy(h->cupsRenderingIntent, "Relative",
+ sizeof(h->cupsRenderingIntent));
+ else if (!strcmp(val, "relative-bpc"))
+ _strlcpy(h->cupsRenderingIntent, "RelativeBpc",
+ sizeof(h->cupsRenderingIntent));
+ else if (!strcmp(val, "saturation"))
+ _strlcpy(h->cupsRenderingIntent, "Saturation",
+ sizeof(h->cupsRenderingIntent));
+ else
+ fprintf(stderr, "DEBUG: Unsupported print-rendering-intent \"%s\".\n",
+ val);
+ }
+ else if (set_defaults)
+ h->cupsRenderingIntent[0] = '\0';
+#endif /* HAVE_CUPS_1_7 */
+
+ return (0);
+}
+
+
+/*
+ * End
+ */
diff --git a/cupsfilters/raster.h b/cupsfilters/raster.h
new file mode 100644
index 000000000..fc82b1ebf
--- /dev/null
+++ b/cupsfilters/raster.h
@@ -0,0 +1,55 @@
+/*
+ * CUPS/PWG Raster utilities header file for CUPS.
+ *
+ * Copyright 2013 by Till Kamppeter.
+ *
+ * Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ */
+
+#ifndef _CUPS_FILTERS_RASTER_H_
+# define _CUPS_FILTERS_RASTER_H_
+
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+
+/*
+ * Include necessary headers...
+ */
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <time.h>
+# include <math.h>
+
+# if defined(WIN32) || defined(__EMX__)
+# include <io.h>
+# else
+# include <unistd.h>
+# include <fcntl.h>
+# endif /* WIN32 || __EMX__ */
+
+# include <cups/cups.h>
+# include <cups/raster.h>
+
+/*
+ * Prototypes...
+ */
+
+extern int cupsRasterParseIPPOptions(cups_page_header2_t *h,
+ int num_options,
+ cups_option_t *options,
+ int pwg_raster,
+ int set_defaults);
+
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+
+#endif /* !_CUPS_FILTERS_RASTER_H_ */
+
+/*
+ * End
+ */
+
diff --git a/cupsfilters/rgb.c b/cupsfilters/rgb.c
new file mode 100644
index 000000000..70a29153e
--- /dev/null
+++ b/cupsfilters/rgb.c
@@ -0,0 +1,551 @@
+/*
+ * RGB color separation code for CUPS.
+ *
+ * Copyright 2007 by Apple Inc.
+ * Copyright 1993-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * cupsRGBDelete() - Delete a color separation.
+ * cupsRGBDoGray() - Do a grayscale separation...
+ * cupsRGBDoRGB() - Do a RGB separation...
+ * cupsRGBLoad() - Load a RGB color profile from a PPD file.
+ * cupsRGBNew() - Create a new RGB color separation.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "driver.h"
+
+
+/*
+ * 'cupsRGBDelete()' - Delete a color separation.
+ */
+
+void
+cupsRGBDelete(cups_rgb_t *rgbptr) /* I - Color separation */
+{
+ if (rgbptr == NULL)
+ return;
+
+ free(rgbptr->colors[0][0][0]);
+ free(rgbptr->colors[0][0]);
+ free(rgbptr->colors[0]);
+ free(rgbptr->colors);
+ free(rgbptr);
+}
+
+
+/*
+ * 'cupsRGBDoGray()' - Do a grayscale separation...
+ */
+
+void
+cupsRGBDoGray(cups_rgb_t *rgbptr,
+ /* I - Color separation */
+ const unsigned char *input,
+ /* I - Input grayscale pixels */
+ unsigned char *output,
+ /* O - Output Device-N pixels */
+ int num_pixels)
+ /* I - Number of pixels */
+{
+ int i; /* Looping var */
+ int lastgray; /* Previous grayscale */
+ int xs, ys, zs, /* Current RGB row offsets */
+ g, gi, gm0, gm1;/* Current gray index and multipliers ... */
+ const unsigned char *color; /* Current color data */
+ int tempg; /* Current separation color */
+ int rgbsize; /* Separation data size */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (!rgbptr || !input || !output || num_pixels <= 0)
+ return;
+
+ /*
+ * Initialize variables used for the duration of the separation...
+ */
+
+ lastgray = -1;
+ rgbsize = rgbptr->num_channels;
+ xs = rgbptr->cube_size * rgbptr->cube_size * rgbptr->num_channels;
+ ys = rgbptr->cube_size * rgbptr->num_channels;
+ zs = rgbptr->num_channels;
+
+ /*
+ * Loop through it all...
+ */
+
+ while (num_pixels > 0)
+ {
+ /*
+ * See if the next pixel is a cached value...
+ */
+
+ num_pixels --;
+
+ g = cups_srgb_lut[*input++];
+
+ if (g == lastgray)
+ {
+ /*
+ * Copy previous color and continue...
+ */
+
+ memcpy(output, output - rgbptr->num_channels, rgbsize);
+
+ output += rgbptr->num_channels;
+ continue;
+ }
+ else if (g == 0x00 && rgbptr->cache_init)
+ {
+ /*
+ * Copy black color and continue...
+ */
+
+ memcpy(output, rgbptr->black, rgbsize);
+
+ output += rgbptr->num_channels;
+ continue;
+ }
+ else if (g == 0xff && rgbptr->cache_init)
+ {
+ /*
+ * Copy white color and continue...
+ */
+
+ memcpy(output, rgbptr->white, rgbsize);
+
+ output += rgbptr->num_channels;
+ continue;
+ }
+
+ /*
+ * Nope, figure this one out on our own...
+ */
+
+ gi = rgbptr->cube_index[g];
+ gm0 = rgbptr->cube_mult[g];
+ gm1 = 256 - gm0;
+
+ color = rgbptr->colors[gi][gi][gi];
+
+ for (i = 0; i < rgbptr->num_channels; i ++, color ++)
+ {
+ tempg = (color[0] * gm0 + color[xs + ys + zs] * gm1) / 256;
+
+ if (tempg > 255)
+ *output++ = 255;
+ else if (tempg < 0)
+ *output++ = 0;
+ else
+ *output++ = tempg;
+ }
+ }
+}
+
+
+/*
+ * 'cupsRGBDoRGB()' - Do a RGB separation...
+ */
+
+void
+cupsRGBDoRGB(cups_rgb_t *rgbptr,
+ /* I - Color separation */
+ const unsigned char *input,
+ /* I - Input RGB pixels */
+ unsigned char *output,
+ /* O - Output Device-N pixels */
+ int num_pixels)
+ /* I - Number of pixels */
+{
+ int i; /* Looping var */
+ int rgb, /* Current RGB color */
+ lastrgb; /* Previous RGB color */
+ int r, ri, rm0, rm1, rs,
+ /* Current red index, multipliexs, and row offset */
+ g, gi, gm0, gm1, gs,
+ /* Current green ... */
+ b, bi, bm0, bm1, bs;
+ /* Current blue ... */
+ const unsigned char *color; /* Current color data */
+ int tempr, /* Current separation colors */
+ tempg, /* ... */
+ tempb ; /* ... */
+ int rgbsize; /* Separation data size */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (!rgbptr || !input || !output || num_pixels <= 0)
+ return;
+
+ /*
+ * Initialize variables used for the duration of the separation...
+ */
+
+ lastrgb = -1;
+ rgbsize = rgbptr->num_channels;
+ rs = rgbptr->cube_size * rgbptr->cube_size * rgbptr->num_channels;
+ gs = rgbptr->cube_size * rgbptr->num_channels;
+ bs = rgbptr->num_channels;
+
+ /*
+ * Loop through it all...
+ */
+
+ while (num_pixels > 0)
+ {
+ /*
+ * See if the next pixel is a cached value...
+ */
+
+ num_pixels --;
+
+ r = cups_srgb_lut[*input++];
+ g = cups_srgb_lut[*input++];
+ b = cups_srgb_lut[*input++];
+ rgb = (((r << 8) | g) << 8) | b;
+
+ if (rgb == lastrgb)
+ {
+ /*
+ * Copy previous color and continue...
+ */
+
+ memcpy(output, output - rgbptr->num_channels, rgbsize);
+
+ output += rgbptr->num_channels;
+ continue;
+ }
+ else if (rgb == 0x000000 && rgbptr->cache_init)
+ {
+ /*
+ * Copy black color and continue...
+ */
+
+ memcpy(output, rgbptr->black, rgbsize);
+
+ output += rgbptr->num_channels;
+ continue;
+ }
+ else if (rgb == 0xffffff && rgbptr->cache_init)
+ {
+ /*
+ * Copy white color and continue...
+ */
+
+ memcpy(output, rgbptr->white, rgbsize);
+
+ output += rgbptr->num_channels;
+ continue;
+ }
+
+ /*
+ * Nope, figure this one out on our own...
+ */
+
+ ri = rgbptr->cube_index[r];
+ rm0 = rgbptr->cube_mult[r];
+ rm1 = 256 - rm0;
+
+ gi = rgbptr->cube_index[g];
+ gm0 = rgbptr->cube_mult[g];
+ gm1 = 256 - gm0;
+
+ bi = rgbptr->cube_index[b];
+ bm0 = rgbptr->cube_mult[b];
+ bm1 = 256 - bm0;
+
+ color = rgbptr->colors[ri][gi][bi];
+
+ for (i = rgbptr->num_channels; i > 0; i --, color ++)
+ {
+ tempb = (color[0] * bm0 + color[bs] * bm1) / 256;
+ tempg = tempb * gm0;
+ tempb = (color[gs] * gm0 + color[gs + bs] * bm1) / 256;
+ tempg = (tempg + tempb * gm1) / 256;
+
+ tempr = tempg * rm0;
+
+ tempb = (color[rs] * bm0 + color[rs + bs] * bm1) / 256;
+ tempg = tempb * gm0;
+ tempb = (color[rs + gs] * bm0 + color[rs + gs + bs] * bm1) / 256;
+ tempg = (tempg + tempb * gm1) / 256;
+
+ tempr = (tempr + tempg * rm1) / 256;
+
+ if (tempr > 255)
+ *output++ = 255;
+ else if (tempr < 0)
+ *output++ = 0;
+ else
+ *output++ = tempr;
+ }
+ }
+}
+
+
+/*
+ * 'cupsRGBLoad()' - Load a RGB color profile from a PPD file.
+ */
+
+cups_rgb_t * /* O - New color profile */
+cupsRGBLoad(ppd_file_t *ppd, /* I - PPD file */
+ const char *colormodel, /* I - Color model */
+ const char *media, /* I - Media type */
+ const char *resolution) /* I - Resolution */
+{
+ int i, /* Looping var */
+ cube_size, /* Size of color lookup cube */
+ num_channels, /* Number of color channels */
+ num_samples; /* Number of color samples */
+ cups_sample_t *samples; /* Color samples */
+ float values[7]; /* Color sample values */
+ char spec[PPD_MAX_NAME]; /* Profile name */
+ ppd_attr_t *attr; /* Attribute from PPD file */
+ cups_rgb_t *rgbptr; /* RGB color profile */
+
+
+ /*
+ * Find the following attributes:
+ *
+ * cupsRGBProfile - Specifies the cube size, number of channels, and
+ * number of samples
+ * cupsRGBSample - Specifies an RGB to CMYK color sample
+ */
+
+ if ((attr = cupsFindAttr(ppd, "cupsRGBProfile", colormodel, media,
+ resolution, spec, sizeof(spec))) == NULL)
+ {
+ fputs("DEBUG2: No cupsRGBProfile attribute found for the current settings!\n", stderr);
+ return (NULL);
+ }
+
+ if (!attr->value || sscanf(attr->value, "%d%d%d", &cube_size, &num_channels,
+ &num_samples) != 3)
+ {
+ fprintf(stderr, "ERROR: Bad cupsRGBProfile attribute \'%s\'!\n",
+ attr->value ? attr->value : "(null)");
+ return (NULL);
+ }
+
+ if (cube_size < 2 || cube_size > 16 ||
+ num_channels < 1 || num_channels > CUPS_MAX_RGB ||
+ num_samples != (cube_size * cube_size * cube_size))
+ {
+ fprintf(stderr, "ERROR: Bad cupsRGBProfile attribute \'%s\'!\n",
+ attr->value);
+ return (NULL);
+ }
+
+ /*
+ * Allocate memory for the samples and read them...
+ */
+
+ if ((samples = calloc(num_samples, sizeof(cups_sample_t))) == NULL)
+ {
+ fputs("ERROR: Unable to allocate memory for RGB profile!\n", stderr);
+ return (NULL);
+ }
+
+ /*
+ * Read all of the samples...
+ */
+
+ for (i = 0; i < num_samples; i ++)
+ if ((attr = ppdFindNextAttr(ppd, "cupsRGBSample", spec)) == NULL)
+ break;
+ else if (!attr->value)
+ {
+ fputs("ERROR: Bad cupsRGBSample value!\n", stderr);
+ break;
+ }
+ else if (sscanf(attr->value, "%f%f%f%f%f%f%f", values + 0,
+ values + 1, values + 2, values + 3, values + 4, values + 5,
+ values + 6) != (3 + num_channels))
+ {
+ fputs("ERROR: Bad cupsRGBSample value!\n", stderr);
+ break;
+ }
+ else
+ {
+ samples[i].rgb[0] = (int)(255.0 * values[0] + 0.5);
+ samples[i].rgb[1] = (int)(255.0 * values[1] + 0.5);
+ samples[i].rgb[2] = (int)(255.0 * values[2] + 0.5);
+ samples[i].colors[0] = (int)(255.0 * values[3] + 0.5);
+ if (num_channels > 1)
+ samples[i].colors[1] = (int)(255.0 * values[4] + 0.5);
+ if (num_channels > 2)
+ samples[i].colors[2] = (int)(255.0 * values[5] + 0.5);
+ if (num_channels > 3)
+ samples[i].colors[3] = (int)(255.0 * values[6] + 0.5);
+ }
+
+ /*
+ * If everything went OK, create the color profile...
+ */
+
+ if (i == num_samples)
+ rgbptr = cupsRGBNew(num_samples, samples, cube_size, num_channels);
+ else
+ rgbptr = NULL;
+
+ /*
+ * Free the temporary sample array and return...
+ */
+
+ free(samples);
+
+ return (rgbptr);
+}
+
+
+/*
+ * 'cupsRGBNew()' - Create a new RGB color separation.
+ */
+
+cups_rgb_t * /* O - New color separation or NULL */
+cupsRGBNew(int num_samples, /* I - Number of samples */
+ cups_sample_t *samples, /* I - Samples */
+ int cube_size, /* I - Size of LUT cube */
+ int num_channels) /* I - Number of color components */
+{
+ cups_rgb_t *rgbptr; /* New color separation */
+ int i; /* Looping var */
+ int r, g, b; /* Current RGB */
+ int tempsize; /* Sibe of main arrays */
+ unsigned char *tempc; /* Pointer for C arrays */
+ unsigned char **tempb ; /* Pointer for Z arrays */
+ unsigned char ***tempg; /* Pointer for Y arrays */
+ unsigned char ****tempr; /* Pointer for X array */
+ unsigned char rgb[3]; /* Temporary RGB value */
+
+
+ /*
+ * Range-check the input...
+ */
+
+ if (!samples || num_samples != (cube_size * cube_size * cube_size) ||
+ num_channels <= 0 || num_channels > CUPS_MAX_RGB)
+ return (NULL);
+
+ /*
+ * Allocate memory for the separation...
+ */
+
+ if ((rgbptr = calloc(1, sizeof(cups_rgb_t))) == NULL)
+ return (NULL);
+
+ /*
+ * Allocate memory for the samples and the LUT cube...
+ */
+
+ tempsize = cube_size * cube_size * cube_size; /* FUTURE: num_samples < cs^3 */
+
+ tempc = calloc(tempsize, num_channels);
+ tempb = calloc(tempsize, sizeof(unsigned char *));
+ tempg = calloc(cube_size * cube_size, sizeof(unsigned char **));
+ tempr = calloc(cube_size, sizeof(unsigned char ***));
+
+ if (tempc == NULL || tempb == NULL || tempg == NULL || tempr == NULL)
+ {
+ free(rgbptr);
+
+ if (tempc)
+ free(tempc);
+
+ if (tempb)
+ free(tempb);
+
+ if (tempg)
+ free(tempg);
+
+ if (tempr)
+ free(tempr);
+
+ return (NULL);
+ }
+
+ /*
+ * Fill in the arrays...
+ */
+
+ for (i = 0, r = 0; r < cube_size; r ++)
+ {
+ tempr[r] = tempg + r * cube_size;
+
+ for (g = 0; g < cube_size; g ++)
+ {
+ tempr[r][g] = tempb + i;
+
+ for (b = 0; b < cube_size; b ++, i ++)
+ tempr[r][g][b] = tempc + i * num_channels;
+ }
+ }
+
+ for (i = 0; i < num_samples; i ++)
+ {
+ r = samples[i].rgb[0] * (cube_size - 1) / 255;
+ g = samples[i].rgb[1] * (cube_size - 1) / 255;
+ b = samples[i].rgb[2] * (cube_size - 1) / 255;
+
+ memcpy(tempr[r][g][b], samples[i].colors, num_channels);
+ }
+
+ rgbptr->cube_size = cube_size;
+ rgbptr->num_channels = num_channels;
+ rgbptr->colors = tempr;
+
+ /*
+ * Generate the lookup tables for the cube indices and multipliers...
+ */
+
+ for (i = 0; i < 256; i ++)
+ {
+ rgbptr->cube_index[i] = i * (cube_size - 1) / 256;
+
+ if (i == 0)
+ rgbptr->cube_mult[i] = 256;
+ else
+ rgbptr->cube_mult[i] = 255 - ((i * (cube_size - 1)) & 255);
+ }
+
+ /*
+ * Generate the black and white cache values for the separation...
+ */
+
+ rgb[0] = 0;
+ rgb[1] = 0;
+ rgb[2] = 0;
+
+ cupsRGBDoRGB(rgbptr, rgb, rgbptr->black, 1);
+
+ rgb[0] = 255;
+ rgb[1] = 255;
+ rgb[2] = 255;
+
+ cupsRGBDoRGB(rgbptr, rgb, rgbptr->white, 1);
+
+ rgbptr->cache_init = 1;
+
+ /*
+ * Return the separation...
+ */
+
+ return (rgbptr);
+}
+
diff --git a/cupsfilters/srgb.c b/cupsfilters/srgb.c
new file mode 100644
index 000000000..bce4e9ef0
--- /dev/null
+++ b/cupsfilters/srgb.c
@@ -0,0 +1,72 @@
+/*
+ * sRGB lookup tables for CUPS.
+ *
+ * Copyright 2007 by Apple Inc.
+ * Copyright 1993-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "driver.h"
+
+
+/*
+ * sRGB gamma lookup table.
+ */
+
+const unsigned char cups_srgb_lut[256] =
+{
+ 0, 20, 28, 33, 38, 42, 46, 49, 52, 55, 58, 61, 63, 65, 68,
+ 70, 72, 74, 76, 78, 80, 81, 83, 85, 87, 88, 90, 91, 93, 94,
+ 96, 97, 99, 100, 102, 103, 104, 106, 107, 108, 109, 111, 112, 113, 114,
+ 115, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 128, 129, 130, 131,
+ 132, 133, 134, 135, 136, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145,
+ 146, 147, 147, 148, 149, 150, 151, 152, 153, 153, 154, 155, 156, 157, 158,
+ 158, 159, 160, 161, 162, 162, 163, 164, 165, 165, 166, 167, 168, 168, 169,
+ 170, 171, 171, 172, 173, 174, 174, 175, 176, 176, 177, 178, 178, 179, 180,
+ 181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188, 189, 189, 190,
+ 190, 191, 192, 192, 193, 194, 194, 195, 196, 196, 197, 197, 198, 199, 199,
+ 200, 200, 201, 202, 202, 203, 203, 204, 205, 205, 206, 206, 207, 208, 208,
+ 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, 214, 215, 216, 216, 217,
+ 217, 218, 218, 219, 219, 220, 220, 221, 222, 222, 223, 223, 224, 224, 225,
+ 225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232,
+ 233, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239, 239, 240,
+ 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 247, 247,
+ 248, 248, 249, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 254,
+ 255
+};
+
+
+/*
+ * sRGB gamma lookup table (inverted output to map to CMYK...)
+ */
+
+const unsigned char cups_scmy_lut[256] =
+{
+ 255, 235, 227, 222, 217, 213, 209, 206, 203, 200, 197, 194, 192, 190, 187,
+ 185, 183, 181, 179, 177, 175, 174, 172, 170, 168, 167, 165, 164, 162, 161,
+ 159, 158, 156, 155, 153, 152, 151, 149, 148, 147, 146, 144, 143, 142, 141,
+ 140, 138, 137, 136, 135, 134, 133, 132, 131, 130, 129, 127, 126, 125, 124,
+ 123, 122, 121, 120, 119, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110,
+ 109, 108, 108, 107, 106, 105, 104, 103, 102, 102, 101, 100, 99, 98, 97,
+ 97, 96, 95, 94, 93, 93, 92, 91, 90, 90, 89, 88, 87, 87, 86,
+ 85, 84, 84, 83, 82, 81, 81, 80, 79, 79, 78, 77, 77, 76, 75,
+ 74, 74, 73, 72, 72, 71, 70, 70, 69, 68, 68, 67, 66, 66, 65,
+ 65, 64, 63, 63, 62, 61, 61, 60, 59, 59, 58, 58, 57, 56, 56,
+ 55, 55, 54, 53, 53, 52, 52, 51, 50, 50, 49, 49, 48, 47, 47,
+ 46, 46, 45, 45, 44, 43, 43, 42, 42, 41, 41, 40, 39, 39, 38,
+ 38, 37, 37, 36, 36, 35, 35, 34, 33, 33, 32, 32, 31, 31, 30,
+ 30, 29, 29, 28, 28, 27, 27, 26, 26, 25, 25, 24, 24, 23, 23,
+ 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16, 16, 15,
+ 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8,
+ 7, 7, 6, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1,
+ 0
+};
+
diff --git a/cupsfilters/testcmyk.c b/cupsfilters/testcmyk.c
new file mode 100644
index 000000000..da7caa0e4
--- /dev/null
+++ b/cupsfilters/testcmyk.c
@@ -0,0 +1,432 @@
+/*
+ * Test the CMYK color separation code for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2006 by Easy Software Products, All Rights Reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * test_gray() - Test grayscale separations...
+ * test_rgb() - Test color separations...
+ * main() - Do color separation tests.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include <config.h>
+#include <string.h>
+#include <ctype.h>
+#include "driver.h"
+#include <sys/stat.h>
+
+
+void test_gray(int num_comps, const char *basename);
+void test_rgb(int num_comps, const char *basename);
+
+
+/*
+ * 'main()' - Do color separation tests.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ /*
+ * Make the test directory...
+ */
+
+ mkdir("test", 0755);
+
+ /*
+ * Run tests for K, Kk, CMY, CMYK, CcMmYK, and CcMmYKk separations...
+ */
+
+ test_rgb(1, "test/K-rgb");
+ test_rgb(2, "test/Kk-rgb");
+ test_rgb(3, "test/CMY-rgb");
+ test_rgb(4, "test/CMYK-rgb");
+ test_rgb(6, "test/CcMmYK-rgb");
+ test_rgb(7, "test/CcMmYKk-rgb");
+
+ test_gray(1, "test/K-gray");
+ test_gray(2, "test/Kk-gray");
+ test_gray(3, "test/CMY-gray");
+ test_gray(4, "test/CMYK-gray");
+ test_gray(6, "test/CcMmYK-gray");
+ test_gray(7, "test/CcMmYKk-gray");
+
+ /*
+ * Return with no errors...
+ */
+
+ return (0);
+}
+
+
+/*
+ * 'test_gray()' - Test grayscale separations...
+ */
+
+void
+test_gray(int num_comps, /* I - Number of components */
+ const char *basename) /* I - Base filename of output */
+{
+ int i; /* Looping var */
+ char filename[255]; /* Output filename */
+ char line[255]; /* Line from PGM file */
+ int width, height; /* Width and height of test image */
+ int x, y; /* Current coordinate in image */
+ int r, g, b; /* Current RGB color */
+ unsigned char input[7000]; /* Line to separate */
+ short output[48000], /* Output separation data */
+ *outptr; /* Pointer in output */
+ FILE *in; /* Input PPM file */
+ FILE *out[CUPS_MAX_CHAN];
+ /* Output PGM files */
+ FILE *comp; /* Composite output */
+ cups_cmyk_t *cmyk; /* Color separation */
+
+
+ /*
+ * Open the test image...
+ */
+
+ in = fopen("image.pgm", "rb");
+ while (fgets(line, sizeof(line), in) != NULL)
+ if (isdigit(line[0]))
+ break;
+
+ sscanf(line, "%d%d", &width, &height);
+
+ fgets(line, sizeof(line), in);
+
+ /*
+ * Create the color separation...
+ */
+
+ cmyk = cupsCMYKNew(num_comps);
+
+ switch (num_comps)
+ {
+ case 2 : /* Kk */
+ cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0);
+ break;
+
+ case 4 :
+ cupsCMYKSetGamma(cmyk, 2, 1.0, 0.9);
+ cupsCMYKSetBlack(cmyk, 0.5, 1.0);
+ break;
+
+ case 6 : /* CcMmYK */
+ cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0);
+ cupsCMYKSetLtDk(cmyk, 2, 0.5, 1.0);
+ cupsCMYKSetGamma(cmyk, 4, 1.0, 0.9);
+ cupsCMYKSetBlack(cmyk, 0.5, 1.0);
+ break;
+
+ case 7 : /* CcMmYKk */
+ cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0);
+ cupsCMYKSetLtDk(cmyk, 2, 0.5, 1.0);
+ cupsCMYKSetGamma(cmyk, 4, 1.0, 0.9);
+ cupsCMYKSetLtDk(cmyk, 5, 0.5, 1.0);
+ break;
+ }
+
+ /*
+ * Open the color separation files...
+ */
+
+ for (i = 0; i < num_comps; i ++)
+ {
+ sprintf(filename, "%s%d.pgm", basename, i);
+ out[i] = fopen(filename, "wb");
+
+ fprintf(out[i], "P5\n%d %d 255\n", width, height);
+ }
+
+ sprintf(filename, "%s.ppm", basename);
+ comp = fopen(filename, "wb");
+
+ fprintf(comp, "P6\n%d %d 255\n", width, height);
+
+ /*
+ * Read the image and do the separations...
+ */
+
+ for (y = 0; y < height; y ++)
+ {
+ fread(input, width, 1, in);
+
+ cupsCMYKDoGray(cmyk, input, output, width);
+
+ for (x = 0, outptr = output; x < width; x ++, outptr += num_comps)
+ {
+ for (i = 0; i < num_comps; i ++)
+ putc(255 - 255 * outptr[i] / 4095, out[i]);
+
+ r = 4095;
+ g = 4095;
+ b = 4095;
+
+ switch (num_comps)
+ {
+ case 1 :
+ r -= outptr[0];
+ g -= outptr[0];
+ b -= outptr[0];
+ break;
+ case 2 :
+ r -= outptr[0];
+ g -= outptr[0];
+ b -= outptr[0];
+
+ r -= outptr[1] / 2;
+ g -= outptr[1] / 2;
+ b -= outptr[1] / 2;
+ break;
+ case 3 :
+ r -= outptr[0];
+ g -= outptr[1];
+ b -= outptr[2];
+ break;
+ case 4 :
+ r -= outptr[0];
+ g -= outptr[1];
+ b -= outptr[2];
+
+ r -= outptr[3];
+ g -= outptr[3];
+ b -= outptr[3];
+ break;
+ case 6 :
+ r -= outptr[0] + outptr[1] / 2;
+ g -= outptr[2] + outptr[3] / 3;
+ b -= outptr[4];
+
+ r -= outptr[5];
+ g -= outptr[5];
+ b -= outptr[5];
+ break;
+ case 7 :
+ r -= outptr[0] + outptr[1] / 2;
+ g -= outptr[2] + outptr[3] / 3;
+ b -= outptr[4];
+
+ r -= outptr[5] + outptr[6] / 2;
+ g -= outptr[5] + outptr[6] / 2;
+ b -= outptr[5] + outptr[6] / 2;
+ break;
+ }
+
+ if (r < 0)
+ putc(0, comp);
+ else
+ putc(255 * r / 4095, comp);
+
+ if (g < 0)
+ putc(0, comp);
+ else
+ putc(255 * g / 4095, comp);
+
+ if (b < 0)
+ putc(0, comp);
+ else
+ putc(255 * b / 4095, comp);
+ }
+ }
+
+ for (i = 0; i < num_comps; i ++)
+ fclose(out[i]);
+
+ fclose(comp);
+ fclose(in);
+
+ cupsCMYKDelete(cmyk);
+}
+
+
+/*
+ * 'test_rgb()' - Test color separations...
+ */
+
+void
+test_rgb(int num_comps, /* I - Number of components */
+ const char *basename) /* I - Base filename of output */
+{
+ int i; /* Looping var */
+ char filename[255]; /* Output filename */
+ char line[255]; /* Line from PPM file */
+ int width, height; /* Width and height of test image */
+ int x, y; /* Current coordinate in image */
+ int r, g, b; /* Current RGB color */
+ unsigned char input[7000]; /* Line to separate */
+ short output[48000], /* Output separation data */
+ *outptr; /* Pointer in output */
+ FILE *in; /* Input PPM file */
+ FILE *out[CUPS_MAX_CHAN];
+ /* Output PGM files */
+ FILE *comp; /* Composite output */
+ cups_cmyk_t *cmyk; /* Color separation */
+
+
+ /*
+ * Open the test image...
+ */
+
+ in = fopen("image.ppm", "rb");
+ while (fgets(line, sizeof(line), in) != NULL)
+ if (isdigit(line[0]))
+ break;
+
+ sscanf(line, "%d%d", &width, &height);
+
+ fgets(line, sizeof(line), in);
+
+ /*
+ * Create the color separation...
+ */
+
+ cmyk = cupsCMYKNew(num_comps);
+
+ cupsCMYKSetBlack(cmyk, 0.5, 1.0);
+
+ switch (num_comps)
+ {
+ case 2 : /* Kk */
+ cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0);
+ break;
+ case 6 : /* CcMmYK */
+ cupsCMYKSetGamma(cmyk, 0, 1.0, 0.8);
+ cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0);
+ cupsCMYKSetGamma(cmyk, 2, 1.0, 0.8);
+ cupsCMYKSetLtDk(cmyk, 2, 0.5, 1.0);
+ break;
+ case 7 : /* CcMmYKk */
+ cupsCMYKSetGamma(cmyk, 0, 1.0, 0.8);
+ cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0);
+ cupsCMYKSetGamma(cmyk, 2, 1.0, 0.8);
+ cupsCMYKSetLtDk(cmyk, 2, 0.5, 1.0);
+ cupsCMYKSetLtDk(cmyk, 5, 0.5, 1.0);
+ break;
+ }
+
+ /*
+ * Open the color separation files...
+ */
+
+ for (i = 0; i < num_comps; i ++)
+ {
+ sprintf(filename, "%s%d.pgm", basename, i);
+ out[i] = fopen(filename, "wb");
+
+ fprintf(out[i], "P5\n%d %d 255\n", width, height);
+ }
+
+ sprintf(filename, "%s.ppm", basename);
+ comp = fopen(filename, "wb");
+
+ fprintf(comp, "P6\n%d %d 255\n", width, height);
+
+ /*
+ * Read the image and do the separations...
+ */
+
+ for (y = 0; y < height; y ++)
+ {
+ fread(input, width, 3, in);
+
+ cupsCMYKDoRGB(cmyk, input, output, width);
+
+ for (x = 0, outptr = output; x < width; x ++, outptr += num_comps)
+ {
+ for (i = 0; i < num_comps; i ++)
+ putc(255 - 255 * outptr[i] / 4095, out[i]);
+
+ r = 4095;
+ g = 4095;
+ b = 4095;
+
+ switch (num_comps)
+ {
+ case 1 :
+ r -= outptr[0];
+ g -= outptr[0];
+ b -= outptr[0];
+ break;
+ case 2 :
+ r -= outptr[0];
+ g -= outptr[0];
+ b -= outptr[0];
+
+ r -= outptr[1] / 2;
+ g -= outptr[1] / 2;
+ b -= outptr[1] / 2;
+ break;
+ case 3 :
+ r -= outptr[0];
+ g -= outptr[1];
+ b -= outptr[2];
+ break;
+ case 4 :
+ r -= outptr[0];
+ g -= outptr[1];
+ b -= outptr[2];
+
+ r -= outptr[3];
+ g -= outptr[3];
+ b -= outptr[3];
+ break;
+ case 6 :
+ r -= outptr[0] + outptr[1] / 2;
+ g -= outptr[2] + outptr[3] / 3;
+ b -= outptr[4];
+
+ r -= outptr[5];
+ g -= outptr[5];
+ b -= outptr[5];
+ break;
+ case 7 :
+ r -= outptr[0] + outptr[1] / 2;
+ g -= outptr[2] + outptr[3] / 3;
+ b -= outptr[4];
+
+ r -= outptr[5] + outptr[6] / 2;
+ g -= outptr[5] + outptr[6] / 2;
+ b -= outptr[5] + outptr[6] / 2;
+ break;
+ }
+
+ if (r < 0)
+ putc(0, comp);
+ else
+ putc(255 * r / 4095, comp);
+
+ if (g < 0)
+ putc(0, comp);
+ else
+ putc(255 * g / 4095, comp);
+
+ if (b < 0)
+ putc(0, comp);
+ else
+ putc(255 * b / 4095, comp);
+ }
+ }
+
+ for (i = 0; i < num_comps; i ++)
+ fclose(out[i]);
+
+ fclose(comp);
+ fclose(in);
+
+ cupsCMYKDelete(cmyk);
+}
+
diff --git a/cupsfilters/testdither.c b/cupsfilters/testdither.c
new file mode 100644
index 000000000..be2eaf203
--- /dev/null
+++ b/cupsfilters/testdither.c
@@ -0,0 +1,186 @@
+/*
+ * Dither test program for CUPS.
+ *
+ * Try the following:
+ *
+ * testdither 0 255 > filename.ppm
+ * testdither 0 127 255 > filename.ppm
+ * testdither 0 85 170 255 > filename.ppm
+ * testdither 0 63 127 170 198 227 255 > filename.ppm
+ * testdither 0 210 383 > filename.ppm
+ * testdither 0 82 255 > filename.ppm
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * main() - Test dithering and output a PPM file.
+ * usage() - Show program usage...
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "driver.h"
+#include <config.h>
+#include <string.h>
+#include <ctype.h>
+
+
+/*
+ * Local functions...
+ */
+
+void usage(void);
+
+
+/*
+ * 'main()' - Test dithering and output a PPM file.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int x, y; /* Current coordinate in image */
+ short line[512]; /* Line to dither */
+ unsigned char pixels[512], /* Dither pixels */
+ *pixptr; /* Pointer in line */
+ int output; /* Output pixel */
+ cups_lut_t *lut; /* Dither lookup table */
+ cups_dither_t *dither; /* Dither state */
+ int nlutvals; /* Number of lookup values */
+ float lutvals[16]; /* Lookup values */
+ int pixvals[16]; /* Pixel values */
+
+
+ /*
+ * See if we have lookup table values on the command-line...
+ */
+
+ if (argc > 1)
+ {
+ /*
+ * Yes, collect them...
+ */
+
+ nlutvals = 0;
+
+ for (x = 1; x < argc; x ++)
+ if (isdigit(argv[x][0]) && nlutvals < 16)
+ {
+ pixvals[nlutvals] = atoi(argv[x]);
+ lutvals[nlutvals] = atof(argv[x]) / 255.0;
+ nlutvals ++;
+ }
+ else
+ usage();
+
+ /*
+ * See if we have at least 2 values...
+ */
+
+ if (nlutvals < 2)
+ usage();
+ }
+ else
+ {
+ /*
+ * Otherwise use the default 2-entry LUT with values of 0 and 255...
+ */
+
+ nlutvals = 2;
+ lutvals[0] = 0.0;
+ lutvals[1] = 1.0;
+ pixvals[0] = 0;
+ pixvals[1] = 255;
+ }
+
+ /*
+ * Create the lookup table and dither state...
+ */
+
+ lut = cupsLutNew(nlutvals, lutvals);
+ dither = cupsDitherNew(512);
+
+ /*
+ * Put out the PGM header for a raw 256x256x8-bit grayscale file...
+ */
+
+ puts("P5\n512\n512\n255");
+
+ /*
+ * Dither 512 lines, which are written out in 256 image lines...
+ */
+
+ for (y = 0; y < 512; y ++)
+ {
+ /*
+ * Create the grayscale data for the current line...
+ */
+
+ for (x = 0; x < 512; x ++)
+ line[x] = 4095 * ((y / 32) * 16 + x / 32) / 255;
+
+ /*
+ * Dither the line...
+ */
+
+ cupsDitherLine(dither, lut, line, 1, pixels);
+
+ if (y == 0)
+ {
+ fputs("DEBUG: pixels =", stderr);
+ for (x = 0; x < 512; x ++)
+ fprintf(stderr, " %d", pixels[x]);
+ fputs("\n", stderr);
+ }
+
+ /*
+ * Add or set the output pixel values...
+ */
+
+ for (x = 0, pixptr = pixels; x < 512; x ++, pixptr ++)
+ {
+ output = 255 - pixvals[*pixptr];
+
+ if (output < 0)
+ putchar(0);
+ else
+ putchar(output);
+ }
+ }
+
+ /*
+ * Free the dither state and lookup table...
+ */
+
+ cupsDitherDelete(dither);
+ cupsLutDelete(lut);
+
+ /*
+ * Return with no errors...
+ */
+
+ return (0);
+}
+
+
+/*
+ * 'usage()' - Show program usage...
+ */
+
+void
+usage(void)
+{
+ puts("Usage: testdither [val1 val2 [... val16]] >filename.ppm");
+ exit(1);
+}
+
diff --git a/cupsfilters/testimage.c b/cupsfilters/testimage.c
new file mode 100644
index 000000000..18e607ab3
--- /dev/null
+++ b/cupsfilters/testimage.c
@@ -0,0 +1,90 @@
+/*
+ * Image library test program for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2006 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * main() - Main entry...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image.h"
+
+
+/*
+ * 'main()' - Main entry...
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ cups_image_t *img; /* Image to print */
+ cups_icspace_t primary; /* Primary image colorspace */
+ FILE *out; /* Output PPM/PGM file */
+ cups_ib_t *line; /* Line from file */
+ int y, /* Current line */
+ width, /* Width of image */
+ height, /* Height of image */
+ depth; /* Depth of image */
+
+
+ if (argc != 3)
+ {
+ puts("Usage: testimage filename.ext filename.[ppm|pgm]");
+ return (1);
+ }
+
+ if (strstr(argv[2], ".ppm") != NULL)
+ primary = CUPS_IMAGE_RGB;
+ else
+ primary = CUPS_IMAGE_WHITE;
+
+ img = cupsImageOpen(argv[1], primary, CUPS_IMAGE_WHITE, 100, 0, NULL);
+
+ if (!img)
+ {
+ perror(argv[1]);
+ return (1);
+ }
+
+ out = fopen(argv[2], "wb");
+
+ if (!out)
+ {
+ perror(argv[2]);
+ cupsImageClose(img);
+ return (1);
+ }
+
+ width = cupsImageGetWidth(img);
+ height = cupsImageGetHeight(img);
+ depth = cupsImageGetDepth(img);
+ line = calloc(width, depth);
+
+ fprintf(out, "P%d\n%d\n%d\n255\n",
+ cupsImageGetColorSpace(img) == CUPS_IMAGE_WHITE ? 5 : 6,
+ width, height);
+
+ for (y = 0; y < height; y ++)
+ {
+ cupsImageGetRow(img, 0, y, width, line);
+ fwrite(line, width, depth, out);
+ }
+
+ cupsImageClose(img);
+ fclose(out);
+
+ return (0);
+}
+
diff --git a/cupsfilters/testrgb.c b/cupsfilters/testrgb.c
new file mode 100644
index 000000000..11fcf7d6c
--- /dev/null
+++ b/cupsfilters/testrgb.c
@@ -0,0 +1,343 @@
+/*
+ * Test the new RGB color separation code for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2006 by Easy Software Products, All Rights Reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * main() - Do color rgb tests.
+ * test_gray() - Test grayscale rgbs...
+ * test_rgb() - Test color rgbs...
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include <config.h>
+#include <string.h>
+#include <ctype.h>
+#include "driver.h"
+#include <sys/stat.h>
+
+#ifdef USE_LCMS1
+# include <lcms.h>
+#endif /* USE_LCMS1 */
+
+
+void test_gray(cups_sample_t *samples, int num_samples,
+ int cube_size, int num_comps, const char *basename);
+void test_rgb(cups_sample_t *samples, int num_samples,
+ int cube_size, int num_comps,
+ const char *basename);
+
+
+/*
+ * 'main()' - Do color rgb tests.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ static cups_sample_t CMYK[] = /* Basic 4-color sep */
+ {
+ /*{ r, g, b }, { C, M, Y, K }*/
+ { { 0, 0, 0 }, { 0, 0, 0, 255 } },
+ { { 255, 0, 0 }, { 0, 255, 240, 0 } },
+ { { 0, 255, 0 }, { 200, 0, 200, 0 } },
+ { { 255, 255, 0 }, { 0, 0, 240, 0 } },
+ { { 0, 0, 255 }, { 200, 200, 0, 0 } },
+ { { 255, 0, 255 }, { 0, 200, 0, 0 } },
+ { { 0, 255, 255 }, { 200, 0, 0, 0 } },
+ { { 255, 255, 255 }, { 0, 0, 0, 0 } }
+ };
+
+
+ /*
+ * Make the test directory...
+ */
+
+ mkdir("test", 0755);
+
+ /*
+ * Run tests for CMYK and CMYK separations...
+ */
+
+ test_rgb(CMYK, 8, 2, 4, "test/rgb-cmyk");
+
+ test_gray(CMYK, 8, 2, 4, "test/gray-cmyk");
+
+ /*
+ * Return with no errors...
+ */
+
+ return (0);
+}
+
+
+/*
+ * 'test_gray()' - Test grayscale rgbs...
+ */
+
+void
+test_gray(cups_sample_t *samples, /* I - Sample values */
+ int num_samples, /* I - Number of samples */
+ int cube_size, /* I - Cube size */
+ int num_comps, /* I - Number of components */
+ const char *basename) /* I - Base filename of output */
+{
+ int i; /* Looping var */
+ char filename[255]; /* Output filename */
+ char line[255]; /* Line from PPM file */
+ int width, height; /* Width and height of test image */
+ int x, y; /* Current coordinate in image */
+ int r, g, b; /* Current RGB color */
+ unsigned char input[7000]; /* Line to rgbarate */
+ unsigned char output[48000], /* Output rgb data */
+ *outptr; /* Pointer in output */
+ FILE *in; /* Input PPM file */
+ FILE *out[CUPS_MAX_CHAN];
+ /* Output PGM files */
+ FILE *comp; /* Composite output */
+ cups_rgb_t *rgb; /* Color separation */
+
+
+ /*
+ * Open the test image...
+ */
+
+ in = fopen("image.pgm", "rb");
+ while (fgets(line, sizeof(line), in) != NULL)
+ if (isdigit(line[0]))
+ break;
+
+ sscanf(line, "%d%d", &width, &height);
+
+ fgets(line, sizeof(line), in);
+
+ /*
+ * Create the color rgb...
+ */
+
+ rgb = cupsRGBNew(num_samples, samples, cube_size, num_comps);
+
+ /*
+ * Open the color rgb files...
+ */
+
+ for (i = 0; i < num_comps; i ++)
+ {
+ sprintf(filename, "%s%d.pgm", basename, i);
+ out[i] = fopen(filename, "wb");
+
+ fprintf(out[i], "P5\n%d %d 255\n", width, height);
+ }
+
+ sprintf(filename, "%s.ppm", basename);
+ comp = fopen(filename, "wb");
+
+ fprintf(comp, "P6\n%d %d 255\n", width, height);
+
+ /*
+ * Read the image and do the rgbs...
+ */
+
+ for (y = 0; y < height; y ++)
+ {
+ fread(input, width, 1, in);
+
+ cupsRGBDoGray(rgb, input, output, width);
+
+ for (x = 0, outptr = output; x < width; x ++, outptr += num_comps)
+ {
+ for (i = 0; i < num_comps; i ++)
+ putc(255 - outptr[i], out[i]);
+
+ r = 255;
+ g = 255;
+ b = 255;
+
+ r -= outptr[0];
+ g -= outptr[1];
+ b -= outptr[2];
+
+ r -= outptr[3];
+ g -= outptr[3];
+ b -= outptr[3];
+
+ if (num_comps > 4)
+ {
+ r -= outptr[4] / 2;
+ g -= outptr[5] / 2;
+ }
+
+ if (num_comps > 6)
+ {
+ r -= outptr[6] / 2;
+ g -= outptr[6] / 2;
+ b -= outptr[6] / 2;
+ }
+
+ if (r < 0)
+ putc(0, comp);
+ else
+ putc(r, comp);
+
+ if (g < 0)
+ putc(0, comp);
+ else
+ putc(g, comp);
+
+ if (b < 0)
+ putc(0, comp);
+ else
+ putc(b, comp);
+ }
+ }
+
+ for (i = 0; i < num_comps; i ++)
+ fclose(out[i]);
+
+ fclose(comp);
+ fclose(in);
+
+ cupsRGBDelete(rgb);
+}
+
+
+/*
+ * 'test_rgb()' - Test color rgbs...
+ */
+
+void
+test_rgb(cups_sample_t *samples, /* I - Sample values */
+ int num_samples, /* I - Number of samples */
+ int cube_size, /* I - Cube size */
+ int num_comps, /* I - Number of components */
+ const char *basename) /* I - Base filename of output */
+{
+ int i; /* Looping var */
+ char filename[255]; /* Output filename */
+ char line[255]; /* Line from PPM file */
+ int width, height; /* Width and height of test image */
+ int x, y; /* Current coordinate in image */
+ int r, g, b; /* Current RGB color */
+ unsigned char input[7000]; /* Line to rgbarate */
+ unsigned char output[48000], /* Output rgb data */
+ *outptr; /* Pointer in output */
+ FILE *in; /* Input PPM file */
+ FILE *out[CUPS_MAX_CHAN];
+ /* Output PGM files */
+ FILE *comp; /* Composite output */
+ cups_rgb_t *rgb; /* Color separation */
+
+
+ /*
+ * Open the test image...
+ */
+
+ in = fopen("image.ppm", "rb");
+ while (fgets(line, sizeof(line), in) != NULL)
+ if (isdigit(line[0]))
+ break;
+
+ sscanf(line, "%d%d", &width, &height);
+
+ fgets(line, sizeof(line), in);
+
+ /*
+ * Create the color rgb...
+ */
+
+ rgb = cupsRGBNew(num_samples, samples, cube_size, num_comps);
+
+ /*
+ * Open the color rgb files...
+ */
+
+ for (i = 0; i < num_comps; i ++)
+ {
+ sprintf(filename, "%s%d.pgm", basename, i);
+ out[i] = fopen(filename, "wb");
+
+ fprintf(out[i], "P5\n%d %d 255\n", width, height);
+ }
+
+ sprintf(filename, "%s.ppm", basename);
+ comp = fopen(filename, "wb");
+
+ fprintf(comp, "P6\n%d %d 255\n", width, height);
+
+ /*
+ * Read the image and do the rgbs...
+ */
+
+ for (y = 0; y < height; y ++)
+ {
+ fread(input, width, 3, in);
+
+ cupsRGBDoRGB(rgb, input, output, width);
+
+ for (x = 0, outptr = output; x < width; x ++, outptr += num_comps)
+ {
+ for (i = 0; i < num_comps; i ++)
+ putc(255 - outptr[i], out[i]);
+
+ r = 255;
+ g = 255;
+ b = 255;
+
+ r -= outptr[0];
+ g -= outptr[1];
+ b -= outptr[2];
+
+ r -= outptr[3];
+ g -= outptr[3];
+ b -= outptr[3];
+
+ if (num_comps > 4)
+ {
+ r -= outptr[4] / 2;
+ g -= outptr[5] / 2;
+ }
+
+ if (num_comps > 6)
+ {
+ r -= outptr[6] / 2;
+ g -= outptr[6] / 2;
+ b -= outptr[6] / 2;
+ }
+
+ if (r < 0)
+ putc(0, comp);
+ else
+ putc(r, comp);
+
+ if (g < 0)
+ putc(0, comp);
+ else
+ putc(g, comp);
+
+ if (b < 0)
+ putc(0, comp);
+ else
+ putc(b, comp);
+ }
+ }
+
+ for (i = 0; i < num_comps; i ++)
+ fclose(out[i]);
+
+ fclose(comp);
+ fclose(in);
+
+ cupsRGBDelete(rgb);
+}
+
diff --git a/data/classified.pdf b/data/classified.pdf
new file mode 100644
index 000000000..ac6a2218d
--- /dev/null
+++ b/data/classified.pdf
Binary files differ
diff --git a/data/confidential.pdf b/data/confidential.pdf
new file mode 100644
index 000000000..1daf52b1e
--- /dev/null
+++ b/data/confidential.pdf
Binary files differ
diff --git a/data/default-testpage.pdf b/data/default-testpage.pdf
new file mode 100644
index 000000000..c357fccaf
--- /dev/null
+++ b/data/default-testpage.pdf
Binary files differ
diff --git a/data/default.pdf b/data/default.pdf
new file mode 100644
index 000000000..3f6865e34
--- /dev/null
+++ b/data/default.pdf
Binary files differ
diff --git a/data/form_english.pdf b/data/form_english.pdf
new file mode 100644
index 000000000..6d278e89b
--- /dev/null
+++ b/data/form_english.pdf
Binary files differ
diff --git a/data/form_english_in.odt b/data/form_english_in.odt
new file mode 100644
index 000000000..6f13e2869
--- /dev/null
+++ b/data/form_english_in.odt
Binary files differ
diff --git a/data/form_russian.pdf b/data/form_russian.pdf
new file mode 100644
index 000000000..8cebbf225
--- /dev/null
+++ b/data/form_russian.pdf
Binary files differ
diff --git a/data/form_russian_in.odt b/data/form_russian_in.odt
new file mode 100644
index 000000000..83e500fa4
--- /dev/null
+++ b/data/form_russian_in.odt
Binary files differ
diff --git a/data/secret.pdf b/data/secret.pdf
new file mode 100644
index 000000000..988fd8f9b
--- /dev/null
+++ b/data/secret.pdf
Binary files differ
diff --git a/data/standard.pdf b/data/standard.pdf
new file mode 100644
index 000000000..dc422bc0b
--- /dev/null
+++ b/data/standard.pdf
Binary files differ
diff --git a/data/testprint b/data/testprint
new file mode 100644
index 000000000..ea3f48f61
--- /dev/null
+++ b/data/testprint
@@ -0,0 +1,4 @@
+#PDF-BANNER
+Template default-testpage.pdf
+Show printer-name printer-info printer-location printer-make-and-model printer-driver-name printer-driver-version paper-size imageable-area job-id options time-at-creation time-at-processing
+
diff --git a/data/topsecret.pdf b/data/topsecret.pdf
new file mode 100644
index 000000000..d56f4e463
--- /dev/null
+++ b/data/topsecret.pdf
Binary files differ
diff --git a/data/unclassified.pdf b/data/unclassified.pdf
new file mode 100644
index 000000000..027c0fdef
--- /dev/null
+++ b/data/unclassified.pdf
Binary files differ
diff --git a/depcomp b/depcomp
new file mode 100755
index 000000000..fc98710e2
--- /dev/null
+++ b/depcomp
@@ -0,0 +1,791 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2013-05-30.07; # UTC
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+ depmode Dependency tracking mode.
+ source Source file read by 'PROGRAMS ARGS'.
+ object Object file output by 'PROGRAMS ARGS'.
+ DEPDIR directory where to store dependencies.
+ depfile Dependency file to output.
+ tmpdepfile Temporary file to use when outputting dependencies.
+ libtool Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "depcomp $scriptversion"
+ exit $?
+ ;;
+esac
+
+# Get the directory component of the given path, and save it in the
+# global variables '$dir'. Note that this directory component will
+# be either empty or ending with a '/' character. This is deliberate.
+set_dir_from ()
+{
+ case $1 in
+ */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
+ *) dir=;;
+ esac
+}
+
+# Get the suffix-stripped basename of the given path, and save it the
+# global variable '$base'.
+set_base_from ()
+{
+ base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
+}
+
+# If no dependency file was actually created by the compiler invocation,
+# we still have to create a dummy depfile, to avoid errors with the
+# Makefile "include basename.Plo" scheme.
+make_dummy_depfile ()
+{
+ echo "#dummy" > "$depfile"
+}
+
+# Factor out some common post-processing of the generated depfile.
+# Requires the auxiliary global variable '$tmpdepfile' to be set.
+aix_post_process_depfile ()
+{
+ # If the compiler actually managed to produce a dependency file,
+ # post-process it.
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form 'foo.o: dependency.h'.
+ # Do two passes, one to just change these to
+ # $object: dependency.h
+ # and one to simply output
+ # dependency.h:
+ # which is needed to avoid the deleted-header problem.
+ { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
+ sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
+ } > "$depfile"
+ rm -f "$tmpdepfile"
+ else
+ make_dummy_depfile
+ fi
+}
+
+# A tabulation character.
+tab=' '
+# A newline character.
+nl='
+'
+# Character ranges might be problematic outside the C locale.
+# These definitions help.
+upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
+lower=abcdefghijklmnopqrstuvwxyz
+digits=0123456789
+alpha=${upper}${lower}
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+ sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Avoid interferences from the environment.
+gccflag= dashmflag=
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+ # This is just like msvisualcpp but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvisualcpp
+fi
+
+if test "$depmode" = msvc7msys; then
+ # This is just like msvc7 but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvc7
+fi
+
+if test "$depmode" = xlc; then
+ # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
+ gccflag=-qmakedep=gcc,-MF
+ depmode=gcc
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am. Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+ for arg
+ do
+ case $arg in
+ -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+ *) set fnord "$@" "$arg" ;;
+ esac
+ shift # fnord
+ shift # $arg
+ done
+ "$@"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
+## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
+## (see the conditional assignment to $gccflag above).
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say). Also, it might not be
+## supported by the other compilers which use the 'gcc' depmode.
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ # The second -e expression handles DOS-style file names with drive
+ # letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the "deleted header file" problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+## Some versions of gcc put a space before the ':'. On the theory
+## that the space means something, we add a space to the output as
+## well. hp depmode also adds that space, but also prefixes the VPATH
+## to the object. Take care to not repeat it in the output.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like '#:fec' to the end of the
+ # dependency line.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
+ | tr "$nl" ' ' >> "$depfile"
+ echo >> "$depfile"
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> "$depfile"
+ else
+ make_dummy_depfile
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+xlc)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts '$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ set_dir_from "$object"
+ set_base_from "$object"
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$base.u
+ tmpdepfile3=$dir.libs/$base.u
+ "$@" -Wc,-M
+ else
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$dir$base.u
+ tmpdepfile3=$dir$base.u
+ "$@" -M
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ aix_post_process_depfile
+ ;;
+
+tcc)
+ # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
+ # FIXME: That version still under development at the moment of writing.
+ # Make that this statement remains true also for stable, released
+ # versions.
+ # It will wrap lines (doesn't matter whether long or short) with a
+ # trailing '\', as in:
+ #
+ # foo.o : \
+ # foo.c \
+ # foo.h \
+ #
+ # It will put a trailing '\' even on the last line, and will use leading
+ # spaces rather than leading tabs (at least since its commit 0394caf7
+ # "Emit spaces for -MD").
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
+ # We have to change lines of the first kind to '$object: \'.
+ sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
+ # And for each line of the second kind, we have to emit a 'dep.h:'
+ # dummy dependency, to avoid the deleted-header problem.
+ sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+## The order of this option in the case statement is important, since the
+## shell code in configure will try each of these formats in the order
+## listed in this file. A plain '-MD' option would be understood by many
+## compilers, so we must ensure this comes after the gcc and icc options.
+pgcc)
+ # Portland's C compiler understands '-MD'.
+ # Will always output deps to 'file.d' where file is the root name of the
+ # source file under compilation, even if file resides in a subdirectory.
+ # The object file name does not affect the name of the '.d' file.
+ # pgcc 10.2 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using '\' :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+ set_dir_from "$object"
+ # Use the source, not the object, to determine the base name, since
+ # that's sadly what pgcc will do too.
+ set_base_from "$source"
+ tmpdepfile=$base.d
+
+ # For projects that build the same source file twice into different object
+ # files, the pgcc approach of using the *source* file root name can cause
+ # problems in parallel builds. Use a locking strategy to avoid stomping on
+ # the same $tmpdepfile.
+ lockdir=$base.d-lock
+ trap "
+ echo '$0: caught signal, cleaning up...' >&2
+ rmdir '$lockdir'
+ exit 1
+ " 1 2 13 15
+ numtries=100
+ i=$numtries
+ while test $i -gt 0; do
+ # mkdir is a portable test-and-set.
+ if mkdir "$lockdir" 2>/dev/null; then
+ # This process acquired the lock.
+ "$@" -MD
+ stat=$?
+ # Release the lock.
+ rmdir "$lockdir"
+ break
+ else
+ # If the lock is being held by a different process, wait
+ # until the winning process is done or we timeout.
+ while test -d "$lockdir" && test $i -gt 0; do
+ sleep 1
+ i=`expr $i - 1`
+ done
+ fi
+ i=`expr $i - 1`
+ done
+ trap - 1 2 13 15
+ if test $i -le 0; then
+ echo "$0: failed to acquire lock after $numtries attempts" >&2
+ echo "$0: check lockdir '$lockdir'" >&2
+ exit 1
+ fi
+
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp2)
+ # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+ # compilers, which have integrated preprocessors. The correct option
+ # to use with these is +Maked; it writes dependencies to a file named
+ # 'foo.d', which lands next to the object file, wherever that
+ # happens to be.
+ # Much of this is similar to the tru64 case; see comments there.
+ set_dir_from "$object"
+ set_base_from "$object"
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir.libs/$base.d
+ "$@" -Wc,+Maked
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ "$@" +Maked
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
+ # Add 'dependent.h:' lines.
+ sed -ne '2,${
+ s/^ *//
+ s/ \\*$//
+ s/$/:/
+ p
+ }' "$tmpdepfile" >> "$depfile"
+ else
+ make_dummy_depfile
+ fi
+ rm -f "$tmpdepfile" "$tmpdepfile2"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in 'foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ set_dir_from "$object"
+ set_base_from "$object"
+
+ if test "$libtool" = yes; then
+ # Libtool generates 2 separate objects for the 2 libraries. These
+ # two compilations output dependencies in $dir.libs/$base.o.d and
+ # in $dir$base.o.d. We have to check for both files, because
+ # one of the two compilations can be disabled. We should prefer
+ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+ # automatically cleaned when .libs/ is deleted, while ignoring
+ # the former would cause a distcleancheck panic.
+ tmpdepfile1=$dir$base.o.d # libtool 1.5
+ tmpdepfile2=$dir.libs/$base.o.d # Likewise.
+ tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ # Same post-processing that is required for AIX mode.
+ aix_post_process_depfile
+ ;;
+
+msvc7)
+ if test "$libtool" = yes; then
+ showIncludes=-Wc,-showIncludes
+ else
+ showIncludes=-showIncludes
+ fi
+ "$@" $showIncludes > "$tmpdepfile"
+ stat=$?
+ grep -v '^Note: including file: ' "$tmpdepfile"
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ # The first sed program below extracts the file names and escapes
+ # backslashes for cygpath. The second sed program outputs the file
+ # name when reading, but also accumulates all include files in the
+ # hold buffer in order to output them again at the end. This only
+ # works with sed implementations that can handle large buffers.
+ sed < "$tmpdepfile" -n '
+/^Note: including file: *\(.*\)/ {
+ s//\1/
+ s/\\/\\\\/g
+ p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/'"$tab"'\1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+ s/.*/'"$tab"'/
+ G
+ p
+}' >> "$depfile"
+ echo >> "$depfile" # make sure the fragment doesn't end with a backslash
+ rm -f "$tmpdepfile"
+ ;;
+
+msvc7msys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove '-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for ':'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
+ "$@" $dashmflag |
+ sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this sed invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no eat=no
+ for arg
+ do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ if test $eat = yes; then
+ eat=no
+ continue
+ fi
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -arch)
+ eat=yes ;;
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix=`echo "$object" | sed 's/^.*\././'`
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ # makedepend may prepend the VPATH from the source file name to the object.
+ # No need to regex-escape $object, excess matching of '.' is harmless.
+ sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process the last invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed '1,2d' "$tmpdepfile" \
+ | tr ' ' "$nl" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove '-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E \
+ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ | sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E 2>/dev/null |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+ echo "$tab" >> "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvcmsys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# 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/drv/cupsfilters.drv b/drv/cupsfilters.drv
new file mode 100644
index 000000000..ddafeaec4
--- /dev/null
+++ b/drv/cupsfilters.drv
@@ -0,0 +1,6262 @@
+// Include standard font and media definitions
+#include <font.defs>
+#include <media.defs>
+
+Version 1.0
+
+{
+// List the fonts that are supported, in this case all standard
+// fonts...
+Font *
+
+// Generic IPP Everywhere Printer
+{
+
+// Copyright
+Copyright "(c) 2014 OpenPrinting"
+
+// Custom driver
+DriverType custom
+
+// Generate copies manually
+ManualCopies Yes
+
+// Color output
+ColorDevice Yes
+
+// 1 page per minute
+Throughput 1
+
+// CUPS filters...
+Filter "image/pwg-raster 0 -"
+Attribute "cupsFilter2" "" "application/vnd.cups-raster image/pwg-raster 0 -"
+
+Attribute "RequiresPageRegion" "All" "True"
+
+// Manufacturer
+Manufacturer "Generic"
+
+//Attribute "cupsEvenDuplex" "" "True"
+//Attribute "cupsBackSide" "" "Rotated"
+//Attribute "cupsFlipDuplex" "" "True"
+
+Attribute "PWGRaster" "" "Yes"
+
+{
+ Group "General/General"
+
+ Option "Duplex/Double-Sided Printing" PickOne AnySetup 10.0
+ Choice "DuplexNoTumble/Long Edge (Standard)" "<</Duplex true/Tumble false>>setpagedevice"
+ Choice "DuplexTumble/Short Edge (Flip)" "<</Duplex true/Tumble true>>setpagedevice"
+ *Choice "None/Off" "<</Duplex false/Tumble false>>setpagedevice"
+
+ Option "InputSlot/Media Source" PickOne AnySetup 10.0
+ *Choice "Auto/Auto-Select" "<</MediaPosition 0>>setpagedevice"
+ Choice "Main/Main Tray" "<</MediaPosition 1>>setpagedevice"
+ Choice "Alternate/Alternate Tray" "<</MediaPosition 2>>setpagedevice"
+ Choice "LargeCapacity/Large Capacity Tray" "<</MediaPosition 3>>setpagedevice"
+ Choice "Manual/Manual Feeder" "<</MediaPosition 4>>setpagedevice"
+ Choice "Envelope/Envelope Feeder" "<</MediaPosition 5>>setpagedevice"
+ Choice "Disc/CD/DVD/BluRay Disc Tray" "<</MediaPosition 6>>setpagedevice"
+ Choice "Photo/Photo Tray" "<</MediaPosition 7>>setpagedevice"
+ Choice "Hagaki/Hagaki Tray" "<</MediaPosition 8>>setpagedevice"
+ Choice "MainRoll/Main Roll" "<</MediaPosition 9>>setpagedevice"
+ Choice "AlternateRoll/Alternate Roll" "<</MediaPosition 10>>setpagedevice"
+ Choice "Top/Upper Tray" "<</MediaPosition 11>>setpagedevice"
+ Choice "Middle/Middle Tray" "<</MediaPosition 12>>setpagedevice"
+ Choice "Bottom/Bottom Tray" "<</MediaPosition 13>>setpagedevice"
+ Choice "Side/Side Tray" "<</MediaPosition 14>>setpagedevice"
+ Choice "Left/Left Tray" "<</MediaPosition 15>>setpagedevice"
+ Choice "Right/Right Tray" "<</MediaPosition 16>>setpagedevice"
+ Choice "Center/Center Tray" "<</MediaPosition 17>>setpagedevice"
+ Choice "Rear/Rear Tray" "<</MediaPosition 18>>setpagedevice"
+ Choice "ByPassTray/By-Pass Tray" "<</MediaPosition 19>>setpagedevice"
+ Choice "Tray1/Tray 1" "<</MediaPosition 20>>setpagedevice"
+ Choice "Tray2/Tray 2" "<</MediaPosition 21>>setpagedevice"
+ Choice "Tray3/Tray 3" "<</MediaPosition 22>>setpagedevice"
+ Choice "Tray4/Tray 4" "<</MediaPosition 23>>setpagedevice"
+ Choice "Tray5/Tray 5" "<</MediaPosition 24>>setpagedevice"
+ Choice "Tray6/Tray 6" "<</MediaPosition 25>>setpagedevice"
+ Choice "Tray7/Tray 7" "<</MediaPosition 26>>setpagedevice"
+ Choice "Tray8/Tray 8" "<</MediaPosition 27>>setpagedevice"
+ Choice "Tray9/Tray 9" "<</MediaPosition 28>>setpagedevice"
+ Choice "Tray10/Tray 10" "<</MediaPosition 29>>setpagedevice"
+ Choice "Tray11/Tray 11" "<</MediaPosition 30>>setpagedevice"
+ Choice "Tray12/Tray 12" "<</MediaPosition 31>>setpagedevice"
+ Choice "Tray13/Tray 13" "<</MediaPosition 32>>setpagedevice"
+ Choice "Tray14/Tray 14" "<</MediaPosition 33>>setpagedevice"
+ Choice "Tray15/Tray 15" "<</MediaPosition 34>>setpagedevice"
+ Choice "Tray16/Tray 16" "<</MediaPosition 35>>setpagedevice"
+ Choice "Tray17/Tray 17" "<</MediaPosition 36>>setpagedevice"
+ Choice "Tray18/Tray 18" "<</MediaPosition 37>>setpagedevice"
+ Choice "Tray19/Tray 19" "<</MediaPosition 38>>setpagedevice"
+ Choice "Tray20/Tray 20" "<</MediaPosition 39>>setpagedevice"
+ Choice "Roll1/Roll 1" "<</MediaPosition 40>>setpagedevice"
+ Choice "Roll2/Roll 2" "<</MediaPosition 41>>setpagedevice"
+ Choice "Roll3/Roll 3" "<</MediaPosition 42>>setpagedevice"
+ Choice "Roll4/Roll 4" "<</MediaPosition 43>>setpagedevice"
+ Choice "Roll5/Roll 5" "<</MediaPosition 44>>setpagedevice"
+ Choice "Roll6/Roll 6" "<</MediaPosition 45>>setpagedevice"
+ Choice "Roll7/Roll 7" "<</MediaPosition 46>>setpagedevice"
+ Choice "Roll8/Roll 8" "<</MediaPosition 47>>setpagedevice"
+ Choice "Roll9/Roll 9" "<</MediaPosition 48>>setpagedevice"
+ Choice "Roll10/Roll 10" "<</MediaPosition 49>>setpagedevice"
+
+ Option "Resolution/Resolution" PickOne AnySetup 10.0
+ Choice "150dpi/150 DPI" "<</HWResolution[150 150]>>setpagedevice"
+ Choice "300dpi/300 DPI" "<</HWResolution[300 300]>>setpagedevice"
+ *Choice "600dpi/600 DPI" "<</HWResolution[600 600]>>setpagedevice"
+ Choice "1200x600dpi/1200x600 DPI" "<</HWResolution[1200 600]>>setpagedevice"
+ Choice "1200dpi/1200 DPI" "<</HWResolution[1200 1200]>>setpagedevice"
+ Choice "2400x1200dpi/2400x1200 DPI" "<</HWResolution[2400 1200]>>setpagedevice"
+ Choice "2400dpi/2400 DPI" "<</HWResolution[2400 2400]>>setpagedevice"
+
+ Option "PwgRasterDocumentType/Color Mode" PickOne AnySetup 10.0
+ Choice "Black_1/Black and White (1 bit)" "<</cupsColorSpace 3/cupsBitsPerColor 1/cupsColorOrder 0>>setpagedevice"
+ Choice "SGRay_1/Grayscale (1 bit SGray)" "<</cupsColorSpace 18/cupsBitsPerColor 1/cupsColorOrder 0>>setpagedevice"
+ *Choice "Black_8/Grayscale (8 bit)" "<</cupsColorSpace 3/cupsBitsPerColor 8/cupsColorOrder 0>>setpagedevice"
+ Choice "SGray_8/Grayscale (8 bit SGray)" "<</cupsColorSpace 18/cupsBitsPerColor 8/cupsColorOrder 0>>setpagedevice"
+ Choice "Black_16/Grayscale (16 bit)" "<</cupsColorSpace 3/cupsBitsPerColor 16/cupsColorOrder 0>>setpagedevice"
+ Choice "SGray_16/Grayscale (16 bit SGray)" "<</cupsColorSpace 18/cupsBitsPerColor 16/cupsColorOrder 0>>setpagedevice"
+ Choice "Rgb_8/Color (8 bit RGB)" "<</cupsColorSpace 1/cupsBitsPerColor 8/cupsColorOrder 0>>setpagedevice"
+ Choice "SRgb_8/Color (8 bit SRGB)" "<</cupsColorSpace 19/cupsBitsPerColor 8/cupsColorOrder 0>>setpagedevice"
+ Choice "AdobeRgb_8/Color (8 bit Adobe RGB)" "<</cupsColorSpace 20/cupsBitsPerColor 8/cupsColorOrder 0>>setpagedevice"
+ Choice "Rgb_16/Color (16 bit RGB)" "<</cupsColorSpace 1/cupsBitsPerColor 16/cupsColorOrder 0>>setpagedevice"
+ Choice "SRgb_16/Color (16 bit SRGB)" "<</cupsColorSpace 19/cupsBitsPerColor 16/cupsColorOrder 0>>setpagedevice"
+ Choice "AdobeRgb_16/Color (16 bit Adobe RGB)" "<</cupsColorSpace 20/cupsBitsPerColor 16/cupsColorOrder 0>>setpagedevice"
+ Choice "Cmyk_8/Color (8 bit CMYK)" "<</cupsColorSpace 6/cupsBitsPerColor 8/cupsColorOrder 0>>setpagedevice"
+ Choice "Cmyk_16/Color (16 bit CMYK)" "<</cupsColorSpace 6/cupsBitsPerColor 16/cupsColorOrder 0>>setpagedevice"
+
+ Option "PrintQuality/Printout Quality" PickOne AnySetup 10.0
+ *Choice "0/Default" ""
+ Choice "3/Draft" ""
+ Choice "4/Normal" ""
+ Choice "5/High" ""
+
+ // Duplexer is optional...
+ Installable "OptionDuplex/Duplexer Installed"
+
+ // Constraints
+ //UIConstraints "*Duplex *OptionDuplex False"
+
+ // Custom page sizes from 1x4in to SuperB
+ HWMargins 0 0 0 0
+ VariablePaperSize Yes
+ MinSize 1in 4in
+ MaxSize 9999 9999
+
+ CustomMedia "3x5/3x5" 216.00 360.00 0 0 0 0 "<</PageSize[216.00 360.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[216.00 360.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvPersonal/EnvPersonal" 261.00 468.00 0 0 0 0 "<</PageSize[261.00 468.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[261.00 468.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvMonarch/EnvMonarch" 279.00 540.00 0 0 0 0 "<</PageSize[279.00 540.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[279.00 540.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "Env9/Env9" 279.00 639.00 0 0 0 0 "<</PageSize[279.00 639.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[279.00 639.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "4x6/4x6" 288.00 432.00 0 0 0 0 "<</PageSize[288.00 432.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[288.00 432.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "Env10/Env10" 297.00 684.00 0 0 0 0 "<</PageSize[297.00 684.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[297.00 684.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvA2/EnvA2" 315.00 414.00 0 0 0 0 "<</PageSize[315.00 414.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[315.00 414.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "Env11/Env11" 324.00 747.00 0 0 0 0 "<</PageSize[324.00 747.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[324.00 747.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "Env12/Env12" 342.00 792.00 0 0 0 0 "<</PageSize[342.00 792.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[342.00 792.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "5x7/5x7" 360.00 504.00 0 0 0 0 "<</PageSize[360.00 504.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[360.00 504.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "5x8/5x8" 360.00 576.00 0 0 0 0 "<</PageSize[360.00 576.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[360.00 576.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "Env14/Env14" 360.00 828.00 0 0 0 0 "<</PageSize[360.00 828.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[360.00 828.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "Statement/Statement" 396.00 612.00 0 0 0 0 "<</PageSize[396.00 612.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[396.00 612.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "na_index-4x6-ext_6x8in/na_index-4x6-ext_6x8in" 432.00 576.00 0 0 0 0 "<</PageSize[432.00 576.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[432.00 576.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "6x9/6x9" 432.00 648.00 0 0 0 0 "<</PageSize[432.00 648.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[432.00 648.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "6.5x9.5/6.5x9.5" 468.00 684.00 0 0 0 0 "<</PageSize[468.00 684.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[468.00 684.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "7x9/7x9" 504.00 648.00 0 0 0 0 "<</PageSize[504.00 648.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[504.00 648.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "Executive/Executive" 522.00 756.00 0 0 0 0 "<</PageSize[522.00 756.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[522.00 756.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "8x10/8x10" 576.00 720.00 0 0 0 0 "<</PageSize[576.00 720.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[576.00 720.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "8x13/8x13" 576.00 936.00 0 0 0 0 "<</PageSize[576.00 936.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[576.00 936.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "Quarto/Quarto" 612.00 779.76 0 0 0 0 "<</PageSize[612.00 779.76]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[612.00 779.76]/ImagingBBox null>>setpagedevice"
+ CustomMedia "Letter/Letter" 612.00 792.00 0 0 0 0 "<</PageSize[612.00 792.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[612.00 792.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "FanFoldGerman/FanFoldGerman" 612.00 864.00 0 0 0 0 "<</PageSize[612.00 864.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[612.00 864.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "LetterPlus/LetterPlus" 612.00 913.68 0 0 0 0 "<</PageSize[612.00 913.68]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[612.00 913.68]/ImagingBBox null>>setpagedevice"
+ CustomMedia "FanFoldGermanLegal/FanFoldGermanLegal" 612.00 936.00 0 0 0 0 "<</PageSize[612.00 936.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[612.00 936.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "Oficio/Oficio" 612.00 964.80 0 0 0 0 "<</PageSize[612.00 964.80]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[612.00 964.80]/ImagingBBox null>>setpagedevice"
+ CustomMedia "Legal/Legal" 612.00 1008.00 0 0 0 0 "<</PageSize[612.00 1008.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[612.00 1008.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "SuperA/SuperA" 643.68 1008.00 0 0 0 0 "<</PageSize[643.68 1008.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[643.68 1008.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "9x11/9x11" 648.00 792.00 0 0 0 0 "<</PageSize[648.00 792.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[648.00 792.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "ARCHA/ARCHA" 648.00 864.00 0 0 0 0 "<</PageSize[648.00 864.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[648.00 864.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "LetterExtra/LetterExtra" 684.00 864.00 0 0 0 0 "<</PageSize[684.00 864.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[684.00 864.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "LegalExtra/LegalExtra" 684.00 1080.00 0 0 0 0 "<</PageSize[684.00 1080.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[684.00 1080.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "10x11/10x11" 720.00 792.00 0 0 0 0 "<</PageSize[720.00 792.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[720.00 792.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "10x13/10x13" 720.00 936.00 0 0 0 0 "<</PageSize[720.00 936.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[720.00 936.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "10x14/10x14" 720.00 1008.00 0 0 0 0 "<</PageSize[720.00 1008.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[720.00 1008.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "10x15/10x15" 720.00 1080.00 0 0 0 0 "<</PageSize[720.00 1080.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[720.00 1080.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "11x12/11x12" 792.00 864.00 0 0 0 0 "<</PageSize[792.00 864.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[792.00 864.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "11x14/11x14" 792.00 1008.00 0 0 0 0 "<</PageSize[792.00 1008.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[792.00 1008.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "na_fanfold-us_11x14.875in/na_fanfold-us_11x14.875in" 792.00 1071.00 0 0 0 0 "<</PageSize[792.00 1071.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[792.00 1071.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "11x15/11x15" 792.00 1080.00 0 0 0 0 "<</PageSize[792.00 1080.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[792.00 1080.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "Tabloid/Tabloid" 792.00 1224.00 0 0 0 0 "<</PageSize[792.00 1224.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[792.00 1224.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "na_eur-edp_12x14in/na_eur-edp_12x14in" 864.00 1008.00 0 0 0 0 "<</PageSize[864.00 1008.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[864.00 1008.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "ARCHB/ARCHB" 864.00 1296.00 0 0 0 0 "<</PageSize[864.00 1296.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[864.00 1296.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "12x19/12x19" 864.00 1368.00 0 0 0 0 "<</PageSize[864.00 1368.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[864.00 1368.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "SuperB/SuperB" 864.00 1380.24 0 0 0 0 "<</PageSize[864.00 1380.24]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[864.00 1380.24]/ImagingBBox null>>setpagedevice"
+ CustomMedia "13x19/13x19" 936.00 1368.00 0 0 0 0 "<</PageSize[936.00 1368.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[936.00 1368.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "AnsiC/AnsiC" 1224.00 1584.00 0 0 0 0 "<</PageSize[1224.00 1584.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1224.00 1584.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "ARCHC/ARCHC" 1296.00 1728.00 0 0 0 0 "<</PageSize[1296.00 1728.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1296.00 1728.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "AnsiD/AnsiD" 1584.00 2448.00 0 0 0 0 "<</PageSize[1584.00 2448.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1584.00 2448.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "ARCHD/ARCHD" 1728.00 2592.00 0 0 0 0 "<</PageSize[1728.00 2592.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1728.00 2592.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "f/f" 2016.00 2880.00 0 0 0 0 "<</PageSize[2016.00 2880.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[2016.00 2880.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "na_wide-format_30x42in/na_wide-format_30x42in" 2160.00 3024.00 0 0 0 0 "<</PageSize[2160.00 3024.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[2160.00 3024.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "AnsiE/AnsiE" 2448.00 3168.00 0 0 0 0 "<</PageSize[2448.00 3168.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[2448.00 3168.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "ARCHE/ARCHE" 2592.00 3456.00 0 0 0 0 "<</PageSize[2592.00 3456.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[2592.00 3456.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "AnsiF/AnsiF" 3168.00 4896.00 0 0 0 0 "<</PageSize[3168.00 4896.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[3168.00 4896.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "A10/A10" 73.70 104.88 0 0 0 0 "<</PageSize[73.70 104.88]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[73.70 104.88]/ImagingBBox null>>setpagedevice"
+ CustomMedia "A9/A9" 104.88 147.40 0 0 0 0 "<</PageSize[104.88 147.40]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[104.88 147.40]/ImagingBBox null>>setpagedevice"
+ CustomMedia "A8/A8" 147.40 209.76 0 0 0 0 "<</PageSize[147.40 209.76]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[147.40 209.76]/ImagingBBox null>>setpagedevice"
+ CustomMedia "A7/A7" 209.76 297.64 0 0 0 0 "<</PageSize[209.76 297.64]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[209.76 297.64]/ImagingBBox null>>setpagedevice"
+ CustomMedia "A6/A6" 297.64 419.53 0 0 0 0 "<</PageSize[297.64 419.53]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[297.64 419.53]/ImagingBBox null>>setpagedevice"
+ CustomMedia "A5/A5" 419.53 595.28 0 0 0 0 "<</PageSize[419.53 595.28]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[419.53 595.28]/ImagingBBox null>>setpagedevice"
+ CustomMedia "A5Extra/A5Extra" 493.23 666.14 0 0 0 0 "<</PageSize[493.23 666.14]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[493.23 666.14]/ImagingBBox null>>setpagedevice"
+ CustomMedia "A4/A4" 595.28 841.89 0 0 0 0 "<</PageSize[595.28 841.89]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[595.28 841.89]/ImagingBBox null>>setpagedevice"
+ CustomMedia "A4Tab/A4Tab" 637.80 841.89 0 0 0 0 "<</PageSize[637.80 841.89]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[637.80 841.89]/ImagingBBox null>>setpagedevice"
+ CustomMedia "A4Extra/A4Extra" 667.56 913.61 0 0 0 0 "<</PageSize[667.56 913.61]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[667.56 913.61]/ImagingBBox null>>setpagedevice"
+ CustomMedia "A3/A3" 841.89 1190.55 0 0 0 0 "<</PageSize[841.89 1190.55]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[841.89 1190.55]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-a4x3/iso-a4x3" 841.89 1785.83 0 0 0 0 "<</PageSize[841.89 1785.83]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[841.89 1785.83]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-a4x4/iso-a4x4" 841.89 2383.94 0 0 0 0 "<</PageSize[841.89 2383.94]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[841.89 2383.94]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-a4x5/iso-a4x5" 841.89 2979.21 0 0 0 0 "<</PageSize[841.89 2979.21]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[841.89 2979.21]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-a4x6/iso-a4x6" 841.89 3574.49 0 0 0 0 "<</PageSize[841.89 3574.49]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[841.89 3574.49]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-a4x7/iso-a4x7" 841.89 4169.76 0 0 0 0 "<</PageSize[841.89 4169.76]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[841.89 4169.76]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-a4x8/iso-a4x8" 841.89 4767.87 0 0 0 0 "<</PageSize[841.89 4767.87]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[841.89 4767.87]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-a4x9/iso-a4x9" 841.89 5363.15 0 0 0 0 "<</PageSize[841.89 5363.15]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[841.89 5363.15]/ImagingBBox null>>setpagedevice"
+ CustomMedia "A3Extra/A3Extra" 912.76 1261.42 0 0 0 0 "<</PageSize[912.76 1261.42]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[912.76 1261.42]/ImagingBBox null>>setpagedevice"
+ CustomMedia "A2/A2" 1190.55 1683.78 0 0 0 0 "<</PageSize[1190.55 1683.78]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1190.55 1683.78]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-a3x3/iso-a3x3" 1190.55 2525.67 0 0 0 0 "<</PageSize[1190.55 2525.67]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1190.55 2525.67]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-a3x4/iso-a3x4" 1190.55 3370.39 0 0 0 0 "<</PageSize[1190.55 3370.39]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1190.55 3370.39]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-a3x5/iso-a3x5" 1190.55 4212.28 0 0 0 0 "<</PageSize[1190.55 4212.28]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1190.55 4212.28]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-a3x6/iso-a3x6" 1190.55 5054.17 0 0 0 0 "<</PageSize[1190.55 5054.17]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1190.55 5054.17]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-a3x7/iso-a3x7" 1190.55 5896.06 0 0 0 0 "<</PageSize[1190.55 5896.06]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1190.55 5896.06]/ImagingBBox null>>setpagedevice"
+ CustomMedia "A1/A1" 1683.78 2383.94 0 0 0 0 "<</PageSize[1683.78 2383.94]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1683.78 2383.94]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-a2x3/iso-a2x3" 1683.78 3574.49 0 0 0 0 "<</PageSize[1683.78 3574.49]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1683.78 3574.49]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-a2x4/iso-a2x4" 1683.78 4767.87 0 0 0 0 "<</PageSize[1683.78 4767.87]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1683.78 4767.87]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-a2x5/iso-a2x5" 1683.78 5958.43 0 0 0 0 "<</PageSize[1683.78 5958.43]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1683.78 5958.43]/ImagingBBox null>>setpagedevice"
+ CustomMedia "A0/A0" 2383.94 3370.39 0 0 0 0 "<</PageSize[2383.94 3370.39]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[2383.94 3370.39]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-a1x3/iso-a1x3" 2383.94 5054.17 0 0 0 0 "<</PageSize[2383.94 5054.17]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[2383.94 5054.17]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-a1x4/iso-a1x4" 2383.94 6740.79 0 0 0 0 "<</PageSize[2383.94 6740.79]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[2383.94 6740.79]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso_2a0_1189x1682mm/iso_2a0_1189x1682mm" 3370.39 4767.87 0 0 0 0 "<</PageSize[3370.39 4767.87]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[3370.39 4767.87]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso_a0x3_1189x2523mm/iso_a0x3_1189x2523mm" 3370.39 7151.81 0 0 0 0 "<</PageSize[3370.39 7151.81]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[3370.39 7151.81]/ImagingBBox null>>setpagedevice"
+ CustomMedia "ISOB10/ISOB10" 87.87 124.72 0 0 0 0 "<</PageSize[87.87 124.72]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[87.87 124.72]/ImagingBBox null>>setpagedevice"
+ CustomMedia "ISOB9/ISOB9" 124.72 175.75 0 0 0 0 "<</PageSize[124.72 175.75]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[124.72 175.75]/ImagingBBox null>>setpagedevice"
+ CustomMedia "ISOB8/ISOB8" 175.75 249.45 0 0 0 0 "<</PageSize[175.75 249.45]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[175.75 249.45]/ImagingBBox null>>setpagedevice"
+ CustomMedia "ISOB7/ISOB7" 249.45 354.33 0 0 0 0 "<</PageSize[249.45 354.33]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[249.45 354.33]/ImagingBBox null>>setpagedevice"
+ CustomMedia "ISOB6/ISOB6" 354.33 498.90 0 0 0 0 "<</PageSize[354.33 498.90]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[354.33 498.90]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso_b6c4_125x324mm/iso_b6c4_125x324mm" 354.33 918.43 0 0 0 0 "<</PageSize[354.33 918.43]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[354.33 918.43]/ImagingBBox null>>setpagedevice"
+ CustomMedia "ISOB5/ISOB5" 498.90 708.66 0 0 0 0 "<</PageSize[498.90 708.66]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[498.90 708.66]/ImagingBBox null>>setpagedevice"
+ CustomMedia "ISOB5Extra/ISOB5Extra" 569.76 782.36 0 0 0 0 "<</PageSize[569.76 782.36]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[569.76 782.36]/ImagingBBox null>>setpagedevice"
+ CustomMedia "ISOB4/ISOB4" 708.66 1000.63 0 0 0 0 "<</PageSize[708.66 1000.63]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[708.66 1000.63]/ImagingBBox null>>setpagedevice"
+ CustomMedia "ISOB3/ISOB3" 1000.63 1417.32 0 0 0 0 "<</PageSize[1000.63 1417.32]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1000.63 1417.32]/ImagingBBox null>>setpagedevice"
+ CustomMedia "ISOB2/ISOB2" 1417.32 2004.09 0 0 0 0 "<</PageSize[1417.32 2004.09]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1417.32 2004.09]/ImagingBBox null>>setpagedevice"
+ CustomMedia "ISOB1/ISOB1" 2004.09 2834.65 0 0 0 0 "<</PageSize[2004.09 2834.65]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[2004.09 2834.65]/ImagingBBox null>>setpagedevice"
+ CustomMedia "ISOB0/ISOB0" 2834.65 4008.19 0 0 0 0 "<</PageSize[2834.65 4008.19]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[2834.65 4008.19]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-c10/iso-c10" 79.37 113.39 0 0 0 0 "<</PageSize[79.37 113.39]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[79.37 113.39]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-c9/iso-c9" 113.39 161.57 0 0 0 0 "<</PageSize[113.39 161.57]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[113.39 161.57]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-c8/iso-c8" 161.57 229.61 0 0 0 0 "<</PageSize[161.57 229.61]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[161.57 229.61]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvC7/EnvC7" 229.61 323.15 0 0 0 0 "<</PageSize[229.61 323.15]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[229.61 323.15]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso_c7c6_81x162mm/iso_c7c6_81x162mm" 229.61 459.21 0 0 0 0 "<</PageSize[229.61 459.21]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[229.61 459.21]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvC6/EnvC6" 323.15 459.21 0 0 0 0 "<</PageSize[323.15 459.21]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[323.15 459.21]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvC65/EnvC65" 323.15 649.13 0 0 0 0 "<</PageSize[323.15 649.13]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[323.15 649.13]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvC5/EnvC5" 459.21 649.13 0 0 0 0 "<</PageSize[459.21 649.13]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[459.21 649.13]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvC4/EnvC4" 649.13 918.43 0 0 0 0 "<</PageSize[649.13 918.43]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[649.13 918.43]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvC3/EnvC3" 918.43 1298.27 0 0 0 0 "<</PageSize[918.43 1298.27]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[918.43 1298.27]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvC2/EnvC2" 1298.27 1836.85 0 0 0 0 "<</PageSize[1298.27 1836.85]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1298.27 1836.85]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvC1/EnvC1" 1836.85 2599.37 0 0 0 0 "<</PageSize[1836.85 2599.37]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1836.85 2599.37]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvC0/EnvC0" 2599.37 3676.54 0 0 0 0 "<</PageSize[2599.37 3676.54]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[2599.37 3676.54]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvDL/EnvDL" 311.81 623.62 0 0 0 0 "<</PageSize[311.81 623.62]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[311.81 623.62]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-ra4/iso-ra4" 609.45 864.57 0 0 0 0 "<</PageSize[609.45 864.57]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[609.45 864.57]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-sra4/iso-sra4" 637.80 907.09 0 0 0 0 "<</PageSize[637.80 907.09]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[637.80 907.09]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-ra3/iso-ra3" 864.57 1218.90 0 0 0 0 "<</PageSize[864.57 1218.90]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[864.57 1218.90]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-sra3/iso-sra3" 907.09 1275.59 0 0 0 0 "<</PageSize[907.09 1275.59]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[907.09 1275.59]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-ra2/iso-ra2" 1218.90 1729.13 0 0 0 0 "<</PageSize[1218.90 1729.13]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1218.90 1729.13]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-sra2/iso-sra2" 1275.59 1814.17 0 0 0 0 "<</PageSize[1275.59 1814.17]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1275.59 1814.17]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-ra1/iso-ra1" 1729.13 2437.80 0 0 0 0 "<</PageSize[1729.13 2437.80]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1729.13 2437.80]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-sra1/iso-sra1" 1814.17 2551.18 0 0 0 0 "<</PageSize[1814.17 2551.18]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1814.17 2551.18]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-ra0/iso-ra0" 2437.80 3458.27 0 0 0 0 "<</PageSize[2437.80 3458.27]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[2437.80 3458.27]/ImagingBBox null>>setpagedevice"
+ CustomMedia "iso-sra0/iso-sra0" 2551.18 3628.35 0 0 0 0 "<</PageSize[2551.18 3628.35]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[2551.18 3628.35]/ImagingBBox null>>setpagedevice"
+ CustomMedia "B10/B10" 90.71 127.56 0 0 0 0 "<</PageSize[90.71 127.56]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[90.71 127.56]/ImagingBBox null>>setpagedevice"
+ CustomMedia "B9/B9" 127.56 181.42 0 0 0 0 "<</PageSize[127.56 181.42]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[127.56 181.42]/ImagingBBox null>>setpagedevice"
+ CustomMedia "B8/B8" 181.42 257.95 0 0 0 0 "<</PageSize[181.42 257.95]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[181.42 257.95]/ImagingBBox null>>setpagedevice"
+ CustomMedia "B7/B7" 257.95 362.83 0 0 0 0 "<</PageSize[257.95 362.83]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[257.95 362.83]/ImagingBBox null>>setpagedevice"
+ CustomMedia "B6/B6" 362.83 515.91 0 0 0 0 "<</PageSize[362.83 515.91]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[362.83 515.91]/ImagingBBox null>>setpagedevice"
+ CustomMedia "B5/B5" 515.91 728.50 0 0 0 0 "<</PageSize[515.91 728.50]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[515.91 728.50]/ImagingBBox null>>setpagedevice"
+ CustomMedia "B4/B4" 728.50 1031.81 0 0 0 0 "<</PageSize[728.50 1031.81]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[728.50 1031.81]/ImagingBBox null>>setpagedevice"
+ CustomMedia "B3/B3" 1031.81 1459.84 0 0 0 0 "<</PageSize[1031.81 1459.84]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1031.81 1459.84]/ImagingBBox null>>setpagedevice"
+ CustomMedia "B2/B2" 1459.84 2063.62 0 0 0 0 "<</PageSize[1459.84 2063.62]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[1459.84 2063.62]/ImagingBBox null>>setpagedevice"
+ CustomMedia "B1/B1" 2063.62 2919.69 0 0 0 0 "<</PageSize[2063.62 2919.69]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[2063.62 2919.69]/ImagingBBox null>>setpagedevice"
+ CustomMedia "B0/B0" 2919.69 4127.24 0 0 0 0 "<</PageSize[2919.69 4127.24]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[2919.69 4127.24]/ImagingBBox null>>setpagedevice"
+ CustomMedia "jis_exec_216x330mm/jis_exec_216x330mm" 612.28 935.43 0 0 0 0 "<</PageSize[612.28 935.43]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[612.28 935.43]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvKaku2/EnvKaku2" 680.31 941.10 0 0 0 0 "<</PageSize[680.31 941.10]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[680.31 941.10]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvKaku3/EnvKaku3" 612.28 785.20 0 0 0 0 "<</PageSize[612.28 785.20]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[612.28 785.20]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvKaku4/EnvKaku4" 558.43 756.85 0 0 0 0 "<</PageSize[558.43 756.85]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[558.43 756.85]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvKaku5/EnvKaku5" 538.58 680.31 0 0 0 0 "<</PageSize[538.58 680.31]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[538.58 680.31]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvKaku7/EnvKaku7" 402.52 581.10 0 0 0 0 "<</PageSize[402.52 581.10]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[402.52 581.10]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvKaku8/EnvKaku8" 337.32 558.43 0 0 0 0 "<</PageSize[337.32 558.43]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[337.32 558.43]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvChou4/EnvChou4" 255.12 581.10 0 0 0 0 "<</PageSize[255.12 581.10]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[255.12 581.10]/ImagingBBox null>>setpagedevice"
+ CustomMedia "Postcard/Postcard" 283.46 419.53 0 0 0 0 "<</PageSize[283.46 419.53]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[283.46 419.53]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvYou4/EnvYou4" 297.64 666.14 0 0 0 0 "<</PageSize[297.64 666.14]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[297.64 666.14]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvYou6/EnvYou6" 277.80 538.58 0 0 0 0 "<</PageSize[277.80 538.58]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[277.80 538.58]/ImagingBBox null>>setpagedevice"
+ CustomMedia "jpn_chou2_111.1x146mm/jpn_chou2_111.1x146mm" 314.93 413.86 0 0 0 0 "<</PageSize[314.93 413.86]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[314.93 413.86]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvChou3/EnvChou3" 340.16 666.14 0 0 0 0 "<</PageSize[340.16 666.14]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[340.16 666.14]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvChou40/EnvChou40" 255.12 637.80 0 0 0 0 "<</PageSize[255.12 637.80]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[255.12 637.80]/ImagingBBox null>>setpagedevice"
+ CustomMedia "DoublePostcardRotated/DoublePostcardRotated" 419.53 566.93 0 0 0 0 "<</PageSize[419.53 566.93]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[419.53 566.93]/ImagingBBox null>>setpagedevice"
+ CustomMedia "jpn_kahu_240x322.1mm/jpn_kahu_240x322.1mm" 680.31 913.04 0 0 0 0 "<</PageSize[680.31 913.04]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[680.31 913.04]/ImagingBBox null>>setpagedevice"
+ CustomMedia "PRC32K/PRC32K" 274.96 428.03 0 0 0 0 "<</PageSize[274.96 428.03]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[274.96 428.03]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvPRC1/EnvPRC1" 289.13 467.72 0 0 0 0 "<</PageSize[289.13 467.72]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[289.13 467.72]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvPRC2/EnvPRC2" 289.13 498.90 0 0 0 0 "<</PageSize[289.13 498.90]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[289.13 498.90]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvPRC4/EnvPRC4" 311.81 589.61 0 0 0 0 "<</PageSize[311.81 589.61]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[311.81 589.61]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvPRC8/EnvPRC8" 340.16 875.91 0 0 0 0 "<</PageSize[340.16 875.91]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[340.16 875.91]/ImagingBBox null>>setpagedevice"
+ CustomMedia "prc_6_120x320mm/prc_6_120x320mm" 340.16 907.09 0 0 0 0 "<</PageSize[340.16 907.09]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[340.16 907.09]/ImagingBBox null>>setpagedevice"
+ CustomMedia "PRC16K/PRC16K" 413.86 609.45 0 0 0 0 "<</PageSize[413.86 609.45]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[413.86 609.45]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvPRC7/EnvPRC7" 453.54 651.97 0 0 0 0 "<</PageSize[453.54 651.97]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[453.54 651.97]/ImagingBBox null>>setpagedevice"
+ CustomMedia "om_juuro-ku-kai_198x275mm/om_juuro-ku-kai_198x275mm" 561.26 779.53 0 0 0 0 "<</PageSize[561.26 779.53]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[561.26 779.53]/ImagingBBox null>>setpagedevice"
+ CustomMedia "om_pa-kai_267x389mm/om_pa-kai_267x389mm" 756.85 1102.68 0 0 0 0 "<</PageSize[756.85 1102.68]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[756.85 1102.68]/ImagingBBox null>>setpagedevice"
+ CustomMedia "om_dai-pa-kai_275x395mm/om_dai-pa-kai_275x395mm" 779.53 1119.69 0 0 0 0 "<</PageSize[779.53 1119.69]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[779.53 1119.69]/ImagingBBox null>>setpagedevice"
+ CustomMedia "roc16k/roc16k" 558.00 774.00 0 0 0 0 "<</PageSize[558.00 774.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[558.00 774.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "roc8k/roc8k" 774.00 1116.00 0 0 0 0 "<</PageSize[774.00 1116.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[774.00 1116.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "3.5x5/3.5x5" 252.00 360.00 0 0 0 0 "<</PageSize[252.00 360.00]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[252.00 360.00]/ImagingBBox null>>setpagedevice"
+ CustomMedia "om_small-photo/om_small-photo" 283.46 425.20 0 0 0 0 "<</PageSize[283.46 425.20]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[283.46 425.20]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvItalian/EnvItalian" 311.81 651.97 0 0 0 0 "<</PageSize[311.81 651.97]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[311.81 651.97]/ImagingBBox null>>setpagedevice"
+ CustomMedia "om_large-photo/om_large-photo" 566.93 850.39 0 0 0 0 "<</PageSize[566.93 850.39]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[566.93 850.39]/ImagingBBox null>>setpagedevice"
+ CustomMedia "Folio/Folio" 595.28 935.43 0 0 0 0 "<</PageSize[595.28 935.43]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[595.28 935.43]/ImagingBBox null>>setpagedevice"
+ CustomMedia "FolioSP/FolioSP" 609.45 892.91 0 0 0 0 "<</PageSize[609.45 892.91]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[609.45 892.91]/ImagingBBox null>>setpagedevice"
+ CustomMedia "EnvInvite/EnvInvite" 623.62 623.62 0 0 0 0 "<</PageSize[623.62 623.62]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[623.62 623.62]/ImagingBBox null>>setpagedevice"
+ CustomMedia "om_wide-photo/om_wide-photo" 283.46 566.93 0 0 0 0 "<</PageSize[283.46 566.93]/ImagingBBox null>>setpagedevice"
+ "<</PageSize[283.46 566.93]/ImagingBBox null>>setpagedevice"
+
+ ModelName "Generic IPP Everywhere Printer"
+ Attribute "NickName" "" "Generic IPP Everywhere Printer"
+ Attribute "ShortNickName" "" "Generic IPP Everywhere Printer"
+ Attribute "1284DeviceID" "" "MFG:Generic;MDL:IPP Everywhere Printer;DES:Generic IPP Everywhere Printer;CLS:PRINTER;CMD:PWGRaster;DRV:Dpwgraster,R1,M0;"
+ PCFileName "pwgrast.ppd"
+ Attribute "Product" "" "(Generic IPP Everywhere Printer)"
+
+}
+}
+
+// HP large format printers
+{
+// Specify that this driver uses the HP-RTL driver...
+#include <pcl.h>
+
+// Specify that this driver uses the HP-PCL driver...
+DriverType pcl
+
+// Manufacturer, model name, and version
+Manufacturer "HP"
+
+Cutter true
+Throughput 1
+
+// Additional Medias
+#media "A0B/A0B - 841x2378mm" 2384 6740
+#media "A0C/A0C - 841x3567mm" 2384 10110
+#media "A0D/A0D - 841x4756mm" 2384 13480
+
+// Supported page sizes
+HWMargins 14.4 28.8 14.4 28.8
+MediaSize Letter
+MediaSize Tabloid
+MediaSize AnsiC
+MediaSize AnsiD
+MediaSize AnsiE
+MediaSize ARCHA
+MediaSize ARCHA.Transverse
+MediaSize ARCHB
+MediaSize ARCHB.Transverse
+MediaSize ARCHC
+MediaSize ARCHC.Transverse
+MediaSize ARCHD
+MediaSize ARCHD.Transverse
+MediaSize A0D
+MediaSize A0C
+MediaSize A0B
+MediaSize A0
+MediaSize A1
+MediaSize A1.Transverse
+MediaSize A2
+MediaSize A2.Transverse
+MediaSize A3
+*MediaSize A3.Transverse
+MediaSize A4
+MediaSize A4.Transverse
+MediaSize A5
+MediaSize A5.Transverse
+
+VariablePaperSize true
+MinSize 200 200
+MaxSize 3024 129600
+
+
+// Supported resolutions
+
+ Option "Resolution/Output Resolution" PickOne AnySetup 20
+ Choice "150dpi/150 DPI" "<</HWResolution[150 150]>>setpagedevice"
+ *Choice "300dpi/300 DPI" "<</HWResolution[300 300]>>setpagedevice"
+ Choice "600dpi/600 DPI" "<</HWResolution[600 600]>>setpagedevice"
+ Option "OutputMode/Print Quality" PickOne AnySetup 50
+ Choice "Draft/Draft" " <</OutputType (Draft)>>setpagedevice"
+ *Choice "Normal/Normal" " <</OutputType (Normal)>>setpagedevice"
+ Choice "Best/Best" " <</OutputType (Best)>>setpagedevice"
+ Option "InputSlot/Mediasource" PickOne JCLSetup 10
+ Choice "manual/Manual" "@PJL SET MEDIASOURCE=MANUALFEED<0A>"
+ *Choice "roll/ROLL" "@PJL SET MEDIASOURCE=ROLL<0A>"
+
+// MediaType
+
+*MediaType 0 "Paper/Plain Paper"
+MediaType 1 "Transpareny/Tranparency film"
+MediaType 2 "Velum/Velum"
+MediaType 3 "Polyester/Polyester film"
+MediaType 4 "Translucent/Translucent paper"
+MediaType 5 "Special/Special paper"
+MediaType 6 "Glossy/Glossy paper"
+
+{
+ ColorDevice No
+
+ //ModelNumber ($RTL_PJL)
+ ModelNumber ($PCL_PAPER_SIZE $PCL_PJL_HPGL2 $PCL_PJL $PCL_PJL_RESOLUTION)
+ ModelName "DesignJet 600 pcl"
+ PCFileName "dsgnjt600pcl.ppd"
+}
+
+{
+ ColorDevice Yes
+ *ColorModel Gray/Grayscale w chunky 1
+ ColorModel Black k chunky 1
+ ColorModel rgb/RGB rgb banded 2
+
+ Attribute cupsPJL cupsRET "@PJL SET RET=%?False:OFF;%?True:ON;%n"
+ // Color models
+ ModelNumber ($PCL_PAPER_SIZE $PCL_RASTER_END_COLOR $PCL_RASTER_CID $PCL_RASTER_SIMPLE $PCL_RASTER_RGB24 $PCL_PJL $PCL_PJL_PAPERWIDTH $PCL_PJL_HPGL2 $PCL_PJL_RESOLUTION)
+ {
+ ModelName "DesignJet 750c pcl"
+ PCFileName "dsgnjt750cpcl.ppd"
+ }
+ {
+ ModelName "DesignJet 1050c pcl"
+ PCFileName "dsgnjt1050cpcl.ppd"
+ }
+ {
+ ModelName "DesignJet 4000 pcl"
+ PCFileName "dsgnjt4000pcl.ppd"
+ }
+ {
+ ModelName "DesignJet T1100 pcl"
+ PCFileName "dsgnjtt1100pcl.ppd"
+ }
+ {
+ ModelName "DesignJet T790 pcl"
+ PCFileName "dsgnjtt790pcl.ppd"
+ }
+
+}
+
+}
+
+}
+
+// Generic Text-Only Printer
+{
+
+// Copyright
+Copyright "(c) 2014 OpenPrinting"
+
+// Custom driver
+DriverType custom
+
+// Generate copies manually
+ManualCopies Yes
+
+// Color output
+ColorDevice No
+
+// 1 page per minute
+Throughput 1
+
+// CUPS filters...
+Filter "text/plain 0 texttotext"
+Attribute "cupsFilter2" "" "text/plain text/plain 0 texttotext"
+
+Attribute "RequiresPageRegion" "All" "True"
+
+// Manufacturer
+Manufacturer "Generic"
+
+// Let margins slightly differ from 0 to not get cupstestppd warnings
+// about "Fullbleed" sizes.
+HWMargins 0.1 0.1 0.1 0.1
+
+// Supported page sizes
+*MediaSize Letter
+MediaSize Legal
+MediaSize Tabloid
+MediaSize Ledger
+MediaSize A4
+MediaSize A3
+MediaSize FanFoldGerman
+MediaSize FanFoldGermanLegal
+
+// Additional Medias
+CustomMedia "11x14Rotated/14 7/8 x 11 in Continuous" 1008 792 0.1 0.1 0.1 0.1 "" ""
+CustomMedia "LegalRotated/14 7/8 x 8 1/2 in Continuous" 1008 612 0.1 0.1 0.1 0.1 "" ""
+CustomMedia "Custom1/Custom Page Size 1" 612 792 0.1 0.1 0.1 0.1 "" ""
+CustomMedia "Custom2/Custom Page Size 2" 612 792 0.1 0.1 0.1 0.1 "" ""
+CustomMedia "Custom3/Custom Page Size 3" 612 792 0.1 0.1 0.1 0.1 "" ""
+
+{
+ Group "General/General"
+
+ Option "OverLongLines/Long Line Handling" PickOne AnySetup 10.0
+ Choice "Truncate/Truncate at Right Edge" ""
+ *Choice "WrapAtWidth/Wrap at Right Edge" ""
+ Choice "WordWrap/Word Wrap" ""
+
+ Option "TabWidth/Tab Stop Width" PickOne AnySetup 10.0
+ Choice "1/1 Space" ""
+ Choice "2/2 Spaces" ""
+ Choice "3/3 Spaces" ""
+ Choice "4/4 Spaces" ""
+ Choice "5/5 Spaces" ""
+ Choice "6/6 Spaces" ""
+ Choice "7/7 Spaces" ""
+ *Choice "8/8 Spaces" ""
+ Choice "9/9 Spaces" ""
+ Choice "10/10 Spaces" ""
+ Choice "11/11 Spaces" ""
+ Choice "12/12 Spaces" ""
+ Choice "13/13 Spaces" ""
+ Choice "14/14 Spaces" ""
+ Choice "15/15 Spaces" ""
+ Choice "16/16 Spaces" ""
+ Attribute CustomTabWidth True ""
+ Attribute ParamCustomTabWidth Spaces "1 int 1 999"
+
+ Option "Pagination/Paginate Output ('On' for sheets, 'Off' for roll/continuous)" Boolean AnySetup 10.0
+ *Choice "True/On" ""
+ Choice "False/Off" ""
+
+ Option "page-left/Left Margin" PickOne AnySetup 10.0
+ Choice "0/0 Columns" ""
+ Choice "1/1 Column" ""
+ Choice "2/2 Columns" ""
+ Choice "3/3 Columns" ""
+ Choice "4/4 Columns" ""
+ *Choice "5/5 Columns" ""
+ Choice "6/6 Columns" ""
+ Choice "7/7 Columns" ""
+ Choice "8/8 Columns" ""
+ Choice "9/9 Columns" ""
+ Choice "10/10 Columns" ""
+ Choice "11/11 Columns" ""
+ Choice "12/12 Columns" ""
+ Choice "13/13 Columns" ""
+ Choice "14/14 Columns" ""
+ Choice "15/15 Columns" ""
+ Choice "16/16 Columns" ""
+ Choice "17/17 Columns" ""
+ Choice "18/18 Columns" ""
+ Choice "19/19 Columns" ""
+ Choice "20/20 Columns" ""
+ Attribute Custompage-left True ""
+ Attribute ParamCustompage-left Columns "1 int 1 99"
+
+ Option "page-right/Right Margin" PickOne AnySetup 10.0
+ Choice "0/0 Columns" ""
+ Choice "1/1 Column" ""
+ *Choice "2/2 Columns" ""
+ Choice "3/3 Columns" ""
+ Choice "4/4 Columns" ""
+ Choice "5/5 Columns" ""
+ Choice "6/6 Columns" ""
+ Choice "7/7 Columns" ""
+ Choice "8/8 Columns" ""
+ Choice "9/9 Columns" ""
+ Choice "10/10 Columns" ""
+ Choice "11/11 Columns" ""
+ Choice "12/12 Columns" ""
+ Choice "13/13 Columns" ""
+ Choice "14/14 Columns" ""
+ Choice "15/15 Columns" ""
+ Choice "16/16 Columns" ""
+ Choice "17/17 Columns" ""
+ Choice "18/18 Columns" ""
+ Choice "19/19 Columns" ""
+ Choice "20/20 Columns" ""
+ Attribute Custompage-right True ""
+ Attribute ParamCustompage-right Columns "1 int 1 99"
+
+ Option "page-top/Top Margin" PickOne AnySetup 10.0
+ Choice "0/0 Lines" ""
+ Choice "1/1 Line" ""
+ *Choice "2/2 Lines" ""
+ Choice "3/3 Lines" ""
+ Choice "4/4 Lines" ""
+ Choice "5/5 Lines" ""
+ Choice "6/6 Lines" ""
+ Choice "7/7 Lines" ""
+ Choice "8/8 Lines" ""
+ Choice "9/9 Lines" ""
+ Choice "10/10 Lines" ""
+ Choice "11/11 Lines" ""
+ Choice "12/12 Lines" ""
+ Choice "13/13 Lines" ""
+ Choice "14/14 Lines" ""
+ Choice "15/15 Lines" ""
+ Choice "16/16 Lines" ""
+ Choice "17/17 Lines" ""
+ Choice "18/18 Lines" ""
+ Choice "19/19 Lines" ""
+ Choice "20/20 Lines" ""
+ Attribute Custompage-top True ""
+ Attribute ParamCustompage-top Lines "1 int 1 99"
+
+ Option "page-bottom/Bottom Margin" PickOne AnySetup 10.0
+ Choice "0/0 Lines" ""
+ Choice "1/1 Line" ""
+ *Choice "2/2 Lines" ""
+ Choice "3/3 Lines" ""
+ Choice "4/4 Lines" ""
+ Choice "5/5 Lines" ""
+ Choice "6/6 Lines" ""
+ Choice "7/7 Lines" ""
+ Choice "8/8 Lines" ""
+ Choice "9/9 Lines" ""
+ Choice "10/10 Lines" ""
+ Choice "11/11 Lines" ""
+ Choice "12/12 Lines" ""
+ Choice "13/13 Lines" ""
+ Choice "14/14 Lines" ""
+ Choice "15/15 Lines" ""
+ Choice "16/16 Lines" ""
+ Choice "17/17 Lines" ""
+ Choice "18/18 Lines" ""
+ Choice "19/19 Lines" ""
+ Choice "20/20 Lines" ""
+ Attribute Custompage-bottom True ""
+ Attribute ParamCustompage-bottom Lines "1 int 1 99"
+
+ Group "InstallableOptions/Installable Options"
+
+ Option "PrinterEncoding/Printer's Character Encoding" PickOne AnySetup 10.0
+ *Choice "ASCII/Standard ASCII" ""
+ Choice "CP437/Code Page 437, PC-8, DOS Latin US (Original IBM)" ""
+ Choice "CP775/Code Page 775, PC-775, DOS Baltic Rim" ""
+ Choice "CP850/Code Page 850, PC-850, DOS Latin 1 (Western European)" ""
+ Choice "CP852/Code Page 852, PC-852, DOS Latin 2 (Central European)" ""
+ Choice "CP1004/Code Page 1004, IBM OS/2" ""
+ Choice "ROMAN8/HP Roman-8, (HP-UX European Latin)" ""
+ Choice "ROMAN9/HP Roman-9, (HP-UX European Latin)" ""
+ Choice "ISO-8859-1/ISO 8859-1, Latin 1 (Western European)" ""
+ Choice "ISO-8859-2/ISO 8859-2, Latin 2 (Eastern European)" ""
+ Choice "ISO-8859-3/ISO 8859-3, Latin 3 (South European)" ""
+ Choice "ISO-8859-4/ISO 8859-4, Latin 4 (North European)" ""
+ Choice "ISO-8859-5/ISO 8859-5, Latin/Cyrillic" ""
+ Choice "ISO-8859-6/ISO 8859-6, Latin/Arabic" ""
+ Choice "ISO-8859-7/ISO 8859-7, Latin/Greek" ""
+ Choice "ISO-8859-8/ISO 8859-8, Latin/Hebrew" ""
+ Choice "ISO-8859-9/ISO 8859-9, Latin 5 (Turkish)" ""
+ Choice "ISO-8859-10/ISO 8859-10, Latin 6 (Nordic)" ""
+ Choice "ISO-8859-13/ISO 8859-13, Latin 7 (Baltic)" ""
+ Choice "ISO-8859-14/ISO 8859-14, Latin 8 (Celtic)" ""
+ Choice "ISO-8859-15/ISO 8859-15, Latin 9 (Western European with Euro)" ""
+ Choice "ISO-8859-16/ISO 8859-16, Latin 10 (South-Eastern European)" ""
+ Choice "WINDOWS-1250/Windows 1250, Code Page 1250 (Central and East European Latin 2)" ""
+ Choice "WINDOWS-1251/Windows 1251, Code Page 1251 (Cyrillic)" ""
+ Choice "WINDOWS-1252/Windows 1252, Code Page 1252 (Western European Latin 1)" ""
+ Choice "WINDOWS-1253/Windows 1253, Code Page 1253 (Greek)" ""
+ Choice "WINDOWS-1254/Windows 1254, Code Page 1254 (Turkish)" ""
+ Choice "WINDOWS-1255/Windows 1255, Code Page 1255 (Hebrew)" ""
+ Choice "WINDOWS-1256/Windows 1256, Code Page 1256 (Arabic)" ""
+ Choice "WINDOWS-1257/Windows 1257, Code Page 1257 (Baltic)" ""
+ Choice "WINDOWS-1258/Windows 1258, Code Page 1258 (Vietnamese)" ""
+ Attribute CustomPrinterEncoding True ""
+ Attribute ParamCustomPrinterEncoding Encoding "1 string 1 32"
+
+ Option "NewlineCharacters/Characters to send for a New Line" PickOne AnySetup 10.0
+ Choice "LF/Line Feed (LF) only (Unix/Linux style)" ""
+ Choice "CR/Carriage Return (CR) only (Mac OS style)" ""
+ *Choice "CRLF/Carriage Return and Line Feed (CR + LF) (DOS/Windows style)" ""
+
+ Option "SendFF/Send Form Feed after each page" Boolean AnySetup 10.0
+ *Choice "True/Yes" ""
+ Choice "False/No" ""
+
+ Option "LetterAvailable/Page Size Letter available" Boolean AnySetup 10.0
+ *Choice "True/Yes" ""
+ Choice "False/No" ""
+
+ Option "LetterNumLines/Page Size Letter Number of Lines" PickOne AnySetup 10.0
+ Choice "1/1 Line" ""
+ Choice "2/2 Lines" ""
+ Choice "3/3 Lines" ""
+ Choice "4/4 Lines" ""
+ Choice "5/5 Lines" ""
+ Choice "6/6 Lines" ""
+ Choice "7/7 Lines" ""
+ Choice "8/8 Lines" ""
+ Choice "9/9 Lines" ""
+ Choice "10/10 Lines" ""
+ Choice "11/11 Lines" ""
+ Choice "12/12 Lines" ""
+ Choice "13/13 Lines" ""
+ Choice "14/14 Lines" ""
+ Choice "15/15 Lines" ""
+ Choice "16/16 Lines" ""
+ Choice "17/17 Lines" ""
+ Choice "18/18 Lines" ""
+ Choice "19/19 Lines" ""
+ Choice "20/20 Lines" ""
+ Choice "21/21 Lines" ""
+ Choice "22/22 Lines" ""
+ Choice "23/23 Lines" ""
+ Choice "24/24 Lines" ""
+ Choice "25/25 Lines" ""
+ Choice "26/26 Lines" ""
+ Choice "27/27 Lines" ""
+ Choice "28/28 Lines" ""
+ Choice "29/29 Lines" ""
+ Choice "30/30 Lines" ""
+ Choice "31/31 Lines" ""
+ Choice "32/32 Lines" ""
+ Choice "33/33 Lines" ""
+ Choice "34/34 Lines" ""
+ Choice "35/35 Lines" ""
+ Choice "36/36 Lines" ""
+ Choice "37/37 Lines" ""
+ Choice "38/38 Lines" ""
+ Choice "39/39 Lines" ""
+ Choice "40/40 Lines" ""
+ Choice "41/41 Lines" ""
+ Choice "42/42 Lines" ""
+ Choice "43/43 Lines" ""
+ Choice "44/44 Lines" ""
+ Choice "45/45 Lines" ""
+ Choice "46/46 Lines" ""
+ Choice "47/47 Lines" ""
+ Choice "48/48 Lines" ""
+ Choice "49/49 Lines" ""
+ Choice "50/50 Lines" ""
+ Choice "51/51 Lines" ""
+ Choice "52/52 Lines" ""
+ Choice "53/53 Lines" ""
+ Choice "54/54 Lines" ""
+ Choice "55/55 Lines" ""
+ Choice "56/56 Lines" ""
+ Choice "57/57 Lines" ""
+ Choice "58/58 Lines" ""
+ Choice "59/59 Lines" ""
+ Choice "60/60 Lines" ""
+ Choice "61/61 Lines" ""
+ Choice "62/62 Lines" ""
+ Choice "63/63 Lines" ""
+ Choice "64/64 Lines" ""
+ Choice "65/65 Lines" ""
+ *Choice "66/66 Lines" ""
+ Choice "67/67 Lines" ""
+ Choice "68/68 Lines" ""
+ Choice "69/69 Lines" ""
+ Choice "70/70 Lines" ""
+ Choice "71/71 Lines" ""
+ Choice "72/72 Lines" ""
+ Choice "73/73 Lines" ""
+ Choice "74/74 Lines" ""
+ Choice "75/75 Lines" ""
+ Choice "76/76 Lines" ""
+ Choice "77/77 Lines" ""
+ Choice "78/78 Lines" ""
+ Choice "79/79 Lines" ""
+ Choice "80/80 Lines" ""
+ Choice "81/81 Lines" ""
+ Choice "82/82 Lines" ""
+ Choice "83/83 Lines" ""
+ Choice "84/84 Lines" ""
+ Choice "85/85 Lines" ""
+ Choice "86/86 Lines" ""
+ Choice "87/87 Lines" ""
+ Choice "88/88 Lines" ""
+ Choice "89/89 Lines" ""
+ Choice "90/90 Lines" ""
+ Choice "91/91 Lines" ""
+ Choice "92/92 Lines" ""
+ Choice "93/93 Lines" ""
+ Choice "94/94 Lines" ""
+ Choice "95/95 Lines" ""
+ Choice "96/96 Lines" ""
+ Choice "97/97 Lines" ""
+ Choice "98/98 Lines" ""
+ Choice "99/99 Lines" ""
+ Choice "100/100 Lines" ""
+ Choice "101/101 Lines" ""
+ Choice "102/102 Lines" ""
+ Choice "103/103 Lines" ""
+ Choice "104/104 Lines" ""
+ Choice "105/105 Lines" ""
+ Choice "106/106 Lines" ""
+ Choice "107/107 Lines" ""
+ Choice "108/108 Lines" ""
+ Choice "109/109 Lines" ""
+ Choice "110/110 Lines" ""
+ Choice "111/111 Lines" ""
+ Choice "112/112 Lines" ""
+ Choice "113/113 Lines" ""
+ Choice "114/114 Lines" ""
+ Choice "115/115 Lines" ""
+ Choice "116/116 Lines" ""
+ Choice "117/117 Lines" ""
+ Choice "118/118 Lines" ""
+ Choice "119/119 Lines" ""
+ Choice "120/120 Lines" ""
+ Choice "121/121 Lines" ""
+ Choice "122/122 Lines" ""
+ Choice "123/123 Lines" ""
+ Choice "124/124 Lines" ""
+ Choice "125/125 Lines" ""
+ Choice "126/126 Lines" ""
+ Choice "127/127 Lines" ""
+ Choice "128/128 Lines" ""
+ Choice "129/129 Lines" ""
+ Choice "130/130 Lines" ""
+ Choice "131/131 Lines" ""
+ Choice "132/132 Lines" ""
+ Choice "133/133 Lines" ""
+ Choice "134/134 Lines" ""
+ Choice "135/135 Lines" ""
+ Choice "136/136 Lines" ""
+ Choice "137/137 Lines" ""
+ Choice "138/138 Lines" ""
+ Choice "139/139 Lines" ""
+ Choice "140/140 Lines" ""
+ Choice "141/141 Lines" ""
+ Choice "142/142 Lines" ""
+ Choice "143/143 Lines" ""
+ Choice "144/144 Lines" ""
+ Choice "145/145 Lines" ""
+ Choice "146/146 Lines" ""
+ Choice "147/147 Lines" ""
+ Choice "148/148 Lines" ""
+ Choice "149/149 Lines" ""
+ Choice "150/150 Lines" ""
+ Choice "151/151 Lines" ""
+ Choice "152/152 Lines" ""
+ Choice "153/153 Lines" ""
+ Choice "154/154 Lines" ""
+ Choice "155/155 Lines" ""
+ Choice "156/156 Lines" ""
+ Choice "157/157 Lines" ""
+ Choice "158/158 Lines" ""
+ Choice "159/159 Lines" ""
+ Choice "160/160 Lines" ""
+ Choice "161/161 Lines" ""
+ Choice "162/162 Lines" ""
+ Choice "163/163 Lines" ""
+ Choice "164/164 Lines" ""
+ Choice "165/165 Lines" ""
+ Choice "166/166 Lines" ""
+ Choice "167/167 Lines" ""
+ Choice "168/168 Lines" ""
+ Choice "169/169 Lines" ""
+ Choice "170/170 Lines" ""
+ Choice "171/171 Lines" ""
+ Choice "172/172 Lines" ""
+ Choice "173/173 Lines" ""
+ Choice "174/174 Lines" ""
+ Choice "175/175 Lines" ""
+ Choice "176/176 Lines" ""
+ Choice "177/177 Lines" ""
+ Choice "178/178 Lines" ""
+ Choice "179/179 Lines" ""
+ Choice "180/180 Lines" ""
+ Choice "181/181 Lines" ""
+ Choice "182/182 Lines" ""
+ Choice "183/183 Lines" ""
+ Choice "184/184 Lines" ""
+ Choice "185/185 Lines" ""
+ Choice "186/186 Lines" ""
+ Choice "187/187 Lines" ""
+ Choice "188/188 Lines" ""
+ Choice "189/189 Lines" ""
+ Choice "190/190 Lines" ""
+ Choice "191/191 Lines" ""
+ Choice "192/192 Lines" ""
+ Choice "193/193 Lines" ""
+ Choice "194/194 Lines" ""
+ Choice "195/195 Lines" ""
+ Choice "196/196 Lines" ""
+ Choice "197/197 Lines" ""
+ Choice "198/198 Lines" ""
+ Choice "199/199 Lines" ""
+ Choice "200/200 Lines" ""
+ Attribute CustomLetterNumLines True ""
+ Attribute ParamCustomLetterNumLines Lines "1 int 1 999"
+
+ Option "LetterNumColumns/Page Size Letter Number of Columns" PickOne AnySetup 10.0
+ Choice "1/1 Column" ""
+ Choice "2/2 Columns" ""
+ Choice "3/3 Columns" ""
+ Choice "4/4 Columns" ""
+ Choice "5/5 Columns" ""
+ Choice "6/6 Columns" ""
+ Choice "7/7 Columns" ""
+ Choice "8/8 Columns" ""
+ Choice "9/9 Columns" ""
+ Choice "10/10 Columns" ""
+ Choice "11/11 Columns" ""
+ Choice "12/12 Columns" ""
+ Choice "13/13 Columns" ""
+ Choice "14/14 Columns" ""
+ Choice "15/15 Columns" ""
+ Choice "16/16 Columns" ""
+ Choice "17/17 Columns" ""
+ Choice "18/18 Columns" ""
+ Choice "19/19 Columns" ""
+ Choice "20/20 Columns" ""
+ Choice "21/21 Columns" ""
+ Choice "22/22 Columns" ""
+ Choice "23/23 Columns" ""
+ Choice "24/24 Columns" ""
+ Choice "25/25 Columns" ""
+ Choice "26/26 Columns" ""
+ Choice "27/27 Columns" ""
+ Choice "28/28 Columns" ""
+ Choice "29/29 Columns" ""
+ Choice "30/30 Columns" ""
+ Choice "31/31 Columns" ""
+ Choice "32/32 Columns" ""
+ Choice "33/33 Columns" ""
+ Choice "34/34 Columns" ""
+ Choice "35/35 Columns" ""
+ Choice "36/36 Columns" ""
+ Choice "37/37 Columns" ""
+ Choice "38/38 Columns" ""
+ Choice "39/39 Columns" ""
+ Choice "40/40 Columns" ""
+ Choice "41/41 Columns" ""
+ Choice "42/42 Columns" ""
+ Choice "43/43 Columns" ""
+ Choice "44/44 Columns" ""
+ Choice "45/45 Columns" ""
+ Choice "46/46 Columns" ""
+ Choice "47/47 Columns" ""
+ Choice "48/48 Columns" ""
+ Choice "49/49 Columns" ""
+ Choice "50/50 Columns" ""
+ Choice "51/51 Columns" ""
+ Choice "52/52 Columns" ""
+ Choice "53/53 Columns" ""
+ Choice "54/54 Columns" ""
+ Choice "55/55 Columns" ""
+ Choice "56/56 Columns" ""
+ Choice "57/57 Columns" ""
+ Choice "58/58 Columns" ""
+ Choice "59/59 Columns" ""
+ Choice "60/60 Columns" ""
+ Choice "61/61 Columns" ""
+ Choice "62/62 Columns" ""
+ Choice "63/63 Columns" ""
+ Choice "64/64 Columns" ""
+ Choice "65/65 Columns" ""
+ Choice "66/66 Columns" ""
+ Choice "67/67 Columns" ""
+ Choice "68/68 Columns" ""
+ Choice "69/69 Columns" ""
+ Choice "70/70 Columns" ""
+ Choice "71/71 Columns" ""
+ Choice "72/72 Columns" ""
+ Choice "73/73 Columns" ""
+ Choice "74/74 Columns" ""
+ Choice "75/75 Columns" ""
+ Choice "76/76 Columns" ""
+ Choice "77/77 Columns" ""
+ Choice "78/78 Columns" ""
+ Choice "79/79 Columns" ""
+ *Choice "80/80 Columns" ""
+ Choice "81/81 Columns" ""
+ Choice "82/82 Columns" ""
+ Choice "83/83 Columns" ""
+ Choice "84/84 Columns" ""
+ Choice "85/85 Columns" ""
+ Choice "86/86 Columns" ""
+ Choice "87/87 Columns" ""
+ Choice "88/88 Columns" ""
+ Choice "89/89 Columns" ""
+ Choice "90/90 Columns" ""
+ Choice "91/91 Columns" ""
+ Choice "92/92 Columns" ""
+ Choice "93/93 Columns" ""
+ Choice "94/94 Columns" ""
+ Choice "95/95 Columns" ""
+ Choice "96/96 Columns" ""
+ Choice "97/97 Columns" ""
+ Choice "98/98 Columns" ""
+ Choice "99/99 Columns" ""
+ Choice "100/100 Columns" ""
+ Choice "101/101 Columns" ""
+ Choice "102/102 Columns" ""
+ Choice "103/103 Columns" ""
+ Choice "104/104 Columns" ""
+ Choice "105/105 Columns" ""
+ Choice "106/106 Columns" ""
+ Choice "107/107 Columns" ""
+ Choice "108/108 Columns" ""
+ Choice "109/109 Columns" ""
+ Choice "110/110 Columns" ""
+ Choice "111/111 Columns" ""
+ Choice "112/112 Columns" ""
+ Choice "113/113 Columns" ""
+ Choice "114/114 Columns" ""
+ Choice "115/115 Columns" ""
+ Choice "116/116 Columns" ""
+ Choice "117/117 Columns" ""
+ Choice "118/118 Columns" ""
+ Choice "119/119 Columns" ""
+ Choice "120/120 Columns" ""
+ Choice "121/121 Columns" ""
+ Choice "122/122 Columns" ""
+ Choice "123/123 Columns" ""
+ Choice "124/124 Columns" ""
+ Choice "125/125 Columns" ""
+ Choice "126/126 Columns" ""
+ Choice "127/127 Columns" ""
+ Choice "128/128 Columns" ""
+ Choice "129/129 Columns" ""
+ Choice "130/130 Columns" ""
+ Choice "131/131 Columns" ""
+ Choice "132/132 Columns" ""
+ Choice "133/133 Columns" ""
+ Choice "134/134 Columns" ""
+ Choice "135/135 Columns" ""
+ Choice "136/136 Columns" ""
+ Choice "137/137 Columns" ""
+ Choice "138/138 Columns" ""
+ Choice "139/139 Columns" ""
+ Choice "140/140 Columns" ""
+ Choice "141/141 Columns" ""
+ Choice "142/142 Columns" ""
+ Choice "143/143 Columns" ""
+ Choice "144/144 Columns" ""
+ Choice "145/145 Columns" ""
+ Choice "146/146 Columns" ""
+ Choice "147/147 Columns" ""
+ Choice "148/148 Columns" ""
+ Choice "149/149 Columns" ""
+ Choice "150/150 Columns" ""
+ Choice "151/151 Columns" ""
+ Choice "152/152 Columns" ""
+ Choice "153/153 Columns" ""
+ Choice "154/154 Columns" ""
+ Choice "155/155 Columns" ""
+ Choice "156/156 Columns" ""
+ Choice "157/157 Columns" ""
+ Choice "158/158 Columns" ""
+ Choice "159/159 Columns" ""
+ Choice "160/160 Columns" ""
+ Choice "161/161 Columns" ""
+ Choice "162/162 Columns" ""
+ Choice "163/163 Columns" ""
+ Choice "164/164 Columns" ""
+ Choice "165/165 Columns" ""
+ Choice "166/166 Columns" ""
+ Choice "167/167 Columns" ""
+ Choice "168/168 Columns" ""
+ Choice "169/169 Columns" ""
+ Choice "170/170 Columns" ""
+ Choice "171/171 Columns" ""
+ Choice "172/172 Columns" ""
+ Choice "173/173 Columns" ""
+ Choice "174/174 Columns" ""
+ Choice "175/175 Columns" ""
+ Choice "176/176 Columns" ""
+ Choice "177/177 Columns" ""
+ Choice "178/178 Columns" ""
+ Choice "179/179 Columns" ""
+ Choice "180/180 Columns" ""
+ Choice "181/181 Columns" ""
+ Choice "182/182 Columns" ""
+ Choice "183/183 Columns" ""
+ Choice "184/184 Columns" ""
+ Choice "185/185 Columns" ""
+ Choice "186/186 Columns" ""
+ Choice "187/187 Columns" ""
+ Choice "188/188 Columns" ""
+ Choice "189/189 Columns" ""
+ Choice "190/190 Columns" ""
+ Choice "191/191 Columns" ""
+ Choice "192/192 Columns" ""
+ Choice "193/193 Columns" ""
+ Choice "194/194 Columns" ""
+ Choice "195/195 Columns" ""
+ Choice "196/196 Columns" ""
+ Choice "197/197 Columns" ""
+ Choice "198/198 Columns" ""
+ Choice "199/199 Columns" ""
+ Choice "200/200 Columns" ""
+ Attribute CustomLetterNumColumns True ""
+ Attribute ParamCustomLetterNumColumns Columns "1 int 1 999"
+
+
+ Option "LegalAvailable/Page Size Legal available" Boolean AnySetup 10.0
+ *Choice "True/Yes" ""
+ Choice "False/No" ""
+
+ Option "LegalNumLines/Page Size Legal Number of Lines" PickOne AnySetup 10.0
+ Choice "1/1 Line" ""
+ Choice "2/2 Lines" ""
+ Choice "3/3 Lines" ""
+ Choice "4/4 Lines" ""
+ Choice "5/5 Lines" ""
+ Choice "6/6 Lines" ""
+ Choice "7/7 Lines" ""
+ Choice "8/8 Lines" ""
+ Choice "9/9 Lines" ""
+ Choice "10/10 Lines" ""
+ Choice "11/11 Lines" ""
+ Choice "12/12 Lines" ""
+ Choice "13/13 Lines" ""
+ Choice "14/14 Lines" ""
+ Choice "15/15 Lines" ""
+ Choice "16/16 Lines" ""
+ Choice "17/17 Lines" ""
+ Choice "18/18 Lines" ""
+ Choice "19/19 Lines" ""
+ Choice "20/20 Lines" ""
+ Choice "21/21 Lines" ""
+ Choice "22/22 Lines" ""
+ Choice "23/23 Lines" ""
+ Choice "24/24 Lines" ""
+ Choice "25/25 Lines" ""
+ Choice "26/26 Lines" ""
+ Choice "27/27 Lines" ""
+ Choice "28/28 Lines" ""
+ Choice "29/29 Lines" ""
+ Choice "30/30 Lines" ""
+ Choice "31/31 Lines" ""
+ Choice "32/32 Lines" ""
+ Choice "33/33 Lines" ""
+ Choice "34/34 Lines" ""
+ Choice "35/35 Lines" ""
+ Choice "36/36 Lines" ""
+ Choice "37/37 Lines" ""
+ Choice "38/38 Lines" ""
+ Choice "39/39 Lines" ""
+ Choice "40/40 Lines" ""
+ Choice "41/41 Lines" ""
+ Choice "42/42 Lines" ""
+ Choice "43/43 Lines" ""
+ Choice "44/44 Lines" ""
+ Choice "45/45 Lines" ""
+ Choice "46/46 Lines" ""
+ Choice "47/47 Lines" ""
+ Choice "48/48 Lines" ""
+ Choice "49/49 Lines" ""
+ Choice "50/50 Lines" ""
+ Choice "51/51 Lines" ""
+ Choice "52/52 Lines" ""
+ Choice "53/53 Lines" ""
+ Choice "54/54 Lines" ""
+ Choice "55/55 Lines" ""
+ Choice "56/56 Lines" ""
+ Choice "57/57 Lines" ""
+ Choice "58/58 Lines" ""
+ Choice "59/59 Lines" ""
+ Choice "60/60 Lines" ""
+ Choice "61/61 Lines" ""
+ Choice "62/62 Lines" ""
+ Choice "63/63 Lines" ""
+ Choice "64/64 Lines" ""
+ Choice "65/65 Lines" ""
+ Choice "66/66 Lines" ""
+ Choice "67/67 Lines" ""
+ Choice "68/68 Lines" ""
+ Choice "69/69 Lines" ""
+ Choice "70/70 Lines" ""
+ Choice "71/71 Lines" ""
+ Choice "72/72 Lines" ""
+ Choice "73/73 Lines" ""
+ Choice "74/74 Lines" ""
+ Choice "75/75 Lines" ""
+ Choice "76/76 Lines" ""
+ Choice "77/77 Lines" ""
+ Choice "78/78 Lines" ""
+ Choice "79/79 Lines" ""
+ Choice "80/80 Lines" ""
+ Choice "81/81 Lines" ""
+ Choice "82/82 Lines" ""
+ Choice "83/83 Lines" ""
+ *Choice "84/84 Lines" ""
+ Choice "85/85 Lines" ""
+ Choice "86/86 Lines" ""
+ Choice "87/87 Lines" ""
+ Choice "88/88 Lines" ""
+ Choice "89/89 Lines" ""
+ Choice "90/90 Lines" ""
+ Choice "91/91 Lines" ""
+ Choice "92/92 Lines" ""
+ Choice "93/93 Lines" ""
+ Choice "94/94 Lines" ""
+ Choice "95/95 Lines" ""
+ Choice "96/96 Lines" ""
+ Choice "97/97 Lines" ""
+ Choice "98/98 Lines" ""
+ Choice "99/99 Lines" ""
+ Choice "100/100 Lines" ""
+ Choice "101/101 Lines" ""
+ Choice "102/102 Lines" ""
+ Choice "103/103 Lines" ""
+ Choice "104/104 Lines" ""
+ Choice "105/105 Lines" ""
+ Choice "106/106 Lines" ""
+ Choice "107/107 Lines" ""
+ Choice "108/108 Lines" ""
+ Choice "109/109 Lines" ""
+ Choice "110/110 Lines" ""
+ Choice "111/111 Lines" ""
+ Choice "112/112 Lines" ""
+ Choice "113/113 Lines" ""
+ Choice "114/114 Lines" ""
+ Choice "115/115 Lines" ""
+ Choice "116/116 Lines" ""
+ Choice "117/117 Lines" ""
+ Choice "118/118 Lines" ""
+ Choice "119/119 Lines" ""
+ Choice "120/120 Lines" ""
+ Choice "121/121 Lines" ""
+ Choice "122/122 Lines" ""
+ Choice "123/123 Lines" ""
+ Choice "124/124 Lines" ""
+ Choice "125/125 Lines" ""
+ Choice "126/126 Lines" ""
+ Choice "127/127 Lines" ""
+ Choice "128/128 Lines" ""
+ Choice "129/129 Lines" ""
+ Choice "130/130 Lines" ""
+ Choice "131/131 Lines" ""
+ Choice "132/132 Lines" ""
+ Choice "133/133 Lines" ""
+ Choice "134/134 Lines" ""
+ Choice "135/135 Lines" ""
+ Choice "136/136 Lines" ""
+ Choice "137/137 Lines" ""
+ Choice "138/138 Lines" ""
+ Choice "139/139 Lines" ""
+ Choice "140/140 Lines" ""
+ Choice "141/141 Lines" ""
+ Choice "142/142 Lines" ""
+ Choice "143/143 Lines" ""
+ Choice "144/144 Lines" ""
+ Choice "145/145 Lines" ""
+ Choice "146/146 Lines" ""
+ Choice "147/147 Lines" ""
+ Choice "148/148 Lines" ""
+ Choice "149/149 Lines" ""
+ Choice "150/150 Lines" ""
+ Choice "151/151 Lines" ""
+ Choice "152/152 Lines" ""
+ Choice "153/153 Lines" ""
+ Choice "154/154 Lines" ""
+ Choice "155/155 Lines" ""
+ Choice "156/156 Lines" ""
+ Choice "157/157 Lines" ""
+ Choice "158/158 Lines" ""
+ Choice "159/159 Lines" ""
+ Choice "160/160 Lines" ""
+ Choice "161/161 Lines" ""
+ Choice "162/162 Lines" ""
+ Choice "163/163 Lines" ""
+ Choice "164/164 Lines" ""
+ Choice "165/165 Lines" ""
+ Choice "166/166 Lines" ""
+ Choice "167/167 Lines" ""
+ Choice "168/168 Lines" ""
+ Choice "169/169 Lines" ""
+ Choice "170/170 Lines" ""
+ Choice "171/171 Lines" ""
+ Choice "172/172 Lines" ""
+ Choice "173/173 Lines" ""
+ Choice "174/174 Lines" ""
+ Choice "175/175 Lines" ""
+ Choice "176/176 Lines" ""
+ Choice "177/177 Lines" ""
+ Choice "178/178 Lines" ""
+ Choice "179/179 Lines" ""
+ Choice "180/180 Lines" ""
+ Choice "181/181 Lines" ""
+ Choice "182/182 Lines" ""
+ Choice "183/183 Lines" ""
+ Choice "184/184 Lines" ""
+ Choice "185/185 Lines" ""
+ Choice "186/186 Lines" ""
+ Choice "187/187 Lines" ""
+ Choice "188/188 Lines" ""
+ Choice "189/189 Lines" ""
+ Choice "190/190 Lines" ""
+ Choice "191/191 Lines" ""
+ Choice "192/192 Lines" ""
+ Choice "193/193 Lines" ""
+ Choice "194/194 Lines" ""
+ Choice "195/195 Lines" ""
+ Choice "196/196 Lines" ""
+ Choice "197/197 Lines" ""
+ Choice "198/198 Lines" ""
+ Choice "199/199 Lines" ""
+ Choice "200/200 Lines" ""
+ Attribute CustomLegalNumLines True ""
+ Attribute ParamCustomLegalNumLines Lines "1 int 1 999"
+
+ Option "LegalNumColumns/Page Size Legal Number of Columns" PickOne AnySetup 10.0
+ Choice "1/1 Column" ""
+ Choice "2/2 Columns" ""
+ Choice "3/3 Columns" ""
+ Choice "4/4 Columns" ""
+ Choice "5/5 Columns" ""
+ Choice "6/6 Columns" ""
+ Choice "7/7 Columns" ""
+ Choice "8/8 Columns" ""
+ Choice "9/9 Columns" ""
+ Choice "10/10 Columns" ""
+ Choice "11/11 Columns" ""
+ Choice "12/12 Columns" ""
+ Choice "13/13 Columns" ""
+ Choice "14/14 Columns" ""
+ Choice "15/15 Columns" ""
+ Choice "16/16 Columns" ""
+ Choice "17/17 Columns" ""
+ Choice "18/18 Columns" ""
+ Choice "19/19 Columns" ""
+ Choice "20/20 Columns" ""
+ Choice "21/21 Columns" ""
+ Choice "22/22 Columns" ""
+ Choice "23/23 Columns" ""
+ Choice "24/24 Columns" ""
+ Choice "25/25 Columns" ""
+ Choice "26/26 Columns" ""
+ Choice "27/27 Columns" ""
+ Choice "28/28 Columns" ""
+ Choice "29/29 Columns" ""
+ Choice "30/30 Columns" ""
+ Choice "31/31 Columns" ""
+ Choice "32/32 Columns" ""
+ Choice "33/33 Columns" ""
+ Choice "34/34 Columns" ""
+ Choice "35/35 Columns" ""
+ Choice "36/36 Columns" ""
+ Choice "37/37 Columns" ""
+ Choice "38/38 Columns" ""
+ Choice "39/39 Columns" ""
+ Choice "40/40 Columns" ""
+ Choice "41/41 Columns" ""
+ Choice "42/42 Columns" ""
+ Choice "43/43 Columns" ""
+ Choice "44/44 Columns" ""
+ Choice "45/45 Columns" ""
+ Choice "46/46 Columns" ""
+ Choice "47/47 Columns" ""
+ Choice "48/48 Columns" ""
+ Choice "49/49 Columns" ""
+ Choice "50/50 Columns" ""
+ Choice "51/51 Columns" ""
+ Choice "52/52 Columns" ""
+ Choice "53/53 Columns" ""
+ Choice "54/54 Columns" ""
+ Choice "55/55 Columns" ""
+ Choice "56/56 Columns" ""
+ Choice "57/57 Columns" ""
+ Choice "58/58 Columns" ""
+ Choice "59/59 Columns" ""
+ Choice "60/60 Columns" ""
+ Choice "61/61 Columns" ""
+ Choice "62/62 Columns" ""
+ Choice "63/63 Columns" ""
+ Choice "64/64 Columns" ""
+ Choice "65/65 Columns" ""
+ Choice "66/66 Columns" ""
+ Choice "67/67 Columns" ""
+ Choice "68/68 Columns" ""
+ Choice "69/69 Columns" ""
+ Choice "70/70 Columns" ""
+ Choice "71/71 Columns" ""
+ Choice "72/72 Columns" ""
+ Choice "73/73 Columns" ""
+ Choice "74/74 Columns" ""
+ Choice "75/75 Columns" ""
+ Choice "76/76 Columns" ""
+ Choice "77/77 Columns" ""
+ Choice "78/78 Columns" ""
+ Choice "79/79 Columns" ""
+ *Choice "80/80 Columns" ""
+ Choice "81/81 Columns" ""
+ Choice "82/82 Columns" ""
+ Choice "83/83 Columns" ""
+ Choice "84/84 Columns" ""
+ Choice "85/85 Columns" ""
+ Choice "86/86 Columns" ""
+ Choice "87/87 Columns" ""
+ Choice "88/88 Columns" ""
+ Choice "89/89 Columns" ""
+ Choice "90/90 Columns" ""
+ Choice "91/91 Columns" ""
+ Choice "92/92 Columns" ""
+ Choice "93/93 Columns" ""
+ Choice "94/94 Columns" ""
+ Choice "95/95 Columns" ""
+ Choice "96/96 Columns" ""
+ Choice "97/97 Columns" ""
+ Choice "98/98 Columns" ""
+ Choice "99/99 Columns" ""
+ Choice "100/100 Columns" ""
+ Choice "101/101 Columns" ""
+ Choice "102/102 Columns" ""
+ Choice "103/103 Columns" ""
+ Choice "104/104 Columns" ""
+ Choice "105/105 Columns" ""
+ Choice "106/106 Columns" ""
+ Choice "107/107 Columns" ""
+ Choice "108/108 Columns" ""
+ Choice "109/109 Columns" ""
+ Choice "110/110 Columns" ""
+ Choice "111/111 Columns" ""
+ Choice "112/112 Columns" ""
+ Choice "113/113 Columns" ""
+ Choice "114/114 Columns" ""
+ Choice "115/115 Columns" ""
+ Choice "116/116 Columns" ""
+ Choice "117/117 Columns" ""
+ Choice "118/118 Columns" ""
+ Choice "119/119 Columns" ""
+ Choice "120/120 Columns" ""
+ Choice "121/121 Columns" ""
+ Choice "122/122 Columns" ""
+ Choice "123/123 Columns" ""
+ Choice "124/124 Columns" ""
+ Choice "125/125 Columns" ""
+ Choice "126/126 Columns" ""
+ Choice "127/127 Columns" ""
+ Choice "128/128 Columns" ""
+ Choice "129/129 Columns" ""
+ Choice "130/130 Columns" ""
+ Choice "131/131 Columns" ""
+ Choice "132/132 Columns" ""
+ Choice "133/133 Columns" ""
+ Choice "134/134 Columns" ""
+ Choice "135/135 Columns" ""
+ Choice "136/136 Columns" ""
+ Choice "137/137 Columns" ""
+ Choice "138/138 Columns" ""
+ Choice "139/139 Columns" ""
+ Choice "140/140 Columns" ""
+ Choice "141/141 Columns" ""
+ Choice "142/142 Columns" ""
+ Choice "143/143 Columns" ""
+ Choice "144/144 Columns" ""
+ Choice "145/145 Columns" ""
+ Choice "146/146 Columns" ""
+ Choice "147/147 Columns" ""
+ Choice "148/148 Columns" ""
+ Choice "149/149 Columns" ""
+ Choice "150/150 Columns" ""
+ Choice "151/151 Columns" ""
+ Choice "152/152 Columns" ""
+ Choice "153/153 Columns" ""
+ Choice "154/154 Columns" ""
+ Choice "155/155 Columns" ""
+ Choice "156/156 Columns" ""
+ Choice "157/157 Columns" ""
+ Choice "158/158 Columns" ""
+ Choice "159/159 Columns" ""
+ Choice "160/160 Columns" ""
+ Choice "161/161 Columns" ""
+ Choice "162/162 Columns" ""
+ Choice "163/163 Columns" ""
+ Choice "164/164 Columns" ""
+ Choice "165/165 Columns" ""
+ Choice "166/166 Columns" ""
+ Choice "167/167 Columns" ""
+ Choice "168/168 Columns" ""
+ Choice "169/169 Columns" ""
+ Choice "170/170 Columns" ""
+ Choice "171/171 Columns" ""
+ Choice "172/172 Columns" ""
+ Choice "173/173 Columns" ""
+ Choice "174/174 Columns" ""
+ Choice "175/175 Columns" ""
+ Choice "176/176 Columns" ""
+ Choice "177/177 Columns" ""
+ Choice "178/178 Columns" ""
+ Choice "179/179 Columns" ""
+ Choice "180/180 Columns" ""
+ Choice "181/181 Columns" ""
+ Choice "182/182 Columns" ""
+ Choice "183/183 Columns" ""
+ Choice "184/184 Columns" ""
+ Choice "185/185 Columns" ""
+ Choice "186/186 Columns" ""
+ Choice "187/187 Columns" ""
+ Choice "188/188 Columns" ""
+ Choice "189/189 Columns" ""
+ Choice "190/190 Columns" ""
+ Choice "191/191 Columns" ""
+ Choice "192/192 Columns" ""
+ Choice "193/193 Columns" ""
+ Choice "194/194 Columns" ""
+ Choice "195/195 Columns" ""
+ Choice "196/196 Columns" ""
+ Choice "197/197 Columns" ""
+ Choice "198/198 Columns" ""
+ Choice "199/199 Columns" ""
+ Choice "200/200 Columns" ""
+ Attribute CustomLegalNumColumns True ""
+ Attribute ParamCustomLegalNumColumns Columns "1 int 1 999"
+
+
+ Option "TabloidAvailable/Page Size Tabloid available" Boolean AnySetup 10.0
+ *Choice "True/Yes" ""
+ Choice "False/No" ""
+
+ Option "TabloidNumLines/Page Size Tabloid Number of Lines" PickOne AnySetup 10.0
+ Choice "1/1 Line" ""
+ Choice "2/2 Lines" ""
+ Choice "3/3 Lines" ""
+ Choice "4/4 Lines" ""
+ Choice "5/5 Lines" ""
+ Choice "6/6 Lines" ""
+ Choice "7/7 Lines" ""
+ Choice "8/8 Lines" ""
+ Choice "9/9 Lines" ""
+ Choice "10/10 Lines" ""
+ Choice "11/11 Lines" ""
+ Choice "12/12 Lines" ""
+ Choice "13/13 Lines" ""
+ Choice "14/14 Lines" ""
+ Choice "15/15 Lines" ""
+ Choice "16/16 Lines" ""
+ Choice "17/17 Lines" ""
+ Choice "18/18 Lines" ""
+ Choice "19/19 Lines" ""
+ Choice "20/20 Lines" ""
+ Choice "21/21 Lines" ""
+ Choice "22/22 Lines" ""
+ Choice "23/23 Lines" ""
+ Choice "24/24 Lines" ""
+ Choice "25/25 Lines" ""
+ Choice "26/26 Lines" ""
+ Choice "27/27 Lines" ""
+ Choice "28/28 Lines" ""
+ Choice "29/29 Lines" ""
+ Choice "30/30 Lines" ""
+ Choice "31/31 Lines" ""
+ Choice "32/32 Lines" ""
+ Choice "33/33 Lines" ""
+ Choice "34/34 Lines" ""
+ Choice "35/35 Lines" ""
+ Choice "36/36 Lines" ""
+ Choice "37/37 Lines" ""
+ Choice "38/38 Lines" ""
+ Choice "39/39 Lines" ""
+ Choice "40/40 Lines" ""
+ Choice "41/41 Lines" ""
+ Choice "42/42 Lines" ""
+ Choice "43/43 Lines" ""
+ Choice "44/44 Lines" ""
+ Choice "45/45 Lines" ""
+ Choice "46/46 Lines" ""
+ Choice "47/47 Lines" ""
+ Choice "48/48 Lines" ""
+ Choice "49/49 Lines" ""
+ Choice "50/50 Lines" ""
+ Choice "51/51 Lines" ""
+ Choice "52/52 Lines" ""
+ Choice "53/53 Lines" ""
+ Choice "54/54 Lines" ""
+ Choice "55/55 Lines" ""
+ Choice "56/56 Lines" ""
+ Choice "57/57 Lines" ""
+ Choice "58/58 Lines" ""
+ Choice "59/59 Lines" ""
+ Choice "60/60 Lines" ""
+ Choice "61/61 Lines" ""
+ Choice "62/62 Lines" ""
+ Choice "63/63 Lines" ""
+ Choice "64/64 Lines" ""
+ Choice "65/65 Lines" ""
+ *Choice "66/66 Lines" ""
+ Choice "67/67 Lines" ""
+ Choice "68/68 Lines" ""
+ Choice "69/69 Lines" ""
+ Choice "70/70 Lines" ""
+ Choice "71/71 Lines" ""
+ Choice "72/72 Lines" ""
+ Choice "73/73 Lines" ""
+ Choice "74/74 Lines" ""
+ Choice "75/75 Lines" ""
+ Choice "76/76 Lines" ""
+ Choice "77/77 Lines" ""
+ Choice "78/78 Lines" ""
+ Choice "79/79 Lines" ""
+ Choice "80/80 Lines" ""
+ Choice "81/81 Lines" ""
+ Choice "82/82 Lines" ""
+ Choice "83/83 Lines" ""
+ Choice "84/84 Lines" ""
+ Choice "85/85 Lines" ""
+ Choice "86/86 Lines" ""
+ Choice "87/87 Lines" ""
+ Choice "88/88 Lines" ""
+ Choice "89/89 Lines" ""
+ Choice "90/90 Lines" ""
+ Choice "91/91 Lines" ""
+ Choice "92/92 Lines" ""
+ Choice "93/93 Lines" ""
+ Choice "94/94 Lines" ""
+ Choice "95/95 Lines" ""
+ Choice "96/96 Lines" ""
+ Choice "97/97 Lines" ""
+ Choice "98/98 Lines" ""
+ Choice "99/99 Lines" ""
+ Choice "100/100 Lines" ""
+ Choice "101/101 Lines" ""
+ Choice "102/102 Lines" ""
+ Choice "103/103 Lines" ""
+ Choice "104/104 Lines" ""
+ Choice "105/105 Lines" ""
+ Choice "106/106 Lines" ""
+ Choice "107/107 Lines" ""
+ Choice "108/108 Lines" ""
+ Choice "109/109 Lines" ""
+ Choice "110/110 Lines" ""
+ Choice "111/111 Lines" ""
+ Choice "112/112 Lines" ""
+ Choice "113/113 Lines" ""
+ Choice "114/114 Lines" ""
+ Choice "115/115 Lines" ""
+ Choice "116/116 Lines" ""
+ Choice "117/117 Lines" ""
+ Choice "118/118 Lines" ""
+ Choice "119/119 Lines" ""
+ Choice "120/120 Lines" ""
+ Choice "121/121 Lines" ""
+ Choice "122/122 Lines" ""
+ Choice "123/123 Lines" ""
+ Choice "124/124 Lines" ""
+ Choice "125/125 Lines" ""
+ Choice "126/126 Lines" ""
+ Choice "127/127 Lines" ""
+ Choice "128/128 Lines" ""
+ Choice "129/129 Lines" ""
+ Choice "130/130 Lines" ""
+ Choice "131/131 Lines" ""
+ Choice "132/132 Lines" ""
+ Choice "133/133 Lines" ""
+ Choice "134/134 Lines" ""
+ Choice "135/135 Lines" ""
+ Choice "136/136 Lines" ""
+ Choice "137/137 Lines" ""
+ Choice "138/138 Lines" ""
+ Choice "139/139 Lines" ""
+ Choice "140/140 Lines" ""
+ Choice "141/141 Lines" ""
+ Choice "142/142 Lines" ""
+ Choice "143/143 Lines" ""
+ Choice "144/144 Lines" ""
+ Choice "145/145 Lines" ""
+ Choice "146/146 Lines" ""
+ Choice "147/147 Lines" ""
+ Choice "148/148 Lines" ""
+ Choice "149/149 Lines" ""
+ Choice "150/150 Lines" ""
+ Choice "151/151 Lines" ""
+ Choice "152/152 Lines" ""
+ Choice "153/153 Lines" ""
+ Choice "154/154 Lines" ""
+ Choice "155/155 Lines" ""
+ Choice "156/156 Lines" ""
+ Choice "157/157 Lines" ""
+ Choice "158/158 Lines" ""
+ Choice "159/159 Lines" ""
+ Choice "160/160 Lines" ""
+ Choice "161/161 Lines" ""
+ Choice "162/162 Lines" ""
+ Choice "163/163 Lines" ""
+ Choice "164/164 Lines" ""
+ Choice "165/165 Lines" ""
+ Choice "166/166 Lines" ""
+ Choice "167/167 Lines" ""
+ Choice "168/168 Lines" ""
+ Choice "169/169 Lines" ""
+ Choice "170/170 Lines" ""
+ Choice "171/171 Lines" ""
+ Choice "172/172 Lines" ""
+ Choice "173/173 Lines" ""
+ Choice "174/174 Lines" ""
+ Choice "175/175 Lines" ""
+ Choice "176/176 Lines" ""
+ Choice "177/177 Lines" ""
+ Choice "178/178 Lines" ""
+ Choice "179/179 Lines" ""
+ Choice "180/180 Lines" ""
+ Choice "181/181 Lines" ""
+ Choice "182/182 Lines" ""
+ Choice "183/183 Lines" ""
+ Choice "184/184 Lines" ""
+ Choice "185/185 Lines" ""
+ Choice "186/186 Lines" ""
+ Choice "187/187 Lines" ""
+ Choice "188/188 Lines" ""
+ Choice "189/189 Lines" ""
+ Choice "190/190 Lines" ""
+ Choice "191/191 Lines" ""
+ Choice "192/192 Lines" ""
+ Choice "193/193 Lines" ""
+ Choice "194/194 Lines" ""
+ Choice "195/195 Lines" ""
+ Choice "196/196 Lines" ""
+ Choice "197/197 Lines" ""
+ Choice "198/198 Lines" ""
+ Choice "199/199 Lines" ""
+ Choice "200/200 Lines" ""
+ Attribute CustomTabloidNumLines True ""
+ Attribute ParamCustomTabloidNumLines Lines "1 int 1 999"
+
+ Option "TabloidNumColumns/Page Size Tabloid Number of Columns" PickOne AnySetup 10.0
+ Choice "1/1 Column" ""
+ Choice "2/2 Columns" ""
+ Choice "3/3 Columns" ""
+ Choice "4/4 Columns" ""
+ Choice "5/5 Columns" ""
+ Choice "6/6 Columns" ""
+ Choice "7/7 Columns" ""
+ Choice "8/8 Columns" ""
+ Choice "9/9 Columns" ""
+ Choice "10/10 Columns" ""
+ Choice "11/11 Columns" ""
+ Choice "12/12 Columns" ""
+ Choice "13/13 Columns" ""
+ Choice "14/14 Columns" ""
+ Choice "15/15 Columns" ""
+ Choice "16/16 Columns" ""
+ Choice "17/17 Columns" ""
+ Choice "18/18 Columns" ""
+ Choice "19/19 Columns" ""
+ Choice "20/20 Columns" ""
+ Choice "21/21 Columns" ""
+ Choice "22/22 Columns" ""
+ Choice "23/23 Columns" ""
+ Choice "24/24 Columns" ""
+ Choice "25/25 Columns" ""
+ Choice "26/26 Columns" ""
+ Choice "27/27 Columns" ""
+ Choice "28/28 Columns" ""
+ Choice "29/29 Columns" ""
+ Choice "30/30 Columns" ""
+ Choice "31/31 Columns" ""
+ Choice "32/32 Columns" ""
+ Choice "33/33 Columns" ""
+ Choice "34/34 Columns" ""
+ Choice "35/35 Columns" ""
+ Choice "36/36 Columns" ""
+ Choice "37/37 Columns" ""
+ Choice "38/38 Columns" ""
+ Choice "39/39 Columns" ""
+ Choice "40/40 Columns" ""
+ Choice "41/41 Columns" ""
+ Choice "42/42 Columns" ""
+ Choice "43/43 Columns" ""
+ Choice "44/44 Columns" ""
+ Choice "45/45 Columns" ""
+ Choice "46/46 Columns" ""
+ Choice "47/47 Columns" ""
+ Choice "48/48 Columns" ""
+ Choice "49/49 Columns" ""
+ Choice "50/50 Columns" ""
+ Choice "51/51 Columns" ""
+ Choice "52/52 Columns" ""
+ Choice "53/53 Columns" ""
+ Choice "54/54 Columns" ""
+ Choice "55/55 Columns" ""
+ Choice "56/56 Columns" ""
+ Choice "57/57 Columns" ""
+ Choice "58/58 Columns" ""
+ Choice "59/59 Columns" ""
+ Choice "60/60 Columns" ""
+ Choice "61/61 Columns" ""
+ Choice "62/62 Columns" ""
+ Choice "63/63 Columns" ""
+ Choice "64/64 Columns" ""
+ Choice "65/65 Columns" ""
+ Choice "66/66 Columns" ""
+ Choice "67/67 Columns" ""
+ Choice "68/68 Columns" ""
+ Choice "69/69 Columns" ""
+ Choice "70/70 Columns" ""
+ Choice "71/71 Columns" ""
+ Choice "72/72 Columns" ""
+ Choice "73/73 Columns" ""
+ Choice "74/74 Columns" ""
+ Choice "75/75 Columns" ""
+ Choice "76/76 Columns" ""
+ Choice "77/77 Columns" ""
+ Choice "78/78 Columns" ""
+ Choice "79/79 Columns" ""
+ Choice "80/80 Columns" ""
+ Choice "81/81 Columns" ""
+ Choice "82/82 Columns" ""
+ Choice "83/83 Columns" ""
+ Choice "84/84 Columns" ""
+ Choice "85/85 Columns" ""
+ Choice "86/86 Columns" ""
+ Choice "87/87 Columns" ""
+ Choice "88/88 Columns" ""
+ Choice "89/89 Columns" ""
+ Choice "90/90 Columns" ""
+ Choice "91/91 Columns" ""
+ Choice "92/92 Columns" ""
+ Choice "93/93 Columns" ""
+ Choice "94/94 Columns" ""
+ Choice "95/95 Columns" ""
+ Choice "96/96 Columns" ""
+ Choice "97/97 Columns" ""
+ Choice "98/98 Columns" ""
+ Choice "99/99 Columns" ""
+ Choice "100/100 Columns" ""
+ Choice "101/101 Columns" ""
+ Choice "102/102 Columns" ""
+ Choice "103/103 Columns" ""
+ Choice "104/104 Columns" ""
+ Choice "105/105 Columns" ""
+ Choice "106/106 Columns" ""
+ Choice "107/107 Columns" ""
+ Choice "108/108 Columns" ""
+ Choice "109/109 Columns" ""
+ Choice "110/110 Columns" ""
+ Choice "111/111 Columns" ""
+ Choice "112/112 Columns" ""
+ Choice "113/113 Columns" ""
+ Choice "114/114 Columns" ""
+ Choice "115/115 Columns" ""
+ Choice "116/116 Columns" ""
+ Choice "117/117 Columns" ""
+ Choice "118/118 Columns" ""
+ Choice "119/119 Columns" ""
+ Choice "120/120 Columns" ""
+ Choice "121/121 Columns" ""
+ Choice "122/122 Columns" ""
+ Choice "123/123 Columns" ""
+ Choice "124/124 Columns" ""
+ Choice "125/125 Columns" ""
+ Choice "126/126 Columns" ""
+ Choice "127/127 Columns" ""
+ Choice "128/128 Columns" ""
+ Choice "129/129 Columns" ""
+ Choice "130/130 Columns" ""
+ Choice "131/131 Columns" ""
+ Choice "132/132 Columns" ""
+ Choice "133/133 Columns" ""
+ Choice "134/134 Columns" ""
+ Choice "135/135 Columns" ""
+ Choice "136/136 Columns" ""
+ Choice "137/137 Columns" ""
+ Choice "138/138 Columns" ""
+ Choice "139/139 Columns" ""
+ Choice "140/140 Columns" ""
+ Choice "141/141 Columns" ""
+ Choice "142/142 Columns" ""
+ Choice "143/143 Columns" ""
+ Choice "144/144 Columns" ""
+ Choice "145/145 Columns" ""
+ Choice "146/146 Columns" ""
+ Choice "147/147 Columns" ""
+ Choice "148/148 Columns" ""
+ Choice "149/149 Columns" ""
+ Choice "150/150 Columns" ""
+ Choice "151/151 Columns" ""
+ Choice "152/152 Columns" ""
+ Choice "153/153 Columns" ""
+ Choice "154/154 Columns" ""
+ Choice "155/155 Columns" ""
+ Choice "156/156 Columns" ""
+ Choice "157/157 Columns" ""
+ Choice "158/158 Columns" ""
+ Choice "159/159 Columns" ""
+ *Choice "160/160 Columns" ""
+ Choice "161/161 Columns" ""
+ Choice "162/162 Columns" ""
+ Choice "163/163 Columns" ""
+ Choice "164/164 Columns" ""
+ Choice "165/165 Columns" ""
+ Choice "166/166 Columns" ""
+ Choice "167/167 Columns" ""
+ Choice "168/168 Columns" ""
+ Choice "169/169 Columns" ""
+ Choice "170/170 Columns" ""
+ Choice "171/171 Columns" ""
+ Choice "172/172 Columns" ""
+ Choice "173/173 Columns" ""
+ Choice "174/174 Columns" ""
+ Choice "175/175 Columns" ""
+ Choice "176/176 Columns" ""
+ Choice "177/177 Columns" ""
+ Choice "178/178 Columns" ""
+ Choice "179/179 Columns" ""
+ Choice "180/180 Columns" ""
+ Choice "181/181 Columns" ""
+ Choice "182/182 Columns" ""
+ Choice "183/183 Columns" ""
+ Choice "184/184 Columns" ""
+ Choice "185/185 Columns" ""
+ Choice "186/186 Columns" ""
+ Choice "187/187 Columns" ""
+ Choice "188/188 Columns" ""
+ Choice "189/189 Columns" ""
+ Choice "190/190 Columns" ""
+ Choice "191/191 Columns" ""
+ Choice "192/192 Columns" ""
+ Choice "193/193 Columns" ""
+ Choice "194/194 Columns" ""
+ Choice "195/195 Columns" ""
+ Choice "196/196 Columns" ""
+ Choice "197/197 Columns" ""
+ Choice "198/198 Columns" ""
+ Choice "199/199 Columns" ""
+ Choice "200/200 Columns" ""
+ Attribute CustomTabloidNumColumns True ""
+ Attribute ParamCustomTabloidNumColumns Columns "1 int 1 999"
+
+
+ Option "LedgerAvailable/Page Size Ledger available" Boolean AnySetup 10.0
+ *Choice "True/Yes" ""
+ Choice "False/No" ""
+
+ Option "LedgerNumLines/Page Size Ledger Number of Lines" PickOne AnySetup 10.0
+ Choice "1/1 Line" ""
+ Choice "2/2 Lines" ""
+ Choice "3/3 Lines" ""
+ Choice "4/4 Lines" ""
+ Choice "5/5 Lines" ""
+ Choice "6/6 Lines" ""
+ Choice "7/7 Lines" ""
+ Choice "8/8 Lines" ""
+ Choice "9/9 Lines" ""
+ Choice "10/10 Lines" ""
+ Choice "11/11 Lines" ""
+ Choice "12/12 Lines" ""
+ Choice "13/13 Lines" ""
+ Choice "14/14 Lines" ""
+ Choice "15/15 Lines" ""
+ Choice "16/16 Lines" ""
+ Choice "17/17 Lines" ""
+ Choice "18/18 Lines" ""
+ Choice "19/19 Lines" ""
+ Choice "20/20 Lines" ""
+ Choice "21/21 Lines" ""
+ Choice "22/22 Lines" ""
+ Choice "23/23 Lines" ""
+ Choice "24/24 Lines" ""
+ Choice "25/25 Lines" ""
+ Choice "26/26 Lines" ""
+ Choice "27/27 Lines" ""
+ Choice "28/28 Lines" ""
+ Choice "29/29 Lines" ""
+ Choice "30/30 Lines" ""
+ Choice "31/31 Lines" ""
+ Choice "32/32 Lines" ""
+ Choice "33/33 Lines" ""
+ Choice "34/34 Lines" ""
+ Choice "35/35 Lines" ""
+ Choice "36/36 Lines" ""
+ Choice "37/37 Lines" ""
+ Choice "38/38 Lines" ""
+ Choice "39/39 Lines" ""
+ Choice "40/40 Lines" ""
+ Choice "41/41 Lines" ""
+ Choice "42/42 Lines" ""
+ Choice "43/43 Lines" ""
+ Choice "44/44 Lines" ""
+ Choice "45/45 Lines" ""
+ Choice "46/46 Lines" ""
+ Choice "47/47 Lines" ""
+ Choice "48/48 Lines" ""
+ Choice "49/49 Lines" ""
+ Choice "50/50 Lines" ""
+ Choice "51/51 Lines" ""
+ Choice "52/52 Lines" ""
+ Choice "53/53 Lines" ""
+ Choice "54/54 Lines" ""
+ Choice "55/55 Lines" ""
+ Choice "56/56 Lines" ""
+ Choice "57/57 Lines" ""
+ Choice "58/58 Lines" ""
+ Choice "59/59 Lines" ""
+ Choice "60/60 Lines" ""
+ Choice "61/61 Lines" ""
+ Choice "62/62 Lines" ""
+ Choice "63/63 Lines" ""
+ Choice "64/64 Lines" ""
+ Choice "65/65 Lines" ""
+ Choice "66/66 Lines" ""
+ Choice "67/67 Lines" ""
+ Choice "68/68 Lines" ""
+ Choice "69/69 Lines" ""
+ Choice "70/70 Lines" ""
+ Choice "71/71 Lines" ""
+ Choice "72/72 Lines" ""
+ Choice "73/73 Lines" ""
+ Choice "74/74 Lines" ""
+ Choice "75/75 Lines" ""
+ Choice "76/76 Lines" ""
+ Choice "77/77 Lines" ""
+ Choice "78/78 Lines" ""
+ Choice "79/79 Lines" ""
+ Choice "80/80 Lines" ""
+ Choice "81/81 Lines" ""
+ Choice "82/82 Lines" ""
+ Choice "83/83 Lines" ""
+ Choice "84/84 Lines" ""
+ Choice "85/85 Lines" ""
+ Choice "86/86 Lines" ""
+ Choice "87/87 Lines" ""
+ Choice "88/88 Lines" ""
+ Choice "89/89 Lines" ""
+ Choice "90/90 Lines" ""
+ Choice "91/91 Lines" ""
+ Choice "92/92 Lines" ""
+ Choice "93/93 Lines" ""
+ Choice "94/94 Lines" ""
+ Choice "95/95 Lines" ""
+ Choice "96/96 Lines" ""
+ Choice "97/97 Lines" ""
+ Choice "98/98 Lines" ""
+ Choice "99/99 Lines" ""
+ Choice "100/100 Lines" ""
+ Choice "101/101 Lines" ""
+ *Choice "102/102 Lines" ""
+ Choice "103/103 Lines" ""
+ Choice "104/104 Lines" ""
+ Choice "105/105 Lines" ""
+ Choice "106/106 Lines" ""
+ Choice "107/107 Lines" ""
+ Choice "108/108 Lines" ""
+ Choice "109/109 Lines" ""
+ Choice "110/110 Lines" ""
+ Choice "111/111 Lines" ""
+ Choice "112/112 Lines" ""
+ Choice "113/113 Lines" ""
+ Choice "114/114 Lines" ""
+ Choice "115/115 Lines" ""
+ Choice "116/116 Lines" ""
+ Choice "117/117 Lines" ""
+ Choice "118/118 Lines" ""
+ Choice "119/119 Lines" ""
+ Choice "120/120 Lines" ""
+ Choice "121/121 Lines" ""
+ Choice "122/122 Lines" ""
+ Choice "123/123 Lines" ""
+ Choice "124/124 Lines" ""
+ Choice "125/125 Lines" ""
+ Choice "126/126 Lines" ""
+ Choice "127/127 Lines" ""
+ Choice "128/128 Lines" ""
+ Choice "129/129 Lines" ""
+ Choice "130/130 Lines" ""
+ Choice "131/131 Lines" ""
+ Choice "132/132 Lines" ""
+ Choice "133/133 Lines" ""
+ Choice "134/134 Lines" ""
+ Choice "135/135 Lines" ""
+ Choice "136/136 Lines" ""
+ Choice "137/137 Lines" ""
+ Choice "138/138 Lines" ""
+ Choice "139/139 Lines" ""
+ Choice "140/140 Lines" ""
+ Choice "141/141 Lines" ""
+ Choice "142/142 Lines" ""
+ Choice "143/143 Lines" ""
+ Choice "144/144 Lines" ""
+ Choice "145/145 Lines" ""
+ Choice "146/146 Lines" ""
+ Choice "147/147 Lines" ""
+ Choice "148/148 Lines" ""
+ Choice "149/149 Lines" ""
+ Choice "150/150 Lines" ""
+ Choice "151/151 Lines" ""
+ Choice "152/152 Lines" ""
+ Choice "153/153 Lines" ""
+ Choice "154/154 Lines" ""
+ Choice "155/155 Lines" ""
+ Choice "156/156 Lines" ""
+ Choice "157/157 Lines" ""
+ Choice "158/158 Lines" ""
+ Choice "159/159 Lines" ""
+ Choice "160/160 Lines" ""
+ Choice "161/161 Lines" ""
+ Choice "162/162 Lines" ""
+ Choice "163/163 Lines" ""
+ Choice "164/164 Lines" ""
+ Choice "165/165 Lines" ""
+ Choice "166/166 Lines" ""
+ Choice "167/167 Lines" ""
+ Choice "168/168 Lines" ""
+ Choice "169/169 Lines" ""
+ Choice "170/170 Lines" ""
+ Choice "171/171 Lines" ""
+ Choice "172/172 Lines" ""
+ Choice "173/173 Lines" ""
+ Choice "174/174 Lines" ""
+ Choice "175/175 Lines" ""
+ Choice "176/176 Lines" ""
+ Choice "177/177 Lines" ""
+ Choice "178/178 Lines" ""
+ Choice "179/179 Lines" ""
+ Choice "180/180 Lines" ""
+ Choice "181/181 Lines" ""
+ Choice "182/182 Lines" ""
+ Choice "183/183 Lines" ""
+ Choice "184/184 Lines" ""
+ Choice "185/185 Lines" ""
+ Choice "186/186 Lines" ""
+ Choice "187/187 Lines" ""
+ Choice "188/188 Lines" ""
+ Choice "189/189 Lines" ""
+ Choice "190/190 Lines" ""
+ Choice "191/191 Lines" ""
+ Choice "192/192 Lines" ""
+ Choice "193/193 Lines" ""
+ Choice "194/194 Lines" ""
+ Choice "195/195 Lines" ""
+ Choice "196/196 Lines" ""
+ Choice "197/197 Lines" ""
+ Choice "198/198 Lines" ""
+ Choice "199/199 Lines" ""
+ Choice "200/200 Lines" ""
+ Attribute CustomLedgerNumLines True ""
+ Attribute ParamCustomLedgerNumLines Lines "1 int 1 999"
+
+ Option "LedgerNumColumns/Page Size Ledger Number of Columns" PickOne AnySetup 10.0
+ Choice "1/1 Column" ""
+ Choice "2/2 Columns" ""
+ Choice "3/3 Columns" ""
+ Choice "4/4 Columns" ""
+ Choice "5/5 Columns" ""
+ Choice "6/6 Columns" ""
+ Choice "7/7 Columns" ""
+ Choice "8/8 Columns" ""
+ Choice "9/9 Columns" ""
+ Choice "10/10 Columns" ""
+ Choice "11/11 Columns" ""
+ Choice "12/12 Columns" ""
+ Choice "13/13 Columns" ""
+ Choice "14/14 Columns" ""
+ Choice "15/15 Columns" ""
+ Choice "16/16 Columns" ""
+ Choice "17/17 Columns" ""
+ Choice "18/18 Columns" ""
+ Choice "19/19 Columns" ""
+ Choice "20/20 Columns" ""
+ Choice "21/21 Columns" ""
+ Choice "22/22 Columns" ""
+ Choice "23/23 Columns" ""
+ Choice "24/24 Columns" ""
+ Choice "25/25 Columns" ""
+ Choice "26/26 Columns" ""
+ Choice "27/27 Columns" ""
+ Choice "28/28 Columns" ""
+ Choice "29/29 Columns" ""
+ Choice "30/30 Columns" ""
+ Choice "31/31 Columns" ""
+ Choice "32/32 Columns" ""
+ Choice "33/33 Columns" ""
+ Choice "34/34 Columns" ""
+ Choice "35/35 Columns" ""
+ Choice "36/36 Columns" ""
+ Choice "37/37 Columns" ""
+ Choice "38/38 Columns" ""
+ Choice "39/39 Columns" ""
+ Choice "40/40 Columns" ""
+ Choice "41/41 Columns" ""
+ Choice "42/42 Columns" ""
+ Choice "43/43 Columns" ""
+ Choice "44/44 Columns" ""
+ Choice "45/45 Columns" ""
+ Choice "46/46 Columns" ""
+ Choice "47/47 Columns" ""
+ Choice "48/48 Columns" ""
+ Choice "49/49 Columns" ""
+ Choice "50/50 Columns" ""
+ Choice "51/51 Columns" ""
+ Choice "52/52 Columns" ""
+ Choice "53/53 Columns" ""
+ Choice "54/54 Columns" ""
+ Choice "55/55 Columns" ""
+ Choice "56/56 Columns" ""
+ Choice "57/57 Columns" ""
+ Choice "58/58 Columns" ""
+ Choice "59/59 Columns" ""
+ Choice "60/60 Columns" ""
+ Choice "61/61 Columns" ""
+ Choice "62/62 Columns" ""
+ Choice "63/63 Columns" ""
+ Choice "64/64 Columns" ""
+ Choice "65/65 Columns" ""
+ Choice "66/66 Columns" ""
+ Choice "67/67 Columns" ""
+ Choice "68/68 Columns" ""
+ Choice "69/69 Columns" ""
+ Choice "70/70 Columns" ""
+ Choice "71/71 Columns" ""
+ Choice "72/72 Columns" ""
+ Choice "73/73 Columns" ""
+ Choice "74/74 Columns" ""
+ Choice "75/75 Columns" ""
+ Choice "76/76 Columns" ""
+ Choice "77/77 Columns" ""
+ Choice "78/78 Columns" ""
+ Choice "79/79 Columns" ""
+ Choice "80/80 Columns" ""
+ Choice "81/81 Columns" ""
+ Choice "82/82 Columns" ""
+ Choice "83/83 Columns" ""
+ Choice "84/84 Columns" ""
+ Choice "85/85 Columns" ""
+ Choice "86/86 Columns" ""
+ Choice "87/87 Columns" ""
+ Choice "88/88 Columns" ""
+ Choice "89/89 Columns" ""
+ Choice "90/90 Columns" ""
+ Choice "91/91 Columns" ""
+ Choice "92/92 Columns" ""
+ Choice "93/93 Columns" ""
+ Choice "94/94 Columns" ""
+ Choice "95/95 Columns" ""
+ Choice "96/96 Columns" ""
+ Choice "97/97 Columns" ""
+ Choice "98/98 Columns" ""
+ Choice "99/99 Columns" ""
+ Choice "100/100 Columns" ""
+ Choice "101/101 Columns" ""
+ Choice "102/102 Columns" ""
+ Choice "103/103 Columns" ""
+ Choice "104/104 Columns" ""
+ Choice "105/105 Columns" ""
+ Choice "106/106 Columns" ""
+ Choice "107/107 Columns" ""
+ Choice "108/108 Columns" ""
+ Choice "109/109 Columns" ""
+ *Choice "110/110 Columns" ""
+ Choice "111/111 Columns" ""
+ Choice "112/112 Columns" ""
+ Choice "113/113 Columns" ""
+ Choice "114/114 Columns" ""
+ Choice "115/115 Columns" ""
+ Choice "116/116 Columns" ""
+ Choice "117/117 Columns" ""
+ Choice "118/118 Columns" ""
+ Choice "119/119 Columns" ""
+ Choice "120/120 Columns" ""
+ Choice "121/121 Columns" ""
+ Choice "122/122 Columns" ""
+ Choice "123/123 Columns" ""
+ Choice "124/124 Columns" ""
+ Choice "125/125 Columns" ""
+ Choice "126/126 Columns" ""
+ Choice "127/127 Columns" ""
+ Choice "128/128 Columns" ""
+ Choice "129/129 Columns" ""
+ Choice "130/130 Columns" ""
+ Choice "131/131 Columns" ""
+ Choice "132/132 Columns" ""
+ Choice "133/133 Columns" ""
+ Choice "134/134 Columns" ""
+ Choice "135/135 Columns" ""
+ Choice "136/136 Columns" ""
+ Choice "137/137 Columns" ""
+ Choice "138/138 Columns" ""
+ Choice "139/139 Columns" ""
+ Choice "140/140 Columns" ""
+ Choice "141/141 Columns" ""
+ Choice "142/142 Columns" ""
+ Choice "143/143 Columns" ""
+ Choice "144/144 Columns" ""
+ Choice "145/145 Columns" ""
+ Choice "146/146 Columns" ""
+ Choice "147/147 Columns" ""
+ Choice "148/148 Columns" ""
+ Choice "149/149 Columns" ""
+ Choice "150/150 Columns" ""
+ Choice "151/151 Columns" ""
+ Choice "152/152 Columns" ""
+ Choice "153/153 Columns" ""
+ Choice "154/154 Columns" ""
+ Choice "155/155 Columns" ""
+ Choice "156/156 Columns" ""
+ Choice "157/157 Columns" ""
+ Choice "158/158 Columns" ""
+ Choice "159/159 Columns" ""
+ Choice "160/160 Columns" ""
+ Choice "161/161 Columns" ""
+ Choice "162/162 Columns" ""
+ Choice "163/163 Columns" ""
+ Choice "164/164 Columns" ""
+ Choice "165/165 Columns" ""
+ Choice "166/166 Columns" ""
+ Choice "167/167 Columns" ""
+ Choice "168/168 Columns" ""
+ Choice "169/169 Columns" ""
+ Choice "170/170 Columns" ""
+ Choice "171/171 Columns" ""
+ Choice "172/172 Columns" ""
+ Choice "173/173 Columns" ""
+ Choice "174/174 Columns" ""
+ Choice "175/175 Columns" ""
+ Choice "176/176 Columns" ""
+ Choice "177/177 Columns" ""
+ Choice "178/178 Columns" ""
+ Choice "179/179 Columns" ""
+ Choice "180/180 Columns" ""
+ Choice "181/181 Columns" ""
+ Choice "182/182 Columns" ""
+ Choice "183/183 Columns" ""
+ Choice "184/184 Columns" ""
+ Choice "185/185 Columns" ""
+ Choice "186/186 Columns" ""
+ Choice "187/187 Columns" ""
+ Choice "188/188 Columns" ""
+ Choice "189/189 Columns" ""
+ Choice "190/190 Columns" ""
+ Choice "191/191 Columns" ""
+ Choice "192/192 Columns" ""
+ Choice "193/193 Columns" ""
+ Choice "194/194 Columns" ""
+ Choice "195/195 Columns" ""
+ Choice "196/196 Columns" ""
+ Choice "197/197 Columns" ""
+ Choice "198/198 Columns" ""
+ Choice "199/199 Columns" ""
+ Choice "200/200 Columns" ""
+ Attribute CustomLedgerNumColumns True ""
+ Attribute ParamCustomLedgerNumColumns Columns "1 int 1 999"
+
+
+ Option "A4Available/Page Size A4 available" Boolean AnySetup 10.0
+ *Choice "True/Yes" ""
+ Choice "False/No" ""
+
+ Option "A4NumLines/Page Size A4 Number of Lines" PickOne AnySetup 10.0
+ Choice "1/1 Line" ""
+ Choice "2/2 Lines" ""
+ Choice "3/3 Lines" ""
+ Choice "4/4 Lines" ""
+ Choice "5/5 Lines" ""
+ Choice "6/6 Lines" ""
+ Choice "7/7 Lines" ""
+ Choice "8/8 Lines" ""
+ Choice "9/9 Lines" ""
+ Choice "10/10 Lines" ""
+ Choice "11/11 Lines" ""
+ Choice "12/12 Lines" ""
+ Choice "13/13 Lines" ""
+ Choice "14/14 Lines" ""
+ Choice "15/15 Lines" ""
+ Choice "16/16 Lines" ""
+ Choice "17/17 Lines" ""
+ Choice "18/18 Lines" ""
+ Choice "19/19 Lines" ""
+ Choice "20/20 Lines" ""
+ Choice "21/21 Lines" ""
+ Choice "22/22 Lines" ""
+ Choice "23/23 Lines" ""
+ Choice "24/24 Lines" ""
+ Choice "25/25 Lines" ""
+ Choice "26/26 Lines" ""
+ Choice "27/27 Lines" ""
+ Choice "28/28 Lines" ""
+ Choice "29/29 Lines" ""
+ Choice "30/30 Lines" ""
+ Choice "31/31 Lines" ""
+ Choice "32/32 Lines" ""
+ Choice "33/33 Lines" ""
+ Choice "34/34 Lines" ""
+ Choice "35/35 Lines" ""
+ Choice "36/36 Lines" ""
+ Choice "37/37 Lines" ""
+ Choice "38/38 Lines" ""
+ Choice "39/39 Lines" ""
+ Choice "40/40 Lines" ""
+ Choice "41/41 Lines" ""
+ Choice "42/42 Lines" ""
+ Choice "43/43 Lines" ""
+ Choice "44/44 Lines" ""
+ Choice "45/45 Lines" ""
+ Choice "46/46 Lines" ""
+ Choice "47/47 Lines" ""
+ Choice "48/48 Lines" ""
+ Choice "49/49 Lines" ""
+ Choice "50/50 Lines" ""
+ Choice "51/51 Lines" ""
+ Choice "52/52 Lines" ""
+ Choice "53/53 Lines" ""
+ Choice "54/54 Lines" ""
+ Choice "55/55 Lines" ""
+ Choice "56/56 Lines" ""
+ Choice "57/57 Lines" ""
+ Choice "58/58 Lines" ""
+ Choice "59/59 Lines" ""
+ Choice "60/60 Lines" ""
+ Choice "61/61 Lines" ""
+ Choice "62/62 Lines" ""
+ Choice "63/63 Lines" ""
+ Choice "64/64 Lines" ""
+ Choice "65/65 Lines" ""
+ Choice "66/66 Lines" ""
+ Choice "67/67 Lines" ""
+ Choice "68/68 Lines" ""
+ Choice "69/69 Lines" ""
+ *Choice "70/70 Lines" ""
+ Choice "71/71 Lines" ""
+ Choice "72/72 Lines" ""
+ Choice "73/73 Lines" ""
+ Choice "74/74 Lines" ""
+ Choice "75/75 Lines" ""
+ Choice "76/76 Lines" ""
+ Choice "77/77 Lines" ""
+ Choice "78/78 Lines" ""
+ Choice "79/79 Lines" ""
+ Choice "80/80 Lines" ""
+ Choice "81/81 Lines" ""
+ Choice "82/82 Lines" ""
+ Choice "83/83 Lines" ""
+ Choice "84/84 Lines" ""
+ Choice "85/85 Lines" ""
+ Choice "86/86 Lines" ""
+ Choice "87/87 Lines" ""
+ Choice "88/88 Lines" ""
+ Choice "89/89 Lines" ""
+ Choice "90/90 Lines" ""
+ Choice "91/91 Lines" ""
+ Choice "92/92 Lines" ""
+ Choice "93/93 Lines" ""
+ Choice "94/94 Lines" ""
+ Choice "95/95 Lines" ""
+ Choice "96/96 Lines" ""
+ Choice "97/97 Lines" ""
+ Choice "98/98 Lines" ""
+ Choice "99/99 Lines" ""
+ Choice "100/100 Lines" ""
+ Choice "101/101 Lines" ""
+ Choice "102/102 Lines" ""
+ Choice "103/103 Lines" ""
+ Choice "104/104 Lines" ""
+ Choice "105/105 Lines" ""
+ Choice "106/106 Lines" ""
+ Choice "107/107 Lines" ""
+ Choice "108/108 Lines" ""
+ Choice "109/109 Lines" ""
+ Choice "110/110 Lines" ""
+ Choice "111/111 Lines" ""
+ Choice "112/112 Lines" ""
+ Choice "113/113 Lines" ""
+ Choice "114/114 Lines" ""
+ Choice "115/115 Lines" ""
+ Choice "116/116 Lines" ""
+ Choice "117/117 Lines" ""
+ Choice "118/118 Lines" ""
+ Choice "119/119 Lines" ""
+ Choice "120/120 Lines" ""
+ Choice "121/121 Lines" ""
+ Choice "122/122 Lines" ""
+ Choice "123/123 Lines" ""
+ Choice "124/124 Lines" ""
+ Choice "125/125 Lines" ""
+ Choice "126/126 Lines" ""
+ Choice "127/127 Lines" ""
+ Choice "128/128 Lines" ""
+ Choice "129/129 Lines" ""
+ Choice "130/130 Lines" ""
+ Choice "131/131 Lines" ""
+ Choice "132/132 Lines" ""
+ Choice "133/133 Lines" ""
+ Choice "134/134 Lines" ""
+ Choice "135/135 Lines" ""
+ Choice "136/136 Lines" ""
+ Choice "137/137 Lines" ""
+ Choice "138/138 Lines" ""
+ Choice "139/139 Lines" ""
+ Choice "140/140 Lines" ""
+ Choice "141/141 Lines" ""
+ Choice "142/142 Lines" ""
+ Choice "143/143 Lines" ""
+ Choice "144/144 Lines" ""
+ Choice "145/145 Lines" ""
+ Choice "146/146 Lines" ""
+ Choice "147/147 Lines" ""
+ Choice "148/148 Lines" ""
+ Choice "149/149 Lines" ""
+ Choice "150/150 Lines" ""
+ Choice "151/151 Lines" ""
+ Choice "152/152 Lines" ""
+ Choice "153/153 Lines" ""
+ Choice "154/154 Lines" ""
+ Choice "155/155 Lines" ""
+ Choice "156/156 Lines" ""
+ Choice "157/157 Lines" ""
+ Choice "158/158 Lines" ""
+ Choice "159/159 Lines" ""
+ Choice "160/160 Lines" ""
+ Choice "161/161 Lines" ""
+ Choice "162/162 Lines" ""
+ Choice "163/163 Lines" ""
+ Choice "164/164 Lines" ""
+ Choice "165/165 Lines" ""
+ Choice "166/166 Lines" ""
+ Choice "167/167 Lines" ""
+ Choice "168/168 Lines" ""
+ Choice "169/169 Lines" ""
+ Choice "170/170 Lines" ""
+ Choice "171/171 Lines" ""
+ Choice "172/172 Lines" ""
+ Choice "173/173 Lines" ""
+ Choice "174/174 Lines" ""
+ Choice "175/175 Lines" ""
+ Choice "176/176 Lines" ""
+ Choice "177/177 Lines" ""
+ Choice "178/178 Lines" ""
+ Choice "179/179 Lines" ""
+ Choice "180/180 Lines" ""
+ Choice "181/181 Lines" ""
+ Choice "182/182 Lines" ""
+ Choice "183/183 Lines" ""
+ Choice "184/184 Lines" ""
+ Choice "185/185 Lines" ""
+ Choice "186/186 Lines" ""
+ Choice "187/187 Lines" ""
+ Choice "188/188 Lines" ""
+ Choice "189/189 Lines" ""
+ Choice "190/190 Lines" ""
+ Choice "191/191 Lines" ""
+ Choice "192/192 Lines" ""
+ Choice "193/193 Lines" ""
+ Choice "194/194 Lines" ""
+ Choice "195/195 Lines" ""
+ Choice "196/196 Lines" ""
+ Choice "197/197 Lines" ""
+ Choice "198/198 Lines" ""
+ Choice "199/199 Lines" ""
+ Choice "200/200 Lines" ""
+ Attribute CustomA4NumLines True ""
+ Attribute ParamCustomA4NumLines Lines "1 int 1 999"
+
+ Option "A4NumColumns/Page Size A4 Number of Columns" PickOne AnySetup 10.0
+ Choice "1/1 Column" ""
+ Choice "2/2 Columns" ""
+ Choice "3/3 Columns" ""
+ Choice "4/4 Columns" ""
+ Choice "5/5 Columns" ""
+ Choice "6/6 Columns" ""
+ Choice "7/7 Columns" ""
+ Choice "8/8 Columns" ""
+ Choice "9/9 Columns" ""
+ Choice "10/10 Columns" ""
+ Choice "11/11 Columns" ""
+ Choice "12/12 Columns" ""
+ Choice "13/13 Columns" ""
+ Choice "14/14 Columns" ""
+ Choice "15/15 Columns" ""
+ Choice "16/16 Columns" ""
+ Choice "17/17 Columns" ""
+ Choice "18/18 Columns" ""
+ Choice "19/19 Columns" ""
+ Choice "20/20 Columns" ""
+ Choice "21/21 Columns" ""
+ Choice "22/22 Columns" ""
+ Choice "23/23 Columns" ""
+ Choice "24/24 Columns" ""
+ Choice "25/25 Columns" ""
+ Choice "26/26 Columns" ""
+ Choice "27/27 Columns" ""
+ Choice "28/28 Columns" ""
+ Choice "29/29 Columns" ""
+ Choice "30/30 Columns" ""
+ Choice "31/31 Columns" ""
+ Choice "32/32 Columns" ""
+ Choice "33/33 Columns" ""
+ Choice "34/34 Columns" ""
+ Choice "35/35 Columns" ""
+ Choice "36/36 Columns" ""
+ Choice "37/37 Columns" ""
+ Choice "38/38 Columns" ""
+ Choice "39/39 Columns" ""
+ Choice "40/40 Columns" ""
+ Choice "41/41 Columns" ""
+ Choice "42/42 Columns" ""
+ Choice "43/43 Columns" ""
+ Choice "44/44 Columns" ""
+ Choice "45/45 Columns" ""
+ Choice "46/46 Columns" ""
+ Choice "47/47 Columns" ""
+ Choice "48/48 Columns" ""
+ Choice "49/49 Columns" ""
+ Choice "50/50 Columns" ""
+ Choice "51/51 Columns" ""
+ Choice "52/52 Columns" ""
+ Choice "53/53 Columns" ""
+ Choice "54/54 Columns" ""
+ Choice "55/55 Columns" ""
+ Choice "56/56 Columns" ""
+ Choice "57/57 Columns" ""
+ Choice "58/58 Columns" ""
+ Choice "59/59 Columns" ""
+ Choice "60/60 Columns" ""
+ Choice "61/61 Columns" ""
+ Choice "62/62 Columns" ""
+ Choice "63/63 Columns" ""
+ Choice "64/64 Columns" ""
+ Choice "65/65 Columns" ""
+ Choice "66/66 Columns" ""
+ Choice "67/67 Columns" ""
+ Choice "68/68 Columns" ""
+ Choice "69/69 Columns" ""
+ Choice "70/70 Columns" ""
+ Choice "71/71 Columns" ""
+ Choice "72/72 Columns" ""
+ Choice "73/73 Columns" ""
+ Choice "74/74 Columns" ""
+ Choice "75/75 Columns" ""
+ Choice "76/76 Columns" ""
+ Choice "77/77 Columns" ""
+ Choice "78/78 Columns" ""
+ Choice "79/79 Columns" ""
+ *Choice "80/80 Columns" ""
+ Choice "81/81 Columns" ""
+ Choice "82/82 Columns" ""
+ Choice "83/83 Columns" ""
+ Choice "84/84 Columns" ""
+ Choice "85/85 Columns" ""
+ Choice "86/86 Columns" ""
+ Choice "87/87 Columns" ""
+ Choice "88/88 Columns" ""
+ Choice "89/89 Columns" ""
+ Choice "90/90 Columns" ""
+ Choice "91/91 Columns" ""
+ Choice "92/92 Columns" ""
+ Choice "93/93 Columns" ""
+ Choice "94/94 Columns" ""
+ Choice "95/95 Columns" ""
+ Choice "96/96 Columns" ""
+ Choice "97/97 Columns" ""
+ Choice "98/98 Columns" ""
+ Choice "99/99 Columns" ""
+ Choice "100/100 Columns" ""
+ Choice "101/101 Columns" ""
+ Choice "102/102 Columns" ""
+ Choice "103/103 Columns" ""
+ Choice "104/104 Columns" ""
+ Choice "105/105 Columns" ""
+ Choice "106/106 Columns" ""
+ Choice "107/107 Columns" ""
+ Choice "108/108 Columns" ""
+ Choice "109/109 Columns" ""
+ Choice "110/110 Columns" ""
+ Choice "111/111 Columns" ""
+ Choice "112/112 Columns" ""
+ Choice "113/113 Columns" ""
+ Choice "114/114 Columns" ""
+ Choice "115/115 Columns" ""
+ Choice "116/116 Columns" ""
+ Choice "117/117 Columns" ""
+ Choice "118/118 Columns" ""
+ Choice "119/119 Columns" ""
+ Choice "120/120 Columns" ""
+ Choice "121/121 Columns" ""
+ Choice "122/122 Columns" ""
+ Choice "123/123 Columns" ""
+ Choice "124/124 Columns" ""
+ Choice "125/125 Columns" ""
+ Choice "126/126 Columns" ""
+ Choice "127/127 Columns" ""
+ Choice "128/128 Columns" ""
+ Choice "129/129 Columns" ""
+ Choice "130/130 Columns" ""
+ Choice "131/131 Columns" ""
+ Choice "132/132 Columns" ""
+ Choice "133/133 Columns" ""
+ Choice "134/134 Columns" ""
+ Choice "135/135 Columns" ""
+ Choice "136/136 Columns" ""
+ Choice "137/137 Columns" ""
+ Choice "138/138 Columns" ""
+ Choice "139/139 Columns" ""
+ Choice "140/140 Columns" ""
+ Choice "141/141 Columns" ""
+ Choice "142/142 Columns" ""
+ Choice "143/143 Columns" ""
+ Choice "144/144 Columns" ""
+ Choice "145/145 Columns" ""
+ Choice "146/146 Columns" ""
+ Choice "147/147 Columns" ""
+ Choice "148/148 Columns" ""
+ Choice "149/149 Columns" ""
+ Choice "150/150 Columns" ""
+ Choice "151/151 Columns" ""
+ Choice "152/152 Columns" ""
+ Choice "153/153 Columns" ""
+ Choice "154/154 Columns" ""
+ Choice "155/155 Columns" ""
+ Choice "156/156 Columns" ""
+ Choice "157/157 Columns" ""
+ Choice "158/158 Columns" ""
+ Choice "159/159 Columns" ""
+ Choice "160/160 Columns" ""
+ Choice "161/161 Columns" ""
+ Choice "162/162 Columns" ""
+ Choice "163/163 Columns" ""
+ Choice "164/164 Columns" ""
+ Choice "165/165 Columns" ""
+ Choice "166/166 Columns" ""
+ Choice "167/167 Columns" ""
+ Choice "168/168 Columns" ""
+ Choice "169/169 Columns" ""
+ Choice "170/170 Columns" ""
+ Choice "171/171 Columns" ""
+ Choice "172/172 Columns" ""
+ Choice "173/173 Columns" ""
+ Choice "174/174 Columns" ""
+ Choice "175/175 Columns" ""
+ Choice "176/176 Columns" ""
+ Choice "177/177 Columns" ""
+ Choice "178/178 Columns" ""
+ Choice "179/179 Columns" ""
+ Choice "180/180 Columns" ""
+ Choice "181/181 Columns" ""
+ Choice "182/182 Columns" ""
+ Choice "183/183 Columns" ""
+ Choice "184/184 Columns" ""
+ Choice "185/185 Columns" ""
+ Choice "186/186 Columns" ""
+ Choice "187/187 Columns" ""
+ Choice "188/188 Columns" ""
+ Choice "189/189 Columns" ""
+ Choice "190/190 Columns" ""
+ Choice "191/191 Columns" ""
+ Choice "192/192 Columns" ""
+ Choice "193/193 Columns" ""
+ Choice "194/194 Columns" ""
+ Choice "195/195 Columns" ""
+ Choice "196/196 Columns" ""
+ Choice "197/197 Columns" ""
+ Choice "198/198 Columns" ""
+ Choice "199/199 Columns" ""
+ Choice "200/200 Columns" ""
+ Attribute CustomA4NumColumns True ""
+ Attribute ParamCustomA4NumColumns Columns "1 int 1 999"
+
+
+ Option "A3Available/Page Size A3 available" Boolean AnySetup 10.0
+ *Choice "True/Yes" ""
+ Choice "False/No" ""
+
+ Option "A3NumLines/Page Size A3 Number of Lines" PickOne AnySetup 10.0
+ Choice "1/1 Line" ""
+ Choice "2/2 Lines" ""
+ Choice "3/3 Lines" ""
+ Choice "4/4 Lines" ""
+ Choice "5/5 Lines" ""
+ Choice "6/6 Lines" ""
+ Choice "7/7 Lines" ""
+ Choice "8/8 Lines" ""
+ Choice "9/9 Lines" ""
+ Choice "10/10 Lines" ""
+ Choice "11/11 Lines" ""
+ Choice "12/12 Lines" ""
+ Choice "13/13 Lines" ""
+ Choice "14/14 Lines" ""
+ Choice "15/15 Lines" ""
+ Choice "16/16 Lines" ""
+ Choice "17/17 Lines" ""
+ Choice "18/18 Lines" ""
+ Choice "19/19 Lines" ""
+ Choice "20/20 Lines" ""
+ Choice "21/21 Lines" ""
+ Choice "22/22 Lines" ""
+ Choice "23/23 Lines" ""
+ Choice "24/24 Lines" ""
+ Choice "25/25 Lines" ""
+ Choice "26/26 Lines" ""
+ Choice "27/27 Lines" ""
+ Choice "28/28 Lines" ""
+ Choice "29/29 Lines" ""
+ Choice "30/30 Lines" ""
+ Choice "31/31 Lines" ""
+ Choice "32/32 Lines" ""
+ Choice "33/33 Lines" ""
+ Choice "34/34 Lines" ""
+ Choice "35/35 Lines" ""
+ Choice "36/36 Lines" ""
+ Choice "37/37 Lines" ""
+ Choice "38/38 Lines" ""
+ Choice "39/39 Lines" ""
+ Choice "40/40 Lines" ""
+ Choice "41/41 Lines" ""
+ Choice "42/42 Lines" ""
+ Choice "43/43 Lines" ""
+ Choice "44/44 Lines" ""
+ Choice "45/45 Lines" ""
+ Choice "46/46 Lines" ""
+ Choice "47/47 Lines" ""
+ Choice "48/48 Lines" ""
+ Choice "49/49 Lines" ""
+ Choice "50/50 Lines" ""
+ Choice "51/51 Lines" ""
+ Choice "52/52 Lines" ""
+ Choice "53/53 Lines" ""
+ Choice "54/54 Lines" ""
+ Choice "55/55 Lines" ""
+ Choice "56/56 Lines" ""
+ Choice "57/57 Lines" ""
+ Choice "58/58 Lines" ""
+ Choice "59/59 Lines" ""
+ Choice "60/60 Lines" ""
+ Choice "61/61 Lines" ""
+ Choice "62/62 Lines" ""
+ Choice "63/63 Lines" ""
+ Choice "64/64 Lines" ""
+ Choice "65/65 Lines" ""
+ Choice "66/66 Lines" ""
+ Choice "67/67 Lines" ""
+ Choice "68/68 Lines" ""
+ Choice "69/69 Lines" ""
+ Choice "70/70 Lines" ""
+ Choice "71/71 Lines" ""
+ Choice "72/72 Lines" ""
+ Choice "73/73 Lines" ""
+ Choice "74/74 Lines" ""
+ Choice "75/75 Lines" ""
+ Choice "76/76 Lines" ""
+ Choice "77/77 Lines" ""
+ Choice "78/78 Lines" ""
+ Choice "79/79 Lines" ""
+ Choice "80/80 Lines" ""
+ Choice "81/81 Lines" ""
+ Choice "82/82 Lines" ""
+ Choice "83/83 Lines" ""
+ Choice "84/84 Lines" ""
+ Choice "85/85 Lines" ""
+ Choice "86/86 Lines" ""
+ Choice "87/87 Lines" ""
+ Choice "88/88 Lines" ""
+ Choice "89/89 Lines" ""
+ Choice "90/90 Lines" ""
+ Choice "91/91 Lines" ""
+ Choice "92/92 Lines" ""
+ Choice "93/93 Lines" ""
+ Choice "94/94 Lines" ""
+ Choice "95/95 Lines" ""
+ Choice "96/96 Lines" ""
+ Choice "97/97 Lines" ""
+ Choice "98/98 Lines" ""
+ *Choice "99/99 Lines" ""
+ Choice "100/100 Lines" ""
+ Choice "101/101 Lines" ""
+ Choice "102/102 Lines" ""
+ Choice "103/103 Lines" ""
+ Choice "104/104 Lines" ""
+ Choice "105/105 Lines" ""
+ Choice "106/106 Lines" ""
+ Choice "107/107 Lines" ""
+ Choice "108/108 Lines" ""
+ Choice "109/109 Lines" ""
+ Choice "110/110 Lines" ""
+ Choice "111/111 Lines" ""
+ Choice "112/112 Lines" ""
+ Choice "113/113 Lines" ""
+ Choice "114/114 Lines" ""
+ Choice "115/115 Lines" ""
+ Choice "116/116 Lines" ""
+ Choice "117/117 Lines" ""
+ Choice "118/118 Lines" ""
+ Choice "119/119 Lines" ""
+ Choice "120/120 Lines" ""
+ Choice "121/121 Lines" ""
+ Choice "122/122 Lines" ""
+ Choice "123/123 Lines" ""
+ Choice "124/124 Lines" ""
+ Choice "125/125 Lines" ""
+ Choice "126/126 Lines" ""
+ Choice "127/127 Lines" ""
+ Choice "128/128 Lines" ""
+ Choice "129/129 Lines" ""
+ Choice "130/130 Lines" ""
+ Choice "131/131 Lines" ""
+ Choice "132/132 Lines" ""
+ Choice "133/133 Lines" ""
+ Choice "134/134 Lines" ""
+ Choice "135/135 Lines" ""
+ Choice "136/136 Lines" ""
+ Choice "137/137 Lines" ""
+ Choice "138/138 Lines" ""
+ Choice "139/139 Lines" ""
+ Choice "140/140 Lines" ""
+ Choice "141/141 Lines" ""
+ Choice "142/142 Lines" ""
+ Choice "143/143 Lines" ""
+ Choice "144/144 Lines" ""
+ Choice "145/145 Lines" ""
+ Choice "146/146 Lines" ""
+ Choice "147/147 Lines" ""
+ Choice "148/148 Lines" ""
+ Choice "149/149 Lines" ""
+ Choice "150/150 Lines" ""
+ Choice "151/151 Lines" ""
+ Choice "152/152 Lines" ""
+ Choice "153/153 Lines" ""
+ Choice "154/154 Lines" ""
+ Choice "155/155 Lines" ""
+ Choice "156/156 Lines" ""
+ Choice "157/157 Lines" ""
+ Choice "158/158 Lines" ""
+ Choice "159/159 Lines" ""
+ Choice "160/160 Lines" ""
+ Choice "161/161 Lines" ""
+ Choice "162/162 Lines" ""
+ Choice "163/163 Lines" ""
+ Choice "164/164 Lines" ""
+ Choice "165/165 Lines" ""
+ Choice "166/166 Lines" ""
+ Choice "167/167 Lines" ""
+ Choice "168/168 Lines" ""
+ Choice "169/169 Lines" ""
+ Choice "170/170 Lines" ""
+ Choice "171/171 Lines" ""
+ Choice "172/172 Lines" ""
+ Choice "173/173 Lines" ""
+ Choice "174/174 Lines" ""
+ Choice "175/175 Lines" ""
+ Choice "176/176 Lines" ""
+ Choice "177/177 Lines" ""
+ Choice "178/178 Lines" ""
+ Choice "179/179 Lines" ""
+ Choice "180/180 Lines" ""
+ Choice "181/181 Lines" ""
+ Choice "182/182 Lines" ""
+ Choice "183/183 Lines" ""
+ Choice "184/184 Lines" ""
+ Choice "185/185 Lines" ""
+ Choice "186/186 Lines" ""
+ Choice "187/187 Lines" ""
+ Choice "188/188 Lines" ""
+ Choice "189/189 Lines" ""
+ Choice "190/190 Lines" ""
+ Choice "191/191 Lines" ""
+ Choice "192/192 Lines" ""
+ Choice "193/193 Lines" ""
+ Choice "194/194 Lines" ""
+ Choice "195/195 Lines" ""
+ Choice "196/196 Lines" ""
+ Choice "197/197 Lines" ""
+ Choice "198/198 Lines" ""
+ Choice "199/199 Lines" ""
+ Choice "200/200 Lines" ""
+ Attribute CustomA3NumLines True ""
+ Attribute ParamCustomA3NumLines Lines "1 int 1 999"
+
+ Option "A3NumColumns/Page Size A3 Number of Columns" PickOne AnySetup 10.0
+ Choice "1/1 Column" ""
+ Choice "2/2 Columns" ""
+ Choice "3/3 Columns" ""
+ Choice "4/4 Columns" ""
+ Choice "5/5 Columns" ""
+ Choice "6/6 Columns" ""
+ Choice "7/7 Columns" ""
+ Choice "8/8 Columns" ""
+ Choice "9/9 Columns" ""
+ Choice "10/10 Columns" ""
+ Choice "11/11 Columns" ""
+ Choice "12/12 Columns" ""
+ Choice "13/13 Columns" ""
+ Choice "14/14 Columns" ""
+ Choice "15/15 Columns" ""
+ Choice "16/16 Columns" ""
+ Choice "17/17 Columns" ""
+ Choice "18/18 Columns" ""
+ Choice "19/19 Columns" ""
+ Choice "20/20 Columns" ""
+ Choice "21/21 Columns" ""
+ Choice "22/22 Columns" ""
+ Choice "23/23 Columns" ""
+ Choice "24/24 Columns" ""
+ Choice "25/25 Columns" ""
+ Choice "26/26 Columns" ""
+ Choice "27/27 Columns" ""
+ Choice "28/28 Columns" ""
+ Choice "29/29 Columns" ""
+ Choice "30/30 Columns" ""
+ Choice "31/31 Columns" ""
+ Choice "32/32 Columns" ""
+ Choice "33/33 Columns" ""
+ Choice "34/34 Columns" ""
+ Choice "35/35 Columns" ""
+ Choice "36/36 Columns" ""
+ Choice "37/37 Columns" ""
+ Choice "38/38 Columns" ""
+ Choice "39/39 Columns" ""
+ Choice "40/40 Columns" ""
+ Choice "41/41 Columns" ""
+ Choice "42/42 Columns" ""
+ Choice "43/43 Columns" ""
+ Choice "44/44 Columns" ""
+ Choice "45/45 Columns" ""
+ Choice "46/46 Columns" ""
+ Choice "47/47 Columns" ""
+ Choice "48/48 Columns" ""
+ Choice "49/49 Columns" ""
+ Choice "50/50 Columns" ""
+ Choice "51/51 Columns" ""
+ Choice "52/52 Columns" ""
+ Choice "53/53 Columns" ""
+ Choice "54/54 Columns" ""
+ Choice "55/55 Columns" ""
+ Choice "56/56 Columns" ""
+ Choice "57/57 Columns" ""
+ Choice "58/58 Columns" ""
+ Choice "59/59 Columns" ""
+ Choice "60/60 Columns" ""
+ Choice "61/61 Columns" ""
+ Choice "62/62 Columns" ""
+ Choice "63/63 Columns" ""
+ Choice "64/64 Columns" ""
+ Choice "65/65 Columns" ""
+ Choice "66/66 Columns" ""
+ Choice "67/67 Columns" ""
+ Choice "68/68 Columns" ""
+ Choice "69/69 Columns" ""
+ Choice "70/70 Columns" ""
+ Choice "71/71 Columns" ""
+ Choice "72/72 Columns" ""
+ Choice "73/73 Columns" ""
+ Choice "74/74 Columns" ""
+ Choice "75/75 Columns" ""
+ Choice "76/76 Columns" ""
+ Choice "77/77 Columns" ""
+ Choice "78/78 Columns" ""
+ Choice "79/79 Columns" ""
+ Choice "80/80 Columns" ""
+ Choice "81/81 Columns" ""
+ Choice "82/82 Columns" ""
+ Choice "83/83 Columns" ""
+ Choice "84/84 Columns" ""
+ Choice "85/85 Columns" ""
+ Choice "86/86 Columns" ""
+ Choice "87/87 Columns" ""
+ Choice "88/88 Columns" ""
+ Choice "89/89 Columns" ""
+ Choice "90/90 Columns" ""
+ Choice "91/91 Columns" ""
+ Choice "92/92 Columns" ""
+ Choice "93/93 Columns" ""
+ Choice "94/94 Columns" ""
+ Choice "95/95 Columns" ""
+ Choice "96/96 Columns" ""
+ Choice "97/97 Columns" ""
+ Choice "98/98 Columns" ""
+ Choice "99/99 Columns" ""
+ Choice "100/100 Columns" ""
+ Choice "101/101 Columns" ""
+ Choice "102/102 Columns" ""
+ Choice "103/103 Columns" ""
+ Choice "104/104 Columns" ""
+ Choice "105/105 Columns" ""
+ Choice "106/106 Columns" ""
+ Choice "107/107 Columns" ""
+ Choice "108/108 Columns" ""
+ Choice "109/109 Columns" ""
+ Choice "110/110 Columns" ""
+ Choice "111/111 Columns" ""
+ Choice "112/112 Columns" ""
+ Choice "113/113 Columns" ""
+ Choice "114/114 Columns" ""
+ Choice "115/115 Columns" ""
+ Choice "116/116 Columns" ""
+ *Choice "117/117 Columns" ""
+ Choice "118/118 Columns" ""
+ Choice "119/119 Columns" ""
+ Choice "120/120 Columns" ""
+ Choice "121/121 Columns" ""
+ Choice "122/122 Columns" ""
+ Choice "123/123 Columns" ""
+ Choice "124/124 Columns" ""
+ Choice "125/125 Columns" ""
+ Choice "126/126 Columns" ""
+ Choice "127/127 Columns" ""
+ Choice "128/128 Columns" ""
+ Choice "129/129 Columns" ""
+ Choice "130/130 Columns" ""
+ Choice "131/131 Columns" ""
+ Choice "132/132 Columns" ""
+ Choice "133/133 Columns" ""
+ Choice "134/134 Columns" ""
+ Choice "135/135 Columns" ""
+ Choice "136/136 Columns" ""
+ Choice "137/137 Columns" ""
+ Choice "138/138 Columns" ""
+ Choice "139/139 Columns" ""
+ Choice "140/140 Columns" ""
+ Choice "141/141 Columns" ""
+ Choice "142/142 Columns" ""
+ Choice "143/143 Columns" ""
+ Choice "144/144 Columns" ""
+ Choice "145/145 Columns" ""
+ Choice "146/146 Columns" ""
+ Choice "147/147 Columns" ""
+ Choice "148/148 Columns" ""
+ Choice "149/149 Columns" ""
+ Choice "150/150 Columns" ""
+ Choice "151/151 Columns" ""
+ Choice "152/152 Columns" ""
+ Choice "153/153 Columns" ""
+ Choice "154/154 Columns" ""
+ Choice "155/155 Columns" ""
+ Choice "156/156 Columns" ""
+ Choice "157/157 Columns" ""
+ Choice "158/158 Columns" ""
+ Choice "159/159 Columns" ""
+ Choice "160/160 Columns" ""
+ Choice "161/161 Columns" ""
+ Choice "162/162 Columns" ""
+ Choice "163/163 Columns" ""
+ Choice "164/164 Columns" ""
+ Choice "165/165 Columns" ""
+ Choice "166/166 Columns" ""
+ Choice "167/167 Columns" ""
+ Choice "168/168 Columns" ""
+ Choice "169/169 Columns" ""
+ Choice "170/170 Columns" ""
+ Choice "171/171 Columns" ""
+ Choice "172/172 Columns" ""
+ Choice "173/173 Columns" ""
+ Choice "174/174 Columns" ""
+ Choice "175/175 Columns" ""
+ Choice "176/176 Columns" ""
+ Choice "177/177 Columns" ""
+ Choice "178/178 Columns" ""
+ Choice "179/179 Columns" ""
+ Choice "180/180 Columns" ""
+ Choice "181/181 Columns" ""
+ Choice "182/182 Columns" ""
+ Choice "183/183 Columns" ""
+ Choice "184/184 Columns" ""
+ Choice "185/185 Columns" ""
+ Choice "186/186 Columns" ""
+ Choice "187/187 Columns" ""
+ Choice "188/188 Columns" ""
+ Choice "189/189 Columns" ""
+ Choice "190/190 Columns" ""
+ Choice "191/191 Columns" ""
+ Choice "192/192 Columns" ""
+ Choice "193/193 Columns" ""
+ Choice "194/194 Columns" ""
+ Choice "195/195 Columns" ""
+ Choice "196/196 Columns" ""
+ Choice "197/197 Columns" ""
+ Choice "198/198 Columns" ""
+ Choice "199/199 Columns" ""
+ Choice "200/200 Columns" ""
+ Attribute CustomA3NumColumns True ""
+ Attribute ParamCustomA3NumColumns Columns "1 int 1 999"
+
+
+ Option "FanFoldGermanAvailable/Page Size FanFoldGerman available" Boolean AnySetup 10.0
+ *Choice "True/Yes" ""
+ Choice "False/No" ""
+
+ Option "FanFoldGermanNumLines/Page Size FanFoldGerman Number of Lines" PickOne AnySetup 10.0
+ Choice "1/1 Line" ""
+ Choice "2/2 Lines" ""
+ Choice "3/3 Lines" ""
+ Choice "4/4 Lines" ""
+ Choice "5/5 Lines" ""
+ Choice "6/6 Lines" ""
+ Choice "7/7 Lines" ""
+ Choice "8/8 Lines" ""
+ Choice "9/9 Lines" ""
+ Choice "10/10 Lines" ""
+ Choice "11/11 Lines" ""
+ Choice "12/12 Lines" ""
+ Choice "13/13 Lines" ""
+ Choice "14/14 Lines" ""
+ Choice "15/15 Lines" ""
+ Choice "16/16 Lines" ""
+ Choice "17/17 Lines" ""
+ Choice "18/18 Lines" ""
+ Choice "19/19 Lines" ""
+ Choice "20/20 Lines" ""
+ Choice "21/21 Lines" ""
+ Choice "22/22 Lines" ""
+ Choice "23/23 Lines" ""
+ Choice "24/24 Lines" ""
+ Choice "25/25 Lines" ""
+ Choice "26/26 Lines" ""
+ Choice "27/27 Lines" ""
+ Choice "28/28 Lines" ""
+ Choice "29/29 Lines" ""
+ Choice "30/30 Lines" ""
+ Choice "31/31 Lines" ""
+ Choice "32/32 Lines" ""
+ Choice "33/33 Lines" ""
+ Choice "34/34 Lines" ""
+ Choice "35/35 Lines" ""
+ Choice "36/36 Lines" ""
+ Choice "37/37 Lines" ""
+ Choice "38/38 Lines" ""
+ Choice "39/39 Lines" ""
+ Choice "40/40 Lines" ""
+ Choice "41/41 Lines" ""
+ Choice "42/42 Lines" ""
+ Choice "43/43 Lines" ""
+ Choice "44/44 Lines" ""
+ Choice "45/45 Lines" ""
+ Choice "46/46 Lines" ""
+ Choice "47/47 Lines" ""
+ Choice "48/48 Lines" ""
+ Choice "49/49 Lines" ""
+ Choice "50/50 Lines" ""
+ Choice "51/51 Lines" ""
+ Choice "52/52 Lines" ""
+ Choice "53/53 Lines" ""
+ Choice "54/54 Lines" ""
+ Choice "55/55 Lines" ""
+ Choice "56/56 Lines" ""
+ Choice "57/57 Lines" ""
+ Choice "58/58 Lines" ""
+ Choice "59/59 Lines" ""
+ Choice "60/60 Lines" ""
+ Choice "61/61 Lines" ""
+ Choice "62/62 Lines" ""
+ Choice "63/63 Lines" ""
+ Choice "64/64 Lines" ""
+ Choice "65/65 Lines" ""
+ Choice "66/66 Lines" ""
+ Choice "67/67 Lines" ""
+ Choice "68/68 Lines" ""
+ Choice "69/69 Lines" ""
+ Choice "70/70 Lines" ""
+ Choice "71/71 Lines" ""
+ *Choice "72/72 Lines" ""
+ Choice "73/73 Lines" ""
+ Choice "74/74 Lines" ""
+ Choice "75/75 Lines" ""
+ Choice "76/76 Lines" ""
+ Choice "77/77 Lines" ""
+ Choice "78/78 Lines" ""
+ Choice "79/79 Lines" ""
+ Choice "80/80 Lines" ""
+ Choice "81/81 Lines" ""
+ Choice "82/82 Lines" ""
+ Choice "83/83 Lines" ""
+ Choice "84/84 Lines" ""
+ Choice "85/85 Lines" ""
+ Choice "86/86 Lines" ""
+ Choice "87/87 Lines" ""
+ Choice "88/88 Lines" ""
+ Choice "89/89 Lines" ""
+ Choice "90/90 Lines" ""
+ Choice "91/91 Lines" ""
+ Choice "92/92 Lines" ""
+ Choice "93/93 Lines" ""
+ Choice "94/94 Lines" ""
+ Choice "95/95 Lines" ""
+ Choice "96/96 Lines" ""
+ Choice "97/97 Lines" ""
+ Choice "98/98 Lines" ""
+ Choice "99/99 Lines" ""
+ Choice "100/100 Lines" ""
+ Choice "101/101 Lines" ""
+ Choice "102/102 Lines" ""
+ Choice "103/103 Lines" ""
+ Choice "104/104 Lines" ""
+ Choice "105/105 Lines" ""
+ Choice "106/106 Lines" ""
+ Choice "107/107 Lines" ""
+ Choice "108/108 Lines" ""
+ Choice "109/109 Lines" ""
+ Choice "110/110 Lines" ""
+ Choice "111/111 Lines" ""
+ Choice "112/112 Lines" ""
+ Choice "113/113 Lines" ""
+ Choice "114/114 Lines" ""
+ Choice "115/115 Lines" ""
+ Choice "116/116 Lines" ""
+ Choice "117/117 Lines" ""
+ Choice "118/118 Lines" ""
+ Choice "119/119 Lines" ""
+ Choice "120/120 Lines" ""
+ Choice "121/121 Lines" ""
+ Choice "122/122 Lines" ""
+ Choice "123/123 Lines" ""
+ Choice "124/124 Lines" ""
+ Choice "125/125 Lines" ""
+ Choice "126/126 Lines" ""
+ Choice "127/127 Lines" ""
+ Choice "128/128 Lines" ""
+ Choice "129/129 Lines" ""
+ Choice "130/130 Lines" ""
+ Choice "131/131 Lines" ""
+ Choice "132/132 Lines" ""
+ Choice "133/133 Lines" ""
+ Choice "134/134 Lines" ""
+ Choice "135/135 Lines" ""
+ Choice "136/136 Lines" ""
+ Choice "137/137 Lines" ""
+ Choice "138/138 Lines" ""
+ Choice "139/139 Lines" ""
+ Choice "140/140 Lines" ""
+ Choice "141/141 Lines" ""
+ Choice "142/142 Lines" ""
+ Choice "143/143 Lines" ""
+ Choice "144/144 Lines" ""
+ Choice "145/145 Lines" ""
+ Choice "146/146 Lines" ""
+ Choice "147/147 Lines" ""
+ Choice "148/148 Lines" ""
+ Choice "149/149 Lines" ""
+ Choice "150/150 Lines" ""
+ Choice "151/151 Lines" ""
+ Choice "152/152 Lines" ""
+ Choice "153/153 Lines" ""
+ Choice "154/154 Lines" ""
+ Choice "155/155 Lines" ""
+ Choice "156/156 Lines" ""
+ Choice "157/157 Lines" ""
+ Choice "158/158 Lines" ""
+ Choice "159/159 Lines" ""
+ Choice "160/160 Lines" ""
+ Choice "161/161 Lines" ""
+ Choice "162/162 Lines" ""
+ Choice "163/163 Lines" ""
+ Choice "164/164 Lines" ""
+ Choice "165/165 Lines" ""
+ Choice "166/166 Lines" ""
+ Choice "167/167 Lines" ""
+ Choice "168/168 Lines" ""
+ Choice "169/169 Lines" ""
+ Choice "170/170 Lines" ""
+ Choice "171/171 Lines" ""
+ Choice "172/172 Lines" ""
+ Choice "173/173 Lines" ""
+ Choice "174/174 Lines" ""
+ Choice "175/175 Lines" ""
+ Choice "176/176 Lines" ""
+ Choice "177/177 Lines" ""
+ Choice "178/178 Lines" ""
+ Choice "179/179 Lines" ""
+ Choice "180/180 Lines" ""
+ Choice "181/181 Lines" ""
+ Choice "182/182 Lines" ""
+ Choice "183/183 Lines" ""
+ Choice "184/184 Lines" ""
+ Choice "185/185 Lines" ""
+ Choice "186/186 Lines" ""
+ Choice "187/187 Lines" ""
+ Choice "188/188 Lines" ""
+ Choice "189/189 Lines" ""
+ Choice "190/190 Lines" ""
+ Choice "191/191 Lines" ""
+ Choice "192/192 Lines" ""
+ Choice "193/193 Lines" ""
+ Choice "194/194 Lines" ""
+ Choice "195/195 Lines" ""
+ Choice "196/196 Lines" ""
+ Choice "197/197 Lines" ""
+ Choice "198/198 Lines" ""
+ Choice "199/199 Lines" ""
+ Choice "200/200 Lines" ""
+ Attribute CustomFanFoldGermanNumLines True ""
+ Attribute ParamCustomFanFoldGermanNumLines Lines "1 int 1 999"
+
+ Option "FanFoldGermanNumColumns/Page Size FanFoldGerman Number of Columns" PickOne AnySetup 10.0
+ Choice "1/1 Column" ""
+ Choice "2/2 Columns" ""
+ Choice "3/3 Columns" ""
+ Choice "4/4 Columns" ""
+ Choice "5/5 Columns" ""
+ Choice "6/6 Columns" ""
+ Choice "7/7 Columns" ""
+ Choice "8/8 Columns" ""
+ Choice "9/9 Columns" ""
+ Choice "10/10 Columns" ""
+ Choice "11/11 Columns" ""
+ Choice "12/12 Columns" ""
+ Choice "13/13 Columns" ""
+ Choice "14/14 Columns" ""
+ Choice "15/15 Columns" ""
+ Choice "16/16 Columns" ""
+ Choice "17/17 Columns" ""
+ Choice "18/18 Columns" ""
+ Choice "19/19 Columns" ""
+ Choice "20/20 Columns" ""
+ Choice "21/21 Columns" ""
+ Choice "22/22 Columns" ""
+ Choice "23/23 Columns" ""
+ Choice "24/24 Columns" ""
+ Choice "25/25 Columns" ""
+ Choice "26/26 Columns" ""
+ Choice "27/27 Columns" ""
+ Choice "28/28 Columns" ""
+ Choice "29/29 Columns" ""
+ Choice "30/30 Columns" ""
+ Choice "31/31 Columns" ""
+ Choice "32/32 Columns" ""
+ Choice "33/33 Columns" ""
+ Choice "34/34 Columns" ""
+ Choice "35/35 Columns" ""
+ Choice "36/36 Columns" ""
+ Choice "37/37 Columns" ""
+ Choice "38/38 Columns" ""
+ Choice "39/39 Columns" ""
+ Choice "40/40 Columns" ""
+ Choice "41/41 Columns" ""
+ Choice "42/42 Columns" ""
+ Choice "43/43 Columns" ""
+ Choice "44/44 Columns" ""
+ Choice "45/45 Columns" ""
+ Choice "46/46 Columns" ""
+ Choice "47/47 Columns" ""
+ Choice "48/48 Columns" ""
+ Choice "49/49 Columns" ""
+ Choice "50/50 Columns" ""
+ Choice "51/51 Columns" ""
+ Choice "52/52 Columns" ""
+ Choice "53/53 Columns" ""
+ Choice "54/54 Columns" ""
+ Choice "55/55 Columns" ""
+ Choice "56/56 Columns" ""
+ Choice "57/57 Columns" ""
+ Choice "58/58 Columns" ""
+ Choice "59/59 Columns" ""
+ Choice "60/60 Columns" ""
+ Choice "61/61 Columns" ""
+ Choice "62/62 Columns" ""
+ Choice "63/63 Columns" ""
+ Choice "64/64 Columns" ""
+ Choice "65/65 Columns" ""
+ Choice "66/66 Columns" ""
+ Choice "67/67 Columns" ""
+ Choice "68/68 Columns" ""
+ Choice "69/69 Columns" ""
+ Choice "70/70 Columns" ""
+ Choice "71/71 Columns" ""
+ Choice "72/72 Columns" ""
+ Choice "73/73 Columns" ""
+ Choice "74/74 Columns" ""
+ Choice "75/75 Columns" ""
+ Choice "76/76 Columns" ""
+ Choice "77/77 Columns" ""
+ Choice "78/78 Columns" ""
+ Choice "79/79 Columns" ""
+ *Choice "80/80 Columns" ""
+ Choice "81/81 Columns" ""
+ Choice "82/82 Columns" ""
+ Choice "83/83 Columns" ""
+ Choice "84/84 Columns" ""
+ Choice "85/85 Columns" ""
+ Choice "86/86 Columns" ""
+ Choice "87/87 Columns" ""
+ Choice "88/88 Columns" ""
+ Choice "89/89 Columns" ""
+ Choice "90/90 Columns" ""
+ Choice "91/91 Columns" ""
+ Choice "92/92 Columns" ""
+ Choice "93/93 Columns" ""
+ Choice "94/94 Columns" ""
+ Choice "95/95 Columns" ""
+ Choice "96/96 Columns" ""
+ Choice "97/97 Columns" ""
+ Choice "98/98 Columns" ""
+ Choice "99/99 Columns" ""
+ Choice "100/100 Columns" ""
+ Choice "101/101 Columns" ""
+ Choice "102/102 Columns" ""
+ Choice "103/103 Columns" ""
+ Choice "104/104 Columns" ""
+ Choice "105/105 Columns" ""
+ Choice "106/106 Columns" ""
+ Choice "107/107 Columns" ""
+ Choice "108/108 Columns" ""
+ Choice "109/109 Columns" ""
+ Choice "110/110 Columns" ""
+ Choice "111/111 Columns" ""
+ Choice "112/112 Columns" ""
+ Choice "113/113 Columns" ""
+ Choice "114/114 Columns" ""
+ Choice "115/115 Columns" ""
+ Choice "116/116 Columns" ""
+ Choice "117/117 Columns" ""
+ Choice "118/118 Columns" ""
+ Choice "119/119 Columns" ""
+ Choice "120/120 Columns" ""
+ Choice "121/121 Columns" ""
+ Choice "122/122 Columns" ""
+ Choice "123/123 Columns" ""
+ Choice "124/124 Columns" ""
+ Choice "125/125 Columns" ""
+ Choice "126/126 Columns" ""
+ Choice "127/127 Columns" ""
+ Choice "128/128 Columns" ""
+ Choice "129/129 Columns" ""
+ Choice "130/130 Columns" ""
+ Choice "131/131 Columns" ""
+ Choice "132/132 Columns" ""
+ Choice "133/133 Columns" ""
+ Choice "134/134 Columns" ""
+ Choice "135/135 Columns" ""
+ Choice "136/136 Columns" ""
+ Choice "137/137 Columns" ""
+ Choice "138/138 Columns" ""
+ Choice "139/139 Columns" ""
+ Choice "140/140 Columns" ""
+ Choice "141/141 Columns" ""
+ Choice "142/142 Columns" ""
+ Choice "143/143 Columns" ""
+ Choice "144/144 Columns" ""
+ Choice "145/145 Columns" ""
+ Choice "146/146 Columns" ""
+ Choice "147/147 Columns" ""
+ Choice "148/148 Columns" ""
+ Choice "149/149 Columns" ""
+ Choice "150/150 Columns" ""
+ Choice "151/151 Columns" ""
+ Choice "152/152 Columns" ""
+ Choice "153/153 Columns" ""
+ Choice "154/154 Columns" ""
+ Choice "155/155 Columns" ""
+ Choice "156/156 Columns" ""
+ Choice "157/157 Columns" ""
+ Choice "158/158 Columns" ""
+ Choice "159/159 Columns" ""
+ Choice "160/160 Columns" ""
+ Choice "161/161 Columns" ""
+ Choice "162/162 Columns" ""
+ Choice "163/163 Columns" ""
+ Choice "164/164 Columns" ""
+ Choice "165/165 Columns" ""
+ Choice "166/166 Columns" ""
+ Choice "167/167 Columns" ""
+ Choice "168/168 Columns" ""
+ Choice "169/169 Columns" ""
+ Choice "170/170 Columns" ""
+ Choice "171/171 Columns" ""
+ Choice "172/172 Columns" ""
+ Choice "173/173 Columns" ""
+ Choice "174/174 Columns" ""
+ Choice "175/175 Columns" ""
+ Choice "176/176 Columns" ""
+ Choice "177/177 Columns" ""
+ Choice "178/178 Columns" ""
+ Choice "179/179 Columns" ""
+ Choice "180/180 Columns" ""
+ Choice "181/181 Columns" ""
+ Choice "182/182 Columns" ""
+ Choice "183/183 Columns" ""
+ Choice "184/184 Columns" ""
+ Choice "185/185 Columns" ""
+ Choice "186/186 Columns" ""
+ Choice "187/187 Columns" ""
+ Choice "188/188 Columns" ""
+ Choice "189/189 Columns" ""
+ Choice "190/190 Columns" ""
+ Choice "191/191 Columns" ""
+ Choice "192/192 Columns" ""
+ Choice "193/193 Columns" ""
+ Choice "194/194 Columns" ""
+ Choice "195/195 Columns" ""
+ Choice "196/196 Columns" ""
+ Choice "197/197 Columns" ""
+ Choice "198/198 Columns" ""
+ Choice "199/199 Columns" ""
+ Choice "200/200 Columns" ""
+ Attribute CustomFanFoldGermanNumColumns True ""
+ Attribute ParamCustomFanFoldGermanNumColumns Columns "1 int 1 999"
+
+
+ Option "FanFoldGermanLegalAvailable/Page Size FanFoldGermanLegal available" Boolean AnySetup 10.0
+ *Choice "True/Yes" ""
+ Choice "False/No" ""
+
+ Option "FanFoldGermanLegalNumLines/Page Size FanFoldGermanLegal Number of Lines" PickOne AnySetup 10.0
+ Choice "1/1 Line" ""
+ Choice "2/2 Lines" ""
+ Choice "3/3 Lines" ""
+ Choice "4/4 Lines" ""
+ Choice "5/5 Lines" ""
+ Choice "6/6 Lines" ""
+ Choice "7/7 Lines" ""
+ Choice "8/8 Lines" ""
+ Choice "9/9 Lines" ""
+ Choice "10/10 Lines" ""
+ Choice "11/11 Lines" ""
+ Choice "12/12 Lines" ""
+ Choice "13/13 Lines" ""
+ Choice "14/14 Lines" ""
+ Choice "15/15 Lines" ""
+ Choice "16/16 Lines" ""
+ Choice "17/17 Lines" ""
+ Choice "18/18 Lines" ""
+ Choice "19/19 Lines" ""
+ Choice "20/20 Lines" ""
+ Choice "21/21 Lines" ""
+ Choice "22/22 Lines" ""
+ Choice "23/23 Lines" ""
+ Choice "24/24 Lines" ""
+ Choice "25/25 Lines" ""
+ Choice "26/26 Lines" ""
+ Choice "27/27 Lines" ""
+ Choice "28/28 Lines" ""
+ Choice "29/29 Lines" ""
+ Choice "30/30 Lines" ""
+ Choice "31/31 Lines" ""
+ Choice "32/32 Lines" ""
+ Choice "33/33 Lines" ""
+ Choice "34/34 Lines" ""
+ Choice "35/35 Lines" ""
+ Choice "36/36 Lines" ""
+ Choice "37/37 Lines" ""
+ Choice "38/38 Lines" ""
+ Choice "39/39 Lines" ""
+ Choice "40/40 Lines" ""
+ Choice "41/41 Lines" ""
+ Choice "42/42 Lines" ""
+ Choice "43/43 Lines" ""
+ Choice "44/44 Lines" ""
+ Choice "45/45 Lines" ""
+ Choice "46/46 Lines" ""
+ Choice "47/47 Lines" ""
+ Choice "48/48 Lines" ""
+ Choice "49/49 Lines" ""
+ Choice "50/50 Lines" ""
+ Choice "51/51 Lines" ""
+ Choice "52/52 Lines" ""
+ Choice "53/53 Lines" ""
+ Choice "54/54 Lines" ""
+ Choice "55/55 Lines" ""
+ Choice "56/56 Lines" ""
+ Choice "57/57 Lines" ""
+ Choice "58/58 Lines" ""
+ Choice "59/59 Lines" ""
+ Choice "60/60 Lines" ""
+ Choice "61/61 Lines" ""
+ Choice "62/62 Lines" ""
+ Choice "63/63 Lines" ""
+ Choice "64/64 Lines" ""
+ Choice "65/65 Lines" ""
+ Choice "66/66 Lines" ""
+ Choice "67/67 Lines" ""
+ Choice "68/68 Lines" ""
+ Choice "69/69 Lines" ""
+ Choice "70/70 Lines" ""
+ Choice "71/71 Lines" ""
+ Choice "72/72 Lines" ""
+ Choice "73/73 Lines" ""
+ Choice "74/74 Lines" ""
+ Choice "75/75 Lines" ""
+ Choice "76/76 Lines" ""
+ Choice "77/77 Lines" ""
+ *Choice "78/78 Lines" ""
+ Choice "79/79 Lines" ""
+ Choice "80/80 Lines" ""
+ Choice "81/81 Lines" ""
+ Choice "82/82 Lines" ""
+ Choice "83/83 Lines" ""
+ Choice "84/84 Lines" ""
+ Choice "85/85 Lines" ""
+ Choice "86/86 Lines" ""
+ Choice "87/87 Lines" ""
+ Choice "88/88 Lines" ""
+ Choice "89/89 Lines" ""
+ Choice "90/90 Lines" ""
+ Choice "91/91 Lines" ""
+ Choice "92/92 Lines" ""
+ Choice "93/93 Lines" ""
+ Choice "94/94 Lines" ""
+ Choice "95/95 Lines" ""
+ Choice "96/96 Lines" ""
+ Choice "97/97 Lines" ""
+ Choice "98/98 Lines" ""
+ Choice "99/99 Lines" ""
+ Choice "100/100 Lines" ""
+ Choice "101/101 Lines" ""
+ Choice "102/102 Lines" ""
+ Choice "103/103 Lines" ""
+ Choice "104/104 Lines" ""
+ Choice "105/105 Lines" ""
+ Choice "106/106 Lines" ""
+ Choice "107/107 Lines" ""
+ Choice "108/108 Lines" ""
+ Choice "109/109 Lines" ""
+ Choice "110/110 Lines" ""
+ Choice "111/111 Lines" ""
+ Choice "112/112 Lines" ""
+ Choice "113/113 Lines" ""
+ Choice "114/114 Lines" ""
+ Choice "115/115 Lines" ""
+ Choice "116/116 Lines" ""
+ Choice "117/117 Lines" ""
+ Choice "118/118 Lines" ""
+ Choice "119/119 Lines" ""
+ Choice "120/120 Lines" ""
+ Choice "121/121 Lines" ""
+ Choice "122/122 Lines" ""
+ Choice "123/123 Lines" ""
+ Choice "124/124 Lines" ""
+ Choice "125/125 Lines" ""
+ Choice "126/126 Lines" ""
+ Choice "127/127 Lines" ""
+ Choice "128/128 Lines" ""
+ Choice "129/129 Lines" ""
+ Choice "130/130 Lines" ""
+ Choice "131/131 Lines" ""
+ Choice "132/132 Lines" ""
+ Choice "133/133 Lines" ""
+ Choice "134/134 Lines" ""
+ Choice "135/135 Lines" ""
+ Choice "136/136 Lines" ""
+ Choice "137/137 Lines" ""
+ Choice "138/138 Lines" ""
+ Choice "139/139 Lines" ""
+ Choice "140/140 Lines" ""
+ Choice "141/141 Lines" ""
+ Choice "142/142 Lines" ""
+ Choice "143/143 Lines" ""
+ Choice "144/144 Lines" ""
+ Choice "145/145 Lines" ""
+ Choice "146/146 Lines" ""
+ Choice "147/147 Lines" ""
+ Choice "148/148 Lines" ""
+ Choice "149/149 Lines" ""
+ Choice "150/150 Lines" ""
+ Choice "151/151 Lines" ""
+ Choice "152/152 Lines" ""
+ Choice "153/153 Lines" ""
+ Choice "154/154 Lines" ""
+ Choice "155/155 Lines" ""
+ Choice "156/156 Lines" ""
+ Choice "157/157 Lines" ""
+ Choice "158/158 Lines" ""
+ Choice "159/159 Lines" ""
+ Choice "160/160 Lines" ""
+ Choice "161/161 Lines" ""
+ Choice "162/162 Lines" ""
+ Choice "163/163 Lines" ""
+ Choice "164/164 Lines" ""
+ Choice "165/165 Lines" ""
+ Choice "166/166 Lines" ""
+ Choice "167/167 Lines" ""
+ Choice "168/168 Lines" ""
+ Choice "169/169 Lines" ""
+ Choice "170/170 Lines" ""
+ Choice "171/171 Lines" ""
+ Choice "172/172 Lines" ""
+ Choice "173/173 Lines" ""
+ Choice "174/174 Lines" ""
+ Choice "175/175 Lines" ""
+ Choice "176/176 Lines" ""
+ Choice "177/177 Lines" ""
+ Choice "178/178 Lines" ""
+ Choice "179/179 Lines" ""
+ Choice "180/180 Lines" ""
+ Choice "181/181 Lines" ""
+ Choice "182/182 Lines" ""
+ Choice "183/183 Lines" ""
+ Choice "184/184 Lines" ""
+ Choice "185/185 Lines" ""
+ Choice "186/186 Lines" ""
+ Choice "187/187 Lines" ""
+ Choice "188/188 Lines" ""
+ Choice "189/189 Lines" ""
+ Choice "190/190 Lines" ""
+ Choice "191/191 Lines" ""
+ Choice "192/192 Lines" ""
+ Choice "193/193 Lines" ""
+ Choice "194/194 Lines" ""
+ Choice "195/195 Lines" ""
+ Choice "196/196 Lines" ""
+ Choice "197/197 Lines" ""
+ Choice "198/198 Lines" ""
+ Choice "199/199 Lines" ""
+ Choice "200/200 Lines" ""
+ Attribute CustomFanFoldGermanLegalNumLines True ""
+ Attribute ParamCustomFanFoldGermanLegalNumLines Lines "1 int 1 999"
+
+ Option "FanFoldGermanLegalNumColumns/Page Size FanFoldGermanLegal Number of Columns" PickOne AnySetup 10.0
+ Choice "1/1 Column" ""
+ Choice "2/2 Columns" ""
+ Choice "3/3 Columns" ""
+ Choice "4/4 Columns" ""
+ Choice "5/5 Columns" ""
+ Choice "6/6 Columns" ""
+ Choice "7/7 Columns" ""
+ Choice "8/8 Columns" ""
+ Choice "9/9 Columns" ""
+ Choice "10/10 Columns" ""
+ Choice "11/11 Columns" ""
+ Choice "12/12 Columns" ""
+ Choice "13/13 Columns" ""
+ Choice "14/14 Columns" ""
+ Choice "15/15 Columns" ""
+ Choice "16/16 Columns" ""
+ Choice "17/17 Columns" ""
+ Choice "18/18 Columns" ""
+ Choice "19/19 Columns" ""
+ Choice "20/20 Columns" ""
+ Choice "21/21 Columns" ""
+ Choice "22/22 Columns" ""
+ Choice "23/23 Columns" ""
+ Choice "24/24 Columns" ""
+ Choice "25/25 Columns" ""
+ Choice "26/26 Columns" ""
+ Choice "27/27 Columns" ""
+ Choice "28/28 Columns" ""
+ Choice "29/29 Columns" ""
+ Choice "30/30 Columns" ""
+ Choice "31/31 Columns" ""
+ Choice "32/32 Columns" ""
+ Choice "33/33 Columns" ""
+ Choice "34/34 Columns" ""
+ Choice "35/35 Columns" ""
+ Choice "36/36 Columns" ""
+ Choice "37/37 Columns" ""
+ Choice "38/38 Columns" ""
+ Choice "39/39 Columns" ""
+ Choice "40/40 Columns" ""
+ Choice "41/41 Columns" ""
+ Choice "42/42 Columns" ""
+ Choice "43/43 Columns" ""
+ Choice "44/44 Columns" ""
+ Choice "45/45 Columns" ""
+ Choice "46/46 Columns" ""
+ Choice "47/47 Columns" ""
+ Choice "48/48 Columns" ""
+ Choice "49/49 Columns" ""
+ Choice "50/50 Columns" ""
+ Choice "51/51 Columns" ""
+ Choice "52/52 Columns" ""
+ Choice "53/53 Columns" ""
+ Choice "54/54 Columns" ""
+ Choice "55/55 Columns" ""
+ Choice "56/56 Columns" ""
+ Choice "57/57 Columns" ""
+ Choice "58/58 Columns" ""
+ Choice "59/59 Columns" ""
+ Choice "60/60 Columns" ""
+ Choice "61/61 Columns" ""
+ Choice "62/62 Columns" ""
+ Choice "63/63 Columns" ""
+ Choice "64/64 Columns" ""
+ Choice "65/65 Columns" ""
+ Choice "66/66 Columns" ""
+ Choice "67/67 Columns" ""
+ Choice "68/68 Columns" ""
+ Choice "69/69 Columns" ""
+ Choice "70/70 Columns" ""
+ Choice "71/71 Columns" ""
+ Choice "72/72 Columns" ""
+ Choice "73/73 Columns" ""
+ Choice "74/74 Columns" ""
+ Choice "75/75 Columns" ""
+ Choice "76/76 Columns" ""
+ Choice "77/77 Columns" ""
+ Choice "78/78 Columns" ""
+ Choice "79/79 Columns" ""
+ *Choice "80/80 Columns" ""
+ Choice "81/81 Columns" ""
+ Choice "82/82 Columns" ""
+ Choice "83/83 Columns" ""
+ Choice "84/84 Columns" ""
+ Choice "85/85 Columns" ""
+ Choice "86/86 Columns" ""
+ Choice "87/87 Columns" ""
+ Choice "88/88 Columns" ""
+ Choice "89/89 Columns" ""
+ Choice "90/90 Columns" ""
+ Choice "91/91 Columns" ""
+ Choice "92/92 Columns" ""
+ Choice "93/93 Columns" ""
+ Choice "94/94 Columns" ""
+ Choice "95/95 Columns" ""
+ Choice "96/96 Columns" ""
+ Choice "97/97 Columns" ""
+ Choice "98/98 Columns" ""
+ Choice "99/99 Columns" ""
+ Choice "100/100 Columns" ""
+ Choice "101/101 Columns" ""
+ Choice "102/102 Columns" ""
+ Choice "103/103 Columns" ""
+ Choice "104/104 Columns" ""
+ Choice "105/105 Columns" ""
+ Choice "106/106 Columns" ""
+ Choice "107/107 Columns" ""
+ Choice "108/108 Columns" ""
+ Choice "109/109 Columns" ""
+ Choice "110/110 Columns" ""
+ Choice "111/111 Columns" ""
+ Choice "112/112 Columns" ""
+ Choice "113/113 Columns" ""
+ Choice "114/114 Columns" ""
+ Choice "115/115 Columns" ""
+ Choice "116/116 Columns" ""
+ Choice "117/117 Columns" ""
+ Choice "118/118 Columns" ""
+ Choice "119/119 Columns" ""
+ Choice "120/120 Columns" ""
+ Choice "121/121 Columns" ""
+ Choice "122/122 Columns" ""
+ Choice "123/123 Columns" ""
+ Choice "124/124 Columns" ""
+ Choice "125/125 Columns" ""
+ Choice "126/126 Columns" ""
+ Choice "127/127 Columns" ""
+ Choice "128/128 Columns" ""
+ Choice "129/129 Columns" ""
+ Choice "130/130 Columns" ""
+ Choice "131/131 Columns" ""
+ Choice "132/132 Columns" ""
+ Choice "133/133 Columns" ""
+ Choice "134/134 Columns" ""
+ Choice "135/135 Columns" ""
+ Choice "136/136 Columns" ""
+ Choice "137/137 Columns" ""
+ Choice "138/138 Columns" ""
+ Choice "139/139 Columns" ""
+ Choice "140/140 Columns" ""
+ Choice "141/141 Columns" ""
+ Choice "142/142 Columns" ""
+ Choice "143/143 Columns" ""
+ Choice "144/144 Columns" ""
+ Choice "145/145 Columns" ""
+ Choice "146/146 Columns" ""
+ Choice "147/147 Columns" ""
+ Choice "148/148 Columns" ""
+ Choice "149/149 Columns" ""
+ Choice "150/150 Columns" ""
+ Choice "151/151 Columns" ""
+ Choice "152/152 Columns" ""
+ Choice "153/153 Columns" ""
+ Choice "154/154 Columns" ""
+ Choice "155/155 Columns" ""
+ Choice "156/156 Columns" ""
+ Choice "157/157 Columns" ""
+ Choice "158/158 Columns" ""
+ Choice "159/159 Columns" ""
+ Choice "160/160 Columns" ""
+ Choice "161/161 Columns" ""
+ Choice "162/162 Columns" ""
+ Choice "163/163 Columns" ""
+ Choice "164/164 Columns" ""
+ Choice "165/165 Columns" ""
+ Choice "166/166 Columns" ""
+ Choice "167/167 Columns" ""
+ Choice "168/168 Columns" ""
+ Choice "169/169 Columns" ""
+ Choice "170/170 Columns" ""
+ Choice "171/171 Columns" ""
+ Choice "172/172 Columns" ""
+ Choice "173/173 Columns" ""
+ Choice "174/174 Columns" ""
+ Choice "175/175 Columns" ""
+ Choice "176/176 Columns" ""
+ Choice "177/177 Columns" ""
+ Choice "178/178 Columns" ""
+ Choice "179/179 Columns" ""
+ Choice "180/180 Columns" ""
+ Choice "181/181 Columns" ""
+ Choice "182/182 Columns" ""
+ Choice "183/183 Columns" ""
+ Choice "184/184 Columns" ""
+ Choice "185/185 Columns" ""
+ Choice "186/186 Columns" ""
+ Choice "187/187 Columns" ""
+ Choice "188/188 Columns" ""
+ Choice "189/189 Columns" ""
+ Choice "190/190 Columns" ""
+ Choice "191/191 Columns" ""
+ Choice "192/192 Columns" ""
+ Choice "193/193 Columns" ""
+ Choice "194/194 Columns" ""
+ Choice "195/195 Columns" ""
+ Choice "196/196 Columns" ""
+ Choice "197/197 Columns" ""
+ Choice "198/198 Columns" ""
+ Choice "199/199 Columns" ""
+ Choice "200/200 Columns" ""
+ Attribute CustomFanFoldGermanLegalNumColumns True ""
+ Attribute ParamCustomFanFoldGermanLegalNumColumns Columns "1 int 1 999"
+
+
+ Option "11x14RotatedAvailable/Page Size 11x14Rotated available" Boolean AnySetup 10.0
+ *Choice "True/Yes" ""
+ Choice "False/No" ""
+
+ Option "11x14RotatedNumLines/Page Size 11x14Rotated Number of Lines" PickOne AnySetup 10.0
+ Choice "1/1 Line" ""
+ Choice "2/2 Lines" ""
+ Choice "3/3 Lines" ""
+ Choice "4/4 Lines" ""
+ Choice "5/5 Lines" ""
+ Choice "6/6 Lines" ""
+ Choice "7/7 Lines" ""
+ Choice "8/8 Lines" ""
+ Choice "9/9 Lines" ""
+ Choice "10/10 Lines" ""
+ Choice "11/11 Lines" ""
+ Choice "12/12 Lines" ""
+ Choice "13/13 Lines" ""
+ Choice "14/14 Lines" ""
+ Choice "15/15 Lines" ""
+ Choice "16/16 Lines" ""
+ Choice "17/17 Lines" ""
+ Choice "18/18 Lines" ""
+ Choice "19/19 Lines" ""
+ Choice "20/20 Lines" ""
+ Choice "21/21 Lines" ""
+ Choice "22/22 Lines" ""
+ Choice "23/23 Lines" ""
+ Choice "24/24 Lines" ""
+ Choice "25/25 Lines" ""
+ Choice "26/26 Lines" ""
+ Choice "27/27 Lines" ""
+ Choice "28/28 Lines" ""
+ Choice "29/29 Lines" ""
+ Choice "30/30 Lines" ""
+ Choice "31/31 Lines" ""
+ Choice "32/32 Lines" ""
+ Choice "33/33 Lines" ""
+ Choice "34/34 Lines" ""
+ Choice "35/35 Lines" ""
+ Choice "36/36 Lines" ""
+ Choice "37/37 Lines" ""
+ Choice "38/38 Lines" ""
+ Choice "39/39 Lines" ""
+ Choice "40/40 Lines" ""
+ Choice "41/41 Lines" ""
+ Choice "42/42 Lines" ""
+ Choice "43/43 Lines" ""
+ Choice "44/44 Lines" ""
+ Choice "45/45 Lines" ""
+ Choice "46/46 Lines" ""
+ Choice "47/47 Lines" ""
+ Choice "48/48 Lines" ""
+ Choice "49/49 Lines" ""
+ Choice "50/50 Lines" ""
+ Choice "51/51 Lines" ""
+ Choice "52/52 Lines" ""
+ Choice "53/53 Lines" ""
+ Choice "54/54 Lines" ""
+ Choice "55/55 Lines" ""
+ Choice "56/56 Lines" ""
+ Choice "57/57 Lines" ""
+ Choice "58/58 Lines" ""
+ Choice "59/59 Lines" ""
+ Choice "60/60 Lines" ""
+ Choice "61/61 Lines" ""
+ Choice "62/62 Lines" ""
+ Choice "63/63 Lines" ""
+ Choice "64/64 Lines" ""
+ Choice "65/65 Lines" ""
+ *Choice "66/66 Lines" ""
+ Choice "67/67 Lines" ""
+ Choice "68/68 Lines" ""
+ Choice "69/69 Lines" ""
+ Choice "70/70 Lines" ""
+ Choice "71/71 Lines" ""
+ Choice "72/72 Lines" ""
+ Choice "73/73 Lines" ""
+ Choice "74/74 Lines" ""
+ Choice "75/75 Lines" ""
+ Choice "76/76 Lines" ""
+ Choice "77/77 Lines" ""
+ Choice "78/78 Lines" ""
+ Choice "79/79 Lines" ""
+ Choice "80/80 Lines" ""
+ Choice "81/81 Lines" ""
+ Choice "82/82 Lines" ""
+ Choice "83/83 Lines" ""
+ Choice "84/84 Lines" ""
+ Choice "85/85 Lines" ""
+ Choice "86/86 Lines" ""
+ Choice "87/87 Lines" ""
+ Choice "88/88 Lines" ""
+ Choice "89/89 Lines" ""
+ Choice "90/90 Lines" ""
+ Choice "91/91 Lines" ""
+ Choice "92/92 Lines" ""
+ Choice "93/93 Lines" ""
+ Choice "94/94 Lines" ""
+ Choice "95/95 Lines" ""
+ Choice "96/96 Lines" ""
+ Choice "97/97 Lines" ""
+ Choice "98/98 Lines" ""
+ Choice "99/99 Lines" ""
+ Choice "100/100 Lines" ""
+ Choice "101/101 Lines" ""
+ Choice "102/102 Lines" ""
+ Choice "103/103 Lines" ""
+ Choice "104/104 Lines" ""
+ Choice "105/105 Lines" ""
+ Choice "106/106 Lines" ""
+ Choice "107/107 Lines" ""
+ Choice "108/108 Lines" ""
+ Choice "109/109 Lines" ""
+ Choice "110/110 Lines" ""
+ Choice "111/111 Lines" ""
+ Choice "112/112 Lines" ""
+ Choice "113/113 Lines" ""
+ Choice "114/114 Lines" ""
+ Choice "115/115 Lines" ""
+ Choice "116/116 Lines" ""
+ Choice "117/117 Lines" ""
+ Choice "118/118 Lines" ""
+ Choice "119/119 Lines" ""
+ Choice "120/120 Lines" ""
+ Choice "121/121 Lines" ""
+ Choice "122/122 Lines" ""
+ Choice "123/123 Lines" ""
+ Choice "124/124 Lines" ""
+ Choice "125/125 Lines" ""
+ Choice "126/126 Lines" ""
+ Choice "127/127 Lines" ""
+ Choice "128/128 Lines" ""
+ Choice "129/129 Lines" ""
+ Choice "130/130 Lines" ""
+ Choice "131/131 Lines" ""
+ Choice "132/132 Lines" ""
+ Choice "133/133 Lines" ""
+ Choice "134/134 Lines" ""
+ Choice "135/135 Lines" ""
+ Choice "136/136 Lines" ""
+ Choice "137/137 Lines" ""
+ Choice "138/138 Lines" ""
+ Choice "139/139 Lines" ""
+ Choice "140/140 Lines" ""
+ Choice "141/141 Lines" ""
+ Choice "142/142 Lines" ""
+ Choice "143/143 Lines" ""
+ Choice "144/144 Lines" ""
+ Choice "145/145 Lines" ""
+ Choice "146/146 Lines" ""
+ Choice "147/147 Lines" ""
+ Choice "148/148 Lines" ""
+ Choice "149/149 Lines" ""
+ Choice "150/150 Lines" ""
+ Choice "151/151 Lines" ""
+ Choice "152/152 Lines" ""
+ Choice "153/153 Lines" ""
+ Choice "154/154 Lines" ""
+ Choice "155/155 Lines" ""
+ Choice "156/156 Lines" ""
+ Choice "157/157 Lines" ""
+ Choice "158/158 Lines" ""
+ Choice "159/159 Lines" ""
+ Choice "160/160 Lines" ""
+ Choice "161/161 Lines" ""
+ Choice "162/162 Lines" ""
+ Choice "163/163 Lines" ""
+ Choice "164/164 Lines" ""
+ Choice "165/165 Lines" ""
+ Choice "166/166 Lines" ""
+ Choice "167/167 Lines" ""
+ Choice "168/168 Lines" ""
+ Choice "169/169 Lines" ""
+ Choice "170/170 Lines" ""
+ Choice "171/171 Lines" ""
+ Choice "172/172 Lines" ""
+ Choice "173/173 Lines" ""
+ Choice "174/174 Lines" ""
+ Choice "175/175 Lines" ""
+ Choice "176/176 Lines" ""
+ Choice "177/177 Lines" ""
+ Choice "178/178 Lines" ""
+ Choice "179/179 Lines" ""
+ Choice "180/180 Lines" ""
+ Choice "181/181 Lines" ""
+ Choice "182/182 Lines" ""
+ Choice "183/183 Lines" ""
+ Choice "184/184 Lines" ""
+ Choice "185/185 Lines" ""
+ Choice "186/186 Lines" ""
+ Choice "187/187 Lines" ""
+ Choice "188/188 Lines" ""
+ Choice "189/189 Lines" ""
+ Choice "190/190 Lines" ""
+ Choice "191/191 Lines" ""
+ Choice "192/192 Lines" ""
+ Choice "193/193 Lines" ""
+ Choice "194/194 Lines" ""
+ Choice "195/195 Lines" ""
+ Choice "196/196 Lines" ""
+ Choice "197/197 Lines" ""
+ Choice "198/198 Lines" ""
+ Choice "199/199 Lines" ""
+ Choice "200/200 Lines" ""
+ Attribute Custom11x14RotatedNumLines True ""
+ Attribute ParamCustom11x14RotatedNumLines Lines "1 int 1 999"
+
+ Option "11x14RotatedNumColumns/Page Size 11x14Rotated Number of Columns" PickOne AnySetup 10.0
+ Choice "1/1 Column" ""
+ Choice "2/2 Columns" ""
+ Choice "3/3 Columns" ""
+ Choice "4/4 Columns" ""
+ Choice "5/5 Columns" ""
+ Choice "6/6 Columns" ""
+ Choice "7/7 Columns" ""
+ Choice "8/8 Columns" ""
+ Choice "9/9 Columns" ""
+ Choice "10/10 Columns" ""
+ Choice "11/11 Columns" ""
+ Choice "12/12 Columns" ""
+ Choice "13/13 Columns" ""
+ Choice "14/14 Columns" ""
+ Choice "15/15 Columns" ""
+ Choice "16/16 Columns" ""
+ Choice "17/17 Columns" ""
+ Choice "18/18 Columns" ""
+ Choice "19/19 Columns" ""
+ Choice "20/20 Columns" ""
+ Choice "21/21 Columns" ""
+ Choice "22/22 Columns" ""
+ Choice "23/23 Columns" ""
+ Choice "24/24 Columns" ""
+ Choice "25/25 Columns" ""
+ Choice "26/26 Columns" ""
+ Choice "27/27 Columns" ""
+ Choice "28/28 Columns" ""
+ Choice "29/29 Columns" ""
+ Choice "30/30 Columns" ""
+ Choice "31/31 Columns" ""
+ Choice "32/32 Columns" ""
+ Choice "33/33 Columns" ""
+ Choice "34/34 Columns" ""
+ Choice "35/35 Columns" ""
+ Choice "36/36 Columns" ""
+ Choice "37/37 Columns" ""
+ Choice "38/38 Columns" ""
+ Choice "39/39 Columns" ""
+ Choice "40/40 Columns" ""
+ Choice "41/41 Columns" ""
+ Choice "42/42 Columns" ""
+ Choice "43/43 Columns" ""
+ Choice "44/44 Columns" ""
+ Choice "45/45 Columns" ""
+ Choice "46/46 Columns" ""
+ Choice "47/47 Columns" ""
+ Choice "48/48 Columns" ""
+ Choice "49/49 Columns" ""
+ Choice "50/50 Columns" ""
+ Choice "51/51 Columns" ""
+ Choice "52/52 Columns" ""
+ Choice "53/53 Columns" ""
+ Choice "54/54 Columns" ""
+ Choice "55/55 Columns" ""
+ Choice "56/56 Columns" ""
+ Choice "57/57 Columns" ""
+ Choice "58/58 Columns" ""
+ Choice "59/59 Columns" ""
+ Choice "60/60 Columns" ""
+ Choice "61/61 Columns" ""
+ Choice "62/62 Columns" ""
+ Choice "63/63 Columns" ""
+ Choice "64/64 Columns" ""
+ Choice "65/65 Columns" ""
+ Choice "66/66 Columns" ""
+ Choice "67/67 Columns" ""
+ Choice "68/68 Columns" ""
+ Choice "69/69 Columns" ""
+ Choice "70/70 Columns" ""
+ Choice "71/71 Columns" ""
+ Choice "72/72 Columns" ""
+ Choice "73/73 Columns" ""
+ Choice "74/74 Columns" ""
+ Choice "75/75 Columns" ""
+ Choice "76/76 Columns" ""
+ Choice "77/77 Columns" ""
+ Choice "78/78 Columns" ""
+ Choice "79/79 Columns" ""
+ Choice "80/80 Columns" ""
+ Choice "81/81 Columns" ""
+ Choice "82/82 Columns" ""
+ Choice "83/83 Columns" ""
+ Choice "84/84 Columns" ""
+ Choice "85/85 Columns" ""
+ Choice "86/86 Columns" ""
+ Choice "87/87 Columns" ""
+ Choice "88/88 Columns" ""
+ Choice "89/89 Columns" ""
+ Choice "90/90 Columns" ""
+ Choice "91/91 Columns" ""
+ Choice "92/92 Columns" ""
+ Choice "93/93 Columns" ""
+ Choice "94/94 Columns" ""
+ Choice "95/95 Columns" ""
+ Choice "96/96 Columns" ""
+ Choice "97/97 Columns" ""
+ Choice "98/98 Columns" ""
+ Choice "99/99 Columns" ""
+ Choice "100/100 Columns" ""
+ Choice "101/101 Columns" ""
+ Choice "102/102 Columns" ""
+ Choice "103/103 Columns" ""
+ Choice "104/104 Columns" ""
+ Choice "105/105 Columns" ""
+ Choice "106/106 Columns" ""
+ Choice "107/107 Columns" ""
+ Choice "108/108 Columns" ""
+ Choice "109/109 Columns" ""
+ Choice "110/110 Columns" ""
+ Choice "111/111 Columns" ""
+ Choice "112/112 Columns" ""
+ Choice "113/113 Columns" ""
+ Choice "114/114 Columns" ""
+ Choice "115/115 Columns" ""
+ Choice "116/116 Columns" ""
+ Choice "117/117 Columns" ""
+ Choice "118/118 Columns" ""
+ Choice "119/119 Columns" ""
+ Choice "120/120 Columns" ""
+ Choice "121/121 Columns" ""
+ Choice "122/122 Columns" ""
+ Choice "123/123 Columns" ""
+ Choice "124/124 Columns" ""
+ Choice "125/125 Columns" ""
+ Choice "126/126 Columns" ""
+ Choice "127/127 Columns" ""
+ Choice "128/128 Columns" ""
+ Choice "129/129 Columns" ""
+ Choice "130/130 Columns" ""
+ Choice "131/131 Columns" ""
+ *Choice "132/132 Columns" ""
+ Choice "133/133 Columns" ""
+ Choice "134/134 Columns" ""
+ Choice "135/135 Columns" ""
+ Choice "136/136 Columns" ""
+ Choice "137/137 Columns" ""
+ Choice "138/138 Columns" ""
+ Choice "139/139 Columns" ""
+ Choice "140/140 Columns" ""
+ Choice "141/141 Columns" ""
+ Choice "142/142 Columns" ""
+ Choice "143/143 Columns" ""
+ Choice "144/144 Columns" ""
+ Choice "145/145 Columns" ""
+ Choice "146/146 Columns" ""
+ Choice "147/147 Columns" ""
+ Choice "148/148 Columns" ""
+ Choice "149/149 Columns" ""
+ Choice "150/150 Columns" ""
+ Choice "151/151 Columns" ""
+ Choice "152/152 Columns" ""
+ Choice "153/153 Columns" ""
+ Choice "154/154 Columns" ""
+ Choice "155/155 Columns" ""
+ Choice "156/156 Columns" ""
+ Choice "157/157 Columns" ""
+ Choice "158/158 Columns" ""
+ Choice "159/159 Columns" ""
+ Choice "160/160 Columns" ""
+ Choice "161/161 Columns" ""
+ Choice "162/162 Columns" ""
+ Choice "163/163 Columns" ""
+ Choice "164/164 Columns" ""
+ Choice "165/165 Columns" ""
+ Choice "166/166 Columns" ""
+ Choice "167/167 Columns" ""
+ Choice "168/168 Columns" ""
+ Choice "169/169 Columns" ""
+ Choice "170/170 Columns" ""
+ Choice "171/171 Columns" ""
+ Choice "172/172 Columns" ""
+ Choice "173/173 Columns" ""
+ Choice "174/174 Columns" ""
+ Choice "175/175 Columns" ""
+ Choice "176/176 Columns" ""
+ Choice "177/177 Columns" ""
+ Choice "178/178 Columns" ""
+ Choice "179/179 Columns" ""
+ Choice "180/180 Columns" ""
+ Choice "181/181 Columns" ""
+ Choice "182/182 Columns" ""
+ Choice "183/183 Columns" ""
+ Choice "184/184 Columns" ""
+ Choice "185/185 Columns" ""
+ Choice "186/186 Columns" ""
+ Choice "187/187 Columns" ""
+ Choice "188/188 Columns" ""
+ Choice "189/189 Columns" ""
+ Choice "190/190 Columns" ""
+ Choice "191/191 Columns" ""
+ Choice "192/192 Columns" ""
+ Choice "193/193 Columns" ""
+ Choice "194/194 Columns" ""
+ Choice "195/195 Columns" ""
+ Choice "196/196 Columns" ""
+ Choice "197/197 Columns" ""
+ Choice "198/198 Columns" ""
+ Choice "199/199 Columns" ""
+ Choice "200/200 Columns" ""
+ Attribute Custom11x14RotatedNumColumns True ""
+ Attribute ParamCustom11x14RotatedNumColumns Columns "1 int 1 999"
+
+
+ Option "LegalRotatedAvailable/Page Size LegalRotated available" Boolean AnySetup 10.0
+ *Choice "True/Yes" ""
+ Choice "False/No" ""
+
+ Option "LegalRotatedNumLines/Page Size LegalRotated Number of Lines" PickOne AnySetup 10.0
+ Choice "1/1 Line" ""
+ Choice "2/2 Lines" ""
+ Choice "3/3 Lines" ""
+ Choice "4/4 Lines" ""
+ Choice "5/5 Lines" ""
+ Choice "6/6 Lines" ""
+ Choice "7/7 Lines" ""
+ Choice "8/8 Lines" ""
+ Choice "9/9 Lines" ""
+ Choice "10/10 Lines" ""
+ Choice "11/11 Lines" ""
+ Choice "12/12 Lines" ""
+ Choice "13/13 Lines" ""
+ Choice "14/14 Lines" ""
+ Choice "15/15 Lines" ""
+ Choice "16/16 Lines" ""
+ Choice "17/17 Lines" ""
+ Choice "18/18 Lines" ""
+ Choice "19/19 Lines" ""
+ Choice "20/20 Lines" ""
+ Choice "21/21 Lines" ""
+ Choice "22/22 Lines" ""
+ Choice "23/23 Lines" ""
+ Choice "24/24 Lines" ""
+ Choice "25/25 Lines" ""
+ Choice "26/26 Lines" ""
+ Choice "27/27 Lines" ""
+ Choice "28/28 Lines" ""
+ Choice "29/29 Lines" ""
+ Choice "30/30 Lines" ""
+ Choice "31/31 Lines" ""
+ Choice "32/32 Lines" ""
+ Choice "33/33 Lines" ""
+ Choice "34/34 Lines" ""
+ Choice "35/35 Lines" ""
+ Choice "36/36 Lines" ""
+ Choice "37/37 Lines" ""
+ Choice "38/38 Lines" ""
+ Choice "39/39 Lines" ""
+ Choice "40/40 Lines" ""
+ Choice "41/41 Lines" ""
+ Choice "42/42 Lines" ""
+ Choice "43/43 Lines" ""
+ Choice "44/44 Lines" ""
+ Choice "45/45 Lines" ""
+ Choice "46/46 Lines" ""
+ Choice "47/47 Lines" ""
+ Choice "48/48 Lines" ""
+ Choice "49/49 Lines" ""
+ Choice "50/50 Lines" ""
+ *Choice "51/51 Lines" ""
+ Choice "52/52 Lines" ""
+ Choice "53/53 Lines" ""
+ Choice "54/54 Lines" ""
+ Choice "55/55 Lines" ""
+ Choice "56/56 Lines" ""
+ Choice "57/57 Lines" ""
+ Choice "58/58 Lines" ""
+ Choice "59/59 Lines" ""
+ Choice "60/60 Lines" ""
+ Choice "61/61 Lines" ""
+ Choice "62/62 Lines" ""
+ Choice "63/63 Lines" ""
+ Choice "64/64 Lines" ""
+ Choice "65/65 Lines" ""
+ Choice "66/66 Lines" ""
+ Choice "67/67 Lines" ""
+ Choice "68/68 Lines" ""
+ Choice "69/69 Lines" ""
+ Choice "70/70 Lines" ""
+ Choice "71/71 Lines" ""
+ Choice "72/72 Lines" ""
+ Choice "73/73 Lines" ""
+ Choice "74/74 Lines" ""
+ Choice "75/75 Lines" ""
+ Choice "76/76 Lines" ""
+ Choice "77/77 Lines" ""
+ Choice "78/78 Lines" ""
+ Choice "79/79 Lines" ""
+ Choice "80/80 Lines" ""
+ Choice "81/81 Lines" ""
+ Choice "82/82 Lines" ""
+ Choice "83/83 Lines" ""
+ Choice "84/84 Lines" ""
+ Choice "85/85 Lines" ""
+ Choice "86/86 Lines" ""
+ Choice "87/87 Lines" ""
+ Choice "88/88 Lines" ""
+ Choice "89/89 Lines" ""
+ Choice "90/90 Lines" ""
+ Choice "91/91 Lines" ""
+ Choice "92/92 Lines" ""
+ Choice "93/93 Lines" ""
+ Choice "94/94 Lines" ""
+ Choice "95/95 Lines" ""
+ Choice "96/96 Lines" ""
+ Choice "97/97 Lines" ""
+ Choice "98/98 Lines" ""
+ Choice "99/99 Lines" ""
+ Choice "100/100 Lines" ""
+ Choice "101/101 Lines" ""
+ Choice "102/102 Lines" ""
+ Choice "103/103 Lines" ""
+ Choice "104/104 Lines" ""
+ Choice "105/105 Lines" ""
+ Choice "106/106 Lines" ""
+ Choice "107/107 Lines" ""
+ Choice "108/108 Lines" ""
+ Choice "109/109 Lines" ""
+ Choice "110/110 Lines" ""
+ Choice "111/111 Lines" ""
+ Choice "112/112 Lines" ""
+ Choice "113/113 Lines" ""
+ Choice "114/114 Lines" ""
+ Choice "115/115 Lines" ""
+ Choice "116/116 Lines" ""
+ Choice "117/117 Lines" ""
+ Choice "118/118 Lines" ""
+ Choice "119/119 Lines" ""
+ Choice "120/120 Lines" ""
+ Choice "121/121 Lines" ""
+ Choice "122/122 Lines" ""
+ Choice "123/123 Lines" ""
+ Choice "124/124 Lines" ""
+ Choice "125/125 Lines" ""
+ Choice "126/126 Lines" ""
+ Choice "127/127 Lines" ""
+ Choice "128/128 Lines" ""
+ Choice "129/129 Lines" ""
+ Choice "130/130 Lines" ""
+ Choice "131/131 Lines" ""
+ Choice "132/132 Lines" ""
+ Choice "133/133 Lines" ""
+ Choice "134/134 Lines" ""
+ Choice "135/135 Lines" ""
+ Choice "136/136 Lines" ""
+ Choice "137/137 Lines" ""
+ Choice "138/138 Lines" ""
+ Choice "139/139 Lines" ""
+ Choice "140/140 Lines" ""
+ Choice "141/141 Lines" ""
+ Choice "142/142 Lines" ""
+ Choice "143/143 Lines" ""
+ Choice "144/144 Lines" ""
+ Choice "145/145 Lines" ""
+ Choice "146/146 Lines" ""
+ Choice "147/147 Lines" ""
+ Choice "148/148 Lines" ""
+ Choice "149/149 Lines" ""
+ Choice "150/150 Lines" ""
+ Choice "151/151 Lines" ""
+ Choice "152/152 Lines" ""
+ Choice "153/153 Lines" ""
+ Choice "154/154 Lines" ""
+ Choice "155/155 Lines" ""
+ Choice "156/156 Lines" ""
+ Choice "157/157 Lines" ""
+ Choice "158/158 Lines" ""
+ Choice "159/159 Lines" ""
+ Choice "160/160 Lines" ""
+ Choice "161/161 Lines" ""
+ Choice "162/162 Lines" ""
+ Choice "163/163 Lines" ""
+ Choice "164/164 Lines" ""
+ Choice "165/165 Lines" ""
+ Choice "166/166 Lines" ""
+ Choice "167/167 Lines" ""
+ Choice "168/168 Lines" ""
+ Choice "169/169 Lines" ""
+ Choice "170/170 Lines" ""
+ Choice "171/171 Lines" ""
+ Choice "172/172 Lines" ""
+ Choice "173/173 Lines" ""
+ Choice "174/174 Lines" ""
+ Choice "175/175 Lines" ""
+ Choice "176/176 Lines" ""
+ Choice "177/177 Lines" ""
+ Choice "178/178 Lines" ""
+ Choice "179/179 Lines" ""
+ Choice "180/180 Lines" ""
+ Choice "181/181 Lines" ""
+ Choice "182/182 Lines" ""
+ Choice "183/183 Lines" ""
+ Choice "184/184 Lines" ""
+ Choice "185/185 Lines" ""
+ Choice "186/186 Lines" ""
+ Choice "187/187 Lines" ""
+ Choice "188/188 Lines" ""
+ Choice "189/189 Lines" ""
+ Choice "190/190 Lines" ""
+ Choice "191/191 Lines" ""
+ Choice "192/192 Lines" ""
+ Choice "193/193 Lines" ""
+ Choice "194/194 Lines" ""
+ Choice "195/195 Lines" ""
+ Choice "196/196 Lines" ""
+ Choice "197/197 Lines" ""
+ Choice "198/198 Lines" ""
+ Choice "199/199 Lines" ""
+ Choice "200/200 Lines" ""
+ Attribute CustomLegalRotatedNumLines True ""
+ Attribute ParamCustomLegalRotatedNumLines Lines "1 int 1 999"
+
+ Option "LegalRotatedNumColumns/Page Size LegalRotated Number of Columns" PickOne AnySetup 10.0
+ Choice "1/1 Column" ""
+ Choice "2/2 Columns" ""
+ Choice "3/3 Columns" ""
+ Choice "4/4 Columns" ""
+ Choice "5/5 Columns" ""
+ Choice "6/6 Columns" ""
+ Choice "7/7 Columns" ""
+ Choice "8/8 Columns" ""
+ Choice "9/9 Columns" ""
+ Choice "10/10 Columns" ""
+ Choice "11/11 Columns" ""
+ Choice "12/12 Columns" ""
+ Choice "13/13 Columns" ""
+ Choice "14/14 Columns" ""
+ Choice "15/15 Columns" ""
+ Choice "16/16 Columns" ""
+ Choice "17/17 Columns" ""
+ Choice "18/18 Columns" ""
+ Choice "19/19 Columns" ""
+ Choice "20/20 Columns" ""
+ Choice "21/21 Columns" ""
+ Choice "22/22 Columns" ""
+ Choice "23/23 Columns" ""
+ Choice "24/24 Columns" ""
+ Choice "25/25 Columns" ""
+ Choice "26/26 Columns" ""
+ Choice "27/27 Columns" ""
+ Choice "28/28 Columns" ""
+ Choice "29/29 Columns" ""
+ Choice "30/30 Columns" ""
+ Choice "31/31 Columns" ""
+ Choice "32/32 Columns" ""
+ Choice "33/33 Columns" ""
+ Choice "34/34 Columns" ""
+ Choice "35/35 Columns" ""
+ Choice "36/36 Columns" ""
+ Choice "37/37 Columns" ""
+ Choice "38/38 Columns" ""
+ Choice "39/39 Columns" ""
+ Choice "40/40 Columns" ""
+ Choice "41/41 Columns" ""
+ Choice "42/42 Columns" ""
+ Choice "43/43 Columns" ""
+ Choice "44/44 Columns" ""
+ Choice "45/45 Columns" ""
+ Choice "46/46 Columns" ""
+ Choice "47/47 Columns" ""
+ Choice "48/48 Columns" ""
+ Choice "49/49 Columns" ""
+ Choice "50/50 Columns" ""
+ Choice "51/51 Columns" ""
+ Choice "52/52 Columns" ""
+ Choice "53/53 Columns" ""
+ Choice "54/54 Columns" ""
+ Choice "55/55 Columns" ""
+ Choice "56/56 Columns" ""
+ Choice "57/57 Columns" ""
+ Choice "58/58 Columns" ""
+ Choice "59/59 Columns" ""
+ Choice "60/60 Columns" ""
+ Choice "61/61 Columns" ""
+ Choice "62/62 Columns" ""
+ Choice "63/63 Columns" ""
+ Choice "64/64 Columns" ""
+ Choice "65/65 Columns" ""
+ Choice "66/66 Columns" ""
+ Choice "67/67 Columns" ""
+ Choice "68/68 Columns" ""
+ Choice "69/69 Columns" ""
+ Choice "70/70 Columns" ""
+ Choice "71/71 Columns" ""
+ Choice "72/72 Columns" ""
+ Choice "73/73 Columns" ""
+ Choice "74/74 Columns" ""
+ Choice "75/75 Columns" ""
+ Choice "76/76 Columns" ""
+ Choice "77/77 Columns" ""
+ Choice "78/78 Columns" ""
+ Choice "79/79 Columns" ""
+ Choice "80/80 Columns" ""
+ Choice "81/81 Columns" ""
+ Choice "82/82 Columns" ""
+ Choice "83/83 Columns" ""
+ Choice "84/84 Columns" ""
+ Choice "85/85 Columns" ""
+ Choice "86/86 Columns" ""
+ Choice "87/87 Columns" ""
+ Choice "88/88 Columns" ""
+ Choice "89/89 Columns" ""
+ Choice "90/90 Columns" ""
+ Choice "91/91 Columns" ""
+ Choice "92/92 Columns" ""
+ Choice "93/93 Columns" ""
+ Choice "94/94 Columns" ""
+ Choice "95/95 Columns" ""
+ Choice "96/96 Columns" ""
+ Choice "97/97 Columns" ""
+ Choice "98/98 Columns" ""
+ Choice "99/99 Columns" ""
+ Choice "100/100 Columns" ""
+ Choice "101/101 Columns" ""
+ Choice "102/102 Columns" ""
+ Choice "103/103 Columns" ""
+ Choice "104/104 Columns" ""
+ Choice "105/105 Columns" ""
+ Choice "106/106 Columns" ""
+ Choice "107/107 Columns" ""
+ Choice "108/108 Columns" ""
+ Choice "109/109 Columns" ""
+ Choice "110/110 Columns" ""
+ Choice "111/111 Columns" ""
+ Choice "112/112 Columns" ""
+ Choice "113/113 Columns" ""
+ Choice "114/114 Columns" ""
+ Choice "115/115 Columns" ""
+ Choice "116/116 Columns" ""
+ Choice "117/117 Columns" ""
+ Choice "118/118 Columns" ""
+ Choice "119/119 Columns" ""
+ Choice "120/120 Columns" ""
+ Choice "121/121 Columns" ""
+ Choice "122/122 Columns" ""
+ Choice "123/123 Columns" ""
+ Choice "124/124 Columns" ""
+ Choice "125/125 Columns" ""
+ Choice "126/126 Columns" ""
+ Choice "127/127 Columns" ""
+ Choice "128/128 Columns" ""
+ Choice "129/129 Columns" ""
+ Choice "130/130 Columns" ""
+ Choice "131/131 Columns" ""
+ *Choice "132/132 Columns" ""
+ Choice "133/133 Columns" ""
+ Choice "134/134 Columns" ""
+ Choice "135/135 Columns" ""
+ Choice "136/136 Columns" ""
+ Choice "137/137 Columns" ""
+ Choice "138/138 Columns" ""
+ Choice "139/139 Columns" ""
+ Choice "140/140 Columns" ""
+ Choice "141/141 Columns" ""
+ Choice "142/142 Columns" ""
+ Choice "143/143 Columns" ""
+ Choice "144/144 Columns" ""
+ Choice "145/145 Columns" ""
+ Choice "146/146 Columns" ""
+ Choice "147/147 Columns" ""
+ Choice "148/148 Columns" ""
+ Choice "149/149 Columns" ""
+ Choice "150/150 Columns" ""
+ Choice "151/151 Columns" ""
+ Choice "152/152 Columns" ""
+ Choice "153/153 Columns" ""
+ Choice "154/154 Columns" ""
+ Choice "155/155 Columns" ""
+ Choice "156/156 Columns" ""
+ Choice "157/157 Columns" ""
+ Choice "158/158 Columns" ""
+ Choice "159/159 Columns" ""
+ Choice "160/160 Columns" ""
+ Choice "161/161 Columns" ""
+ Choice "162/162 Columns" ""
+ Choice "163/163 Columns" ""
+ Choice "164/164 Columns" ""
+ Choice "165/165 Columns" ""
+ Choice "166/166 Columns" ""
+ Choice "167/167 Columns" ""
+ Choice "168/168 Columns" ""
+ Choice "169/169 Columns" ""
+ Choice "170/170 Columns" ""
+ Choice "171/171 Columns" ""
+ Choice "172/172 Columns" ""
+ Choice "173/173 Columns" ""
+ Choice "174/174 Columns" ""
+ Choice "175/175 Columns" ""
+ Choice "176/176 Columns" ""
+ Choice "177/177 Columns" ""
+ Choice "178/178 Columns" ""
+ Choice "179/179 Columns" ""
+ Choice "180/180 Columns" ""
+ Choice "181/181 Columns" ""
+ Choice "182/182 Columns" ""
+ Choice "183/183 Columns" ""
+ Choice "184/184 Columns" ""
+ Choice "185/185 Columns" ""
+ Choice "186/186 Columns" ""
+ Choice "187/187 Columns" ""
+ Choice "188/188 Columns" ""
+ Choice "189/189 Columns" ""
+ Choice "190/190 Columns" ""
+ Choice "191/191 Columns" ""
+ Choice "192/192 Columns" ""
+ Choice "193/193 Columns" ""
+ Choice "194/194 Columns" ""
+ Choice "195/195 Columns" ""
+ Choice "196/196 Columns" ""
+ Choice "197/197 Columns" ""
+ Choice "198/198 Columns" ""
+ Choice "199/199 Columns" ""
+ Choice "200/200 Columns" ""
+ Attribute CustomLegalRotatedNumColumns True ""
+ Attribute ParamCustomLegalRotatedNumColumns Columns "1 int 1 999"
+
+
+ Option "Custom1Available/Page Size Custom1 available" Boolean AnySetup 10.0
+ Choice "True/Yes" ""
+ *Choice "False/No" ""
+
+ Option "Custom1NumLines/Page Size Custom1 Number of Lines" PickOne AnySetup 10.0
+ Choice "1/1 Line" ""
+ Choice "2/2 Lines" ""
+ Choice "3/3 Lines" ""
+ Choice "4/4 Lines" ""
+ Choice "5/5 Lines" ""
+ Choice "6/6 Lines" ""
+ Choice "7/7 Lines" ""
+ Choice "8/8 Lines" ""
+ Choice "9/9 Lines" ""
+ Choice "10/10 Lines" ""
+ Choice "11/11 Lines" ""
+ Choice "12/12 Lines" ""
+ Choice "13/13 Lines" ""
+ Choice "14/14 Lines" ""
+ Choice "15/15 Lines" ""
+ Choice "16/16 Lines" ""
+ Choice "17/17 Lines" ""
+ Choice "18/18 Lines" ""
+ Choice "19/19 Lines" ""
+ Choice "20/20 Lines" ""
+ Choice "21/21 Lines" ""
+ Choice "22/22 Lines" ""
+ Choice "23/23 Lines" ""
+ Choice "24/24 Lines" ""
+ Choice "25/25 Lines" ""
+ Choice "26/26 Lines" ""
+ Choice "27/27 Lines" ""
+ Choice "28/28 Lines" ""
+ Choice "29/29 Lines" ""
+ Choice "30/30 Lines" ""
+ Choice "31/31 Lines" ""
+ Choice "32/32 Lines" ""
+ Choice "33/33 Lines" ""
+ Choice "34/34 Lines" ""
+ Choice "35/35 Lines" ""
+ Choice "36/36 Lines" ""
+ Choice "37/37 Lines" ""
+ Choice "38/38 Lines" ""
+ Choice "39/39 Lines" ""
+ Choice "40/40 Lines" ""
+ Choice "41/41 Lines" ""
+ Choice "42/42 Lines" ""
+ Choice "43/43 Lines" ""
+ Choice "44/44 Lines" ""
+ Choice "45/45 Lines" ""
+ Choice "46/46 Lines" ""
+ Choice "47/47 Lines" ""
+ Choice "48/48 Lines" ""
+ Choice "49/49 Lines" ""
+ Choice "50/50 Lines" ""
+ Choice "51/51 Lines" ""
+ Choice "52/52 Lines" ""
+ Choice "53/53 Lines" ""
+ Choice "54/54 Lines" ""
+ Choice "55/55 Lines" ""
+ Choice "56/56 Lines" ""
+ Choice "57/57 Lines" ""
+ Choice "58/58 Lines" ""
+ Choice "59/59 Lines" ""
+ Choice "60/60 Lines" ""
+ Choice "61/61 Lines" ""
+ Choice "62/62 Lines" ""
+ Choice "63/63 Lines" ""
+ Choice "64/64 Lines" ""
+ Choice "65/65 Lines" ""
+ *Choice "66/66 Lines" ""
+ Choice "67/67 Lines" ""
+ Choice "68/68 Lines" ""
+ Choice "69/69 Lines" ""
+ Choice "70/70 Lines" ""
+ Choice "71/71 Lines" ""
+ Choice "72/72 Lines" ""
+ Choice "73/73 Lines" ""
+ Choice "74/74 Lines" ""
+ Choice "75/75 Lines" ""
+ Choice "76/76 Lines" ""
+ Choice "77/77 Lines" ""
+ Choice "78/78 Lines" ""
+ Choice "79/79 Lines" ""
+ Choice "80/80 Lines" ""
+ Choice "81/81 Lines" ""
+ Choice "82/82 Lines" ""
+ Choice "83/83 Lines" ""
+ Choice "84/84 Lines" ""
+ Choice "85/85 Lines" ""
+ Choice "86/86 Lines" ""
+ Choice "87/87 Lines" ""
+ Choice "88/88 Lines" ""
+ Choice "89/89 Lines" ""
+ Choice "90/90 Lines" ""
+ Choice "91/91 Lines" ""
+ Choice "92/92 Lines" ""
+ Choice "93/93 Lines" ""
+ Choice "94/94 Lines" ""
+ Choice "95/95 Lines" ""
+ Choice "96/96 Lines" ""
+ Choice "97/97 Lines" ""
+ Choice "98/98 Lines" ""
+ Choice "99/99 Lines" ""
+ Choice "100/100 Lines" ""
+ Choice "101/101 Lines" ""
+ Choice "102/102 Lines" ""
+ Choice "103/103 Lines" ""
+ Choice "104/104 Lines" ""
+ Choice "105/105 Lines" ""
+ Choice "106/106 Lines" ""
+ Choice "107/107 Lines" ""
+ Choice "108/108 Lines" ""
+ Choice "109/109 Lines" ""
+ Choice "110/110 Lines" ""
+ Choice "111/111 Lines" ""
+ Choice "112/112 Lines" ""
+ Choice "113/113 Lines" ""
+ Choice "114/114 Lines" ""
+ Choice "115/115 Lines" ""
+ Choice "116/116 Lines" ""
+ Choice "117/117 Lines" ""
+ Choice "118/118 Lines" ""
+ Choice "119/119 Lines" ""
+ Choice "120/120 Lines" ""
+ Choice "121/121 Lines" ""
+ Choice "122/122 Lines" ""
+ Choice "123/123 Lines" ""
+ Choice "124/124 Lines" ""
+ Choice "125/125 Lines" ""
+ Choice "126/126 Lines" ""
+ Choice "127/127 Lines" ""
+ Choice "128/128 Lines" ""
+ Choice "129/129 Lines" ""
+ Choice "130/130 Lines" ""
+ Choice "131/131 Lines" ""
+ Choice "132/132 Lines" ""
+ Choice "133/133 Lines" ""
+ Choice "134/134 Lines" ""
+ Choice "135/135 Lines" ""
+ Choice "136/136 Lines" ""
+ Choice "137/137 Lines" ""
+ Choice "138/138 Lines" ""
+ Choice "139/139 Lines" ""
+ Choice "140/140 Lines" ""
+ Choice "141/141 Lines" ""
+ Choice "142/142 Lines" ""
+ Choice "143/143 Lines" ""
+ Choice "144/144 Lines" ""
+ Choice "145/145 Lines" ""
+ Choice "146/146 Lines" ""
+ Choice "147/147 Lines" ""
+ Choice "148/148 Lines" ""
+ Choice "149/149 Lines" ""
+ Choice "150/150 Lines" ""
+ Choice "151/151 Lines" ""
+ Choice "152/152 Lines" ""
+ Choice "153/153 Lines" ""
+ Choice "154/154 Lines" ""
+ Choice "155/155 Lines" ""
+ Choice "156/156 Lines" ""
+ Choice "157/157 Lines" ""
+ Choice "158/158 Lines" ""
+ Choice "159/159 Lines" ""
+ Choice "160/160 Lines" ""
+ Choice "161/161 Lines" ""
+ Choice "162/162 Lines" ""
+ Choice "163/163 Lines" ""
+ Choice "164/164 Lines" ""
+ Choice "165/165 Lines" ""
+ Choice "166/166 Lines" ""
+ Choice "167/167 Lines" ""
+ Choice "168/168 Lines" ""
+ Choice "169/169 Lines" ""
+ Choice "170/170 Lines" ""
+ Choice "171/171 Lines" ""
+ Choice "172/172 Lines" ""
+ Choice "173/173 Lines" ""
+ Choice "174/174 Lines" ""
+ Choice "175/175 Lines" ""
+ Choice "176/176 Lines" ""
+ Choice "177/177 Lines" ""
+ Choice "178/178 Lines" ""
+ Choice "179/179 Lines" ""
+ Choice "180/180 Lines" ""
+ Choice "181/181 Lines" ""
+ Choice "182/182 Lines" ""
+ Choice "183/183 Lines" ""
+ Choice "184/184 Lines" ""
+ Choice "185/185 Lines" ""
+ Choice "186/186 Lines" ""
+ Choice "187/187 Lines" ""
+ Choice "188/188 Lines" ""
+ Choice "189/189 Lines" ""
+ Choice "190/190 Lines" ""
+ Choice "191/191 Lines" ""
+ Choice "192/192 Lines" ""
+ Choice "193/193 Lines" ""
+ Choice "194/194 Lines" ""
+ Choice "195/195 Lines" ""
+ Choice "196/196 Lines" ""
+ Choice "197/197 Lines" ""
+ Choice "198/198 Lines" ""
+ Choice "199/199 Lines" ""
+ Choice "200/200 Lines" ""
+ Attribute CustomCustom1NumLines True ""
+ Attribute ParamCustomCustom1NumLines Lines "1 int 1 999"
+
+ Option "Custom1NumColumns/Page Size Custom1 Number of Columns" PickOne AnySetup 10.0
+ Choice "1/1 Column" ""
+ Choice "2/2 Columns" ""
+ Choice "3/3 Columns" ""
+ Choice "4/4 Columns" ""
+ Choice "5/5 Columns" ""
+ Choice "6/6 Columns" ""
+ Choice "7/7 Columns" ""
+ Choice "8/8 Columns" ""
+ Choice "9/9 Columns" ""
+ Choice "10/10 Columns" ""
+ Choice "11/11 Columns" ""
+ Choice "12/12 Columns" ""
+ Choice "13/13 Columns" ""
+ Choice "14/14 Columns" ""
+ Choice "15/15 Columns" ""
+ Choice "16/16 Columns" ""
+ Choice "17/17 Columns" ""
+ Choice "18/18 Columns" ""
+ Choice "19/19 Columns" ""
+ Choice "20/20 Columns" ""
+ Choice "21/21 Columns" ""
+ Choice "22/22 Columns" ""
+ Choice "23/23 Columns" ""
+ Choice "24/24 Columns" ""
+ Choice "25/25 Columns" ""
+ Choice "26/26 Columns" ""
+ Choice "27/27 Columns" ""
+ Choice "28/28 Columns" ""
+ Choice "29/29 Columns" ""
+ Choice "30/30 Columns" ""
+ Choice "31/31 Columns" ""
+ Choice "32/32 Columns" ""
+ Choice "33/33 Columns" ""
+ Choice "34/34 Columns" ""
+ Choice "35/35 Columns" ""
+ Choice "36/36 Columns" ""
+ Choice "37/37 Columns" ""
+ Choice "38/38 Columns" ""
+ Choice "39/39 Columns" ""
+ Choice "40/40 Columns" ""
+ Choice "41/41 Columns" ""
+ Choice "42/42 Columns" ""
+ Choice "43/43 Columns" ""
+ Choice "44/44 Columns" ""
+ Choice "45/45 Columns" ""
+ Choice "46/46 Columns" ""
+ Choice "47/47 Columns" ""
+ Choice "48/48 Columns" ""
+ Choice "49/49 Columns" ""
+ Choice "50/50 Columns" ""
+ Choice "51/51 Columns" ""
+ Choice "52/52 Columns" ""
+ Choice "53/53 Columns" ""
+ Choice "54/54 Columns" ""
+ Choice "55/55 Columns" ""
+ Choice "56/56 Columns" ""
+ Choice "57/57 Columns" ""
+ Choice "58/58 Columns" ""
+ Choice "59/59 Columns" ""
+ Choice "60/60 Columns" ""
+ Choice "61/61 Columns" ""
+ Choice "62/62 Columns" ""
+ Choice "63/63 Columns" ""
+ Choice "64/64 Columns" ""
+ Choice "65/65 Columns" ""
+ Choice "66/66 Columns" ""
+ Choice "67/67 Columns" ""
+ Choice "68/68 Columns" ""
+ Choice "69/69 Columns" ""
+ Choice "70/70 Columns" ""
+ Choice "71/71 Columns" ""
+ Choice "72/72 Columns" ""
+ Choice "73/73 Columns" ""
+ Choice "74/74 Columns" ""
+ Choice "75/75 Columns" ""
+ Choice "76/76 Columns" ""
+ Choice "77/77 Columns" ""
+ Choice "78/78 Columns" ""
+ Choice "79/79 Columns" ""
+ *Choice "80/80 Columns" ""
+ Choice "81/81 Columns" ""
+ Choice "82/82 Columns" ""
+ Choice "83/83 Columns" ""
+ Choice "84/84 Columns" ""
+ Choice "85/85 Columns" ""
+ Choice "86/86 Columns" ""
+ Choice "87/87 Columns" ""
+ Choice "88/88 Columns" ""
+ Choice "89/89 Columns" ""
+ Choice "90/90 Columns" ""
+ Choice "91/91 Columns" ""
+ Choice "92/92 Columns" ""
+ Choice "93/93 Columns" ""
+ Choice "94/94 Columns" ""
+ Choice "95/95 Columns" ""
+ Choice "96/96 Columns" ""
+ Choice "97/97 Columns" ""
+ Choice "98/98 Columns" ""
+ Choice "99/99 Columns" ""
+ Choice "100/100 Columns" ""
+ Choice "101/101 Columns" ""
+ Choice "102/102 Columns" ""
+ Choice "103/103 Columns" ""
+ Choice "104/104 Columns" ""
+ Choice "105/105 Columns" ""
+ Choice "106/106 Columns" ""
+ Choice "107/107 Columns" ""
+ Choice "108/108 Columns" ""
+ Choice "109/109 Columns" ""
+ Choice "110/110 Columns" ""
+ Choice "111/111 Columns" ""
+ Choice "112/112 Columns" ""
+ Choice "113/113 Columns" ""
+ Choice "114/114 Columns" ""
+ Choice "115/115 Columns" ""
+ Choice "116/116 Columns" ""
+ Choice "117/117 Columns" ""
+ Choice "118/118 Columns" ""
+ Choice "119/119 Columns" ""
+ Choice "120/120 Columns" ""
+ Choice "121/121 Columns" ""
+ Choice "122/122 Columns" ""
+ Choice "123/123 Columns" ""
+ Choice "124/124 Columns" ""
+ Choice "125/125 Columns" ""
+ Choice "126/126 Columns" ""
+ Choice "127/127 Columns" ""
+ Choice "128/128 Columns" ""
+ Choice "129/129 Columns" ""
+ Choice "130/130 Columns" ""
+ Choice "131/131 Columns" ""
+ Choice "132/132 Columns" ""
+ Choice "133/133 Columns" ""
+ Choice "134/134 Columns" ""
+ Choice "135/135 Columns" ""
+ Choice "136/136 Columns" ""
+ Choice "137/137 Columns" ""
+ Choice "138/138 Columns" ""
+ Choice "139/139 Columns" ""
+ Choice "140/140 Columns" ""
+ Choice "141/141 Columns" ""
+ Choice "142/142 Columns" ""
+ Choice "143/143 Columns" ""
+ Choice "144/144 Columns" ""
+ Choice "145/145 Columns" ""
+ Choice "146/146 Columns" ""
+ Choice "147/147 Columns" ""
+ Choice "148/148 Columns" ""
+ Choice "149/149 Columns" ""
+ Choice "150/150 Columns" ""
+ Choice "151/151 Columns" ""
+ Choice "152/152 Columns" ""
+ Choice "153/153 Columns" ""
+ Choice "154/154 Columns" ""
+ Choice "155/155 Columns" ""
+ Choice "156/156 Columns" ""
+ Choice "157/157 Columns" ""
+ Choice "158/158 Columns" ""
+ Choice "159/159 Columns" ""
+ Choice "160/160 Columns" ""
+ Choice "161/161 Columns" ""
+ Choice "162/162 Columns" ""
+ Choice "163/163 Columns" ""
+ Choice "164/164 Columns" ""
+ Choice "165/165 Columns" ""
+ Choice "166/166 Columns" ""
+ Choice "167/167 Columns" ""
+ Choice "168/168 Columns" ""
+ Choice "169/169 Columns" ""
+ Choice "170/170 Columns" ""
+ Choice "171/171 Columns" ""
+ Choice "172/172 Columns" ""
+ Choice "173/173 Columns" ""
+ Choice "174/174 Columns" ""
+ Choice "175/175 Columns" ""
+ Choice "176/176 Columns" ""
+ Choice "177/177 Columns" ""
+ Choice "178/178 Columns" ""
+ Choice "179/179 Columns" ""
+ Choice "180/180 Columns" ""
+ Choice "181/181 Columns" ""
+ Choice "182/182 Columns" ""
+ Choice "183/183 Columns" ""
+ Choice "184/184 Columns" ""
+ Choice "185/185 Columns" ""
+ Choice "186/186 Columns" ""
+ Choice "187/187 Columns" ""
+ Choice "188/188 Columns" ""
+ Choice "189/189 Columns" ""
+ Choice "190/190 Columns" ""
+ Choice "191/191 Columns" ""
+ Choice "192/192 Columns" ""
+ Choice "193/193 Columns" ""
+ Choice "194/194 Columns" ""
+ Choice "195/195 Columns" ""
+ Choice "196/196 Columns" ""
+ Choice "197/197 Columns" ""
+ Choice "198/198 Columns" ""
+ Choice "199/199 Columns" ""
+ Choice "200/200 Columns" ""
+ Attribute CustomCustom1NumColumns True ""
+ Attribute ParamCustomCustom1NumColumns Columns "1 int 1 999"
+
+
+ Option "Custom2Available/Page Size Custom2 available" Boolean AnySetup 10.0
+ Choice "True/Yes" ""
+ *Choice "False/No" ""
+
+ Option "Custom2NumLines/Page Size Custom2 Number of Lines" PickOne AnySetup 10.0
+ Choice "1/1 Line" ""
+ Choice "2/2 Lines" ""
+ Choice "3/3 Lines" ""
+ Choice "4/4 Lines" ""
+ Choice "5/5 Lines" ""
+ Choice "6/6 Lines" ""
+ Choice "7/7 Lines" ""
+ Choice "8/8 Lines" ""
+ Choice "9/9 Lines" ""
+ Choice "10/10 Lines" ""
+ Choice "11/11 Lines" ""
+ Choice "12/12 Lines" ""
+ Choice "13/13 Lines" ""
+ Choice "14/14 Lines" ""
+ Choice "15/15 Lines" ""
+ Choice "16/16 Lines" ""
+ Choice "17/17 Lines" ""
+ Choice "18/18 Lines" ""
+ Choice "19/19 Lines" ""
+ Choice "20/20 Lines" ""
+ Choice "21/21 Lines" ""
+ Choice "22/22 Lines" ""
+ Choice "23/23 Lines" ""
+ Choice "24/24 Lines" ""
+ Choice "25/25 Lines" ""
+ Choice "26/26 Lines" ""
+ Choice "27/27 Lines" ""
+ Choice "28/28 Lines" ""
+ Choice "29/29 Lines" ""
+ Choice "30/30 Lines" ""
+ Choice "31/31 Lines" ""
+ Choice "32/32 Lines" ""
+ Choice "33/33 Lines" ""
+ Choice "34/34 Lines" ""
+ Choice "35/35 Lines" ""
+ Choice "36/36 Lines" ""
+ Choice "37/37 Lines" ""
+ Choice "38/38 Lines" ""
+ Choice "39/39 Lines" ""
+ Choice "40/40 Lines" ""
+ Choice "41/41 Lines" ""
+ Choice "42/42 Lines" ""
+ Choice "43/43 Lines" ""
+ Choice "44/44 Lines" ""
+ Choice "45/45 Lines" ""
+ Choice "46/46 Lines" ""
+ Choice "47/47 Lines" ""
+ Choice "48/48 Lines" ""
+ Choice "49/49 Lines" ""
+ Choice "50/50 Lines" ""
+ Choice "51/51 Lines" ""
+ Choice "52/52 Lines" ""
+ Choice "53/53 Lines" ""
+ Choice "54/54 Lines" ""
+ Choice "55/55 Lines" ""
+ Choice "56/56 Lines" ""
+ Choice "57/57 Lines" ""
+ Choice "58/58 Lines" ""
+ Choice "59/59 Lines" ""
+ Choice "60/60 Lines" ""
+ Choice "61/61 Lines" ""
+ Choice "62/62 Lines" ""
+ Choice "63/63 Lines" ""
+ Choice "64/64 Lines" ""
+ Choice "65/65 Lines" ""
+ *Choice "66/66 Lines" ""
+ Choice "67/67 Lines" ""
+ Choice "68/68 Lines" ""
+ Choice "69/69 Lines" ""
+ Choice "70/70 Lines" ""
+ Choice "71/71 Lines" ""
+ Choice "72/72 Lines" ""
+ Choice "73/73 Lines" ""
+ Choice "74/74 Lines" ""
+ Choice "75/75 Lines" ""
+ Choice "76/76 Lines" ""
+ Choice "77/77 Lines" ""
+ Choice "78/78 Lines" ""
+ Choice "79/79 Lines" ""
+ Choice "80/80 Lines" ""
+ Choice "81/81 Lines" ""
+ Choice "82/82 Lines" ""
+ Choice "83/83 Lines" ""
+ Choice "84/84 Lines" ""
+ Choice "85/85 Lines" ""
+ Choice "86/86 Lines" ""
+ Choice "87/87 Lines" ""
+ Choice "88/88 Lines" ""
+ Choice "89/89 Lines" ""
+ Choice "90/90 Lines" ""
+ Choice "91/91 Lines" ""
+ Choice "92/92 Lines" ""
+ Choice "93/93 Lines" ""
+ Choice "94/94 Lines" ""
+ Choice "95/95 Lines" ""
+ Choice "96/96 Lines" ""
+ Choice "97/97 Lines" ""
+ Choice "98/98 Lines" ""
+ Choice "99/99 Lines" ""
+ Choice "100/100 Lines" ""
+ Choice "101/101 Lines" ""
+ Choice "102/102 Lines" ""
+ Choice "103/103 Lines" ""
+ Choice "104/104 Lines" ""
+ Choice "105/105 Lines" ""
+ Choice "106/106 Lines" ""
+ Choice "107/107 Lines" ""
+ Choice "108/108 Lines" ""
+ Choice "109/109 Lines" ""
+ Choice "110/110 Lines" ""
+ Choice "111/111 Lines" ""
+ Choice "112/112 Lines" ""
+ Choice "113/113 Lines" ""
+ Choice "114/114 Lines" ""
+ Choice "115/115 Lines" ""
+ Choice "116/116 Lines" ""
+ Choice "117/117 Lines" ""
+ Choice "118/118 Lines" ""
+ Choice "119/119 Lines" ""
+ Choice "120/120 Lines" ""
+ Choice "121/121 Lines" ""
+ Choice "122/122 Lines" ""
+ Choice "123/123 Lines" ""
+ Choice "124/124 Lines" ""
+ Choice "125/125 Lines" ""
+ Choice "126/126 Lines" ""
+ Choice "127/127 Lines" ""
+ Choice "128/128 Lines" ""
+ Choice "129/129 Lines" ""
+ Choice "130/130 Lines" ""
+ Choice "131/131 Lines" ""
+ Choice "132/132 Lines" ""
+ Choice "133/133 Lines" ""
+ Choice "134/134 Lines" ""
+ Choice "135/135 Lines" ""
+ Choice "136/136 Lines" ""
+ Choice "137/137 Lines" ""
+ Choice "138/138 Lines" ""
+ Choice "139/139 Lines" ""
+ Choice "140/140 Lines" ""
+ Choice "141/141 Lines" ""
+ Choice "142/142 Lines" ""
+ Choice "143/143 Lines" ""
+ Choice "144/144 Lines" ""
+ Choice "145/145 Lines" ""
+ Choice "146/146 Lines" ""
+ Choice "147/147 Lines" ""
+ Choice "148/148 Lines" ""
+ Choice "149/149 Lines" ""
+ Choice "150/150 Lines" ""
+ Choice "151/151 Lines" ""
+ Choice "152/152 Lines" ""
+ Choice "153/153 Lines" ""
+ Choice "154/154 Lines" ""
+ Choice "155/155 Lines" ""
+ Choice "156/156 Lines" ""
+ Choice "157/157 Lines" ""
+ Choice "158/158 Lines" ""
+ Choice "159/159 Lines" ""
+ Choice "160/160 Lines" ""
+ Choice "161/161 Lines" ""
+ Choice "162/162 Lines" ""
+ Choice "163/163 Lines" ""
+ Choice "164/164 Lines" ""
+ Choice "165/165 Lines" ""
+ Choice "166/166 Lines" ""
+ Choice "167/167 Lines" ""
+ Choice "168/168 Lines" ""
+ Choice "169/169 Lines" ""
+ Choice "170/170 Lines" ""
+ Choice "171/171 Lines" ""
+ Choice "172/172 Lines" ""
+ Choice "173/173 Lines" ""
+ Choice "174/174 Lines" ""
+ Choice "175/175 Lines" ""
+ Choice "176/176 Lines" ""
+ Choice "177/177 Lines" ""
+ Choice "178/178 Lines" ""
+ Choice "179/179 Lines" ""
+ Choice "180/180 Lines" ""
+ Choice "181/181 Lines" ""
+ Choice "182/182 Lines" ""
+ Choice "183/183 Lines" ""
+ Choice "184/184 Lines" ""
+ Choice "185/185 Lines" ""
+ Choice "186/186 Lines" ""
+ Choice "187/187 Lines" ""
+ Choice "188/188 Lines" ""
+ Choice "189/189 Lines" ""
+ Choice "190/190 Lines" ""
+ Choice "191/191 Lines" ""
+ Choice "192/192 Lines" ""
+ Choice "193/193 Lines" ""
+ Choice "194/194 Lines" ""
+ Choice "195/195 Lines" ""
+ Choice "196/196 Lines" ""
+ Choice "197/197 Lines" ""
+ Choice "198/198 Lines" ""
+ Choice "199/199 Lines" ""
+ Choice "200/200 Lines" ""
+ Attribute CustomCustom2NumLines True ""
+ Attribute ParamCustomCustom2NumLines Lines "1 int 1 999"
+
+ Option "Custom2NumColumns/Page Size Custom2 Number of Columns" PickOne AnySetup 10.0
+ Choice "1/1 Column" ""
+ Choice "2/2 Columns" ""
+ Choice "3/3 Columns" ""
+ Choice "4/4 Columns" ""
+ Choice "5/5 Columns" ""
+ Choice "6/6 Columns" ""
+ Choice "7/7 Columns" ""
+ Choice "8/8 Columns" ""
+ Choice "9/9 Columns" ""
+ Choice "10/10 Columns" ""
+ Choice "11/11 Columns" ""
+ Choice "12/12 Columns" ""
+ Choice "13/13 Columns" ""
+ Choice "14/14 Columns" ""
+ Choice "15/15 Columns" ""
+ Choice "16/16 Columns" ""
+ Choice "17/17 Columns" ""
+ Choice "18/18 Columns" ""
+ Choice "19/19 Columns" ""
+ Choice "20/20 Columns" ""
+ Choice "21/21 Columns" ""
+ Choice "22/22 Columns" ""
+ Choice "23/23 Columns" ""
+ Choice "24/24 Columns" ""
+ Choice "25/25 Columns" ""
+ Choice "26/26 Columns" ""
+ Choice "27/27 Columns" ""
+ Choice "28/28 Columns" ""
+ Choice "29/29 Columns" ""
+ Choice "30/30 Columns" ""
+ Choice "31/31 Columns" ""
+ Choice "32/32 Columns" ""
+ Choice "33/33 Columns" ""
+ Choice "34/34 Columns" ""
+ Choice "35/35 Columns" ""
+ Choice "36/36 Columns" ""
+ Choice "37/37 Columns" ""
+ Choice "38/38 Columns" ""
+ Choice "39/39 Columns" ""
+ Choice "40/40 Columns" ""
+ Choice "41/41 Columns" ""
+ Choice "42/42 Columns" ""
+ Choice "43/43 Columns" ""
+ Choice "44/44 Columns" ""
+ Choice "45/45 Columns" ""
+ Choice "46/46 Columns" ""
+ Choice "47/47 Columns" ""
+ Choice "48/48 Columns" ""
+ Choice "49/49 Columns" ""
+ Choice "50/50 Columns" ""
+ Choice "51/51 Columns" ""
+ Choice "52/52 Columns" ""
+ Choice "53/53 Columns" ""
+ Choice "54/54 Columns" ""
+ Choice "55/55 Columns" ""
+ Choice "56/56 Columns" ""
+ Choice "57/57 Columns" ""
+ Choice "58/58 Columns" ""
+ Choice "59/59 Columns" ""
+ Choice "60/60 Columns" ""
+ Choice "61/61 Columns" ""
+ Choice "62/62 Columns" ""
+ Choice "63/63 Columns" ""
+ Choice "64/64 Columns" ""
+ Choice "65/65 Columns" ""
+ Choice "66/66 Columns" ""
+ Choice "67/67 Columns" ""
+ Choice "68/68 Columns" ""
+ Choice "69/69 Columns" ""
+ Choice "70/70 Columns" ""
+ Choice "71/71 Columns" ""
+ Choice "72/72 Columns" ""
+ Choice "73/73 Columns" ""
+ Choice "74/74 Columns" ""
+ Choice "75/75 Columns" ""
+ Choice "76/76 Columns" ""
+ Choice "77/77 Columns" ""
+ Choice "78/78 Columns" ""
+ Choice "79/79 Columns" ""
+ *Choice "80/80 Columns" ""
+ Choice "81/81 Columns" ""
+ Choice "82/82 Columns" ""
+ Choice "83/83 Columns" ""
+ Choice "84/84 Columns" ""
+ Choice "85/85 Columns" ""
+ Choice "86/86 Columns" ""
+ Choice "87/87 Columns" ""
+ Choice "88/88 Columns" ""
+ Choice "89/89 Columns" ""
+ Choice "90/90 Columns" ""
+ Choice "91/91 Columns" ""
+ Choice "92/92 Columns" ""
+ Choice "93/93 Columns" ""
+ Choice "94/94 Columns" ""
+ Choice "95/95 Columns" ""
+ Choice "96/96 Columns" ""
+ Choice "97/97 Columns" ""
+ Choice "98/98 Columns" ""
+ Choice "99/99 Columns" ""
+ Choice "100/100 Columns" ""
+ Choice "101/101 Columns" ""
+ Choice "102/102 Columns" ""
+ Choice "103/103 Columns" ""
+ Choice "104/104 Columns" ""
+ Choice "105/105 Columns" ""
+ Choice "106/106 Columns" ""
+ Choice "107/107 Columns" ""
+ Choice "108/108 Columns" ""
+ Choice "109/109 Columns" ""
+ Choice "110/110 Columns" ""
+ Choice "111/111 Columns" ""
+ Choice "112/112 Columns" ""
+ Choice "113/113 Columns" ""
+ Choice "114/114 Columns" ""
+ Choice "115/115 Columns" ""
+ Choice "116/116 Columns" ""
+ Choice "117/117 Columns" ""
+ Choice "118/118 Columns" ""
+ Choice "119/119 Columns" ""
+ Choice "120/120 Columns" ""
+ Choice "121/121 Columns" ""
+ Choice "122/122 Columns" ""
+ Choice "123/123 Columns" ""
+ Choice "124/124 Columns" ""
+ Choice "125/125 Columns" ""
+ Choice "126/126 Columns" ""
+ Choice "127/127 Columns" ""
+ Choice "128/128 Columns" ""
+ Choice "129/129 Columns" ""
+ Choice "130/130 Columns" ""
+ Choice "131/131 Columns" ""
+ Choice "132/132 Columns" ""
+ Choice "133/133 Columns" ""
+ Choice "134/134 Columns" ""
+ Choice "135/135 Columns" ""
+ Choice "136/136 Columns" ""
+ Choice "137/137 Columns" ""
+ Choice "138/138 Columns" ""
+ Choice "139/139 Columns" ""
+ Choice "140/140 Columns" ""
+ Choice "141/141 Columns" ""
+ Choice "142/142 Columns" ""
+ Choice "143/143 Columns" ""
+ Choice "144/144 Columns" ""
+ Choice "145/145 Columns" ""
+ Choice "146/146 Columns" ""
+ Choice "147/147 Columns" ""
+ Choice "148/148 Columns" ""
+ Choice "149/149 Columns" ""
+ Choice "150/150 Columns" ""
+ Choice "151/151 Columns" ""
+ Choice "152/152 Columns" ""
+ Choice "153/153 Columns" ""
+ Choice "154/154 Columns" ""
+ Choice "155/155 Columns" ""
+ Choice "156/156 Columns" ""
+ Choice "157/157 Columns" ""
+ Choice "158/158 Columns" ""
+ Choice "159/159 Columns" ""
+ Choice "160/160 Columns" ""
+ Choice "161/161 Columns" ""
+ Choice "162/162 Columns" ""
+ Choice "163/163 Columns" ""
+ Choice "164/164 Columns" ""
+ Choice "165/165 Columns" ""
+ Choice "166/166 Columns" ""
+ Choice "167/167 Columns" ""
+ Choice "168/168 Columns" ""
+ Choice "169/169 Columns" ""
+ Choice "170/170 Columns" ""
+ Choice "171/171 Columns" ""
+ Choice "172/172 Columns" ""
+ Choice "173/173 Columns" ""
+ Choice "174/174 Columns" ""
+ Choice "175/175 Columns" ""
+ Choice "176/176 Columns" ""
+ Choice "177/177 Columns" ""
+ Choice "178/178 Columns" ""
+ Choice "179/179 Columns" ""
+ Choice "180/180 Columns" ""
+ Choice "181/181 Columns" ""
+ Choice "182/182 Columns" ""
+ Choice "183/183 Columns" ""
+ Choice "184/184 Columns" ""
+ Choice "185/185 Columns" ""
+ Choice "186/186 Columns" ""
+ Choice "187/187 Columns" ""
+ Choice "188/188 Columns" ""
+ Choice "189/189 Columns" ""
+ Choice "190/190 Columns" ""
+ Choice "191/191 Columns" ""
+ Choice "192/192 Columns" ""
+ Choice "193/193 Columns" ""
+ Choice "194/194 Columns" ""
+ Choice "195/195 Columns" ""
+ Choice "196/196 Columns" ""
+ Choice "197/197 Columns" ""
+ Choice "198/198 Columns" ""
+ Choice "199/199 Columns" ""
+ Choice "200/200 Columns" ""
+ Attribute CustomCustom2NumColumns True ""
+ Attribute ParamCustomCustom2NumColumns Columns "1 int 1 999"
+
+
+ Option "Custom3Available/Page Size Custom3 available" Boolean AnySetup 10.0
+ Choice "True/Yes" ""
+ *Choice "False/No" ""
+
+ Option "Custom3NumLines/Page Size Custom3 Number of Lines" PickOne AnySetup 10.0
+ Choice "1/1 Line" ""
+ Choice "2/2 Lines" ""
+ Choice "3/3 Lines" ""
+ Choice "4/4 Lines" ""
+ Choice "5/5 Lines" ""
+ Choice "6/6 Lines" ""
+ Choice "7/7 Lines" ""
+ Choice "8/8 Lines" ""
+ Choice "9/9 Lines" ""
+ Choice "10/10 Lines" ""
+ Choice "11/11 Lines" ""
+ Choice "12/12 Lines" ""
+ Choice "13/13 Lines" ""
+ Choice "14/14 Lines" ""
+ Choice "15/15 Lines" ""
+ Choice "16/16 Lines" ""
+ Choice "17/17 Lines" ""
+ Choice "18/18 Lines" ""
+ Choice "19/19 Lines" ""
+ Choice "20/20 Lines" ""
+ Choice "21/21 Lines" ""
+ Choice "22/22 Lines" ""
+ Choice "23/23 Lines" ""
+ Choice "24/24 Lines" ""
+ Choice "25/25 Lines" ""
+ Choice "26/26 Lines" ""
+ Choice "27/27 Lines" ""
+ Choice "28/28 Lines" ""
+ Choice "29/29 Lines" ""
+ Choice "30/30 Lines" ""
+ Choice "31/31 Lines" ""
+ Choice "32/32 Lines" ""
+ Choice "33/33 Lines" ""
+ Choice "34/34 Lines" ""
+ Choice "35/35 Lines" ""
+ Choice "36/36 Lines" ""
+ Choice "37/37 Lines" ""
+ Choice "38/38 Lines" ""
+ Choice "39/39 Lines" ""
+ Choice "40/40 Lines" ""
+ Choice "41/41 Lines" ""
+ Choice "42/42 Lines" ""
+ Choice "43/43 Lines" ""
+ Choice "44/44 Lines" ""
+ Choice "45/45 Lines" ""
+ Choice "46/46 Lines" ""
+ Choice "47/47 Lines" ""
+ Choice "48/48 Lines" ""
+ Choice "49/49 Lines" ""
+ Choice "50/50 Lines" ""
+ Choice "51/51 Lines" ""
+ Choice "52/52 Lines" ""
+ Choice "53/53 Lines" ""
+ Choice "54/54 Lines" ""
+ Choice "55/55 Lines" ""
+ Choice "56/56 Lines" ""
+ Choice "57/57 Lines" ""
+ Choice "58/58 Lines" ""
+ Choice "59/59 Lines" ""
+ Choice "60/60 Lines" ""
+ Choice "61/61 Lines" ""
+ Choice "62/62 Lines" ""
+ Choice "63/63 Lines" ""
+ Choice "64/64 Lines" ""
+ Choice "65/65 Lines" ""
+ *Choice "66/66 Lines" ""
+ Choice "67/67 Lines" ""
+ Choice "68/68 Lines" ""
+ Choice "69/69 Lines" ""
+ Choice "70/70 Lines" ""
+ Choice "71/71 Lines" ""
+ Choice "72/72 Lines" ""
+ Choice "73/73 Lines" ""
+ Choice "74/74 Lines" ""
+ Choice "75/75 Lines" ""
+ Choice "76/76 Lines" ""
+ Choice "77/77 Lines" ""
+ Choice "78/78 Lines" ""
+ Choice "79/79 Lines" ""
+ Choice "80/80 Lines" ""
+ Choice "81/81 Lines" ""
+ Choice "82/82 Lines" ""
+ Choice "83/83 Lines" ""
+ Choice "84/84 Lines" ""
+ Choice "85/85 Lines" ""
+ Choice "86/86 Lines" ""
+ Choice "87/87 Lines" ""
+ Choice "88/88 Lines" ""
+ Choice "89/89 Lines" ""
+ Choice "90/90 Lines" ""
+ Choice "91/91 Lines" ""
+ Choice "92/92 Lines" ""
+ Choice "93/93 Lines" ""
+ Choice "94/94 Lines" ""
+ Choice "95/95 Lines" ""
+ Choice "96/96 Lines" ""
+ Choice "97/97 Lines" ""
+ Choice "98/98 Lines" ""
+ Choice "99/99 Lines" ""
+ Choice "100/100 Lines" ""
+ Choice "101/101 Lines" ""
+ Choice "102/102 Lines" ""
+ Choice "103/103 Lines" ""
+ Choice "104/104 Lines" ""
+ Choice "105/105 Lines" ""
+ Choice "106/106 Lines" ""
+ Choice "107/107 Lines" ""
+ Choice "108/108 Lines" ""
+ Choice "109/109 Lines" ""
+ Choice "110/110 Lines" ""
+ Choice "111/111 Lines" ""
+ Choice "112/112 Lines" ""
+ Choice "113/113 Lines" ""
+ Choice "114/114 Lines" ""
+ Choice "115/115 Lines" ""
+ Choice "116/116 Lines" ""
+ Choice "117/117 Lines" ""
+ Choice "118/118 Lines" ""
+ Choice "119/119 Lines" ""
+ Choice "120/120 Lines" ""
+ Choice "121/121 Lines" ""
+ Choice "122/122 Lines" ""
+ Choice "123/123 Lines" ""
+ Choice "124/124 Lines" ""
+ Choice "125/125 Lines" ""
+ Choice "126/126 Lines" ""
+ Choice "127/127 Lines" ""
+ Choice "128/128 Lines" ""
+ Choice "129/129 Lines" ""
+ Choice "130/130 Lines" ""
+ Choice "131/131 Lines" ""
+ Choice "132/132 Lines" ""
+ Choice "133/133 Lines" ""
+ Choice "134/134 Lines" ""
+ Choice "135/135 Lines" ""
+ Choice "136/136 Lines" ""
+ Choice "137/137 Lines" ""
+ Choice "138/138 Lines" ""
+ Choice "139/139 Lines" ""
+ Choice "140/140 Lines" ""
+ Choice "141/141 Lines" ""
+ Choice "142/142 Lines" ""
+ Choice "143/143 Lines" ""
+ Choice "144/144 Lines" ""
+ Choice "145/145 Lines" ""
+ Choice "146/146 Lines" ""
+ Choice "147/147 Lines" ""
+ Choice "148/148 Lines" ""
+ Choice "149/149 Lines" ""
+ Choice "150/150 Lines" ""
+ Choice "151/151 Lines" ""
+ Choice "152/152 Lines" ""
+ Choice "153/153 Lines" ""
+ Choice "154/154 Lines" ""
+ Choice "155/155 Lines" ""
+ Choice "156/156 Lines" ""
+ Choice "157/157 Lines" ""
+ Choice "158/158 Lines" ""
+ Choice "159/159 Lines" ""
+ Choice "160/160 Lines" ""
+ Choice "161/161 Lines" ""
+ Choice "162/162 Lines" ""
+ Choice "163/163 Lines" ""
+ Choice "164/164 Lines" ""
+ Choice "165/165 Lines" ""
+ Choice "166/166 Lines" ""
+ Choice "167/167 Lines" ""
+ Choice "168/168 Lines" ""
+ Choice "169/169 Lines" ""
+ Choice "170/170 Lines" ""
+ Choice "171/171 Lines" ""
+ Choice "172/172 Lines" ""
+ Choice "173/173 Lines" ""
+ Choice "174/174 Lines" ""
+ Choice "175/175 Lines" ""
+ Choice "176/176 Lines" ""
+ Choice "177/177 Lines" ""
+ Choice "178/178 Lines" ""
+ Choice "179/179 Lines" ""
+ Choice "180/180 Lines" ""
+ Choice "181/181 Lines" ""
+ Choice "182/182 Lines" ""
+ Choice "183/183 Lines" ""
+ Choice "184/184 Lines" ""
+ Choice "185/185 Lines" ""
+ Choice "186/186 Lines" ""
+ Choice "187/187 Lines" ""
+ Choice "188/188 Lines" ""
+ Choice "189/189 Lines" ""
+ Choice "190/190 Lines" ""
+ Choice "191/191 Lines" ""
+ Choice "192/192 Lines" ""
+ Choice "193/193 Lines" ""
+ Choice "194/194 Lines" ""
+ Choice "195/195 Lines" ""
+ Choice "196/196 Lines" ""
+ Choice "197/197 Lines" ""
+ Choice "198/198 Lines" ""
+ Choice "199/199 Lines" ""
+ Choice "200/200 Lines" ""
+ Attribute CustomCustom3NumLines True ""
+ Attribute ParamCustomCustom3NumLines Lines "1 int 1 999"
+
+ Option "Custom3NumColumns/Page Size Custom3 Number of Columns" PickOne AnySetup 10.0
+ Choice "1/1 Column" ""
+ Choice "2/2 Columns" ""
+ Choice "3/3 Columns" ""
+ Choice "4/4 Columns" ""
+ Choice "5/5 Columns" ""
+ Choice "6/6 Columns" ""
+ Choice "7/7 Columns" ""
+ Choice "8/8 Columns" ""
+ Choice "9/9 Columns" ""
+ Choice "10/10 Columns" ""
+ Choice "11/11 Columns" ""
+ Choice "12/12 Columns" ""
+ Choice "13/13 Columns" ""
+ Choice "14/14 Columns" ""
+ Choice "15/15 Columns" ""
+ Choice "16/16 Columns" ""
+ Choice "17/17 Columns" ""
+ Choice "18/18 Columns" ""
+ Choice "19/19 Columns" ""
+ Choice "20/20 Columns" ""
+ Choice "21/21 Columns" ""
+ Choice "22/22 Columns" ""
+ Choice "23/23 Columns" ""
+ Choice "24/24 Columns" ""
+ Choice "25/25 Columns" ""
+ Choice "26/26 Columns" ""
+ Choice "27/27 Columns" ""
+ Choice "28/28 Columns" ""
+ Choice "29/29 Columns" ""
+ Choice "30/30 Columns" ""
+ Choice "31/31 Columns" ""
+ Choice "32/32 Columns" ""
+ Choice "33/33 Columns" ""
+ Choice "34/34 Columns" ""
+ Choice "35/35 Columns" ""
+ Choice "36/36 Columns" ""
+ Choice "37/37 Columns" ""
+ Choice "38/38 Columns" ""
+ Choice "39/39 Columns" ""
+ Choice "40/40 Columns" ""
+ Choice "41/41 Columns" ""
+ Choice "42/42 Columns" ""
+ Choice "43/43 Columns" ""
+ Choice "44/44 Columns" ""
+ Choice "45/45 Columns" ""
+ Choice "46/46 Columns" ""
+ Choice "47/47 Columns" ""
+ Choice "48/48 Columns" ""
+ Choice "49/49 Columns" ""
+ Choice "50/50 Columns" ""
+ Choice "51/51 Columns" ""
+ Choice "52/52 Columns" ""
+ Choice "53/53 Columns" ""
+ Choice "54/54 Columns" ""
+ Choice "55/55 Columns" ""
+ Choice "56/56 Columns" ""
+ Choice "57/57 Columns" ""
+ Choice "58/58 Columns" ""
+ Choice "59/59 Columns" ""
+ Choice "60/60 Columns" ""
+ Choice "61/61 Columns" ""
+ Choice "62/62 Columns" ""
+ Choice "63/63 Columns" ""
+ Choice "64/64 Columns" ""
+ Choice "65/65 Columns" ""
+ Choice "66/66 Columns" ""
+ Choice "67/67 Columns" ""
+ Choice "68/68 Columns" ""
+ Choice "69/69 Columns" ""
+ Choice "70/70 Columns" ""
+ Choice "71/71 Columns" ""
+ Choice "72/72 Columns" ""
+ Choice "73/73 Columns" ""
+ Choice "74/74 Columns" ""
+ Choice "75/75 Columns" ""
+ Choice "76/76 Columns" ""
+ Choice "77/77 Columns" ""
+ Choice "78/78 Columns" ""
+ Choice "79/79 Columns" ""
+ *Choice "80/80 Columns" ""
+ Choice "81/81 Columns" ""
+ Choice "82/82 Columns" ""
+ Choice "83/83 Columns" ""
+ Choice "84/84 Columns" ""
+ Choice "85/85 Columns" ""
+ Choice "86/86 Columns" ""
+ Choice "87/87 Columns" ""
+ Choice "88/88 Columns" ""
+ Choice "89/89 Columns" ""
+ Choice "90/90 Columns" ""
+ Choice "91/91 Columns" ""
+ Choice "92/92 Columns" ""
+ Choice "93/93 Columns" ""
+ Choice "94/94 Columns" ""
+ Choice "95/95 Columns" ""
+ Choice "96/96 Columns" ""
+ Choice "97/97 Columns" ""
+ Choice "98/98 Columns" ""
+ Choice "99/99 Columns" ""
+ Choice "100/100 Columns" ""
+ Choice "101/101 Columns" ""
+ Choice "102/102 Columns" ""
+ Choice "103/103 Columns" ""
+ Choice "104/104 Columns" ""
+ Choice "105/105 Columns" ""
+ Choice "106/106 Columns" ""
+ Choice "107/107 Columns" ""
+ Choice "108/108 Columns" ""
+ Choice "109/109 Columns" ""
+ Choice "110/110 Columns" ""
+ Choice "111/111 Columns" ""
+ Choice "112/112 Columns" ""
+ Choice "113/113 Columns" ""
+ Choice "114/114 Columns" ""
+ Choice "115/115 Columns" ""
+ Choice "116/116 Columns" ""
+ Choice "117/117 Columns" ""
+ Choice "118/118 Columns" ""
+ Choice "119/119 Columns" ""
+ Choice "120/120 Columns" ""
+ Choice "121/121 Columns" ""
+ Choice "122/122 Columns" ""
+ Choice "123/123 Columns" ""
+ Choice "124/124 Columns" ""
+ Choice "125/125 Columns" ""
+ Choice "126/126 Columns" ""
+ Choice "127/127 Columns" ""
+ Choice "128/128 Columns" ""
+ Choice "129/129 Columns" ""
+ Choice "130/130 Columns" ""
+ Choice "131/131 Columns" ""
+ Choice "132/132 Columns" ""
+ Choice "133/133 Columns" ""
+ Choice "134/134 Columns" ""
+ Choice "135/135 Columns" ""
+ Choice "136/136 Columns" ""
+ Choice "137/137 Columns" ""
+ Choice "138/138 Columns" ""
+ Choice "139/139 Columns" ""
+ Choice "140/140 Columns" ""
+ Choice "141/141 Columns" ""
+ Choice "142/142 Columns" ""
+ Choice "143/143 Columns" ""
+ Choice "144/144 Columns" ""
+ Choice "145/145 Columns" ""
+ Choice "146/146 Columns" ""
+ Choice "147/147 Columns" ""
+ Choice "148/148 Columns" ""
+ Choice "149/149 Columns" ""
+ Choice "150/150 Columns" ""
+ Choice "151/151 Columns" ""
+ Choice "152/152 Columns" ""
+ Choice "153/153 Columns" ""
+ Choice "154/154 Columns" ""
+ Choice "155/155 Columns" ""
+ Choice "156/156 Columns" ""
+ Choice "157/157 Columns" ""
+ Choice "158/158 Columns" ""
+ Choice "159/159 Columns" ""
+ Choice "160/160 Columns" ""
+ Choice "161/161 Columns" ""
+ Choice "162/162 Columns" ""
+ Choice "163/163 Columns" ""
+ Choice "164/164 Columns" ""
+ Choice "165/165 Columns" ""
+ Choice "166/166 Columns" ""
+ Choice "167/167 Columns" ""
+ Choice "168/168 Columns" ""
+ Choice "169/169 Columns" ""
+ Choice "170/170 Columns" ""
+ Choice "171/171 Columns" ""
+ Choice "172/172 Columns" ""
+ Choice "173/173 Columns" ""
+ Choice "174/174 Columns" ""
+ Choice "175/175 Columns" ""
+ Choice "176/176 Columns" ""
+ Choice "177/177 Columns" ""
+ Choice "178/178 Columns" ""
+ Choice "179/179 Columns" ""
+ Choice "180/180 Columns" ""
+ Choice "181/181 Columns" ""
+ Choice "182/182 Columns" ""
+ Choice "183/183 Columns" ""
+ Choice "184/184 Columns" ""
+ Choice "185/185 Columns" ""
+ Choice "186/186 Columns" ""
+ Choice "187/187 Columns" ""
+ Choice "188/188 Columns" ""
+ Choice "189/189 Columns" ""
+ Choice "190/190 Columns" ""
+ Choice "191/191 Columns" ""
+ Choice "192/192 Columns" ""
+ Choice "193/193 Columns" ""
+ Choice "194/194 Columns" ""
+ Choice "195/195 Columns" ""
+ Choice "196/196 Columns" ""
+ Choice "197/197 Columns" ""
+ Choice "198/198 Columns" ""
+ Choice "199/199 Columns" ""
+ Choice "200/200 Columns" ""
+ Attribute CustomCustom3NumColumns True ""
+ Attribute ParamCustomCustom3NumColumns Columns "1 int 1 999"
+
+
+ // Constraints
+ UIConstraints "*PageSize Letter *LetterAvailable False"
+ UIConstraints "*PageSize Legal *LegalAvailable False"
+ UIConstraints "*PageSize Tabloid *TabloidAvailable False"
+ UIConstraints "*PageSize Ledger *LedgerAvailable False"
+ UIConstraints "*PageSize A4 *A4Available False"
+ UIConstraints "*PageSize A3 *A3Available False"
+ UIConstraints "*PageSize FanFoldGerman *FanFoldGermanAvailable False"
+ UIConstraints "*PageSize FanFoldGermanLegal *FanFoldGermanLegalAvailable False"
+ UIConstraints "*PageSize 11x14Rotated *11x14RotatedAvailable False"
+ UIConstraints "*PageSize LegalRotated *LegalRotatedAvailable False"
+ UIConstraints "*PageSize Custom1 *Custom1Available False"
+ UIConstraints "*PageSize Custom2 *Custom2Available False"
+ UIConstraints "*PageSize Custom3 *Custom3Available False"
+ UIConstraints "*PageRegion Letter *LetterAvailable False"
+ UIConstraints "*PageRegion Legal *LegalAvailable False"
+ UIConstraints "*PageRegion Tabloid *TabloidAvailable False"
+ UIConstraints "*PageRegion Ledger *LedgerAvailable False"
+ UIConstraints "*PageRegion A4 *A4Available False"
+ UIConstraints "*PageRegion A3 *A3Available False"
+ UIConstraints "*PageRegion FanFoldGerman *FanFoldGermanAvailable False"
+ UIConstraints "*PageRegion FanFoldGermanLegal *FanFoldGermanLegalAvailable False"
+ UIConstraints "*PageRegion 11x14Rotated *11x14RotatedAvailable False"
+ UIConstraints "*PageRegion LegalRotated *LegalRotatedAvailable False"
+ UIConstraints "*PageRegion Custom1 *Custom1Available False"
+ UIConstraints "*PageRegion Custom2 *Custom2Available False"
+ UIConstraints "*PageRegion Custom3 *Custom3Available False"
+
+
+ ModelName "Generic Text-Only Printer"
+ Attribute "NickName" "" "Generic Text-Only Printer"
+ Attribute "ShortNickName" "" "Generic Text-Only Printer"
+ Attribute "1284DeviceID" "" "MFG:Generic;MDL:Text-Only Printer;DES:Generic Text-Only Printer;CLS:PRINTER;CMD:TXT;DRV:Dtextonly,R1,M0;"
+ PCFileName "textonly.ppd"
+ Attribute "Product" "" "(Generic Text-Only Printer)"
+
+}
+}
diff --git a/drv/generic-brf.drv b/drv/generic-brf.drv
new file mode 100644
index 000000000..32883fa74
--- /dev/null
+++ b/drv/generic-brf.drv
@@ -0,0 +1,120 @@
+//
+// Copyright (c) 2015, 2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include <media.defs>
+#include <media-braille.defs>
+#include <liblouis.defs>
+#include <imagemagick.defs>
+#include <braille.defs>
+
+#po fr "fr-braille.po"
+
+Manufacturer "Generic"
+Version 1.0
+
+Throughput 1
+
+Filter text/vnd.cups-brf 0 brftoembosser
+Filter image/vnd.cups-brf 0 brftoembosser
+
+MediaSize Legal
+MediaSize Letter
+MediaSize A3
+MediaSize A4
+*MediaSize A4TF
+MediaSize A5
+MediaSize 110x115
+MediaSize 110x120
+MediaSize 110x170
+MediaSize 115x110
+MediaSize 120x120
+
+ColorDevice no
+HWMargins 1cm 1cm 1cm 1cm
+VariablePaperSize true
+MinSize 1in 1in
+MaxSize 9999in 9999in
+
+Option "SendFF/Send FormFeed" Boolean AnySetup 10
+ Choice "True/Yes" ""
+ *Choice "False/No" ""
+
+Option "SendSUB/Send Sub (^Z)" Boolean AnySetup 10
+ *Choice "True/Yes" ""
+ Choice "False/No" ""
+
+Option "TopMargin/Top margin" PickOne AnySetup 10
+ Choice "0" ""
+ Choice "1" ""
+ *Choice "2" ""
+ Choice "3" ""
+ Choice "4" ""
+ Choice "5" ""
+ Choice "6" ""
+ Choice "7" ""
+ Choice "8" ""
+ Choice "9" ""
+ Choice "10" ""
+
+Option "BottomMargin/Bottom margin" PickOne AnySetup 10
+ Choice "0" ""
+ Choice "1" ""
+ *Choice "2" ""
+ Choice "3" ""
+ Choice "4" ""
+ Choice "5" ""
+ Choice "6" ""
+ Choice "7" ""
+ Choice "8" ""
+ Choice "9" ""
+ Choice "10" ""
+
+Option "LeftMargin/Left margin" PickOne AnySetup 10
+ Choice "0" ""
+ Choice "1" ""
+ *Choice "2" ""
+ Choice "3" ""
+ Choice "4" ""
+ Choice "5" ""
+ Choice "6" ""
+ Choice "7" ""
+ Choice "8" ""
+ Choice "9" ""
+ Choice "10" ""
+
+Option "RightMargin/Right margin" PickOne AnySetup 10
+ Choice "0" ""
+ Choice "1" ""
+ *Choice "2" ""
+ Choice "3" ""
+ Choice "4" ""
+ Choice "5" ""
+ Choice "6" ""
+ Choice "7" ""
+ Choice "8" ""
+ Choice "9" ""
+ Choice "10" ""
+
+ModelName "Braille embosser"
+PCFileName "gen-brf.ppd"
diff --git a/drv/generic-ubrl.drv b/drv/generic-ubrl.drv
new file mode 100644
index 000000000..4e273aa4d
--- /dev/null
+++ b/drv/generic-ubrl.drv
@@ -0,0 +1,112 @@
+//
+// Copyright (c) 2015, 2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include <media.defs>
+#include <media-braille.defs>
+#include <liblouis.defs>
+#include <imagemagick.defs>
+#include <braille.defs>
+
+#po fr "fr-braille.po"
+
+Manufacturer "Generic"
+Version 1.0
+
+Throughput 1
+
+Filter text/vnd.cups-ubrl 0 -
+Filter image/vnd.cups-ubrl 0 -
+
+MediaSize Legal
+MediaSize Letter
+MediaSize A3
+MediaSize A4
+*MediaSize A4TF
+MediaSize A5
+MediaSize 110x115
+MediaSize 110x120
+MediaSize 110x170
+MediaSize 115x110
+MediaSize 120x120
+
+ColorDevice no
+HWMargins 1cm 1cm 1cm 1cm
+VariablePaperSize true
+MinSize 1in 1in
+MaxSize 9999in 9999in
+
+Option "TopMargin/Top margin" PickOne AnySetup 10
+ Choice "0" ""
+ Choice "1" ""
+ *Choice "2" ""
+ Choice "3" ""
+ Choice "4" ""
+ Choice "5" ""
+ Choice "6" ""
+ Choice "7" ""
+ Choice "8" ""
+ Choice "9" ""
+ Choice "10" ""
+
+Option "BottomMargin/Bottom margin" PickOne AnySetup 10
+ Choice "0" ""
+ Choice "1" ""
+ *Choice "2" ""
+ Choice "3" ""
+ Choice "4" ""
+ Choice "5" ""
+ Choice "6" ""
+ Choice "7" ""
+ Choice "8" ""
+ Choice "9" ""
+ Choice "10" ""
+
+Option "LeftMargin/Left margin" PickOne AnySetup 10
+ Choice "0" ""
+ Choice "1" ""
+ *Choice "2" ""
+ Choice "3" ""
+ Choice "4" ""
+ Choice "5" ""
+ Choice "6" ""
+ Choice "7" ""
+ Choice "8" ""
+ Choice "9" ""
+ Choice "10" ""
+
+Option "RightMargin/Right margin" PickOne AnySetup 10
+ Choice "0" ""
+ Choice "1" ""
+ *Choice "2" ""
+ Choice "3" ""
+ Choice "4" ""
+ Choice "5" ""
+ Choice "6" ""
+ Choice "7" ""
+ Choice "8" ""
+ Choice "9" ""
+ Choice "10" ""
+
+ModelName "UBRL generator"
+PCFileName "gen-ubrl.ppd"
diff --git a/drv/indexv3.drv b/drv/indexv3.drv
new file mode 100644
index 000000000..aef78c25c
--- /dev/null
+++ b/drv/indexv3.drv
@@ -0,0 +1,132 @@
+//
+// Copyright (c) 2015, 2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include <media.defs>
+#include <media-braille.defs>
+#include <liblouis.defs>
+#include <imagemagick.defs>
+#include <braille.defs>
+#include <index.defs>
+
+#po fr "fr-braille.po"
+
+Manufacturer "Index"
+Version 1.0
+
+Filter text/vnd.cups-brf 0 textbrftoindexv3
+Filter image/vnd.cups-ubrl 0 imageubrltoindexv3
+
+//
+// Common options
+//
+
+HWMargins 0mm 5mm 0mm 2mm
+VariablePaperSize true
+MinSize 1in 1in
+
+Group "Index/Index support"
+ Option "IndexFirmwareVersion/Installed firmware version" PickOne AnySetup 10
+ Choice "102000/10.20 or above" ""
+ *Choice "103000/10.30 or above" ""
+ // Provides DBT but we just use transparent mode
+ //Choice "110210/11.02.1 or above" ""
+ // Provides user-defined interline size
+ Choice "120130/12.01.3 or above" ""
+
+
+//
+// Basic-D
+//
+{
+ ModelName "Basic-D V3"
+ PCFileName "ibasicd3.ppd"
+
+ MaxSize 325mm 10m
+
+ Group "Index"
+ Option "IndexFolding" PickOne AnySetup 10
+ Choice "SingleZ/Single-sided z-folding" ""
+ Choice "DoubleZ/Double-sided z-folding" ""
+
+ Attribute "IndexPaperLength" "" In
+}
+
+
+//
+// Basic-S
+//
+{
+ ModelName "Basic-S V3"
+ PCFileName "ibasics3.ppd"
+
+ MaxSize 325mm 10m
+
+ Attribute "IndexPaperLength" "" In
+}
+
+
+//
+// 4-Waves PRO
+//
+{
+ ModelName "4-Waves PRO"
+ PCFileName "i4waves3.ppd"
+
+ MaxSize 325mm 10m
+
+ Group "Index"
+ Option "IndexFolding" PickOne AnySetup 10
+ Choice "SingleZ/Single-sided z-folding" ""
+ Choice "DoubleZ/Double-sided z-folding" ""
+}
+
+
+//
+// Everest-D
+//
+{
+ ModelName "Everest-D V3"
+ PCFileName "ieveres3.ppd"
+
+ MaxSize 297mm 10m
+
+ Attribute "IndexPaperLength" "" Mm
+}
+
+
+//
+// 4x4 PRO
+//
+{
+ ModelName "4x4 PRO V3"
+ PCFileName "i4x4pro3.ppd"
+
+ MaxSize 297mm 10m
+
+ Group "Index"
+ Option "IndexFolding" PickOne AnySetup 10
+ Choice "DoubleS/Double-sided saddle stitch 4 pages" ""
+
+ Attribute "IndexPaperLength" "" Mm
+}
diff --git a/drv/indexv4.drv b/drv/indexv4.drv
new file mode 100644
index 000000000..a6e1cf0a1
--- /dev/null
+++ b/drv/indexv4.drv
@@ -0,0 +1,139 @@
+//
+// Copyright (c) 2015, 2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include <media.defs>
+#include <media-braille.defs>
+#include <liblouis.defs>
+#include <imagemagick.defs>
+#include <braille.defs>
+#include <index.defs>
+
+#po fr "fr-braille.po"
+
+Manufacturer "Index"
+Version 1.0
+
+Filter text/vnd.cups-brf 0 textbrftoindexv4
+Filter image/vnd.cups-ubrl 0 imageubrltoindexv4
+
+//
+// Common options
+//
+
+HWMargins 5mm 5mm 5mm 5mm
+VariablePaperSize true
+MinSize 1in 1in
+
+Group "Index/Index support"
+ Option "IndexFirmwareVersion/Installed firmware version" PickOne AnySetup 10
+ Choice "102000/10.20 or above" ""
+ *Choice "103000/10.30 or above" ""
+ // Provides DBT but we just use transparent mode
+ //Choice "110210/11.02.1 or above" ""
+
+Group "Braille"
+ Option "IndexTable/Firmware Braille Table" PickOne AnySetup 10
+ Choice "5/American computer 6 dots" ""
+ Choice "6/American computer 8 dots" ""
+ Choice "7/English computer 8 dots" ""
+ Choice "8/English literal without capital" ""
+ Choice "9/IBM 437 computer 6 dots" ""
+ Choice "10/IBM 437 computer 8 dots" ""
+ Choice "11/IBM 850 computer 8 dots" ""
+ Choice "12/German computer 8 dots" ""
+ Choice "13/Italian literal with capital" ""
+ Choice "14/Italian literal without capital" ""
+ Choice "15/Portuguese literal with capital" ""
+ Choice "16/Spanish computer 6 dots" ""
+ Choice "17/Spanish computer 8 dots" ""
+ Choice "18/Spanish user defined 3 ANSI" ""
+ Choice "19/Spanish user defined 4 ASCII" ""
+ Choice "20/Swedish literal without capital" ""
+ Choice "21/Polish computer 6 dots" ""
+ Choice "22/Polish literal with capital" ""
+ Choice "23/Polish own table 03" ""
+ Choice "24/Polish own table 04" ""
+ Choice "25/Dutch computer 6 dots" ""
+ Choice "26/Dutch own table 02" ""
+
+
+//
+// Basic-D
+//
+{
+ ModelName "Basic-D V4"
+ PCFileName "ibasicd4.ppd"
+
+ MaxSize 325mm 10m
+
+ Group "Index"
+ Option "IndexFolding" PickOne AnySetup 10
+ Choice "SingleZ/Single-sided z-folding" ""
+ Choice "DoubleZ/Double-sided z-folding" ""
+ Choice "SingleSZ/Single-sided sideways z-folding" ""
+ Choice "DoubleSZ/Double-sided sideways z-folding" ""
+}
+
+
+//
+// Basic-S
+//
+{
+ ModelName "Basic-S V4"
+ PCFileName "ibasics4.ppd"
+
+ MaxSize 325mm 10m
+}
+
+
+//
+// Everest-D
+//
+{
+ ModelName "Everest-D V4"
+ PCFileName "ieveres4.ppd"
+
+ MaxSize 297mm 10m
+
+ Group "Index"
+ Option "IndexFolding" PickOne AnySetup 10
+ Choice "DoubleS/Double-sided saddle stitch 4 pages" ""
+ Choice "SingleS/Single-sided saddle stitch 4 pages" ""
+}
+
+
+//
+// Braille Box
+//
+{
+ ModelName "Braille Box V4"
+ PCFileName "ibrlbox4.ppd"
+
+ MaxSize 297mm 10m
+
+ Group "Index"
+ Option "IndexFolding" PickOne AnySetup 10
+ Choice "DoubleS/Double-sided saddle stitch 4 pages" ""
+ Choice "SingleS/Single-sided saddle stitch 4 pages" ""
+}
diff --git a/filter/PDFError.h b/filter/PDFError.h
new file mode 100644
index 000000000..9fb58bcd4
--- /dev/null
+++ b/filter/PDFError.h
@@ -0,0 +1,44 @@
+/*
+
+Copyright (c) 2012, BBR Inc. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+/*
+ P2PError.h
+*/
+#ifndef _P2PERROR_H_
+#define _P2PERROR_H_
+
+#include <config.h>
+#include <stdarg.h>
+#include <Error.h>
+#ifdef HAVE_CPP_POPPLER_VERSION_H
+#include "cpp/poppler-version.h"
+#endif
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+#define pdfError(pos,...) error(errInternal,pos,__VA_ARGS__)
+#else
+#define pdfError(pos,...) error(pos,__VA_ARGS__)
+#endif
+
+#endif
diff --git a/filter/banner.c b/filter/banner.c
new file mode 100644
index 000000000..1a4d0b1ae
--- /dev/null
+++ b/filter/banner.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2012 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "banner.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <libgen.h>
+
+
+static int parse_line(char *line, char **key, char **value)
+{
+ char *p = line;
+
+ *key = *value = NULL;
+
+ while (isspace(*p)) p++;
+ if (!*p || *p == '#')
+ return 0;
+
+ *key = p;
+ while (*p && !isspace(*p))
+ p++;
+ if (!*p)
+ return 1;
+
+ *p++ = '\0';
+
+ while (isspace(*p)) p++;
+ if (!*p)
+ return 1;
+
+ *value = p;
+
+ /* remove trailing space */
+ while (*p)
+ p++;
+ while (isspace(*--p))
+ *p = '\0';
+
+ return 1;
+}
+
+
+static unsigned parse_show(char *s)
+{
+ unsigned info = 0;
+ char *tok;
+
+ for (tok = strtok(s, " \t"); tok; tok = strtok(NULL, " \t")) {
+ if (!strcasecmp(tok, "imageable-area"))
+ info |= INFO_IMAGEABLE_AREA;
+ else if (!strcasecmp(tok, "job-billing"))
+ info |= INFO_JOB_BILLING;
+ else if (!strcasecmp(tok, "job-id"))
+ info |= INFO_JOB_ID;
+ else if (!strcasecmp(tok, "job-name"))
+ info |= INFO_JOB_NAME;
+ else if (!strcasecmp(tok, "job-originating-host-name"))
+ info |= INFO_JOB_ORIGINATING_HOST_NAME;
+ else if (!strcasecmp(tok, "job-originating-user-name"))
+ info |= INFO_JOB_ORIGINATING_USER_NAME;
+ else if (!strcasecmp(tok, "job-uuid"))
+ info |= INFO_JOB_UUID;
+ else if (!strcasecmp(tok, "options"))
+ info |= INFO_OPTIONS;
+ else if (!strcasecmp(tok, "paper-name"))
+ info |= INFO_PAPER_NAME;
+ else if (!strcasecmp(tok, "paper-size"))
+ info |= INFO_PAPER_SIZE;
+ else if (!strcasecmp(tok, "printer-driver-name"))
+ info |= INFO_PRINTER_DRIVER_NAME;
+ else if (!strcasecmp(tok, "printer-driver-version"))
+ info |= INFO_PRINTER_DRIVER_VERSION;
+ else if (!strcasecmp(tok, "printer-info"))
+ info |= INFO_PRINTER_INFO;
+ else if (!strcasecmp(tok, "printer-location"))
+ info |= INFO_PRINTER_LOCATION;
+ else if (!strcasecmp(tok, "printer-make-and-model"))
+ info |= INFO_PRINTER_MAKE_AND_MODEL;
+ else if (!strcasecmp(tok, "printer-name"))
+ info |= INFO_PRINTER_NAME;
+ else if (!strcasecmp(tok, "time-at-creation"))
+ info |= INFO_TIME_AT_CREATION;
+ else if (!strcasecmp(tok, "time-at-processing"))
+ info |= INFO_TIME_AT_PROCESSING;
+ else
+ fprintf(stderr, "error: unknown value for 'Show': %s\n", tok);
+ }
+ return info;
+}
+
+
+static char * template_path(const char *name)
+{
+ char *datadir, *result;
+
+ if (name[0] == '/')
+ return strdup(name);
+
+ if ((datadir = getenv("CUPS_DATADIR")) == NULL) {
+ result = malloc(strlen(BANNERTOPDF_DATADIR) + strlen(name) + 2);
+ sprintf(result, "%s/%s", BANNERTOPDF_DATADIR, name);
+ } else {
+ result = malloc(strlen(datadir) + strlen(name) + 7);
+ sprintf(result, "%s/data/%s", datadir, name);
+ }
+
+ return result;
+}
+
+
+banner_t * banner_new_from_file(const char *filename,
+ int *num_options, cups_option_t **options)
+{
+ FILE *f;
+ char *line = NULL;
+ size_t len = 0;
+ int linenr = 0;
+ banner_t *banner = NULL;
+
+ if (!strcmp(filename, "-"))
+ f = stdin;
+ else if (!(f = fopen(filename, "r"))) {
+ perror("Error opening banner file");
+ goto out;
+ }
+
+ if (getline(&line, &len, f) == -1 ||
+ strncmp(line, "#PDF-BANNER", 11) != 0)
+ goto out;
+
+ banner = calloc(1, sizeof *banner);
+
+ while (getline(&line, &len, f) != -1) {
+ char *key, *value;
+
+ linenr++;
+ if (!parse_line(line, &key, &value))
+ continue;
+
+ if (!value) {
+ fprintf(stderr, "error: line %d is missing a value\n", linenr);
+ continue;
+ }
+
+ if (!strcasecmp(key, "template"))
+ banner->template_file = template_path(value);
+ else if (!strcasecmp(key, "header"))
+ banner->header = strdup(value);
+ else if (!strcasecmp(key, "footer"))
+ banner->header = strdup(value);
+ else if (!strcasecmp(key, "font")) {
+ *num_options = cupsAddOption("banner-font",
+ strdup(value), *num_options, options);
+ }
+ else if (!strcasecmp(key, "font-size")) {
+ *num_options = cupsAddOption("banner-font-size",
+ strdup(value), *num_options, options);
+ }
+ else if (!strcasecmp(key, "show"))
+ banner->infos = parse_show(value);
+ else if (!strcasecmp(key, "image") ||
+ !strcasecmp(key, "notice"))
+ fprintf(stderr,
+ "note:%d: bannertopdf does not support '%s'\n",
+ linenr, key);
+ else
+ fprintf(stderr,
+ "error:%d: unknown keyword '%s'\n",
+ linenr, key);
+ }
+
+ /* load default template if none was specified */
+ if (!banner->template_file)
+ banner->template_file = template_path ("default.pdf");
+
+out:
+ free(line);
+ if (f)
+ fclose(f);
+ return banner;
+}
+
+
+void banner_free(banner_t *banner)
+{
+ if (banner) {
+ free(banner->template_file);
+ free(banner->header);
+ free(banner->footer);
+ free(banner);
+ }
+}
+
diff --git a/filter/banner.h b/filter/banner.h
new file mode 100644
index 000000000..951baefa9
--- /dev/null
+++ b/filter/banner.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2012 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef banner_h
+#define banner_h
+
+#include <config.h>
+#include <stdio.h>
+#include <cups/cups.h>
+
+enum banner_info {
+ INFO_IMAGEABLE_AREA = 1,
+ INFO_JOB_BILLING = 1 << 1,
+ INFO_JOB_ID = 1 << 2,
+ INFO_JOB_NAME = 1 << 3,
+ INFO_JOB_ORIGINATING_HOST_NAME = 1 << 4,
+ INFO_JOB_ORIGINATING_USER_NAME = 1 << 5,
+ INFO_JOB_UUID = 1 << 6,
+ INFO_OPTIONS = 1 << 7,
+ INFO_PAPER_NAME = 1 << 8,
+ INFO_PAPER_SIZE = 1 << 9,
+ INFO_PRINTER_DRIVER_NAME = 1 << 10,
+ INFO_PRINTER_DRIVER_VERSION = 1 << 11,
+ INFO_PRINTER_INFO = 1 << 12,
+ INFO_PRINTER_LOCATION = 1 << 13,
+ INFO_PRINTER_MAKE_AND_MODEL = 1 << 14,
+ INFO_PRINTER_NAME = 1 << 15,
+ INFO_TIME_AT_CREATION = 1 << 16,
+ INFO_TIME_AT_PROCESSING = 1 << 17
+};
+
+
+typedef struct {
+ char *template_file;
+ char *header, *footer;
+ unsigned infos;
+} banner_t;
+
+
+banner_t * banner_new_from_file(const char *filename,
+ int *num_options, cups_option_t **options);
+void banner_free(banner_t *banner);
+
+#endif
+
diff --git a/filter/bannertopdf.c b/filter/bannertopdf.c
new file mode 100644
index 000000000..b78ea377a
--- /dev/null
+++ b/filter/bannertopdf.c
@@ -0,0 +1,564 @@
+/*
+ * Copyright 2012 Canonical Ltd.
+ * Copyright 2013 ALT Linux, Andrew V. Stepanov <stanv@altlinux.com>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <math.h>
+
+#ifndef HAVE_OPEN_MEMSTREAM
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#endif
+
+#include <cups/cups.h>
+#include <cups/ppd.h>
+#if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 6)
+#define HAVE_CUPS_1_7 1
+#endif
+#ifdef HAVE_CUPS_1_7
+#include <cups/pwg.h>
+#endif /* HAVE_CUPS_1_7 */
+
+#include "banner.h"
+#include "pdf.h"
+
+
+static float get_float_option(const char *name,
+ int noptions,
+ cups_option_t *options,
+ float def)
+{
+ const char *value = cupsGetOption(name, noptions, options);
+ return value ? atof(value) : def;
+}
+
+
+static int get_int_option(const char *name,
+ int noptions,
+ cups_option_t *options,
+ int def)
+{
+ const char *value = cupsGetOption(name, noptions, options);
+ return value ? atoi(value) : def;
+}
+
+
+static void get_pagesize(ppd_file_t *ppd,
+ int noptions,
+ cups_option_t *options,
+ float *width,
+ float *length,
+ float media_limits[4])
+{
+ static const ppd_size_t defaultsize = {
+ 0, /* marked */
+ "", /* name */
+ 612.0, /* width */
+ 792.0, /* length */
+ 18.0, /* left */
+ 36.0, /* bottom */
+ 594.0, /* right */
+ 756.0, /* top */
+ };
+ const ppd_size_t *pagesize;
+#ifdef HAVE_CUPS_1_7
+ pwg_media_t *size_found; /* page size found for given name */
+ const char *val; /* Pointer into value */
+ char *ptr1, *ptr2, /* Pointer into string */
+ s[255]; /* Temporary string */
+#endif /* HAVE_CUPS_1_7 */
+
+ if (!ppd || !(pagesize = ppdPageSize(ppd, NULL)))
+ pagesize = &defaultsize;
+
+ *width = pagesize->width;
+ *length = pagesize->length;
+
+ media_limits[0] = get_float_option("page-left",
+ noptions, options,
+ pagesize->left);
+ media_limits[1] = get_float_option("page-bottom",
+ noptions, options,
+ pagesize->bottom);
+ media_limits[2] = get_float_option("page-right",
+ noptions, options,
+ fabs(pagesize->right));
+ media_limits[3] = get_float_option("page-top",
+ noptions, options,
+ fabs(pagesize->top));
+
+#ifdef HAVE_CUPS_1_7
+ if (!ppd) {
+ if ((val = cupsGetOption("media-size", noptions, options)) != NULL ||
+ (val = cupsGetOption("MediaSize", noptions, options)) != NULL ||
+ (val = cupsGetOption("page-size", noptions, options)) != NULL ||
+ (val = cupsGetOption("PageSize", noptions, options)) != NULL ||
+ (val = cupsGetOption("media", noptions, options)) != NULL) {
+ for (ptr1 = (char *)val; *ptr1;) {
+ for (ptr2 = s; *ptr1 && *ptr1 != ',' && (ptr2 - s) < (sizeof(s) - 1);)
+ *ptr2++ = *ptr1++;
+ *ptr2++ = '\0';
+ if (*ptr1 == ',')
+ ptr1 ++;
+ size_found = NULL;
+ if ((size_found = pwgMediaForPWG(s)) == NULL)
+ if ((size_found = pwgMediaForPPD(s)) == NULL)
+ size_found = pwgMediaForLegacy(s);
+ if (size_found != NULL) {
+ *width = size_found->width * 72.0 / 2540.0;
+ *length = size_found->length * 72.0 / 2540.0;
+ media_limits[2] += (*width - 612.0);
+ media_limits[3] += (*length - 792.0);
+ }
+ }
+ }
+ if ((val = cupsGetOption("media-left-margin", noptions, options))
+ != NULL)
+ media_limits[0] = atol(val) * 72.0 / 2540.0;
+ if ((val = cupsGetOption("media-bottom-margin", noptions, options))
+ != NULL)
+ media_limits[1] = atol(val) * 72.0 / 2540.0;
+ if ((val = cupsGetOption("media-right-margin", noptions, options))
+ != NULL)
+ media_limits[2] = *width - atol(val) * 72.0 / 2540.0;
+ if ((val = cupsGetOption("media-top-margin", noptions, options))
+ != NULL)
+ media_limits[3] = *length - atol(val) * 72.0 / 2540.0;
+ }
+#endif /* HAVE_CUPS_1_7 */
+}
+
+
+static int duplex_marked(ppd_file_t *ppd,
+ int noptions,
+ cups_option_t *options)
+{
+ const char *val; /* Pointer into value */
+ return
+ (ppd &&
+ (ppdIsMarked(ppd, "Duplex", "DuplexNoTumble") ||
+ ppdIsMarked(ppd, "Duplex", "DuplexTumble") ||
+ ppdIsMarked(ppd, "JCLDuplex", "DuplexNoTumble") ||
+ ppdIsMarked(ppd, "JCLDuplex", "DuplexTumble") ||
+ ppdIsMarked(ppd, "EFDuplex", "DuplexNoTumble") ||
+ ppdIsMarked(ppd, "EFDuplex", "DuplexTumble") ||
+ ppdIsMarked(ppd, "KD03Duplex", "DuplexNoTumble") ||
+ ppdIsMarked(ppd, "KD03Duplex", "DuplexTumble"))) ||
+ ((val = cupsGetOption("Duplex", noptions, options))
+ != NULL &&
+ (!strcasecmp(val, "DuplexNoTumble") ||
+ !strcasecmp(val, "DuplexTumble"))) ||
+ ((val = cupsGetOption("sides", noptions, options))
+ != NULL &&
+ (!strcasecmp(val, "two-sided-long-edge") ||
+ !strcasecmp(val, "two-sided-short-edge")));
+}
+
+
+static void info_linef(FILE *s,
+ const char *key,
+ const char *valuefmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, valuefmt);
+ fprintf(s, "(%s: ", key);
+ vfprintf(s, valuefmt, ap);
+ fprintf(s, ") Tj T*\n");
+ va_end(ap);
+}
+
+
+static void info_line(FILE *s,
+ const char *key,
+ const char *value)
+{
+ info_linef(s, key, "%s", value);
+}
+
+
+static void info_line_time(FILE *s,
+ const char *key,
+ const char *timestamp)
+{
+ char buf[40];
+ time_t time;
+
+ if (timestamp) {
+ time = (time_t)atoll(timestamp);
+ strftime(buf, sizeof buf, "%c", localtime(&time));
+ info_line(s, key, buf);
+ }
+ else
+ info_line(s, key, "unknown");
+}
+
+static const char *human_time(const char *timestamp)
+{
+ time_t time;
+ int size = sizeof(char) * 40;
+ char *buf = malloc(size);
+ strcpy(buf, "unknown");
+
+ if (timestamp) {
+ time = (time_t)atoll(timestamp);
+ strftime(buf, size, "%c", localtime(&time));
+ }
+
+ return buf;
+}
+
+/*
+ * Add new key & value.
+ */
+static opt_t* add_opt(opt_t *in_opt, const char *key, const char *val) {
+ if ( ! key || ! val ) {
+ return in_opt;
+ }
+
+ if ( !strlen(key) || !strlen(val) ) {
+ return in_opt;
+ }
+
+ opt_t *entry = malloc(sizeof(opt_t));
+ if ( ! entry ) {
+ return in_opt;
+ }
+
+ entry->key = key;
+ entry->val = val;
+ entry->next = in_opt;
+
+ return entry;
+}
+
+/*
+ * Collect all known info about current task.
+ * Bond PDF form field name with collected info.
+ *
+ * Create PDF form's field names according above.
+ */
+opt_t *get_known_opts(
+ ppd_file_t *ppd,
+ const char *jobid,
+ const char *user,
+ const char *jobtitle,
+ int noptions,
+ cups_option_t *options) {
+
+ ppd_attr_t *attr;
+ opt_t *opt = NULL;
+
+ /* Job ID */
+ opt = add_opt(opt, "job-id", jobid);
+
+ /* Job title */
+ opt = add_opt(opt, "job-title", jobtitle);
+
+ /* Printer by */
+ opt = add_opt(opt, "user", user);
+
+ /* Printer name */
+ opt = add_opt(opt, "printer-name", getenv("PRINTER"));
+
+ /* Printer info */
+ opt = add_opt(opt, "printer-info", getenv("PRINTER_INFO"));
+
+ /* Time at creation */
+ opt = add_opt(opt, "time-at-creation",
+ human_time(cupsGetOption("time-at-creation", noptions, options)));
+
+ /* Processing time */
+ opt = add_opt(opt, "time-at-processing",
+ human_time(cupsGetOption("time-at-processing", noptions, options)));
+
+ /* Billing information */
+ opt = add_opt(opt, "job-billing",
+ cupsGetOption("job-billing", noptions, options));
+
+ /* Source hostname */
+ opt = add_opt(opt, "job-originating-host-name",
+ cupsGetOption("job-originating-host-name", noptions, options));
+
+ /* Banner font */
+ opt = add_opt(opt, "banner-font",
+ cupsGetOption("banner-font", noptions, options));
+
+ /* Banner font size */
+ opt = add_opt(opt, "banner-font-size",
+ cupsGetOption("banner-font-size", noptions, options));
+
+ /* Job UUID */
+ opt = add_opt(opt, "job-uuid",
+ cupsGetOption("job-uuid", noptions, options));
+
+ /* Security context */
+ opt = add_opt(opt, "security-context",
+ cupsGetOption("security-context", noptions, options));
+
+ /* Security context range part */
+ opt = add_opt(opt, "security-context-range",
+ cupsGetOption("security-context-range", noptions, options));
+
+ /* Security context current range part */
+ const char * full_range = cupsGetOption("security-context-range", noptions, options);
+ if ( full_range ) {
+ size_t cur_size = strcspn(full_range, "-");
+ char * cur_range = strndup(full_range, cur_size);
+ opt = add_opt(opt, "security-context-range-cur", cur_range);
+ }
+
+ /* Security context type part */
+ opt = add_opt(opt, "security-context-type",
+ cupsGetOption("security-context-type", noptions, options));
+
+ /* Security context role part */
+ opt = add_opt(opt, "security-context-role",
+ cupsGetOption("security-context-role", noptions, options));
+
+ /* Security context user part */
+ opt = add_opt(opt, "security-context-user",
+ cupsGetOption("security-context-user", noptions, options));
+
+ if (ppd) {
+ /* Driver */
+ opt = add_opt(opt, "driver", ppd->pcfilename);
+
+ /* Driver version */
+ opt = add_opt(opt, "driver-version",
+ (attr = ppdFindAttr(ppd, "FileVersion", NULL)) ?
+ attr->value : "");
+
+ /* Make and model */
+ opt = add_opt(opt, "make-and-model", ppd->nickname);
+ }
+
+ return opt;
+}
+
+static int generate_banner_pdf(banner_t *banner,
+ ppd_file_t *ppd,
+ const char *jobid,
+ const char *user,
+ const char *jobtitle,
+ int noptions,
+ cups_option_t *options)
+{
+ char *buf;
+ size_t len;
+ FILE *s;
+ pdf_t *doc;
+ float page_width, page_length;
+ float media_limits[4];
+ float page_scale;
+ ppd_attr_t *attr;
+ int copies;
+#ifndef HAVE_OPEN_MEMSTREAM
+ struct stat st;
+#endif
+
+ if (!(doc = pdf_load_template(banner->template_file)))
+ return 1;
+
+ get_pagesize(ppd, noptions, options,
+ &page_width, &page_length, media_limits);
+
+ pdf_resize_page (doc, 1, page_width, page_length, &page_scale);
+
+ pdf_add_type1_font(doc, 1, "Courier");
+
+#ifdef HAVE_OPEN_MEMSTREAM
+ s = open_memstream(&buf, &len);
+#else
+ if ((s = tmpfile()) == NULL) {
+ fprintf (stderr, "ERROR: bannertopdf: cannot create temp file: %s\n",
+ strerror (errno));
+ return 1;
+ }
+#endif
+
+ if (banner->infos & INFO_IMAGEABLE_AREA) {
+ fprintf(s, "q\n");
+ fprintf(s, "0 0 0 RG\n");
+ fprintf(s, "%f %f %f %f re S\n", media_limits[0] + 1.0,
+ media_limits[1] + 1.0,
+ media_limits[2] - media_limits[0] - 2.0,
+ media_limits[3] - media_limits[1] - 2.0);
+ fprintf(s, "Q\n");
+ }
+
+ fprintf(s, "%f 0 0 %f 0 0 cm\n", page_scale, page_scale);
+
+ fprintf(s, "0 0 0 rg\n");
+ fprintf(s, "BT\n");
+ fprintf(s, "/bannertopdf-font 14 Tf\n");
+ fprintf(s, "83.662 335.0 Td\n");
+ fprintf(s, "17 TL\n");
+
+ if (banner->infos & INFO_IMAGEABLE_AREA)
+ info_linef(s, "Media Limits", "%.2f x %.2f to %.2f x %.2f inches",
+ media_limits[0] / 72.0,
+ media_limits[1] / 72.0,
+ media_limits[2] / 72.0,
+ media_limits[3] / 72.0);
+
+ if (banner->infos & INFO_JOB_BILLING)
+ info_line(s, "Billing Information\n",
+ cupsGetOption("job-billing", noptions, options));
+
+ if (banner->infos & INFO_JOB_ID)
+ info_linef(s, "Job ID", "%s-%s", getenv("PRINTER"), jobid);
+
+ if (banner->infos & INFO_JOB_NAME)
+ info_line(s, "Job Title", jobtitle);
+
+ if (banner->infos & INFO_JOB_ORIGINATING_HOST_NAME)
+ info_line(s, "Printed from",
+ cupsGetOption("job-originating-host-name",
+ noptions, options));
+
+ if (banner->infos & INFO_JOB_ORIGINATING_USER_NAME)
+ info_line(s, "Printed by", user);
+
+ if (banner->infos & INFO_JOB_UUID)
+ info_line(s, "Job UUID",
+ cupsGetOption("job-uuid", noptions, options));
+
+ if (ppd && banner->infos & INFO_PRINTER_DRIVER_NAME)
+ info_line(s, "Driver", ppd->pcfilename);
+
+ if (ppd && banner->infos & INFO_PRINTER_DRIVER_VERSION)
+ info_line(s, "Driver Version",
+ (attr = ppdFindAttr(ppd, "FileVersion", NULL)) ? attr->value : "");
+
+ if (banner->infos & INFO_PRINTER_INFO)
+ info_line(s, "Description", getenv("PRINTER_INFO"));
+
+ if (banner->infos & INFO_PRINTER_LOCATION)
+ info_line(s, "Printer Location", getenv("PRINTER_LOCATION"));
+
+ if (ppd && banner->infos & INFO_PRINTER_MAKE_AND_MODEL)
+ info_line(s, "Make and Model", ppd->nickname);
+
+ if (banner->infos & INFO_PRINTER_NAME)
+ info_line(s, "Printer", getenv("PRINTER"));
+
+ if (banner->infos & INFO_TIME_AT_CREATION)
+ info_line_time(s, "Created at",
+ cupsGetOption("time-at-creation", noptions, options));
+
+ if (banner->infos & INFO_TIME_AT_PROCESSING)
+ info_line_time(s, "Printed at",
+ cupsGetOption("time-at-processing", noptions, options));
+
+ fprintf(s, "ET\n");
+#ifndef HAVE_OPEN_MEMSTREAM
+ fflush (s);
+ if (fstat (fileno (s), &st) < 0) {
+ fprintf (stderr, "ERROR: bannertopdf: cannot fstat(): %s\n", strerror(errno));
+ return 1 ;
+ }
+ fseek (s, 0L, SEEK_SET);
+ if ((buf = malloc(st.st_size + 1)) == NULL) {
+ fprintf (stderr, "ERROR: bannertopdf: cannot malloc(): %s\n", strerror(errno));
+ return 1 ;
+ }
+ size_t nbytes = fread (buf, 1, st.st_size, s);
+ buf[st.st_size] = '\0';
+ len = strlen (buf);
+#endif /* !HAVE_OPEN_MEMSTREAM */
+ fclose(s);
+
+ opt_t * known_opts = get_known_opts(ppd,
+ jobid,
+ user,
+ jobtitle,
+ noptions,
+ options);
+
+ /*
+ * Try to find a PDF form in PDF template and fill it.
+ */
+ int ret = pdf_fill_form(doc, known_opts);
+
+ /*
+ * Could we fill a PDF form? If no, just add PDF stream.
+ */
+ if ( ! ret ) {
+ pdf_prepend_stream(doc, 1, buf, len);
+ }
+
+ copies = get_int_option("number-up", noptions, options, 1);
+ if (duplex_marked(ppd, noptions, options))
+ copies *= 2;
+
+ if (copies > 1)
+ pdf_duplicate_page(doc, 1, copies);
+
+ pdf_write(doc, stdout);
+ free(buf);
+ pdf_free(doc);
+ return 0;
+}
+
+
+int main(int argc, char *argv[])
+{
+ banner_t *banner;
+ int noptions;
+ cups_option_t *options;
+ ppd_file_t *ppd;
+ int ret;
+
+ if (argc < 6) {
+ fprintf(stderr,
+ "Usage: %s job-id user job-title nr-copies options [file]\n",
+ argv[0]);
+ return 1;
+ }
+
+ ppd = ppdOpenFile(getenv("PPD"));
+ if (!ppd)
+ fprintf(stderr, "DEBUG: Could not open PPD file '%s'\n", getenv("PPD"));
+
+ noptions = cupsParseOptions(argv[5], 0, &options);
+ if (ppd) {
+ ppdMarkDefaults(ppd);
+ cupsMarkOptions(ppd, noptions, options);
+ }
+
+ banner = banner_new_from_file(argc == 7 ? argv[6] : "-", &noptions, &options);
+ if (!banner) {
+ fprintf(stderr, "Error: could not read banner file\n");
+ return 1;
+ }
+
+ ret = generate_banner_pdf(banner,
+ ppd,
+ argv[1],
+ argv[2],
+ argv[3],
+ noptions,
+ options);
+
+ banner_free(banner);
+ cupsFreeOptions(noptions, options);
+ return ret;
+}
diff --git a/filter/braille/drivers/common/fr-braille.po b/filter/braille/drivers/common/fr-braille.po
new file mode 100644
index 000000000..3f0181d4f
--- /dev/null
+++ b/filter/braille/drivers/common/fr-braille.po
@@ -0,0 +1,239 @@
+#
+# Copyright (c) 2015, 2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+msgid "Generic"
+msgstr "Generique"
+
+msgid "Braille embosser"
+msgstr "Embosseuse braille"
+
+msgid "A4 Tractor Feed"
+msgstr "A4 Traction papier"
+
+msgid "Yes"
+msgstr "Oui"
+
+msgid "No"
+msgstr "Non"
+
+msgid "Braille transcription"
+msgstr "Transcription Braille"
+
+msgid "None"
+msgstr "Aucune"
+
+msgid "Additional Braille transcription (2)"
+msgstr "Transcription Braille additionnelle (2)"
+
+msgid "Additional Braille transcription (3)"
+msgstr "Transcription Braille additionnelle (3)"
+
+msgid "Additional Braille transcription (4)"
+msgstr "Transcription Braille additionnelle (4)"
+
+msgid "Default for language"
+msgstr "Par défaut pour la langue"
+
+msgid "Default for language grade 0"
+msgstr "Par défaut pour la langue grade 0"
+
+msgid "Default for language grade 1"
+msgstr "Par défaut pour la langue grade 1"
+
+msgid "Default for language grade 2"
+msgstr "Par défaut pour la langue grade 2"
+
+msgid "Default for language grade 3"
+msgstr "Par défaut pour la langue grade 3"
+
+msgid "Text dot distance"
+msgstr "Distance points texte"
+
+msgid "Text dots"
+msgstr "Points texte"
+
+msgid "8 dots"
+msgstr "8 points"
+
+msgid "6 dots"
+msgstr "6 points"
+
+msgid "Graphic dot distance"
+msgstr "Distance points graphique"
+
+msgid "Line spacing"
+msgstr "Espacement de ligne"
+
+msgid "Top margin"
+msgstr "Marge haut"
+
+msgid "Bottom margin"
+msgstr "Marge bas"
+
+msgid "Inner margin"
+msgstr "Marge intérieure"
+
+msgid "Outer margin"
+msgstr "Marge extérieure"
+
+msgid "Page number"
+msgstr "Numéro de page"
+
+msgid "Graphical top margin"
+msgstr "Marge graphique haut"
+
+msgid "Graphical bottom margin"
+msgstr "Marge graphique bas"
+
+msgid "Graphical left margin"
+msgstr "Marge graphique gauche"
+
+msgid "Graphical right margin"
+msgstr "Marge graphique droite"
+
+msgid "Image conversion"
+msgstr "Conversion d'image"
+
+msgid "Resize"
+msgstr "Retailler"
+
+msgid "Mirror"
+msgstr "Miroir"
+
+msgid "Rotation"
+msgstr "Rotation"
+
+msgid "No rotation"
+msgstr "Pas de rotation"
+
+msgid "Rotate clockwise to fit paper"
+msgstr "Rotation horaire pour correspondre au papier"
+
+msgid "Rotate counter clockwise to fit paper"
+msgstr "Rotation anti-horaire pour correspondre au papier"
+
+msgid "Clockwise"
+msgstr "Horaire"
+
+msgid "Counter clockwise"
+msgstr "Anti-horaire"
+
+msgid "Upside Down"
+msgstr "Retourner"
+
+msgid "Edge detection"
+msgstr "Détection de contour"
+
+msgid "Simple"
+msgstr "Simple"
+
+msgid "Canny"
+msgstr "Canny"
+
+msgid "Negate"
+msgstr "Inversion"
+
+msgid "EdgeFactor"
+msgstr "Facteur de contour"
+
+msgid "CannyRadius"
+msgstr "Radius Canny"
+
+msgid "CannySigma"
+msgstr "Sigma Canny"
+
+msgid "CannyLower"
+msgstr "Lower Canny"
+
+msgid "CannyUpper"
+msgstr "Upper Canny"
+
+msgid "Index support"
+msgstr "Support Index"
+
+msgid "Installed firmware version"
+msgstr "Version de firmware installée"
+
+msgid "10.20 or above"
+msgstr "10.20 ou supérieur"
+
+msgid "10.30 or above"
+msgstr "10.30 ou supérieur"
+
+msgid "11.02.1 or above"
+msgstr "11.02.1 ou supérieur"
+
+msgid "11.03.2 or above"
+msgstr "11.03.2 ou supérieur"
+
+msgid "12.01.3 or above"
+msgstr "12.01.3 ou supérieur"
+
+msgid "Page folding"
+msgstr "Recto-Verso"
+
+msgid "Single-sided"
+msgstr "Recto seul"
+
+msgid "Double-sided"
+msgstr "Recto-Verso"
+
+msgid "Single-sided z-folding"
+msgstr "Recto seul, pliage Z"
+
+msgid "Double-sided z-folding"
+msgstr "Recto-Verso, pliage Z"
+
+msgid "Single-sided sideways z-folding"
+msgstr "Recto seul paysage, pliage Z"
+
+msgid "Double-sided sideways z-folding"
+msgstr "Recto-Verso paysage, pliage Z"
+
+msgid "Double-sided saddle stitch 4 pages"
+msgstr "Recto-Verso cahier 4 pages"
+
+msgid "Single-sided saddle stitch 4 pages"
+msgstr "Recto cahier 4 pages"
+
+msgid "Firmware Braille Table"
+msgstr "Table Braille Firmware"
+
+msgid "6-dot MIT table"
+msgstr "Table MIT 6 points"
+
+msgid "User-defined Table 1"
+msgstr "Table 1 définie par l'utilisateur"
+
+msgid "User-defined Table 2"
+msgstr "Table 2 définie par l'utilisateur"
+
+msgid "User-defined Table 3"
+msgstr "Table 3 définie par l'utilisateur"
+
+msgid "User-defined Table 4"
+msgstr "Table 4 définie par l'utilisateur"
+
+msgid "Multiple Impact"
+msgstr "Impact multiple"
diff --git a/filter/braille/drivers/common/media-braille.defs b/filter/braille/drivers/common/media-braille.defs
new file mode 100644
index 000000000..e1179862e
--- /dev/null
+++ b/filter/braille/drivers/common/media-braille.defs
@@ -0,0 +1,30 @@
+//
+// Copyright (c) 2015 Samuel Thibault <samuel.thibault@ens-lyon.org>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#media "110x115/11x11.5" 792 828
+#media "110x120/11x12" 792 864
+#media "110x170/11x17" 792 1224
+#media "115x110/11.5x11" 828 792
+#media "120x120/12x12" 864 864
+#media "A4TF/A4 Tractor Feed" 594 864
diff --git a/filter/braille/drivers/generic/brftoembosser.in b/filter/braille/drivers/generic/brftoembosser.in
new file mode 100755
index 000000000..d2aea9648
--- /dev/null
+++ b/filter/braille/drivers/generic/brftoembosser.in
@@ -0,0 +1,91 @@
+#!/bin/bash
+
+#
+# Copyright (c) 2015, 2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+# Make sure we have enough options
+if [ $# != 5 -a $# != 6 ]; then
+ echo "ERROR: $0 jobid user name nb options [filename]" >&2
+ exit 1
+fi
+
+NB=$4
+OPTIONS=$5
+FILE=$6
+if [ -z "$FILE" ]
+then
+ # Get input from stdin
+ unset FILE
+ trap -- 'rm -f "$FILE"' EXIT
+ FILE=$(mktemp "${TMPDIR:-/tmp}/brftoembosser.XXXXXX")
+ cat > "$FILE"
+fi
+
+. @CUPS_DATADIR@/braille/cups-braille.sh
+
+SENDFF=$(getOption SendFF)
+SENDSUB=$(getOption SendSUB)
+
+TOPMARGIN=$(getOptionNumber TopMargin)
+LEFTMARGIN=$(getOptionNumber LeftMargin)
+
+echo "INFO: Writing text to generic embosser" >&2
+
+while [ $NB -gt 0 ]
+do
+ # Produce top margin
+ if [ -n "$TOPMARGIN" ]; then
+ while [ $TOPMARGIN -gt 0 ]
+ do
+ echo
+ TOPMARGIN=$(($TOPMARGIN - 1))
+ done
+ fi
+ LEFTSPACES=""
+ if [ -n "$LEFTMARGIN" ]; then
+ while [ $LEFTMARGIN -gt 0 ]
+ do
+ LEFTSPACES="$LEFTSPACES "
+ LEFTMARGIN=$(($LEFTMARGIN - 1))
+ done
+ fi
+
+ < "$FILE" \
+ sed -e "s/^/$LEFTSPACES/" \
+ -e 's/^$/'$'\015''/' \
+ -e 's/\([^'$'\015'']\)$/\1'$'\015''/'
+
+ if [ "$SENDFF" = True ]
+ then
+ printf '\014'
+ fi
+ if [ "$SENDSUB" = True ]
+ then
+ printf '\032'
+ fi
+ NB=$(($NB - 1))
+done
+
+echo "INFO: Ready" >&2
+exit 0
diff --git a/filter/braille/drivers/index/imageubrltoindexv3.in b/filter/braille/drivers/index/imageubrltoindexv3.in
new file mode 100755
index 000000000..8294ff1b9
--- /dev/null
+++ b/filter/braille/drivers/index/imageubrltoindexv3.in
@@ -0,0 +1,318 @@
+#!/bin/bash
+
+#
+# Copyright (c) 2015-2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+# Make sure we have enough options
+if [ $# != 5 -a $# != 6 ]; then
+ echo "ERROR: $0 jobid user name nb options [filename]" >&2
+ exit 1
+fi
+
+NB=$4
+OPTIONS=$5
+FILE=$6
+
+# Disable margins, they are done by imagemagick before this
+NOMARGIN=1
+
+. @CUPS_DATADIR@/braille/indexv3.sh
+printf "$INIT"
+
+# Enter 4-dot graphic mode
+printf "\033\007"
+
+echo "INFO: Writing text to Index embosser" >&2
+( if [ -z "$FILE" ]
+then
+ cat
+else
+ cat "$FILE"
+fi ) | sed \
+ -e 's/⠀/@@/g' \
+ -e 's/⠁/A@/g' \
+ -e 's/⠂/B@/g' \
+ -e 's/⠃/C@/g' \
+ -e 's/⠄/D@/g' \
+ -e 's/⠅/E@/g' \
+ -e 's/⠆/F@/g' \
+ -e 's/⠇/G@/g' \
+ -e 's/⡀/H@/g' \
+ -e 's/⡁/I@/g' \
+ -e 's/⡂/J@/g' \
+ -e 's/⡃/K@/g' \
+ -e 's/⡄/L@/g' \
+ -e 's/⡅/M@/g' \
+ -e 's/⡆/N@/g' \
+ -e 's/⡇/O@/g' \
+ -e 's/⠈/@A/g' \
+ -e 's/⠉/AA/g' \
+ -e 's/⠊/BA/g' \
+ -e 's/⠋/CA/g' \
+ -e 's/⠌/DA/g' \
+ -e 's/⠍/EA/g' \
+ -e 's/⠎/FA/g' \
+ -e 's/⠏/GA/g' \
+ -e 's/⡈/HA/g' \
+ -e 's/⡉/IA/g' \
+ -e 's/⡊/JA/g' \
+ -e 's/⡋/KA/g' \
+ -e 's/⡌/LA/g' \
+ -e 's/⡍/MA/g' \
+ -e 's/⡎/NA/g' \
+ -e 's/⡏/OA/g' \
+ -e 's/⠐/@B/g' \
+ -e 's/⠑/AB/g' \
+ -e 's/⠒/BB/g' \
+ -e 's/⠓/CB/g' \
+ -e 's/⠔/DB/g' \
+ -e 's/⠕/EB/g' \
+ -e 's/⠖/FB/g' \
+ -e 's/⠗/GB/g' \
+ -e 's/⡐/HB/g' \
+ -e 's/⡑/IB/g' \
+ -e 's/⡒/JB/g' \
+ -e 's/⡓/KB/g' \
+ -e 's/⡔/LB/g' \
+ -e 's/⡕/MB/g' \
+ -e 's/⡖/NB/g' \
+ -e 's/⡗/OB/g' \
+ -e 's/⠘/@C/g' \
+ -e 's/⠙/AC/g' \
+ -e 's/⠚/BC/g' \
+ -e 's/⠛/CC/g' \
+ -e 's/⠜/DC/g' \
+ -e 's/⠝/EC/g' \
+ -e 's/⠞/FC/g' \
+ -e 's/⠟/GC/g' \
+ -e 's/⡘/HC/g' \
+ -e 's/⡙/IC/g' \
+ -e 's/⡚/JC/g' \
+ -e 's/⡛/KC/g' \
+ -e 's/⡜/LC/g' \
+ -e 's/⡝/MC/g' \
+ -e 's/⡞/NC/g' \
+ -e 's/⡟/OC/g' \
+ -e 's/⠠/@D/g' \
+ -e 's/⠡/AD/g' \
+ -e 's/⠢/BD/g' \
+ -e 's/⠣/CD/g' \
+ -e 's/⠤/DD/g' \
+ -e 's/⠥/ED/g' \
+ -e 's/⠦/FD/g' \
+ -e 's/⠧/GD/g' \
+ -e 's/⡠/HD/g' \
+ -e 's/⡡/ID/g' \
+ -e 's/⡢/JD/g' \
+ -e 's/⡣/KD/g' \
+ -e 's/⡤/LD/g' \
+ -e 's/⡥/MD/g' \
+ -e 's/⡦/ND/g' \
+ -e 's/⡧/OD/g' \
+ -e 's/⠨/@E/g' \
+ -e 's/⠩/AE/g' \
+ -e 's/⠪/BE/g' \
+ -e 's/⠫/CE/g' \
+ -e 's/⠬/DE/g' \
+ -e 's/⠭/EE/g' \
+ -e 's/⠮/FE/g' \
+ -e 's/⠯/GE/g' \
+ -e 's/⡨/HE/g' \
+ -e 's/⡩/IE/g' \
+ -e 's/⡪/JE/g' \
+ -e 's/⡫/KE/g' \
+ -e 's/⡬/LE/g' \
+ -e 's/⡭/ME/g' \
+ -e 's/⡮/NE/g' \
+ -e 's/⡯/OE/g' \
+ -e 's/⠰/@F/g' \
+ -e 's/⠱/AF/g' \
+ -e 's/⠲/BF/g' \
+ -e 's/⠳/CF/g' \
+ -e 's/⠴/DF/g' \
+ -e 's/⠵/EF/g' \
+ -e 's/⠶/FF/g' \
+ -e 's/⠷/GF/g' \
+ -e 's/⡰/HF/g' \
+ -e 's/⡱/IF/g' \
+ -e 's/⡲/JF/g' \
+ -e 's/⡳/KF/g' \
+ -e 's/⡴/LF/g' \
+ -e 's/⡵/MF/g' \
+ -e 's/⡶/NF/g' \
+ -e 's/⡷/OF/g' \
+ -e 's/⠸/@G/g' \
+ -e 's/⠹/AG/g' \
+ -e 's/⠺/BG/g' \
+ -e 's/⠻/CG/g' \
+ -e 's/⠼/DG/g' \
+ -e 's/⠽/EG/g' \
+ -e 's/⠾/FG/g' \
+ -e 's/⠿/GG/g' \
+ -e 's/⡸/HG/g' \
+ -e 's/⡹/IG/g' \
+ -e 's/⡺/JG/g' \
+ -e 's/⡻/KG/g' \
+ -e 's/⡼/LG/g' \
+ -e 's/⡽/MG/g' \
+ -e 's/⡾/NG/g' \
+ -e 's/⡿/OG/g' \
+ -e 's/⢀/@H/g' \
+ -e 's/⢁/AH/g' \
+ -e 's/⢂/BH/g' \
+ -e 's/⢃/CH/g' \
+ -e 's/⢄/DH/g' \
+ -e 's/⢅/EH/g' \
+ -e 's/⢆/FH/g' \
+ -e 's/⢇/GH/g' \
+ -e 's/⣀/HH/g' \
+ -e 's/⣁/IH/g' \
+ -e 's/⣂/JH/g' \
+ -e 's/⣃/KH/g' \
+ -e 's/⣄/LH/g' \
+ -e 's/⣅/MH/g' \
+ -e 's/⣆/NH/g' \
+ -e 's/⣇/OH/g' \
+ -e 's/⢈/@I/g' \
+ -e 's/⢉/AI/g' \
+ -e 's/⢊/BI/g' \
+ -e 's/⢋/CI/g' \
+ -e 's/⢌/DI/g' \
+ -e 's/⢍/EI/g' \
+ -e 's/⢎/FI/g' \
+ -e 's/⢏/GI/g' \
+ -e 's/⣈/HI/g' \
+ -e 's/⣉/II/g' \
+ -e 's/⣊/JI/g' \
+ -e 's/⣋/KI/g' \
+ -e 's/⣌/LI/g' \
+ -e 's/⣍/MI/g' \
+ -e 's/⣎/NI/g' \
+ -e 's/⣏/OI/g' \
+ -e 's/⢐/@J/g' \
+ -e 's/⢑/AJ/g' \
+ -e 's/⢒/BJ/g' \
+ -e 's/⢓/CJ/g' \
+ -e 's/⢔/DJ/g' \
+ -e 's/⢕/EJ/g' \
+ -e 's/⢖/FJ/g' \
+ -e 's/⢗/GJ/g' \
+ -e 's/⣐/HJ/g' \
+ -e 's/⣑/IJ/g' \
+ -e 's/⣒/JJ/g' \
+ -e 's/⣓/KJ/g' \
+ -e 's/⣔/LJ/g' \
+ -e 's/⣕/MJ/g' \
+ -e 's/⣖/NJ/g' \
+ -e 's/⣗/OJ/g' \
+ -e 's/⢘/@K/g' \
+ -e 's/⢙/AK/g' \
+ -e 's/⢚/BK/g' \
+ -e 's/⢛/CK/g' \
+ -e 's/⢜/DK/g' \
+ -e 's/⢝/EK/g' \
+ -e 's/⢞/FK/g' \
+ -e 's/⢟/GK/g' \
+ -e 's/⣘/HK/g' \
+ -e 's/⣙/IK/g' \
+ -e 's/⣚/JK/g' \
+ -e 's/⣛/KK/g' \
+ -e 's/⣜/LK/g' \
+ -e 's/⣝/MK/g' \
+ -e 's/⣞/NK/g' \
+ -e 's/⣟/OK/g' \
+ -e 's/⢠/@L/g' \
+ -e 's/⢡/AL/g' \
+ -e 's/⢢/BL/g' \
+ -e 's/⢣/CL/g' \
+ -e 's/⢤/DL/g' \
+ -e 's/⢥/EL/g' \
+ -e 's/⢦/FL/g' \
+ -e 's/⢧/GL/g' \
+ -e 's/⣠/HL/g' \
+ -e 's/⣡/IL/g' \
+ -e 's/⣢/JL/g' \
+ -e 's/⣣/KL/g' \
+ -e 's/⣤/LL/g' \
+ -e 's/⣥/ML/g' \
+ -e 's/⣦/NL/g' \
+ -e 's/⣧/OL/g' \
+ -e 's/⢨/@M/g' \
+ -e 's/⢩/AM/g' \
+ -e 's/⢪/BM/g' \
+ -e 's/⢫/CM/g' \
+ -e 's/⢬/DM/g' \
+ -e 's/⢭/EM/g' \
+ -e 's/⢮/FM/g' \
+ -e 's/⢯/GM/g' \
+ -e 's/⣨/HM/g' \
+ -e 's/⣩/IM/g' \
+ -e 's/⣪/JM/g' \
+ -e 's/⣫/KM/g' \
+ -e 's/⣬/LM/g' \
+ -e 's/⣭/MM/g' \
+ -e 's/⣮/NM/g' \
+ -e 's/⣯/OM/g' \
+ -e 's/⢰/@N/g' \
+ -e 's/⢱/AN/g' \
+ -e 's/⢲/BN/g' \
+ -e 's/⢳/CN/g' \
+ -e 's/⢴/DN/g' \
+ -e 's/⢵/EN/g' \
+ -e 's/⢶/FN/g' \
+ -e 's/⢷/GN/g' \
+ -e 's/⣰/HN/g' \
+ -e 's/⣱/IN/g' \
+ -e 's/⣲/JN/g' \
+ -e 's/⣳/KN/g' \
+ -e 's/⣴/LN/g' \
+ -e 's/⣵/MN/g' \
+ -e 's/⣶/NN/g' \
+ -e 's/⣷/ON/g' \
+ -e 's/⢸/@O/g' \
+ -e 's/⢹/AO/g' \
+ -e 's/⢺/BO/g' \
+ -e 's/⢻/CO/g' \
+ -e 's/⢼/DO/g' \
+ -e 's/⢽/EO/g' \
+ -e 's/⢾/FO/g' \
+ -e 's/⢿/GO/g' \
+ -e 's/⣸/HO/g' \
+ -e 's/⣹/IO/g' \
+ -e 's/⣺/JO/g' \
+ -e 's/⣻/KO/g' \
+ -e 's/⣼/LO/g' \
+ -e 's/⣽/MO/g' \
+ -e 's/⣾/NO/g' \
+ -e 's/⣿/OO/g' \
+ \
+ -e 's/@*$//' \
+ -e 's/^$/'$'\015''/' -e 's/\([^'$'\015'']\)$/\1'$'\015''/'
+
+# Exit 4-dot graphic mode
+printf '\033\006'
+# Finish document
+printf '\032'
+
+echo "INFO: Ready" >&2
diff --git a/filter/braille/drivers/index/imageubrltoindexv4.in b/filter/braille/drivers/index/imageubrltoindexv4.in
new file mode 100755
index 000000000..b2b24d5c4
--- /dev/null
+++ b/filter/braille/drivers/index/imageubrltoindexv4.in
@@ -0,0 +1,319 @@
+#!/bin/bash
+
+#
+# Copyright (c) 2015-2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+# Make sure we have enough options
+if [ $# != 5 -a $# != 6 ]; then
+ echo "ERROR: $0 jobid user name nb options [filename]" >&2
+ exit 1
+fi
+
+NB=$4
+OPTIONS=$5
+FILE=$6
+
+# Disable margins, they are done by imagemagick before this
+NOMARGIN=1
+
+. @CUPS_SERVERBIN@/filter/indexv4.sh
+printf "$INIT"
+
+# Enter 4-dot graphic mode
+# TODO: use image mode instead, to benefit from much better resolution
+printf "\033\007"
+
+echo "INFO: Writing text to Index embosser" >&2
+( if [ -z "$FILE" ]
+then
+ cat
+else
+ cat "$FILE"
+fi ) | sed \
+ -e 's/⠀/@@/g' \
+ -e 's/⠁/A@/g' \
+ -e 's/⠂/B@/g' \
+ -e 's/⠃/C@/g' \
+ -e 's/⠄/D@/g' \
+ -e 's/⠅/E@/g' \
+ -e 's/⠆/F@/g' \
+ -e 's/⠇/G@/g' \
+ -e 's/⡀/H@/g' \
+ -e 's/⡁/I@/g' \
+ -e 's/⡂/J@/g' \
+ -e 's/⡃/K@/g' \
+ -e 's/⡄/L@/g' \
+ -e 's/⡅/M@/g' \
+ -e 's/⡆/N@/g' \
+ -e 's/⡇/O@/g' \
+ -e 's/⠈/@A/g' \
+ -e 's/⠉/AA/g' \
+ -e 's/⠊/BA/g' \
+ -e 's/⠋/CA/g' \
+ -e 's/⠌/DA/g' \
+ -e 's/⠍/EA/g' \
+ -e 's/⠎/FA/g' \
+ -e 's/⠏/GA/g' \
+ -e 's/⡈/HA/g' \
+ -e 's/⡉/IA/g' \
+ -e 's/⡊/JA/g' \
+ -e 's/⡋/KA/g' \
+ -e 's/⡌/LA/g' \
+ -e 's/⡍/MA/g' \
+ -e 's/⡎/NA/g' \
+ -e 's/⡏/OA/g' \
+ -e 's/⠐/@B/g' \
+ -e 's/⠑/AB/g' \
+ -e 's/⠒/BB/g' \
+ -e 's/⠓/CB/g' \
+ -e 's/⠔/DB/g' \
+ -e 's/⠕/EB/g' \
+ -e 's/⠖/FB/g' \
+ -e 's/⠗/GB/g' \
+ -e 's/⡐/HB/g' \
+ -e 's/⡑/IB/g' \
+ -e 's/⡒/JB/g' \
+ -e 's/⡓/KB/g' \
+ -e 's/⡔/LB/g' \
+ -e 's/⡕/MB/g' \
+ -e 's/⡖/NB/g' \
+ -e 's/⡗/OB/g' \
+ -e 's/⠘/@C/g' \
+ -e 's/⠙/AC/g' \
+ -e 's/⠚/BC/g' \
+ -e 's/⠛/CC/g' \
+ -e 's/⠜/DC/g' \
+ -e 's/⠝/EC/g' \
+ -e 's/⠞/FC/g' \
+ -e 's/⠟/GC/g' \
+ -e 's/⡘/HC/g' \
+ -e 's/⡙/IC/g' \
+ -e 's/⡚/JC/g' \
+ -e 's/⡛/KC/g' \
+ -e 's/⡜/LC/g' \
+ -e 's/⡝/MC/g' \
+ -e 's/⡞/NC/g' \
+ -e 's/⡟/OC/g' \
+ -e 's/⠠/@D/g' \
+ -e 's/⠡/AD/g' \
+ -e 's/⠢/BD/g' \
+ -e 's/⠣/CD/g' \
+ -e 's/⠤/DD/g' \
+ -e 's/⠥/ED/g' \
+ -e 's/⠦/FD/g' \
+ -e 's/⠧/GD/g' \
+ -e 's/⡠/HD/g' \
+ -e 's/⡡/ID/g' \
+ -e 's/⡢/JD/g' \
+ -e 's/⡣/KD/g' \
+ -e 's/⡤/LD/g' \
+ -e 's/⡥/MD/g' \
+ -e 's/⡦/ND/g' \
+ -e 's/⡧/OD/g' \
+ -e 's/⠨/@E/g' \
+ -e 's/⠩/AE/g' \
+ -e 's/⠪/BE/g' \
+ -e 's/⠫/CE/g' \
+ -e 's/⠬/DE/g' \
+ -e 's/⠭/EE/g' \
+ -e 's/⠮/FE/g' \
+ -e 's/⠯/GE/g' \
+ -e 's/⡨/HE/g' \
+ -e 's/⡩/IE/g' \
+ -e 's/⡪/JE/g' \
+ -e 's/⡫/KE/g' \
+ -e 's/⡬/LE/g' \
+ -e 's/⡭/ME/g' \
+ -e 's/⡮/NE/g' \
+ -e 's/⡯/OE/g' \
+ -e 's/⠰/@F/g' \
+ -e 's/⠱/AF/g' \
+ -e 's/⠲/BF/g' \
+ -e 's/⠳/CF/g' \
+ -e 's/⠴/DF/g' \
+ -e 's/⠵/EF/g' \
+ -e 's/⠶/FF/g' \
+ -e 's/⠷/GF/g' \
+ -e 's/⡰/HF/g' \
+ -e 's/⡱/IF/g' \
+ -e 's/⡲/JF/g' \
+ -e 's/⡳/KF/g' \
+ -e 's/⡴/LF/g' \
+ -e 's/⡵/MF/g' \
+ -e 's/⡶/NF/g' \
+ -e 's/⡷/OF/g' \
+ -e 's/⠸/@G/g' \
+ -e 's/⠹/AG/g' \
+ -e 's/⠺/BG/g' \
+ -e 's/⠻/CG/g' \
+ -e 's/⠼/DG/g' \
+ -e 's/⠽/EG/g' \
+ -e 's/⠾/FG/g' \
+ -e 's/⠿/GG/g' \
+ -e 's/⡸/HG/g' \
+ -e 's/⡹/IG/g' \
+ -e 's/⡺/JG/g' \
+ -e 's/⡻/KG/g' \
+ -e 's/⡼/LG/g' \
+ -e 's/⡽/MG/g' \
+ -e 's/⡾/NG/g' \
+ -e 's/⡿/OG/g' \
+ -e 's/⢀/@H/g' \
+ -e 's/⢁/AH/g' \
+ -e 's/⢂/BH/g' \
+ -e 's/⢃/CH/g' \
+ -e 's/⢄/DH/g' \
+ -e 's/⢅/EH/g' \
+ -e 's/⢆/FH/g' \
+ -e 's/⢇/GH/g' \
+ -e 's/⣀/HH/g' \
+ -e 's/⣁/IH/g' \
+ -e 's/⣂/JH/g' \
+ -e 's/⣃/KH/g' \
+ -e 's/⣄/LH/g' \
+ -e 's/⣅/MH/g' \
+ -e 's/⣆/NH/g' \
+ -e 's/⣇/OH/g' \
+ -e 's/⢈/@I/g' \
+ -e 's/⢉/AI/g' \
+ -e 's/⢊/BI/g' \
+ -e 's/⢋/CI/g' \
+ -e 's/⢌/DI/g' \
+ -e 's/⢍/EI/g' \
+ -e 's/⢎/FI/g' \
+ -e 's/⢏/GI/g' \
+ -e 's/⣈/HI/g' \
+ -e 's/⣉/II/g' \
+ -e 's/⣊/JI/g' \
+ -e 's/⣋/KI/g' \
+ -e 's/⣌/LI/g' \
+ -e 's/⣍/MI/g' \
+ -e 's/⣎/NI/g' \
+ -e 's/⣏/OI/g' \
+ -e 's/⢐/@J/g' \
+ -e 's/⢑/AJ/g' \
+ -e 's/⢒/BJ/g' \
+ -e 's/⢓/CJ/g' \
+ -e 's/⢔/DJ/g' \
+ -e 's/⢕/EJ/g' \
+ -e 's/⢖/FJ/g' \
+ -e 's/⢗/GJ/g' \
+ -e 's/⣐/HJ/g' \
+ -e 's/⣑/IJ/g' \
+ -e 's/⣒/JJ/g' \
+ -e 's/⣓/KJ/g' \
+ -e 's/⣔/LJ/g' \
+ -e 's/⣕/MJ/g' \
+ -e 's/⣖/NJ/g' \
+ -e 's/⣗/OJ/g' \
+ -e 's/⢘/@K/g' \
+ -e 's/⢙/AK/g' \
+ -e 's/⢚/BK/g' \
+ -e 's/⢛/CK/g' \
+ -e 's/⢜/DK/g' \
+ -e 's/⢝/EK/g' \
+ -e 's/⢞/FK/g' \
+ -e 's/⢟/GK/g' \
+ -e 's/⣘/HK/g' \
+ -e 's/⣙/IK/g' \
+ -e 's/⣚/JK/g' \
+ -e 's/⣛/KK/g' \
+ -e 's/⣜/LK/g' \
+ -e 's/⣝/MK/g' \
+ -e 's/⣞/NK/g' \
+ -e 's/⣟/OK/g' \
+ -e 's/⢠/@L/g' \
+ -e 's/⢡/AL/g' \
+ -e 's/⢢/BL/g' \
+ -e 's/⢣/CL/g' \
+ -e 's/⢤/DL/g' \
+ -e 's/⢥/EL/g' \
+ -e 's/⢦/FL/g' \
+ -e 's/⢧/GL/g' \
+ -e 's/⣠/HL/g' \
+ -e 's/⣡/IL/g' \
+ -e 's/⣢/JL/g' \
+ -e 's/⣣/KL/g' \
+ -e 's/⣤/LL/g' \
+ -e 's/⣥/ML/g' \
+ -e 's/⣦/NL/g' \
+ -e 's/⣧/OL/g' \
+ -e 's/⢨/@M/g' \
+ -e 's/⢩/AM/g' \
+ -e 's/⢪/BM/g' \
+ -e 's/⢫/CM/g' \
+ -e 's/⢬/DM/g' \
+ -e 's/⢭/EM/g' \
+ -e 's/⢮/FM/g' \
+ -e 's/⢯/GM/g' \
+ -e 's/⣨/HM/g' \
+ -e 's/⣩/IM/g' \
+ -e 's/⣪/JM/g' \
+ -e 's/⣫/KM/g' \
+ -e 's/⣬/LM/g' \
+ -e 's/⣭/MM/g' \
+ -e 's/⣮/NM/g' \
+ -e 's/⣯/OM/g' \
+ -e 's/⢰/@N/g' \
+ -e 's/⢱/AN/g' \
+ -e 's/⢲/BN/g' \
+ -e 's/⢳/CN/g' \
+ -e 's/⢴/DN/g' \
+ -e 's/⢵/EN/g' \
+ -e 's/⢶/FN/g' \
+ -e 's/⢷/GN/g' \
+ -e 's/⣰/HN/g' \
+ -e 's/⣱/IN/g' \
+ -e 's/⣲/JN/g' \
+ -e 's/⣳/KN/g' \
+ -e 's/⣴/LN/g' \
+ -e 's/⣵/MN/g' \
+ -e 's/⣶/NN/g' \
+ -e 's/⣷/ON/g' \
+ -e 's/⢸/@O/g' \
+ -e 's/⢹/AO/g' \
+ -e 's/⢺/BO/g' \
+ -e 's/⢻/CO/g' \
+ -e 's/⢼/DO/g' \
+ -e 's/⢽/EO/g' \
+ -e 's/⢾/FO/g' \
+ -e 's/⢿/GO/g' \
+ -e 's/⣸/HO/g' \
+ -e 's/⣹/IO/g' \
+ -e 's/⣺/JO/g' \
+ -e 's/⣻/KO/g' \
+ -e 's/⣼/LO/g' \
+ -e 's/⣽/MO/g' \
+ -e 's/⣾/NO/g' \
+ -e 's/⣿/OO/g' \
+ \
+ -e 's/@*$//' \
+ -e 's/^$/'$'\015''/' -e 's/\([^'$'\015'']\)$/\1'$'\015''/'
+
+# Exit 4-dot graphic mode
+printf '\033\006'
+# Finish document
+printf '\032'
+
+echo "INFO: Ready" >&2
diff --git a/filter/braille/drivers/index/index.defs b/filter/braille/drivers/index/index.defs
new file mode 100644
index 000000000..7a4e41fa8
--- /dev/null
+++ b/filter/braille/drivers/index/index.defs
@@ -0,0 +1,125 @@
+//
+// Copyright (c) 2015-2016 Samuel Thibault <samuel.thibault@ens-lyon.org>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+Throughput 1
+
+MediaSize Legal
+MediaSize Letter
+MediaSize A3
+MediaSize A4
+*MediaSize A4TF
+MediaSize A5
+MediaSize 110x115
+MediaSize 110x120
+MediaSize 110x170
+MediaSize 115x110
+MediaSize 120x120
+
+ColorDevice no
+
+Group "Index/Index support"
+ Option "IndexFolding/Page folding" PickOne AnySetup 10
+ Choice "Single/Single-sided" ""
+ *Choice "Double/Double-sided" ""
+
+ Option "IndexMultipleImpact/Multiple Impact" PickOne AnySetup 10
+ *Choice "1" ""
+ Choice "2" ""
+ Choice "3" ""
+
+Group "Braille"
+ Option "IndexTable/Firmware Braille Table" PickOne AnySetup 10
+ *Choice "0/6-dot MIT table" ""
+ Choice "1/User-defined Table 1" ""
+ Choice "2/User-defined Table 2" ""
+ Choice "3/User-defined Table 3" ""
+ Choice "4/User-defined Table 4" ""
+
+Option "TopMargin/Top margin" PickOne AnySetup 10
+ Choice "0" ""
+ Choice "1" ""
+ *Choice "2" ""
+ Choice "3" ""
+ Choice "4" ""
+ Choice "5" ""
+ Choice "6" ""
+ Choice "7" ""
+ Choice "8" ""
+ Choice "9" ""
+ Choice "10" ""
+
+Option "BottomMargin/Bottom margin" PickOne AnySetup 10
+ Choice "0" ""
+ Choice "1" ""
+ *Choice "2" ""
+ Choice "3" ""
+ Choice "4" ""
+ Choice "5" ""
+ Choice "6" ""
+ Choice "7" ""
+ Choice "8" ""
+ Choice "9" ""
+ Choice "10" ""
+
+Option "InnerMargin/Inner margin" PickOne AnySetup 10
+ Choice "0" ""
+ Choice "1" ""
+ *Choice "2" ""
+ Choice "3" ""
+ Choice "4" ""
+ Choice "5" ""
+ Choice "6" ""
+ Choice "7" ""
+ Choice "8" ""
+ Choice "9" ""
+ Choice "10" ""
+
+Option "OuterMargin/Outer margin" PickOne AnySetup 10
+ Choice "0" ""
+ Choice "1" ""
+ *Choice "2" ""
+ Choice "3" ""
+ Choice "4" ""
+ Choice "5" ""
+ Choice "6" ""
+ Choice "7" ""
+ Choice "8" ""
+ Choice "9" ""
+ Choice "10" ""
+
+Option "PageNumber/Page Number" PickOne AnySetup 10
+ Choice "None/None" ""
+ Choice "Top/Top-middle" ""
+ Choice "TopLeft/Top-left" ""
+ Choice "TopRight/Top-right" ""
+ Choice "Bottom/Bottom-middle" ""
+ Choice "BottomLeft/Bottom-left" ""
+ Choice "BottomRight/Bottom-right" ""
+
+UIConstraints "*TopMargin 0 *PageNumber Top"
+UIConstraints "*TopMargin 0 *PageNumber TopLeft"
+UIConstraints "*TopMargin 0 *PageNumber TopRight"
+UIConstraints "*BottomMargin 0 *PageNumber Bottom"
+UIConstraints "*BottomMargin 0 *PageNumber BottomLeft"
+UIConstraints "*BottomMargin 0 *PageNumber BottomRight"
diff --git a/filter/braille/drivers/index/index.sh.in b/filter/braille/drivers/index/index.sh.in
new file mode 100644
index 000000000..e300313a2
--- /dev/null
+++ b/filter/braille/drivers/index/index.sh.in
@@ -0,0 +1,124 @@
+#
+# Copyright (c) 2015-2016 Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+. @CUPS_DATADIR@/braille/cups-braille.sh
+
+FIRMWARE=$(getOptionNumber IndexFirmwareVersion)
+FOLDING=$(getOption IndexFolding)
+TABLE=$(getOptionNumber IndexTable)
+MULTIPLEIMPACT=$(getOptionNumber IndexMultipleImpact)
+PAGENUMBER=$(getOption PageNumber)
+
+# Convert from 100th of mm to Inch fraction
+mmToIndexIn () {
+ # 100th of mm
+ MM=$1
+
+ # 120th of inches
+ IN120=$(($MM * 12 / 254))
+
+ # Integer part
+ INT=$(($IN120 / 120 ))
+
+ # Fractional part, first in 120th of inch
+ FRAC=$(($IN120 % 120))
+
+ # Convert to Index-specific values
+ if [ $FRAC -lt 30 ]; then
+ # Round down to zero
+ FRAC=0
+ elif [ $FRAC -ge 30 -a $FRAC -lt 40 ]; then
+ # Round down to a quarter
+ FRAC=1
+ elif [ $FRAC -ge 40 -a $FRAC -lt 60 ]; then
+ # Round down to a third
+ FRAC=2
+ elif [ $FRAC -ge 60 -a $FRAC -lt 80 ]; then
+ # Round down to a half
+ FRAC=3
+ elif [ $FRAC -ge 80 -a $FRAC -lt 90 ]; then
+ # Round down to two thirds
+ FRAC=4
+ else
+ # Round down to three quarters
+ FRAC=5
+ fi
+
+ echo $INT$FRAC
+}
+
+# Return options common to v3 and v4
+commonOptions() {
+ INIT=
+ # Disable options we don't want: first line offset and page numbering
+ INIT+=,FO0
+
+ # Support hardware-assisted multiple copies
+ if [ $NB != 1 ]
+ then
+ INIT+=,MC$NB
+ fi
+
+ INIT+=,MI$MULTIPLEIMPACT
+
+ # Support page folding
+ case "$FOLDING" in
+ Single) INIT+=,DP1 ;;
+ Double) INIT+=,DP2 ;;
+ SingleZ) INIT+=,DP5 ;;
+ DoubleZ) INIT+=,DP3 ;;
+ DoubleS) INIT+=,DP4 ;;
+ SingleSZ) INIT+=,DP7 ;;
+ DoubleSZ) INIT+=,DP6 ;;
+ SingleS) INIT+=,DP8 ;;
+ *) printf "ERROR: unsupported '%s' page folding\n" "$FOLDING" >&2 ; exit 1 ;;
+ esac
+
+ # Configure dots spacing
+ case "$TEXTDOTDISTANCE" in
+ 220) INIT+=,TD1 ;;
+ 250) INIT+=,TD0 ;;
+ 320) INIT+=,TD2 ;;
+ *) printf "ERROR: unsupported '%s' text dot distance\n" "$TEXTDOTDISTANCE" >&2 ; exit 1 ;;
+ esac
+ case "$GRAPHICDOTDISTANCE" in
+ 160) INIT+=,GD2 ;;
+ 200) INIT+=,GD0 ;;
+ 250) INIT+=,GD1 ;;
+ *) printf "ERROR: unsupported '%s' graphic dot distance\n" "$GRAPHICDOTDISTANCE" >&2 ; exit 1 ;;
+ esac
+
+ case "$PAGENUMBER" in
+ None) INIT+=,PN0 ;;
+ Top) INIT+=,PN1 ;;
+ TopLeft) INIT+=,PN2 ;;
+ TopRight) INIT+=,PN3 ;;
+ Bottom) INIT+=,PN4 ;;
+ BottomLeft) INIT+=,PN5 ;;
+ BottomRight) INIT+=,PN6 ;;
+ *) echo "ERROR: unsupported $PAGENUMBER page number" >&2 ; exit 1 ;;
+ esac
+
+ echo "$INIT"
+}
diff --git a/filter/braille/drivers/index/indexv3.sh.in b/filter/braille/drivers/index/indexv3.sh.in
new file mode 100644
index 000000000..c795f104e
--- /dev/null
+++ b/filter/braille/drivers/index/indexv3.sh.in
@@ -0,0 +1,110 @@
+#
+# Copyright (c) 2015-2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+. @CUPS_DATADIR@/braille/index.sh
+
+# Whether lengths should be given to the embosser in In or Mm
+PAPERLENGTH=$(getAttribute IndexPaperLength)
+
+if [ $FIRMWARE -ge 103000 ]
+then
+ # Firmware 10.30 and above support temporary parameters
+ INIT=$'\033'D
+
+ if [ -z "$NOMARGIN" ]
+ then
+ # Configure margins
+ INIT+=TM$TOPMARGIN,BM$BOTTOMMARGIN,IM$INNERMARGIN,OM$OUTERMARGIN
+ else
+ # disable margins
+ INIT+=TM0,BM0,IM0,OM0
+ fi
+
+ # Trying to disable banner page seems to pose problems
+ #INIT+=,BP
+
+ # Common options
+ INIT+=$(commonOptions)
+
+ # Paper size
+ case "$PAPERLENGTH" in
+ In)
+ INIT+=,PW$(mmToIndexIn $PAGEWIDTH),PL$(mmToIndexIn $PAGEHEIGHT)
+ ;;
+ Mm)
+ INIT+=,PW$(($PAGEWIDTH / 100)),PL$(($PAGEHEIGHT / 100))
+ ;;
+ *) ;;
+ esac
+
+ case $LINESPACING in
+ 250) INIT+=,LS0 ;;
+ 375) INIT+=,LS1 ;;
+ 450) INIT+=,LS2 ;;
+ 475) INIT+=,LS3 ;;
+ 500) INIT+=,LS4 ;;
+ 525) INIT+=,LS5 ;;
+ 550) INIT+=,LS6 ;;
+ 750) INIT+=,LS7 ;;
+ 1000) INIT+=,LS8 ;;
+ *)
+ if [ $FIRMWARE -lt 120130 ]
+ then
+ echo "ERROR: unsupported $LINESPACING line spacing, please upgrade firmware to at least 12.01.3" >&2
+ exit 1
+ fi
+ if [ $LINESPACING -lt 100 ]
+ then
+ echo "ERROR: too small $LINESPACING line spacing" >&2
+ exit 1
+ fi
+ INIT+=,LS$(($LINESPACING / 10))
+ ;;
+ esac
+
+ if [ $LIBLOUIS1 != None -o \
+ $LIBLOUIS2 != None -o \
+ $LIBLOUIS3 != None -o \
+ $LIBLOUIS4 != None ]
+ then
+ # software-translated, enforce a 6-dot table if needed
+ case $TEXTDOTS in
+ # Firmware 11.02.1 and above allow to make sure to be using a 6-dot table
+ 6) INIT+=,BT0 ;;
+ # Hoping the user properly configured an 8-dot table
+ 8) ;;
+ *) echo "ERROR: unsupported $TEXTDOTS dots" >&2 ; exit 1 ;;
+ esac
+ else
+ # Hoping the user configured a table with appropriate number of dots
+ INIT+=,BT$TABLE
+ fi
+
+ # roger
+ INIT+=";"
+else
+ # No support for temporary parameters. Hoping that the user configured CUPS
+ # the same way as the embosser.
+ INIT=
+fi
diff --git a/filter/braille/drivers/index/indexv4.sh.in b/filter/braille/drivers/index/indexv4.sh.in
new file mode 100644
index 000000000..0285f76b9
--- /dev/null
+++ b/filter/braille/drivers/index/indexv4.sh.in
@@ -0,0 +1,81 @@
+#
+# Copyright (c) 2015-2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+. @CUPS_DATADIR@/braille/index.sh
+
+if [ $FIRMWARE -ge 103000 ]
+then
+ # Firmware 10.30 and above support temporary parameters
+ INIT=$'\033'D
+
+ if [ -z "$NOMARGIN" ]
+ then
+ # Configure margins
+ INIT+=TM$TOPMARGIN,BI$INNERMARGIN
+ else
+ # disable margins
+ INIT+=TM0,BM0,IM0,OM0
+ fi
+
+
+ # Common options
+ INIT+="$(setCommonOptions)"
+
+ # Paper size
+ INIT+=,CH$TEXTWIDTH,LP$TEXTHEIGHT
+
+ case $LINESPACING in
+ 500) INIT+=,LS50 ;;
+ 1000) INIT+=,LS100 ;;
+ *)
+ echo "ERROR: unsupported $LINESPACING line spacing" >&2
+ exit 1
+ ;;
+ esac
+
+ if [ $LIBLOUIS1 != None -o \
+ $LIBLOUIS2 != None -o \
+ $LIBLOUIS3 != None -o \
+ $LIBLOUIS4 != None ]
+ then
+ # software-translated, enforce a 6-dot table if needed
+ case $TEXTDOTS in
+ # Firmware 11.02.1 and above allow to make sure to be using a 6-dot table
+ 6) INIT+=,BT0 ;;
+ # Firmware 11.02.1 and above allow to make sure to be using a 8-dot table
+ 8) INIT+=,BT6 ;;
+ *) echo "ERROR: unsupported $TEXTDOTS dots" >&2 ; exit 1 ;;
+ esac
+ else
+ # Hoping the user configured a table with appropriate number of dots
+ INIT+=,BT$TABLE
+ fi
+
+ # roger
+ INIT+=";"
+else
+ # No support for temporary parameters. Hoping that the user configured CUPS
+ # the same way as the embosser.
+ INIT=
+fi
diff --git a/filter/braille/drivers/index/textbrftoindexv3.in b/filter/braille/drivers/index/textbrftoindexv3.in
new file mode 100755
index 000000000..5f9be1fd8
--- /dev/null
+++ b/filter/braille/drivers/index/textbrftoindexv3.in
@@ -0,0 +1,96 @@
+#!/bin/bash
+
+#
+# Copyright (c) 2015-2016 Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+# Make sure we have enough options
+if [ $# != 5 -a $# != 6 ]; then
+ echo "ERROR: $0 jobid user name nb options [filename]" >&2
+ exit 1
+fi
+
+NB=$4
+OPTIONS=$5
+FILE=$6
+
+case $0 in
+ *indexv3*) . @CUPS_DATADIR@/braille/indexv3.sh ;;
+ *indexv4*) . @CUPS_DATADIR@/braille/indexv4.sh ;;
+ *) echo "ERROR: $0 must be called as somethingindexv3 or somethingindexv4" >&2
+ exit 1
+ ;;
+esac
+
+printf "$INIT"
+
+if [ $LIBLOUIS1 != None -o \
+ $LIBLOUIS2 != None -o \
+ $LIBLOUIS3 != None -o \
+ $LIBLOUIS4 != None ]
+then
+ # software-translated, send to printer in transparent mode
+ echo "INFO: Writing text to Index embosser in transparent mode" >&2
+ if [ -z "$FILE" ]
+ then
+ cat
+ else
+ cat "$FILE"
+ fi | (
+ while read LINE
+ do
+ # Strip CRs
+ LINE=${LINE//$'\015'}
+ CHARS=$(printf %s "$LINE" | wc -c)
+ if [ "$CHARS" -gt 127 ]
+ then
+ # Index printers have a bug with numbers between 128 and 255 in
+ # transparent mode escape sequence. This is normally not a problem since
+ # 128 chars is more than a line worth of text
+ echo "ERROR: Line too long ($CHARS)" >&2
+ exit 1
+ fi
+ if [ "$CHARS" -gt 0 ]
+ then
+ # Enter transparent mode for $CHARS characters
+ printf "\\033\\\\\\x$(printf %02x $CHARS)\\x00"
+ # Echo those $CHARS characters
+ printf %s "$LINE" | tr " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_{}|~\`abcdefghijklmnopqrstuvwxyz" "\\0V tSQW"$'\004'"gvAT@DP"$'\024'"d"$'\002\006'"\"bB&fF\$a\`Cw4q"$'\020\001\003\021'"1!"$'\023'"3#"$'\022'"2"$'\005\007\025'"5%"$'\027'"7'"$'\026'"6EGrUueRcs0pRsc0"$'\020\001\003\021'"1!"$'\023'"3#"$'\022'"2"$'\005\007\025'"5%"$'\027'"7'"$'\026'"6EGrUue"
+ fi
+ printf "\\r\\n"
+ done
+ )
+else
+ # not software-translated, send to printer as such
+ echo "INFO: Writing text to Index embosser" >&2
+ if [ -z "$FILE" ]
+ then
+ cat
+ else
+ cat "$FILE"
+ fi
+fi
+
+printf '\032'
+
+echo "INFO: Ready" >&2
diff --git a/filter/braille/drivers/index/ubrlto4dot.c b/filter/braille/drivers/index/ubrlto4dot.c
new file mode 100644
index 000000000..3d3e7dae9
--- /dev/null
+++ b/filter/braille/drivers/index/ubrlto4dot.c
@@ -0,0 +1,40 @@
+/*
+ Copyright (c) 2015 Samuel Thibault <samuel.thibault@ens-lyon.org>
+ j
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+#include <locale.h>
+#include <pthread.h>
+#include <stdio.h>
+
+int main(int argc, char *argv[]) {
+ int i, j, lo, hi;
+ setlocale(LC_ALL,"");
+ for (i = 0; i < 256; i++)
+ {
+ j = (i&0x7) | ((i&0x8) << 3) | ((i&0x70) >> 1) | (i&0x80);
+ lo = i & 0xf;
+ hi = (i & 0xf0) >> 4;
+ printf(" -e 's/%lc/%c%c/g' \\\n", 0x2800+j, '@'+lo, '@'+hi);
+ }
+ return 0;
+}
diff --git a/filter/braille/filters/TODO.txt b/filter/braille/filters/TODO.txt
new file mode 100644
index 000000000..43bf90a4d
--- /dev/null
+++ b/filter/braille/filters/TODO.txt
@@ -0,0 +1,3 @@
+Add title option for pictures
+
+In addition to drawing contour, use textures to render colors of areas
diff --git a/filter/braille/filters/braille.defs b/filter/braille/filters/braille.defs
new file mode 100644
index 000000000..43d93de30
--- /dev/null
+++ b/filter/braille/filters/braille.defs
@@ -0,0 +1,44 @@
+//
+// Copyright (c) 2015, 2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+Group "Braille/Braille transcription"
+Option "TextDotDistance/Text dot distance" PickOne AnySetup 10
+ Choice "220/2.2mm" ""
+ *Choice "250/2.5mm" ""
+ Choice "320/3.2mm" ""
+
+Option "TextDots/Text dots" PickOne AnySetup 10
+ Choice "8/8 dots" ""
+ *Choice "6/6 dots" ""
+
+Option "LineSpacing/Line spacing" PickOne AnySetup 10
+ Choice "250/2.5mm" ""
+ Choice "375/3.75mm" ""
+ Choice "450/4.5mm" ""
+ Choice "475/4.75mm" ""
+ *Choice "500/5.0mm" ""
+ Choice "525/5.25mm" ""
+ Choice "550/5.5mm" ""
+ Choice "750/7.5mm" ""
+ Choice "1000/10.0mm" ""
diff --git a/filter/braille/filters/cups-braille.sh.in b/filter/braille/filters/cups-braille.sh.in
new file mode 100644
index 000000000..c58125090
--- /dev/null
+++ b/filter/braille/filters/cups-braille.sh.in
@@ -0,0 +1,384 @@
+#
+# Copyright (c) 2015-2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+# Get an attribute from the ppd file
+getAttribute () {
+ ATTRIBUTE=$1
+ VALUE=`grep "^\*$ATTRIBUTE:" "$PPD" | cut -d" " -f2-`
+ VALUE=${VALUE##\"}
+ VALUE=${VALUE%%\"}
+ printf "DEBUG: Attribute $ATTRIBUTE is '%s'\n" "$VALUE" >&2
+ printf "%s" "$VALUE"
+}
+
+# Get an option for the document: either default ppd attribute or user-provided value
+getOption () {
+ OPTION=$1
+ VALUE=$(getAttribute Default$OPTION)
+ printf "DEBUG: Default $OPTION is '%s'\n" "$VALUE" >&2
+
+ if [ -n "$OPTIONS" ]
+ then
+ # Case of the very first option
+ if [ -z "${OPTIONS/$OPTION=*}" ]
+ then
+ VALUE=${OPTIONS#$OPTION=}
+ VALUE=${VALUE%% *}
+ printf "DEBUG: Selected $OPTION is '%s'\n" "$VALUE" >&2
+ fi
+ # Case of other options
+ if [ -z "${OPTIONS/* $OPTION=*}" ]
+ then
+ VALUE=${OPTIONS##* $OPTION=}
+ VALUE=${VALUE%% *}
+ printf "DEBUG: Selected $OPTION is '%s'\n" "$VALUE" >&2
+ fi
+
+ # Boolean options
+ if [ -z "${OPTIONS/* $OPTION *}" ]
+ then
+ VALUE=True
+ printf "DEBUG: Selected $OPTION is '%s'\n" "$VALUE" >&2
+ fi
+ if [ -z "${OPTIONS/* no$OPTION *}" ]
+ then
+ VALUE=False
+ printf "DEBUG: Selected $OPTION is '%s'\n" "$VALUE" >&2
+ fi
+ fi
+
+ printf "%s" "$VALUE"
+}
+
+# Get an option for the document and check that it is a number
+getOptionNumber () {
+ OPTION=$1
+ VALUE=$(getOption $OPTION)
+ VALUE=${VALUE#Custom.}
+ case "$VALUE" in
+ [0-9]*) ;;
+ *) printf "ERROR: Option $OPTION must be a number, got '%s'\n" "$VALUE" >&2
+ exit 1
+ ;;
+ esac
+ printf "%s" "$VALUE"
+}
+
+[ -z "$NB" ] && NB=1
+
+#
+# Page size
+# Units in 100th of mm
+#
+
+# TODO: better handle imageable area
+PAGESIZE=$(getOption PageSize)
+case "$PAGESIZE" in
+ Legal)
+ PAGEWIDTH=21590
+ PAGEHEIGHT=35560
+ ;;
+ Letter)
+ PAGEWIDTH=21590
+ PAGEHEIGHT=27940
+ ;;
+ A3)
+ PAGEWIDTH=29700
+ PAGEHEIGHT=42000
+ ;;
+ A4)
+ PAGEWIDTH=21000
+ PAGEHEIGHT=29700
+ ;;
+ A4TF)
+ PAGEWIDTH=21000
+ PAGEHEIGHT=30480
+ ;;
+ A5)
+ PAGEWIDTH=14850
+ PAGEHEIGHT=21000
+ ;;
+ 110x115)
+ PAGEWIDTH=27940
+ PAGEHEIGHT=29210
+ ;;
+ 110x120)
+ PAGEWIDTH=27940
+ PAGEHEIGHT=30480
+ ;;
+ 110x170)
+ PAGEWIDTH=27940
+ PAGEHEIGHT=43180
+ ;;
+ 115x110)
+ PAGEWIDTH=29210
+ PAGEHEIGHT=27940
+ ;;
+ 120x120)
+ PAGEWIDTH=30480
+ PAGEHEIGHT=30480
+ ;;
+ *)
+ printf "ERROR: Unknown page size '%s'\n" "$PAGESIZE" >&2
+ exit 1
+ ;;
+esac
+
+# Margins as announced by embosser
+HWMARGINS=$(getAttribute HWMargins)
+echo "DEBUG: HW margins are $HWMARGINS" >&2
+HWMARGIN_LEFT="${HWMARGINS%% *}"
+HWMARGINS="${HWMARGINS#* }"
+HWMARGIN_BOTTOM="${HWMARGINS%% *}"
+HWMARGINS="${HWMARGINS#* }"
+HWMARGIN_RIGHT="${HWMARGINS%% *}"
+HWMARGINS="${HWMARGINS#* }"
+HWMARGIN_TOP="${HWMARGINS%% *}"
+
+# Convert from points (1/72 of inch) to 1/100th of mm
+points2mm() {
+ # First get an integer so bash can compute
+ # I.e. convert to 10^15th of point
+ # Note: bash's integer computation will work until about 1000mm, that's plenty :)
+ POINTS="$1"
+ INT_POINTS="${POINTS%.*}"
+ if [ "$INT_POINTS" = "$POINTS" ]
+ then
+ FRAC_POINTS=000000000000000
+ else
+ FRAC_POINTS="${POINTS#*.}000000000000000"
+ fi
+ FRAC_POINTS="${FRAC_POINTS:0:15}"
+ FRAC_POINTS="$INT_POINTS$FRAC_POINTS"
+ # Then we can compute conversion
+ # We round up to be safe
+ FRAC_INCH=$((("$FRAC_POINTS" + 71) / 72))
+ FRAC_CM=$((("$FRAC_INCH" * 254 + 99) / 100))
+ HUNDRENDTH_MM=$((("$FRAC_CM" + 999999999999) / 1000000000000))
+ echo $HUNDRENDTH_MM
+}
+
+MARGIN_LEFT=$(points2mm "$HWMARGIN_LEFT")
+MARGIN_RIGHT=$(points2mm "$HWMARGIN_RIGHT")
+MARGIN_TOP=$(points2mm "$HWMARGIN_TOP")
+MARGIN_BOTTOM=$(points2mm "$HWMARGIN_BOTTOM")
+
+# Margins requested by user
+PAGE_LEFT=$(points2mm $(getOptionNumber page-left))
+PAGE_RIGHT=$(points2mm $(getOptionNumber page-right))
+PAGE_TOP=$(points2mm $(getOptionNumber page-top))
+PAGE_BOTTOM=$(points2mm $(getOptionNumber page-bottom))
+
+[ -n "$PAGE_LEFT" -a "$MARGIN_LEFT" -le "$PAGE_LEFT" ] || PAGE_LEFT=$MARGIN_LEFT
+[ -n "$PAGE_RIGHT" -a "$MARGIN_RIGHT" -le "$PAGE_RIGHT" ] || PAGE_RIGHT=$MARGIN_RIGHT
+[ -n "$PAGE_TOP" -a "$MARGIN_TOP" -le "$PAGE_TOP" ] || PAGE_TOP=$MARGIN_TOP
+[ -n "$PAGE_BOTTOM" -a "$MARGIN_BOTTOM" -le "$PAGE_BOTTOM" ] || PAGE_BOTTOM=$MARGIN_BOTTOM
+
+echo "DEBUG: hard margins are left $MARGIN_LEFT right $MARGIN_RIGHT top $MARGIN_TOP bottom $MARGIN_BOTTOM" >&2
+echo "DEBUG: graphical margins are left $PAGE_LEFT right $PAGE_RIGHT top $PAGE_TOP bottom $PAGE_BOTTOM" >&2
+
+# This is the hardware-printable area
+PRINTABLEWIDTH=$(($PAGEWIDTH - $MARGIN_LEFT - $MARGIN_RIGHT))
+PRINTABLEHEIGHT=$(($PAGEHEIGHT - $MARGIN_TOP - $MARGIN_BOTTOM))
+
+echo "DEBUG: printable area is ${PRINTABLEWIDTH}x${PRINTABLEHEIGHT}" >&2
+
+#
+# Text spacing
+#
+
+TEXTDOTDISTANCE=$(getOptionNumber TextDotDistance)
+case "$TEXTDOTDISTANCE" in
+ 220) TEXTCELLDISTANCE=310 ;;
+ 250) TEXTCELLDISTANCE=350 ;;
+ 320) TEXTCELLDISTANCE=525 ;;
+ *)
+ printf "ERROR: Unknown text dot distance '%s'\n" "$TEXTDOTDISTANCE" >&2
+ exit 1
+ ;;
+esac
+
+TEXTDOTS=$(getOptionNumber TextDots)
+LINESPACING=$(getOptionNumber LineSpacing)
+
+# Cell dimension, including spacing
+TEXTCELLWIDTH=$(( $TEXTDOTDISTANCE + $TEXTCELLDISTANCE ))
+TEXTCELLHEIGHT=$(( $TEXTDOTDISTANCE * ($TEXTDOTS / 2 - 1) + $LINESPACING ))
+
+if [ "$(getOption TopMargin)" = "" ]
+then
+ # No margin
+ TEXTAREAWIDTH=$PRINTABLEWIDTH
+ TEXTAREAHEIGHT=$PRINTABLEHEIGHT
+else
+ # Margins in cells
+ TOPMARGIN=$(getOptionNumber TopMargin)
+ BOTTOMMARGIN=$(getOptionNumber BottomMargin)
+ if [ "$(getOption InnerMargin)" = "" ]
+ then
+ LEFTMARGIN=$(getOptionNumber LeftMargin)
+ RIGHTMARGIN=$(getOptionNumber RightMargin)
+ WIDTHMARGIN=$(( $LEFTMARGIN + $RIGHTMARGIN ))
+ else
+ INNERMARGIN=$(getOptionNumber InnerMargin)
+ OUTERMARGIN=$(getOptionNumber OuterMargin)
+ WIDTHMARGIN=$(( $INNERMARGIN + $OUTERMARGIN ))
+ fi
+
+ # Subtract margins from printable area
+ TEXTAREAWIDTH=$(( $PRINTABLEWIDTH - $WIDTHMARGIN * $TEXTCELLWIDTH ))
+ TEXTAREAHEIGHT=$(( $PRINTABLEHEIGHT - ($TOPMARGIN + $BOTTOMMARGIN) * $TEXTCELLHEIGHT ))
+fi
+
+# Compute number of printable cells according to page width and height
+TEXTWIDTH=$(( ($TEXTAREAWIDTH + $TEXTCELLDISTANCE) / $TEXTCELLWIDTH ))
+TEXTHEIGHT=$(( ($TEXTAREAHEIGHT + $LINESPACING) / $TEXTCELLHEIGHT ))
+
+#
+# Graphic spacing
+#
+
+# Compute number of printable cells according to page size
+GRAPHICDOTDISTANCE=$(getOptionNumber GraphicDotDistance)
+
+# This is the total area we will send to the embosser
+TOTALGRAPHICWIDTH=$(( ( ($PRINTABLEWIDTH - 160) / $GRAPHICDOTDISTANCE ) / 2 * 2 ))
+TOTALGRAPHICHEIGHT=$(( ( ($PRINTABLEHEIGHT - 160) / $GRAPHICDOTDISTANCE ) / 4 * 4 ))
+
+echo "DEBUG: total graphical: ${TOTALGRAPHICWIDTH}x${TOTALGRAPHICHEIGHT}" >&2
+
+# This is how many dots we have to introduce to respect at least the software left+top margin
+GRAPHICHOFFSET=$(( ($PAGE_LEFT - $MARGIN_LEFT + $GRAPHICDOTDISTANCE - 1) / $GRAPHICDOTDISTANCE ))
+GRAPHICVOFFSET=$(( ($PAGE_TOP - $MARGIN_TOP + $GRAPHICDOTDISTANCE - 1) / $GRAPHICDOTDISTANCE ))
+
+echo "DEBUG: graphical offset: ${GRAPHICHOFFSET}x${GRAPHICVOFFSET}" >&2
+
+# This is the resulting actual margin
+GRAPHICLEFTMARGIN=$(( $MARGIN_LEFT + $GRAPHICHOFFSET * $GRAPHICDOTDISTANCE ))
+GRAPHICTOPMARGIN=$(( $MARGIN_TOP + $GRAPHICVOFFSET * $GRAPHICDOTDISTANCE ))
+
+echo "DEBUG: rounded graphical top-left corner margin: ${GRAPHICLEFTMARGIN}x${GRAPHICTOPMARGIN}" >&2
+
+# Then compute how many dots we can afford until reaching the software right+bottom margin
+GRAPHICWIDTH=$(( ( ( $PAGEWIDTH - $GRAPHICLEFTMARGIN - $PAGE_RIGHT ) - 160) / $GRAPHICDOTDISTANCE ))
+GRAPHICHEIGHT=$(( ( ( $PAGEHEIGHT - $GRAPHICTOPMARGIN - $PAGE_BOTTOM ) - 160) / $GRAPHICDOTDISTANCE ))
+
+echo "DEBUG: resulting graphical area: ${GRAPHICWIDTH}x${GRAPHICHEIGHT}" >&2
+
+#
+# Text translation
+#
+
+TABLESDIR=@TABLESDIR@
+echo "DEBUG: Liblouis table directory is $TABLESDIR" >&2
+
+getOptionLibLouis () {
+ OPTION=$1
+ VALUE=$(getOption $OPTION)
+
+ # Check validity of input
+ case "$VALUE" in
+ [-_.0-9A-Za-z]*) ;;
+ *) printf "ERROR: Option $OPTION must be a valid liblouis table name, got '%s'\n" "$VALUE" >&2
+ exit 1
+ ;;
+ esac
+
+ LOCALE=${LANG%@*}
+ LOCALE=${LOCALE%.*}
+ LANGUAGE=${LOCALE%_*}
+
+ # Check presence of table
+ case "$VALUE" in
+ None)
+ printf None
+ ;;
+ Locale)
+ if [ -f "$TABLESDIR/$LOCALE.tbl" ]
+ then
+ printf "%s" "$LOCALE.tbl"
+ elif [ -f "$TABLESDIR/$LANGUAGE.tbl" ]
+ then
+ printf "%s" "$LANGUAGE.tbl"
+ else
+ printf "WARN: Could not find $OPTION table '%s.tbl' or '%s.tbl'\n" "$LOCALE" "$LANGUAGE" >&2
+ printf None
+ fi
+ ;;
+ Locale-g[0-3])
+ GRADE=${VALUE#Locale-g}
+ for i in "$TABLESDIR/$LOCALE.tbl" "$TABLESDIR/$LOCALE"*.tbl "$TABLESDIR/$LANGUAGE.tbl" "$TABLESDIR/$LANGUAGE"*.tbl
+ do
+ if grep -q "^#+grade:$GRADE$" "$i"
+ then
+ printf "%s" "${i//*\/}"
+ exit 0
+ fi
+ done
+ printf "ERROR: Could not find $OPTION table '%s*.tbl' or '%s*.tbl' with grade $GRADE\n" "$LOCALE" "$LANGUAGE" >&2
+ printf None
+ exit 1
+ ;;
+ *)
+ [ -f "$TABLESDIR/$VALUE".utb ] && VALUE="$VALUE".utb
+ [ -f "$TABLESDIR/$VALUE".ctb ] && VALUE="$VALUE".ctb
+ if [ ! -f "$TABLESDIR/$VALUE" ]
+ then
+ printf "ERROR: Could not find $OPTION table '%s'\n" "$VALUE" >&2
+ exit 1
+ fi
+
+ printf "%s" "$VALUE"
+ ;;
+ esac
+}
+
+LIBLOUIS1=$(getOptionLibLouis LibLouis)
+LIBLOUIS2=$(getOptionLibLouis LibLouis2)
+LIBLOUIS3=$(getOptionLibLouis LibLouis3)
+LIBLOUIS4=$(getOptionLibLouis LibLouis4)
+
+echo "DEBUG: Table1 $LIBLOUIS1" >&2
+echo "DEBUG: Table2 $LIBLOUIS2" >&2
+echo "DEBUG: Table3 $LIBLOUIS3" >&2
+echo "DEBUG: Table4 $LIBLOUIS4" >&2
+
+[ "$LIBLOUIS1" != None ] && LIBLOUIS_TABLES="$LIBLOUIS1"
+[ "$LIBLOUIS2" != None ] && LIBLOUIS_TABLES="${LIBLOUIS_TABLES:+$LIBLOUIS_TABLES,}$LIBLOUIS2"
+[ "$LIBLOUIS3" != None ] && LIBLOUIS_TABLES="${LIBLOUIS_TABLES:+$LIBLOUIS_TABLES,}$LIBLOUIS3"
+[ "$LIBLOUIS4" != None ] && LIBLOUIS_TABLES="${LIBLOUIS_TABLES:+$LIBLOUIS_TABLES,}$LIBLOUIS4"
+
+#
+# Checking for presence of tools
+#
+checkTool() {
+ TOOL=$1
+ PACKAGE=$2
+ USE=$3
+ if ! type $TOOL > /dev/null
+ then
+ printf "ERROR: The $PACKAGE package is required for $USE\n" >&2
+ exit 1
+ fi
+}
diff --git a/filter/braille/filters/imagemagick.defs b/filter/braille/filters/imagemagick.defs
new file mode 100644
index 000000000..d209dcc95
--- /dev/null
+++ b/filter/braille/filters/imagemagick.defs
@@ -0,0 +1,126 @@
+//
+// Copyright (c) 2015, 2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+Group "Image/Image conversion"
+
+Option "GraphicDotDistance/Graphic dot distance" PickOne AnySetup 10
+ Choice "160/1.6mm" ""
+ *Choice "200/2.0mm" ""
+ Choice "250/2.5mm" ""
+
+Option "Rotate/Rotation" PickOne AnySetup 10
+ Choice "0/No rotation" ""
+ *Choice "90>/Rotate clockwise to fit paper" ""
+ Choice "270>/Rotate counter clockwise to fit paper" ""
+ Choice "90/Clockwise" ""
+ Choice "270/Counter clockwise" ""
+ Choice "180/Upside Down" ""
+
+Option "fitplot/Resize" Boolean AnySetup 10
+ *Choice "True/Yes" ""
+ Choice "False/No" ""
+
+Option "mirror/Mirror" Boolean AnySetup 10
+ Choice "True/Yes" ""
+ *Choice "False/No" ""
+
+Option "Edge/Edge detection" PickOne AnySetup 10
+ Choice "None/None" ""
+ Choice "Edge/Simple" ""
+ *Choice "Canny/Canny" ""
+
+Option "Negate/Negate" Boolean AnySetup 10
+ Choice "True/Yes" ""
+ *Choice "False/No" ""
+
+Option "EdgeFactor/EdgeFactor" PickOne AnySetup 10
+ *Choice "1/1" ""
+ Choice "2/2" ""
+ Choice "5/5" ""
+ Choice "10/10" ""
+
+Option "CannyRadius/CannyRadius" PickOne AnySetup 10
+ *Choice "0/0" ""
+ Choice "1/1" ""
+ Choice "2/2" ""
+
+Option "CannySigma/CannySigma" PickOne AnySetup 10
+ Choice "0/0" ""
+ *Choice "1/1" ""
+ Choice "2/2" ""
+
+Option "CannyLower/CannyLower" PickOne AnySetup 10
+ Choice "0/0" ""
+ Choice "5/5" ""
+ *Choice "10/10" ""
+ Choice "15/15" ""
+ Choice "20/20" ""
+
+Option "CannyUpper/CannyUpper" PickOne AnySetup 10
+ Choice "10/10" ""
+ Choice "20/20" ""
+ *Choice "30/30" ""
+ Choice "40/40" ""
+ Choice "50/50" ""
+
+Option "page-top/Graphical top margin" PickOne AnySetup 10.0
+ Choice "0/0" ""
+ Choice "5/5" ""
+ Choice "10/10" ""
+ *Choice "15/15" ""
+ Choice "20/20" ""
+ Choice "25/25" ""
+ Attribute Custompage-top True ""
+ Attribute ParamCustompage-top Points "1 int 1 999"
+
+Option "page-bottom/Graphical bottom margin" PickOne AnySetup 10.0
+ Choice "0/0" ""
+ Choice "5/5" ""
+ Choice "10/10" ""
+ *Choice "15/15" ""
+ Choice "20/20" ""
+ Choice "25/25" ""
+ Attribute Custompage-bottom True ""
+ Attribute ParamCustompage-bottom Points "1 int 1 999"
+
+Option "page-left/Graphical left margin" PickOne AnySetup 10.0
+ Choice "0/0" ""
+ Choice "5/5" ""
+ Choice "10/10" ""
+ *Choice "15/15" ""
+ Choice "20/20" ""
+ Choice "25/25" ""
+ Attribute Custompage-left True ""
+ Attribute ParamCustompage-left Points "1 int 1 999"
+
+Option "page-right/Graphical right margin" PickOne AnySetup 10.0
+ Choice "0/0" ""
+ Choice "5/5" ""
+ Choice "10/10" ""
+ *Choice "15/15" ""
+ Choice "20/20" ""
+ Choice "25/25" ""
+ Attribute Custompage-right True ""
+ Attribute ParamCustompage-right Points "1 int 1 999"
+
diff --git a/filter/braille/filters/imagetobrf.in b/filter/braille/filters/imagetobrf.in
new file mode 100755
index 000000000..5339c8536
--- /dev/null
+++ b/filter/braille/filters/imagetobrf.in
@@ -0,0 +1,125 @@
+#!/bin/bash
+
+#
+# Copyright (c) 2015-2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+# Make sure we have enough options
+if [ $# != 5 -a $# != 6 ]; then
+ echo "ERROR: $0 jobid user name nb options [filename]" >&2
+ exit 1
+fi
+
+NB=$4
+OPTIONS=$5
+FILE=$6
+
+OUTPUT_FORMAT=brf
+
+case $0 in
+ *imagetoubrl*) OUTPUT_FORMAT=ubrl ;;
+esac
+
+. @CUPS_DATADIR@/braille/cups-braille.sh
+
+checkTool convert imagemagick "embossing images"
+
+NEGATE=$(getOption Negate)
+case "$NEGATE" in
+ True|true) NEGATE=-negate ;;
+ False|false) NEGATE= ;;
+ *)
+ printf "ERROR: Option Negate must either True or False, got '%s'\n" "$NEGATE" >&2
+ exit 1
+ ;;
+esac
+
+ROTATE=$(getOption Rotate)
+case "$ROTATE" in
+ 90\>|270\>)
+ if [ "$GRAPHICWIDTH" -gt "$GRAPHICHEIGHT" ]
+ then
+ # Landscape paper, rotate to landscape instead of to portrait
+ ROTATE=${ROTATE/\>/\<}
+ fi
+ ;;
+ 0|90|270|180) ;;
+ *)
+ printf "ERROR: Option Rotate must be a valid rotation value, got '%s'\n" "$ROTATE" >&2
+ exit 1
+ ;;
+esac
+
+MIRROR=$(getOption mirror)
+case "$MIRROR" in
+ True|true) MIRROR="-flop" ;;
+ False|false) MIRROR="" ;;
+ *)
+ printf "ERROR: Option mirror must either True or False, got '%s'\n" "$MIRROR" >&2
+ exit 1
+ ;;
+esac
+
+PAGE="-page ${TOTALGRAPHICWIDTH}x${TOTALGRAPHICHEIGHT}+${GRAPHICHOFFSET}+${GRAPHICVOFFSET}"
+
+RESIZE=$(getOption fitplot)
+case "$RESIZE" in
+ True|true) RESIZE="-size ${GRAPHICWIDTH}x${GRAPHICHEIGHT} -resize ${GRAPHICWIDTH}x${GRAPHICHEIGHT}" ;;
+ False|false) RESIZE="-crop ${GRAPHICWIDTH}x${GRAPHICHEIGHT}+${GRAPHICHOFFSET}+${GRAPHICVOFFSET}" ;;
+ *)
+ printf "ERROR: Option fitplot must either True or False, got '%s'\n" "$RESIZE" >&2
+ exit 1
+ ;;
+esac
+
+EDGE=$(getOption Edge)
+EDGEFACTOR=$(getOptionNumber EdgeFactor)
+
+CANNY_RADIUS=$(getOptionNumber CannyRadius)
+CANNY_SIGMA=$(getOptionNumber CannySigma)
+CANNY_LOWER=$(getOptionNumber CannyLower)
+CANNY_UPPER=$(getOptionNumber CannyUpper)
+
+case $EDGE in
+ None) WORK=$NEGATE;;
+ Edge) WORK="$NEGATE -edge $EDGEFACTOR -negate" ;;
+ Canny) WORK="-canny ${CANNY_RADIUS}x${CANNY_SIGMA}+$CANNY_LOWER%+$CANNY_UPPER% -negate" ;;
+ *)
+ printf "ERROR: Unknown Edge option value '%s'\n" "$EDGE" >&2
+ exit 1
+ ;;
+esac
+
+RENDER_CALL="convert $WORK -rotate $ROTATE $PAGE $RESIZE $MIRROR -flatten - $OUTPUT_FORMAT:-"
+
+# Now proceeed
+echo "INFO: Converting image" 1>&2
+if [ -z "$FILE" ]
+then
+ printf "DEBUG: Calling %s from stdin\n" "$RENDER_CALL" 1>&2
+ $RENDER_CALL | sed -e '/^\(Width\|X\|Y\): [0-9]*$/,/^$/d'
+else
+ printf "DEBUG: Calling %s on '%s'\n" "$RENDER_CALL" "$FILE" 1>&2
+ $RENDER_CALL < "$FILE" | sed -e '/^\(Width\|X\|Y\): [0-9]*$/,/^$/d'
+fi
+echo "INFO: Ready" >&2
diff --git a/filter/braille/filters/liblouis.defs b/filter/braille/filters/liblouis.defs
new file mode 100644
index 000000000..265149662
--- /dev/null
+++ b/filter/braille/filters/liblouis.defs
@@ -0,0 +1,28 @@
+//
+// Copyright (c) 2015 Samuel Thibault <samuel.thibault@ens-lyon.org>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include <liblouis1.defs>
+#include <liblouis2.defs>
+#include <liblouis3.defs>
+#include <liblouis4.defs>
diff --git a/filter/braille/filters/liblouis1.defs.gen.in b/filter/braille/filters/liblouis1.defs.gen.in
new file mode 100644
index 000000000..bb85e8627
--- /dev/null
+++ b/filter/braille/filters/liblouis1.defs.gen.in
@@ -0,0 +1,265 @@
+#!/bin/bash
+
+#
+# Copyright (c) 2015, 2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+TABLESDIR=@TABLESDIR@
+
+echo 'Group "Braille/Braille transcription"'
+echo 'Option "LibLouis/Braille transcription" PickOne AnySetup 10'
+echo ' Choice "None/None" ""'
+echo ' *Choice "Locale/Default for language" ""'
+echo ' Choice "Locale-g0/Default for language grade 0" ""'
+echo ' Choice "Locale-g1/Default for language grade 1" ""'
+echo ' Choice "Locale-g2/Default for language grade 2" ""'
+echo ' Choice "Locale-g3/Default for language grade 3" ""'
+
+(
+ for i in $TABLESDIR/*.utb $TABLESDIR/*.ctb
+ do
+ file=${i##*/}
+ name=${file%.ctb}
+ name=${name%.utb}
+ DESC=$name
+ LANGUAGE=""
+ LOCATION=""
+ GRADE=""
+ case $name in
+ "afr-za-g1") LANGUAGE=Afrikaans DESC="grade 1" ;;
+ "ar-ar-g1") LANGUAGE=Arabic DESC="grade 1" ;;
+ "ar-fa") LANGUAGE=Persian DESC="grade 1" ;;
+ "as-in-g1") LANGUAGE=Assamese DESC="grade 1" ;;
+ "aw-in-g1") LANGUAGE=Awadhi DESC="grade 1" ;;
+ "be-in-g1") LANGUAGE=Bengali DESC="grade 1" ;;
+ "bg") LANGUAGE=Bulgarian DESC="grade 1" ;;
+ "bh") LANGUAGE=Bihari DESC="grade 1" ;;
+ "bo") LANGUAGE=Tibetan DESC="grade 1" ;;
+ "boxes") DESC="Box drawing" ;;
+ "br-in-g1") LANGUAGE=Braj DESC="Box drawing" ;;
+ "ca-g1") LANGUAGE=Catalan DESC="grade 1" ;;
+ "chr-us-g1") LANGUAGE=Cherokee DESC="grade 1" ;;
+ "ckb-g1") LANGUAGE="Sorani (Kurdish)" DESC="grade 1" ;;
+ "cs-g1") LANGUAGE=Czech DESC="grade 1" ;;
+ "cy-cy-g1") LANGUAGE=Welsh DESC="grade 1" ;;
+ "cy-cy-g2") LANGUAGE=Welsh DESC="grade 2" ;;
+ "Cz-Cz-g1") LANGUAGE=Czech DESC="grade 1" ;;
+ "da-dk-g08") LANGUAGE=Danish DESC="grade 0" ;;
+ "da-dk-g16") LANGUAGE=Danish DESC="grade 1 6 dots" ;;
+ "da-dk-g18") LANGUAGE=Danish DESC="grade 1 8 dots" ;;
+ "da-dk-g26") LANGUAGE=Danish DESC="grade 2 6 dots" ;;
+ "da-dk-g26l") LANGUAGE=Danish DESC="grade 2 6 dots limited" ;;
+ "da-dk-g28") LANGUAGE=Danish DESC="grade 2 8 dots" ;;
+ "da-dk-g28l") LANGUAGE=Danish DESC="grade 2 8 dots limited" ;;
+ "da-lt") LANGUAGE=Danish DESC="LogText" ;;
+ "de-chess") LANGUAGE=German DESC="Chess" ;;
+ "de-ch-g0") LANGUAGE=German LOCATION=Swiss DESC="grade 0" ;;
+ "de-ch-g1") LANGUAGE=German LOCATION=Swiss DESC="grade 1" ;;
+ "de-ch-g2") LANGUAGE=German LOCATION=Swiss DESC="grade 2" ;;
+ "de-de-comp8") LANGUAGE=German LOCATION=Germany DESC="computer" ;;
+ "de-de-g0") LANGUAGE=German LOCATION=Germany DESC="grade 0" ;;
+ "de-de-g1") LANGUAGE=German LOCATION=Germany DESC="grade 1" ;;
+ "de-de-g2") LANGUAGE=German LOCATION=Germany DESC="grade 2" ;;
+ "dra") LANGUAGE=Dravidian DESC="grade 1" ;;
+ "en_CA") LANGUAGE=English LOCATION=Canada DESC="grade 1" ;;
+ "en-chess") LANGUAGE=English DESC="Chess" ;;
+ "en-gb-comp8") LANGUAGE=English LOCATION=U.K. DESC="computer" ;;
+ "en-gb-g1") LANGUAGE=English LOCATION=U.K. DESC="grade 1" ;;
+ "en-GB-g2") LANGUAGE=English LOCATION=U.K. DESC="grade 2" ;;
+ "en-in-g1") LANGUAGE=English LOCATION=India DESC="grade 1" ;;
+ "en-ueb-g1") LANGUAGE=English DESC="Unified grade 1" ;;
+ "en-ueb-g2") LANGUAGE=English DESC="Unified grade 2" ;;
+ "en-us-comp6") LANGUAGE=English LOCATION=U.S. DESC="computer 6 dots" ;;
+ "en-us-comp8") LANGUAGE=English LOCATION=U.S. DESC="computer 8 dots" ;;
+ "en-us-compbrl") LANGUAGE=English LOCATION=U.S. DESC="computer" ;;
+ "en-us-g1") LANGUAGE=English LOCATION=U.S. DESC="grade 1" ;;
+ "en-us-g2") LANGUAGE=English LOCATION=U.S. DESC="grade 2" ;;
+ "en-us-interline") LANGUAGE=English LOCATION=U.S. DESC="interline" ;;
+ "en-us-mathtext") LANGUAGE=English LOCATION=U.S. DESC="mathtext" ;;
+ "eo-g1") LANGUAGE=Esperanto DESC="grade 1" ;;
+ "eo-g1-x-system") LANGUAGE=Esperanto DESC="grade 1 x-system" ;;
+ "Es-Es-G0") LANGUAGE=Spanish DESC="grade 0" ;;
+ "Es-Es-g1") LANGUAGE=Spanish DESC="grade 1" ;;
+ "es-g1") LANGUAGE=Spanish DESC="grade 1" ;;
+ "et") LANGUAGE=Estonian DESC="grade 1" ;;
+ "et-g0") LANGUAGE=Estonian DESC="grade 0" ;;
+ "ethio-g1") LANGUAGE=Ethiopic DESC="grade 1" ;;
+ "fi") LANGUAGE=Finnish DESC="6 dot" ;;
+ "fi1") LANGUAGE=Finnish DESC="grade 1" ;;
+ "fi2") LANGUAGE=Finnish DESC="grade 2" ;;
+ "fi-fi-8dot") LANGUAGE=Finnish DESC="8dot" ;;
+ "fi-fi") LANGUAGE=Finnish DESC="6dot" ;;
+ "fr-2007") LANGUAGE=French DESC="2007" ;;
+ "fr-bfu-comp6") LANGUAGE=French DESC="Braille Français Unifié computer 6 dots" ;;
+ "fr-bfu-comp8") LANGUAGE=French DESC="Braille Français Unifié computer 8 dots" ;;
+ "fr-bfu-g2") LANGUAGE=French DESC="Braille Français Unifié grade 2" ;;
+ "fr-ca-g1") LANGUAGE=French LOCATION=Canada DESC="grade 1" ;;
+ "Fr-Ca-g2") LANGUAGE=French LOCATION=Canada DESC="grade 2" ;;
+ "fr-fr-g1") LANGUAGE=French LOCATION=France DESC="grade 1" ;;
+ "Fr-Fr-g2") LANGUAGE=French LOCATION=France DESC="grade 2" ;;
+ "ga-g1") LANGUAGE=Gaeilge DESC="grade 1" ;;
+ "ga-g2") LANGUAGE=Gaeilge DESC="grade 2" ;;
+ "gd") LANGUAGE=Gaelic DESC="grade 1" ;;
+ "gon") LANGUAGE=Gondi DESC="grade 1" ;;
+ "gr-bb") LANGUAGE=Greek DESC="bb" ;;
+ "gr-gr-g1") LANGUAGE=Greek DESC="grade 1" ;;
+ "gu-in-g1") LANGUAGE=Gujarati DESC="grade 1" ;;
+ "haw-us-g1") LANGUAGE=Hawaiian DESC="grade 1" ;;
+ "he") LANGUAGE=Hebrew DESC="grade 1" ;;
+ "hi-in-g1") LANGUAGE=Hindi DESC="grade 1" ;;
+ "hr") LANGUAGE=Croatian DESC="grade 1" ;;
+ "hu-hu-comp8") LANGUAGE=Hungarian DESC="computer 8 dots" ;;
+ "hu-hu-g1") LANGUAGE=Hungarian DESC="grade 1" ;;
+ "hy") LANGUAGE=Armenian DESC="grade 1" ;;
+ "is") LANGUAGE=Icelandic DESC="grade 1" ;;
+ "it-it-comp6") LANGUAGE=Italian DESC="computer 6 dots" ;;
+ "it-it-comp8") LANGUAGE=Italian DESC="computer 8 dots" ;;
+ "iu-ca-g1") LANGUAGE=Inuktitut DESC="grade 1" ;;
+ "ka-in-g1") LANGUAGE=Kannada DESC="grade 1" ;;
+ "kh-in-g1") LANGUAGE=Khasi DESC="grade 1" ;;
+ "ko-2006-g1") LANGUAGE=Korean DESC="grade 1 2006" ;;
+ "ko-2006-g2") LANGUAGE=Korean DESC="grade 2 2006" ;;
+ "ko-g1") LANGUAGE=Korean DESC="grade 1" ;;
+ "ko-g2") LANGUAGE=Korean DESC="grade 2" ;;
+ "kok") LANGUAGE=Konkani DESC="grade 1" ;;
+ "kru") LANGUAGE=Kurukh DESC="grade 1" ;;
+ "ks-in-g1") LANGUAGE=Kashmiri DESC="grade 1" ;;
+ "lt") LANGUAGE=Lithuanian DESC="grade 1" ;;
+ "Lv-Lv-g1") LANGUAGE=Latvian DESC="grade 1" ;;
+ "mao-nz-g1") LANGUAGE=Maori DESC="grade 1" ;;
+ "marburg") DESC="Marburg maths" ;;
+ "marburg_edit") DESC="Marburg maths post-translation editing" ;;
+ "ml-in-g1") LANGUAGE=Malayalam DESC="grade 1" ;;
+ "mn-in-g1") LANGUAGE=Manipuri DESC="grade 1" ;;
+ "mn-MN") LANGUAGE=Mongolian DESC="grade 1" ;;
+ "mr-in-g1") LANGUAGE=Marathi DESC="grade 1" ;;
+ "mt") LANGUAGE=Maltese DESC="grade 1" ;;
+ "mun") LANGUAGE=Munda DESC="grade 1" ;;
+ "mwr") LANGUAGE=Marwari DESC="grade 1" ;;
+ "ne") LANGUAGE=Nepali DESC="grade 1" ;;
+ "nemeth") DESC="Nemeth Maths" ;;
+ "nemeth_edit") DESC="Nemeth Maths post-translation editing" ;;
+ "nl-BE-g0") LANGUAGE=Dutch LOCATION=Belgium DESC="grade 0" ;;
+ "nl-g0") LANGUAGE=Dutch DESC="grade 0" ;;
+ "nl-NL-g0") LANGUAGE=Dutch LOCATION="Netherlands" DESC="grade 0" ;;
+ "Nl-Nl-g1") LANGUAGE=Dutch LOCATION=Netherlands DESC="grade 1" ;;
+ "no-no-8dot-fallback-6dot-g0") LANGUAGE=Norwegian DESC="grade 0 8 dots fallback 6 dots" ;;
+ "no-no-8dot") LANGUAGE=Norwegian DESC="grade 0 8 dots" ;;
+ "no-no-comp8") LANGUAGE=Norwegian DESC="grade 0 computer" ;;
+ "no-no-g0") LANGUAGE=Norwegian DESC="grade 0" ;;
+ "no-no-g1") LANGUAGE=Norwegian DESC="grade 1" ;;
+ "no-no-g2") LANGUAGE=Norwegian DESC="grade 2" ;;
+ "no-no-g3") LANGUAGE=Norwegian DESC="grade 3" ;;
+ "no-no-generic") LANGUAGE=Norwegian DESC="generic" ;;
+ "np-in-g1") LANGUAGE=Nepali DESC="grade 1" ;;
+ "or-in-g1") LANGUAGE=Oriya DESC="grade 1" ;;
+ "pi") LANGUAGE=Pali DESC="grade 1" ;;
+ "pl-pl-comp8") LANGUAGE=Polish DESC="computer" ;;
+ "Pl-Pl-g1") LANGUAGE=Polish DESC="grade 1" ;;
+ "pt-pt-comp8") LANGUAGE=Portuguese DESC="computer" ;;
+ "pt-pt-g1") LANGUAGE=Portuguese DESC="grade 1" ;;
+ "pt-pt-g2") LANGUAGE=Portuguese DESC="grade 2" ;;
+ "pu-in-g1") LANGUAGE=Punjabi DESC="grade 1" ;;
+ "ro") LANGUAGE=Romanian DESC="grade 1" ;;
+ "ru-compbrl") LANGUAGE=Russian DESC="computer" ;;
+ "ru") LANGUAGE=Russian DESC="grade 1" ;;
+ "ru-litbrl") LANGUAGE=Russian DESC="literary" ;;
+ "ru-ru-g1") LANGUAGE=Russian DESC="grade 1" ;;
+ "sa-in-g1") LANGUAGE=Sasnskrit DESC="grade 1" ;;
+ "se-se") LANGUAGE=Swedish DESC="grade 1" ;;
+ "Se-Se-g1") LANGUAGE=Swedish DESC="grade 1" ;;
+ "si-in-g1") LANGUAGE=Sindhi DESC="grade 1" ;;
+ "sk-g1") LANGUAGE=Slovak DESC="grade 1" ;;
+ "sk-sk-g1") LANGUAGE=Slovak DESC="grade 1" ;;
+ "sk-sk") LANGUAGE=Slovak DESC="grade 1" ;;
+ "sl-si-comp8") LANGUAGE=Slovenian DESC="computer" ;;
+ "sl-si-g1") LANGUAGE=Slovenian DESC="grade 1" ;;
+ "sot-za-g1") LANGUAGE=Sotho DESC="grade 1" ;;
+ "spaces") DESC="Spaces" ;;
+ "sr-g1") LANGUAGE=Serbian DESC="grade 1" ;;
+ "sv-1989") LANGUAGE=Swedish DESC="1989" ;;
+ "sv-1996") LANGUAGE=Swedish DESC="1996" ;;
+ "ta") LANGUAGE=Tamil DESC="grade 1" ;;
+ "ta-ta-g1") LANGUAGE=Tamil DESC="grade 1" ;;
+ "te-in-g1") LANGUAGE=Telugu DESC="grade 1" ;;
+ "tr") LANGUAGE=Turkish DESC="grade 1" ;;
+ "tsn-za-g1") LANGUAGE=Tswana DESC="grade 1" ;;
+ "UEBC-g1") LANGUAGE=English DESC="Unified grade 1" ;;
+ "UEBC-g2") LANGUAGE=English DESC="Unified grade 2" ;;
+ "ukmaths") DESC="U.K maths" ;;
+ "ukmaths_edit") DESC="U.K maths post-translation editing" ;;
+ "vi") LANGUAGE=Vietnamese DESC="grade 1" ;;
+ "vi-g1") LANGUAGE=Vietnamese DESC="grade 1" ;;
+ "wiskunde") LANGUAGE=Flemish DESC="grade 1" ;;
+ "zh-hk") LANGUAGE=Chinese LOCATION="Hong Kong" DESC="grade 1" ;;
+ "zh-tw") LANGUAGE=Chinese LOCATION="Taiwan" DESC="grade 1" ;;
+ esac
+ echo "$file:$LANGUAGE:$LOCATION:$DESC"
+ done
+
+ for i in $TABLESDIR/hyph_*.dic
+ do
+ file=${i##*/}
+ name=${file%.dic}
+ name=${name#hyph_}
+ DESC=$name
+ LANGUAGE=""
+ LOCATION=""
+ GRADE=""
+ case $name in
+ brl_da_dk) LANGUAGE=Danish ;;
+ cs_CZ) LANGUAGE=Czech ;;
+ de_DE) LANGUAGE=German ;;
+ en_US) LANGUAGE=English ;;
+ eo) LANGUAGE=Esperanto ;;
+ es_ES) LANGUAGE=Spanish ;;
+ fr_FR) LANGUAGE=French ;;
+ hu_HU) LANGUAGE=Hungarian ;;
+ it_IT) LANGUAGE=Italian ;;
+ nb_NO) LANGUAGE="Norwegian Bokmål" ;;
+ nl_NL) LANGUAGE=Dutch ;;
+ nn_NO) LANGUAGE="Norwegian Nynorsk" ;;
+ pl_PL) LANGUAGE=Polish ;;
+ pt_PT) LANGUAGE=Portuguese ;;
+ ru) LANGUAGE=Russian ;;
+ sv_SE) LANGUAGE=Swedish ;;
+ esac
+ echo "$file:$LANGUAGE:$LOCATION:hyphenation rules"
+ done
+
+) | sort -t : -k 2,3 | (
+
+IFS=:
+while read file LANGUAGE LOCATION DESC
+do
+ if [ -z "$DESC" ]
+ then
+ echo "empty description for $file!"
+ exit 1
+ fi
+ [ -n "$LOCATION" ] && DESC="$LOCATION $DESC"
+ [ -n "$LANGUAGE" ] && DESC="$LANGUAGE $DESC"
+ echo " Choice \"$file/$DESC\" \"\""
+done
+)
+
diff --git a/filter/braille/filters/musicxmltobrf.in b/filter/braille/filters/musicxmltobrf.in
new file mode 100644
index 000000000..91a092159
--- /dev/null
+++ b/filter/braille/filters/musicxmltobrf.in
@@ -0,0 +1,56 @@
+#!/bin/bash
+
+#
+# Copyright (c) 2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+# Make sure we have enough options
+if [ $# != 5 -a $# != 6 ]; then
+ echo "ERROR: $0 jobid user name nb options [filename]" >&2
+ exit 1
+fi
+
+NB=$4
+OPTIONS=$5
+FILE=$6
+
+. @CUPS_DATADIR@/braille/cups-braille.sh
+
+checkTool FreeDots FreeDots "translating musicxml files"
+checkTool lou_translate liblouis "translating musicxml files"
+
+CONVERT="FreeDots -nw -w $TEXTWIDTH /dev/stdin"
+TRANSLATE="lou_translate $LIBLOUIS_TABLES,braille-patterns.cti"
+
+cd $TMPDIR
+echo "INFO: Translating MusicXML" >&2
+
+printf "DEBUG: Calling $CONVERT | $TRANSLATE on '%s'\n" "$FILE" >&2
+if [ -z "$FILE" ]
+then
+ $CONVERT | $TRANSLATE
+else
+ < "$FILE" $CONVERT | $TRANSLATE
+fi
+
+echo "INFO: Ready" >&2
diff --git a/filter/braille/filters/texttobrf.in b/filter/braille/filters/texttobrf.in
new file mode 100755
index 000000000..0fe6ed910
--- /dev/null
+++ b/filter/braille/filters/texttobrf.in
@@ -0,0 +1,205 @@
+#!/bin/bash
+
+#
+# Copyright (c) 2015-2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+# Make sure we have enough options
+if [ $# != 5 -a $# != 6 ]; then
+ echo "ERROR: $0 jobid user name nb options [filename]" >&2
+ exit 1
+fi
+
+NB=$4
+OPTIONS=$5
+FILE=$6
+
+. @CUPS_DATADIR@/braille/cups-braille.sh
+
+####################
+# Liblouis options #
+####################
+LIBLOUIS_CONFIG=""
+
+# number of cells per line
+LIBLOUIS_CONFIG+=" -CcellsPerLine=$TEXTWIDTH -ClinesPerPage=$TEXTHEIGHT -CbraillePages=yes"
+
+# input encoding
+if [ "$CHARSET" = utf-8 ]
+then
+ LIBLOUIS_CONFIG+=" -CinputTextEncoding=UTF8"
+else
+ LIBLOUIS_CONFIG+=" -CinputTextEncoding=ascii8"
+fi
+
+echo "DEBUG: Input content type: $CONTENT_TYPE" >&2
+
+# FIXME CONTENT_TYPE contains original document, not document passed as parameter ?!!
+
+setupTextRendering() {
+ # Default rendering without translation: just reformat paragraphs
+ RENDER_CALL="fmt -$TEXTWIDTH"
+
+ # Tool to be used for the conversion
+ case $CONTENT_TYPE in
+ text/plain)
+ CONVERT=""
+ ;;
+ text/html)
+ CONVERT=""
+ RENDER_CALL="lynx -width=$TEXTWIDTH -dump -stdin"
+ checkTool lynx lynx "translating html files"
+ ;;
+ application/msword)
+ CONVERT="antiword -"
+ checkTool antiword antiword "translating MS-Word doc files"
+ ;;
+ application/vnd.openxmlformats-officedocument.wordprocessingml.document)
+ CONVERT="docx2txt"
+ checkTool docx2txt docx2txt "translating MS-Word docx files"
+ ;;
+ text/rtf|application/rtf)
+ CONVERT="rtf2txt /dev/stdin"
+ checkTool rtf2txt rtf2txt "translating RTF files"
+ ;;
+ application/pdf|application/vnd.cups-pdf-banner)
+ CONVERT="pdftotext -raw - -"
+ checkTool pdftotext poppler "translating PDF files"
+ ;;
+ *)
+ echo "ERROR: unsupported content type $CONTENT_TYPE" >&2
+ exit 1
+ ;;
+ esac
+}
+
+# sometimes we can't filter directly from stdin because the tools need to seek
+# within the file (e.g. unzip). This can be called in such case to dump stdin to
+# a file
+dumptofile() {
+ [ -z "$FILE" ] || return 0 # Already a file
+ trap -- 'rm -f "$FILE"' EXIT
+ FILE=$(mktemp "${TMPDIR:-/tmp}/texttobrf.tmp")
+ cat > "$FILE"
+}
+
+# Selected braille table
+if [ -n "$LIBLOUIS_TABLES" ]
+then
+ if type file2brl > /dev/null
+ then
+ # Good, we can use liblouisutdml
+ case $CONTENT_TYPE in
+ text/plain)
+ LIBLOUIS_TOOL="file2brl"
+ CONVERT=""
+ ;;
+ text/html)
+ LIBLOUIS_TOOL="file2brl -t"
+ CONVERT=""
+ ;;
+ text/xml|application/xml|application/xhtml+xml|application/sgml)
+ LIBLOUIS_TOOL="file2brl"
+ CONVERT=""
+ ;;
+ application/msword)
+ LIBLOUIS_TOOL="file2brl"
+ CONVERT="antiword -x db -"
+ checkTool antiword antiword "translating MS-Word doc files"
+ ;;
+ application/vnd.oasis.opendocument*)
+ LIBLOUIS_TOOL="file2brl"
+ dumptofile
+ CONVERT="unzip -p $FILE content.xml"
+ checkTool unzip unzip "translating LibreOffice/OpenOffice OpenDocument files"
+ ;;
+ application/vnd.openxmlformats-officedocument*)
+ LIBLOUIS_TOOL="file2brl"
+ dumptofile
+ CONVERT="unzip -p $FILE word/document.xml"
+ checkTool unzip unzip "translating MS-Word docx files"
+ ;;
+ text/rtf|application/rtf)
+ LIBLOUIS_TOOL="file2brl"
+ CONVERT="rtf2xml /dev/stdin"
+ checkTool rtf2xml rtf2xml "translating RTF files"
+ ;;
+ application/pdf|application/vnd.cups-pdf-banner)
+ LIBLOUIS_TOOL="file2brl -p"
+ CONVERT="pdftotext -raw - -"
+ checkTool pdftotext poppler "translating PDF files"
+ ;;
+ *)
+ echo "ERROR: unsupported content type $CONTENT_TYPE" >&2
+ exit 1
+ ;;
+ esac
+ RENDER_CALL="$LIBLOUIS_TOOL -CliteraryTextTable=$LIBLOUIS_TABLES,braille-patterns.cti $LIBLOUIS_CONFIG"
+ elif type lou_translate > /dev/null
+ then
+ # Only liblouis, but better than nothing
+ setupTextRendering
+ printf "WARN: The liblouisutdml package is required for translating braille better\n" >&2
+ TRANSLATE="lou_translate $LIBLOUIS_TABLES,braille-patterns.cti"
+ else
+ printf "ERROR: The liblouisutdml package is required for translating braille\n" >&2
+ exit 1
+ fi
+else
+ # No translation, only text rendering
+ setupTextRendering
+fi
+
+# Now proceeed
+cd $TMPDIR
+echo "INFO: Reformating text" >&2
+
+if [ -z "$CONVERT" ]
+then
+ printf "DEBUG: Calling $RENDER_CALL on '%s'\n" "$FILE" >&2
+ if [ -z "$FILE" ]
+ then
+ $RENDER_CALL 2> /dev/null
+ else
+ < "$FILE" $RENDER_CALL 2> /dev/null
+ fi
+elif [ -z "$TRANSLATE" ]
+then
+ printf "DEBUG: Calling $CONVERT | $RENDER_CALL on '%s'\n" "$FILE" >&2
+ if [ -z "$FILE" ]
+ then
+ $CONVERT | $RENDER_CALL 2> /dev/null
+ else
+ < "$FILE" $CONVERT | $RENDER_CALL 2> /dev/null
+ fi
+else
+ printf "DEBUG: Calling $CONVERT | $RENDER_CALL | $TRANSLATE on '%s'\n" "$FILE" >&2
+ if [ -z "$FILE" ]
+ then
+ $CONVERT | $RENDER_CALL 2> /dev/null | $TRANSLATE
+ else
+ < "$FILE" $CONVERT | $RENDER_CALL 2> /dev/null | $TRANSLATE
+ fi
+fi
+
+echo "INFO: Ready" >&2
diff --git a/filter/braille/filters/vectortobrf.in b/filter/braille/filters/vectortobrf.in
new file mode 100644
index 000000000..4ed4cd206
--- /dev/null
+++ b/filter/braille/filters/vectortobrf.in
@@ -0,0 +1,72 @@
+#!/bin/bash
+
+#
+# Copyright (c) 2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+# Make sure we have enough options
+if [ $# != 5 -a $# != 6 ]; then
+ echo "ERROR: $0 jobid user name nb options [filename]" >&2
+ exit 1
+fi
+
+NB=$4
+OPTIONS=$5
+FILE=$6
+
+OUTPUT_FORMAT=brf
+
+case $0 in
+ *vectortoubrl*) OUTPUT_FORMAT=ubrl ;;
+esac
+
+. @CUPS_DATADIR@/braille/cups-braille.sh
+
+checkTool convert imagemagick "embossing images"
+
+NEGATE=$(getOption Negate)
+case "$NEGATE" in
+ True|true) NEGATE=-negate ;;
+ False|false) NEGATE= ;;
+ *)
+ printf "ERROR: Option Negate must either True or False, got '%s'\n" "$NEGATE" >&2
+ exit 1
+ ;;
+esac
+
+PAGE="-page ${TOTALGRAPHICWIDTH}x${TOTALGRAPHICHEIGHT}+${GRAPHICHOFFSET}+${GRAPHICVOFFSET}"
+
+GS_CALL="gs -q -dDEVICEWIDTHPOINTS=${GRAPHICWIDTH} -dDEVICEHEIGHTPOINTS=${GRAPHICHEIGHT} -noantialias -dTextAlphaBits=1 -dGraphicsAlphaBits=1 -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pngmono -dFitPage -r72 -sOutputFile=-"
+RENDER_CALL="convert $NEGATE $PAGE -flatten - $OUTPUT_FORMAT:-"
+
+# Now proceeed
+echo "INFO: Converting image" 1>&2
+if [ -z "$FILE" ]
+then
+ printf "DEBUG: Calling %s and %s from stdin\n" "$GS_CALL" "$RENDER_CALL" 1>&2
+ $GS_CALL - | sed -e '/-noantialias/d' | $RENDER_CALL | sed -e '/^\(Width\|X\|Y\): [0-9]*$/,/^$/d'
+else
+ printf "DEBUG: Calling %s and %s on '%s'\n" "$GS_CALL" "$RENDER_CALL" "$FILE" 1>&2
+ $GS_CALL "$FILE" | sed -e '/-noantialias/d' | $RENDER_CALL | sed -e '/^\(Width\|X\|Y\): [0-9]*$/,/^$/d'
+fi
+echo "INFO: Ready" >&2
diff --git a/filter/braille/filters/vectortopdf.in b/filter/braille/filters/vectortopdf.in
new file mode 100644
index 000000000..df0df0abc
--- /dev/null
+++ b/filter/braille/filters/vectortopdf.in
@@ -0,0 +1,69 @@
+#!/bin/bash
+
+#
+# Copyright (c) 2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+# Make sure we have enough options
+if [ $# != 5 -a $# != 6 ]; then
+ echo "ERROR: $0 jobid user name nb options [filename]" >&2
+ exit 1
+fi
+
+NB=$4
+OPTIONS=$5
+FILE=$6
+
+case $0 in
+ *svgtopdf*) INPUT_FORMAT=svg ;;
+ *xfigtopdf*) INPUT_FORMAT=fig ;;
+ *wmftopdf*) INPUT_FORMAT=wmf ;;
+ *emftopdf*) INPUT_FORMAT=emf ;;
+ *cgmtopdf*) INPUT_FORMAT=cgm ;;
+ *cmxtopdf*) INPUT_FORMAT=cmx ;;
+esac
+
+trap -- 'rm -f "$FILE_FORMAT" "$FILE_PDF"' EXIT
+FILE_FORMAT=$(mktemp "${TMPDIR:-/tmp}/vectortopdf.XXXXXX.${INPUT_FORMAT}")
+FILE_PDF=$(mktemp "${TMPDIR:-/tmp}/vectortopdf.XXXXXX.pdf")
+
+if [ -z "$FILE" ]
+then
+ # Get input from stdin
+ cat > "$FILE_FORMAT"
+else
+ cat "$FILE" > "$FILE_FORMAT"
+fi
+
+. @CUPS_DATADIR@/braille/cups-braille.sh
+
+checkTool inkscape inkscape "embossing ${INPUT_FORMAT} vector images"
+
+INKSCAPE="inkscape -z --export-area-drawing"
+
+echo "INFO: Converting image" 1>&2
+printf "DEBUG: Calling $INKSCAPE on '%s'\n" "$FILE_FORMAT" 1>&2
+$INKSCAPE -A "$FILE_PDF" "$FILE_FORMAT"
+cat "$FILE_PDF"
+
+echo "INFO: Ready" >&2
diff --git a/filter/commandtoescpx.c b/filter/commandtoescpx.c
new file mode 100644
index 000000000..565099a1d
--- /dev/null
+++ b/filter/commandtoescpx.c
@@ -0,0 +1,240 @@
+/*
+ * Advanced EPSON ESC/P command filter for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ *
+ * Contents:
+ *
+ * main() - Main entry and command processing.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <cups/cups.h>
+#include <cups/ppd.h>
+#include <cupsfilters/driver.h>
+#include <string.h>
+#include <ctype.h>
+#include "escp.h"
+
+
+/*
+ * 'main()' - Main entry and processing of driver.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ FILE *fp; /* Command file */
+ char line[1024], /* Line from file */
+ *lineptr; /* Pointer into line */
+ int feedpage; /* Feed the page */
+ ppd_file_t *ppd; /* PPD file */
+
+
+ /*
+ * Check for valid arguments...
+ */
+
+ if (argc < 6 || argc > 7)
+ {
+ /*
+ * We don't have the correct number of arguments; write an error message
+ * and return.
+ */
+
+ fprintf(stderr, "Usage: %s job-id user title copies options [file]\n",
+ argv[0]);
+ return (1);
+ }
+
+ /*
+ * Open the PPD file...
+ */
+
+ if ((ppd = ppdOpenFile(getenv("PPD"))) == NULL)
+ {
+ fputs("ERROR: Unable to open PPD file!\n", stderr);
+ return (1);
+ }
+
+ /*
+ * Open the command file as needed...
+ */
+
+ if (argc == 7)
+ {
+ if ((fp = fopen(argv[6], "r")) == NULL)
+ {
+ perror("ERROR: Unable to open command file - ");
+ return (1);
+ }
+ }
+ else
+ fp = stdin;
+
+ /*
+ * Some EPSON printers need an additional command issued at the
+ * beginning of each job to exit from USB "packet" mode...
+ */
+
+ if (ppd->model_number & ESCP_USB)
+ cupsWritePrintData("\000\000\000\033\001@EJL 1284.4\n@EJL \n\033@", 29);
+
+ /*
+ * Reset the printer...
+ */
+
+ cupsWritePrintData("\033@", 2);
+
+ /*
+ * Enter remote mode...
+ */
+
+ cupsWritePrintData("\033(R\010\000\000REMOTE1", 13);
+ feedpage = 0;
+
+ /*
+ * Read the commands from the file and send the appropriate commands...
+ */
+
+ while (fgets(line, sizeof(line), fp) != NULL)
+ {
+ /*
+ * Drop trailing newline...
+ */
+
+ lineptr = line + strlen(line) - 1;
+ if (*lineptr == '\n')
+ *lineptr = '\0';
+
+ /*
+ * Skip leading whitespace...
+ */
+
+ for (lineptr = line; isspace(*lineptr); lineptr ++);
+
+ /*
+ * Skip comments and blank lines...
+ */
+
+ if (*lineptr == '#' || !*lineptr)
+ continue;
+
+ /*
+ * Parse the command...
+ */
+
+ if (strncasecmp(lineptr, "Clean", 5) == 0)
+ {
+ /*
+ * Clean heads...
+ */
+
+ cupsWritePrintData("CH\002\000\000\000", 6);
+ }
+ else if (strncasecmp(lineptr, "PrintAlignmentPage", 18) == 0)
+ {
+ /*
+ * Print alignment page...
+ */
+
+ int phase;
+
+ phase = atoi(lineptr + 18);
+
+ cupsWritePrintData("DT\003\000\000", 5);
+ putchar(phase & 255);
+ putchar(phase >> 8);
+ feedpage = 1;
+ }
+ else if (strncasecmp(lineptr, "PrintSelfTestPage", 17) == 0)
+ {
+ /*
+ * Print version info and nozzle check...
+ */
+
+ cupsWritePrintData("VI\002\000\000\000", 6);
+ cupsWritePrintData("NC\002\000\000\000", 6);
+ feedpage = 1;
+ }
+ else if (strncasecmp(lineptr, "ReportLevels", 12) == 0)
+ {
+ /*
+ * Report ink levels...
+ */
+
+ cupsWritePrintData("IQ\001\000\001", 5);
+ }
+ else if (strncasecmp(lineptr, "SetAlignment", 12) == 0)
+ {
+ /*
+ * Set head alignment...
+ */
+
+ int phase, x;
+
+ if (sscanf(lineptr + 12, "%d%d", &phase, &x) != 2)
+ {
+ fprintf(stderr, "ERROR: Invalid printer command \"%s\"!\n", lineptr);
+ continue;
+ }
+
+ cupsWritePrintData("DA\004\000", 4);
+ putchar(0);
+ putchar(phase);
+ putchar(0);
+ putchar(x);
+ cupsWritePrintData("SV\000\000", 4);
+ }
+ else
+ fprintf(stderr, "ERROR: Invalid printer command \"%s\"!\n", lineptr);
+ }
+
+ /*
+ * Exit remote mode...
+ */
+
+ cupsWritePrintData("\033\000\000\000", 4);
+
+ /*
+ * Eject the page as needed...
+ */
+
+ if (feedpage)
+ {
+ fputs("PAGE: 1 1\n", stderr);
+
+ putchar(13);
+ putchar(10);
+ putchar(12);
+ }
+
+ /*
+ * Reset the printer...
+ */
+
+ cupsWritePrintData("\033@", 2);
+
+ /*
+ * Close the command file and return...
+ */
+
+ ppdClose(ppd);
+
+ if (fp != stdin)
+ fclose(fp);
+
+ return (0);
+}
+
diff --git a/filter/commandtopclx.c b/filter/commandtopclx.c
new file mode 100644
index 000000000..07962ceef
--- /dev/null
+++ b/filter/commandtopclx.c
@@ -0,0 +1,167 @@
+/*
+ * Advanced PCL command filter for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ *
+ * Contents:
+ *
+ * main() - Main entry and command processing.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <cups/cups.h>
+#include <cups/ppd.h>
+#include <cupsfilters/driver.h>
+#include <string.h>
+#include <ctype.h>
+#include "pcl.h"
+
+
+/*
+ * 'main()' - Main entry and processing of driver.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ FILE *fp; /* Command file */
+ char line[1024], /* Line from file */
+ *lineptr; /* Pointer into line */
+ int feedpage; /* Feed the page */
+ ppd_file_t *ppd; /* PPD file */
+
+
+ /*
+ * Check for valid arguments...
+ */
+
+ if (argc < 6 || argc > 7)
+ {
+ /*
+ * We don't have the correct number of arguments; write an error message
+ * and return.
+ */
+
+ fprintf(stderr, "Usage: %s job-id user title copies options [file]\n",
+ argv[0]);
+ return (1);
+ }
+
+ /*
+ * Open the PPD file...
+ */
+
+ if ((ppd = ppdOpenFile(getenv("PPD"))) == NULL)
+ {
+ fputs("ERROR: Unable to open PPD file!\n", stderr);
+ return (1);
+ }
+
+ /*
+ * Open the command file as needed...
+ */
+
+ if (argc == 7)
+ {
+ if ((fp = fopen(argv[6], "r")) == NULL)
+ {
+ perror("ERROR: Unable to open command file - ");
+ return (1);
+ }
+ }
+ else
+ fp = stdin;
+
+ /*
+ * Reset the printer...
+ */
+
+ cupsWritePrintData("\033E", 2);
+
+ /*
+ * Read the commands from the file and send the appropriate commands...
+ */
+
+ feedpage = 0;
+
+ while (fgets(line, sizeof(line), fp) != NULL)
+ {
+ /*
+ * Drop trailing newline...
+ */
+
+ lineptr = line + strlen(line) - 1;
+ if (*lineptr == '\n')
+ *lineptr = '\0';
+
+ /*
+ * Skip leading whitespace...
+ */
+
+ for (lineptr = line; isspace(*lineptr); lineptr ++);
+
+ /*
+ * Skip comments and blank lines...
+ */
+
+ if (*lineptr == '#' || !*lineptr)
+ continue;
+
+ /*
+ * Parse the command...
+ */
+
+ if (strncasecmp(lineptr, "Clean", 5) == 0 &&
+ (ppd->model_number & PCL_INKJET))
+ {
+ /*
+ * Clean heads...
+ */
+
+ cupsWritePrintData("\033&b16WPML \004\000\006\001\004\001\005\001"
+ "\001\004\001\144", 22);
+ }
+ else
+ fprintf(stderr, "ERROR: Invalid printer command \"%s\"!\n", lineptr);
+ }
+
+ /*
+ * Eject the page as needed...
+ */
+
+ if (feedpage)
+ {
+ fputs("PAGE: 1 1\n", stderr);
+
+ putchar(12);
+ }
+
+ /*
+ * Reset the printer...
+ */
+
+ cupsWritePrintData("\033E", 2);
+
+ /*
+ * Close the command file and return...
+ */
+
+ ppdClose(ppd);
+
+ if (fp != stdin)
+ fclose(fp);
+
+ return (0);
+}
+
diff --git a/filter/common.c b/filter/common.c
new file mode 100644
index 000000000..87b953f0c
--- /dev/null
+++ b/filter/common.c
@@ -0,0 +1,632 @@
+/*
+ * Common filter routines for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1997-2006 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * SetCommonOptions() - Set common filter options for media size,
+ * etc.
+ * UpdatePageVars() - Update the page variables for the orientation.
+ * WriteComment() - Write a DSC comment.
+ * WriteCommon() - Write common procedures...
+ * WriteLabelProlog() - Write the prolog with the classification
+ * and page label.
+ * WriteLabels() - Write the actual page labels.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "common.h"
+#include <locale.h>
+
+
+/*
+ * Globals...
+ */
+
+int Orientation = 0, /* 0 = portrait, 1 = landscape, etc. */
+ Duplex = 0, /* Duplexed? */
+ LanguageLevel = 1, /* Language level of printer */
+ ColorDevice = 1; /* Do color text? */
+float PageLeft = 18.0f, /* Left margin */
+ PageRight = 594.0f, /* Right margin */
+ PageBottom = 36.0f, /* Bottom margin */
+ PageTop = 756.0f, /* Top margin */
+ PageWidth = 612.0f, /* Total page width */
+ PageLength = 792.0f; /* Total page length */
+
+
+/*
+ * 'SetCommonOptions()' - Set common filter options for media size, etc.
+ */
+
+ppd_file_t * /* O - PPD file */
+SetCommonOptions(
+ int num_options, /* I - Number of options */
+ cups_option_t *options, /* I - Options */
+ int change_size) /* I - Change page size? */
+{
+ ppd_file_t *ppd; /* PPD file */
+ ppd_size_t *pagesize; /* Current page size */
+ const char *val; /* Option value */
+
+
+#ifdef LC_TIME
+ setlocale(LC_TIME, "");
+#endif /* LC_TIME */
+
+ ppd = ppdOpenFile(getenv("PPD"));
+
+ ppdMarkDefaults(ppd);
+ cupsMarkOptions(ppd, num_options, options);
+
+ if ((pagesize = ppdPageSize(ppd, NULL)) != NULL)
+ {
+ int corrected = 0;
+ if (pagesize->width > 0)
+ PageWidth = pagesize->width;
+ else
+ {
+ fprintf(stderr, "ERROR: Invalid value for page width: %.0f\n",
+ pagesize->width);
+ corrected = 1;
+ }
+ if (pagesize->length > 0)
+ PageLength = pagesize->length;
+ else
+ {
+ fprintf(stderr, "ERROR: Invalid value for page length: %.0f\n",
+ pagesize->length);
+ corrected = 1;
+ }
+ if (pagesize->top >= 0 && pagesize->top <= PageLength)
+ PageTop = pagesize->top;
+ else
+ {
+ fprintf(stderr, "ERROR: Invalid value for page top margin: %.0f\n",
+ pagesize->top);
+ if (PageLength >= PageBottom)
+ PageTop = PageLength - PageBottom;
+ else
+ PageTop = PageLength;
+ corrected = 1;
+ }
+ if (pagesize->bottom >= 0 && pagesize->bottom <= PageLength)
+ PageBottom = pagesize->bottom;
+ else
+ {
+ fprintf(stderr, "ERROR: Invalid value for page bottom margin: %.0f\n",
+ pagesize->bottom);
+ if (PageLength <= PageBottom)
+ PageBottom = 0.0f;
+ corrected = 1;
+ }
+ if (PageBottom == PageTop)
+ {
+ fprintf(stderr, "ERROR: Invalid values for page margins: Bottom: %.0f; Top: %.0f\n",
+ PageBottom, PageTop);
+ PageTop = PageLength - PageBottom;
+ if (PageBottom == PageTop)
+ {
+ PageBottom = 0.0f;
+ PageTop = PageLength;
+ }
+ corrected = 1;
+ }
+ if (PageBottom > PageTop)
+ {
+ fprintf(stderr, "ERROR: Invalid values for page margins: Bottom: %.0f; Top: %.0f\n",
+ PageBottom, PageTop);
+ float swap = PageBottom;
+ PageBottom = PageTop;
+ PageTop = swap;
+ corrected = 1;
+ }
+
+ if (pagesize->left >= 0 && pagesize->left <= PageWidth)
+ PageLeft = pagesize->left;
+ else
+ {
+ fprintf(stderr, "ERROR: Invalid value for page left margin: %.0f\n",
+ pagesize->left);
+ if (PageWidth <= PageLeft)
+ PageLeft = 0.0f;
+ corrected = 1;
+ }
+ if (pagesize->right >= 0 && pagesize->right <= PageWidth)
+ PageRight = pagesize->right;
+ else
+ {
+ fprintf(stderr, "ERROR: Invalid value for page right margin: %.0f\n",
+ pagesize->right);
+ if (PageWidth >= PageLeft)
+ PageRight = PageWidth - PageLeft;
+ else
+ PageRight = PageWidth;
+ corrected = 1;
+ }
+ if (PageLeft == PageRight)
+ {
+ fprintf(stderr, "ERROR: Invalid values for page margins: Left: %.0f; Right: %.0f\n",
+ PageLeft, PageRight);
+ PageRight = PageWidth - PageLeft;
+ if (PageLeft == PageRight)
+ {
+ PageLeft = 0.0f;
+ PageRight = PageWidth;
+ }
+ corrected = 1;
+ }
+ if (PageLeft > PageRight)
+ {
+ fprintf(stderr, "ERROR: Invalid values for page margins: Left: %.0f; Right: %.0f\n",
+ PageLeft, PageRight);
+ float swap = PageLeft;
+ PageLeft = PageRight;
+ PageRight = swap;
+ corrected = 1;
+ }
+
+ if (corrected)
+ {
+ fprintf(stderr, "ERROR: PPD Page = %.0fx%.0f; %.0f,%.0f to %.0f,%.0f\n",
+ pagesize->width, pagesize->length, pagesize->left, pagesize->bottom, pagesize->right, pagesize->top);
+ fprintf(stderr, "ERROR: Corrected Page = %.0fx%.0f; %.0f,%.0f to %.0f,%.0f\n",
+ PageWidth, PageLength, PageLeft, PageBottom, PageRight, PageTop);
+ }
+ else
+ fprintf(stderr, "DEBUG: Page = %.0fx%.0f; %.0f,%.0f to %.0f,%.0f\n",
+ pagesize->width, pagesize->length, pagesize->left, pagesize->bottom, pagesize->right, pagesize->top);
+ }
+
+ if (ppd != NULL)
+ {
+ ColorDevice = ppd->color_device;
+ LanguageLevel = ppd->language_level;
+ }
+
+ if ((val = cupsGetOption("landscape", num_options, options)) != NULL)
+ {
+ if (strcasecmp(val, "no") != 0 && strcasecmp(val, "off") != 0 &&
+ strcasecmp(val, "false") != 0)
+ {
+ if (ppd && ppd->landscape > 0)
+ Orientation = 1;
+ else
+ Orientation = 3;
+ }
+ }
+ else if ((val = cupsGetOption("orientation-requested", num_options, options)) != NULL)
+ {
+ /*
+ * Map IPP orientation values to 0 to 3:
+ *
+ * 3 = 0 degrees = 0
+ * 4 = 90 degrees = 1
+ * 5 = -90 degrees = 3
+ * 6 = 180 degrees = 2
+ */
+
+ Orientation = atoi(val) - 3;
+ if (Orientation >= 2)
+ Orientation ^= 1;
+ }
+
+ if ((val = cupsGetOption("page-left", num_options, options)) != NULL)
+ {
+ switch (Orientation & 3)
+ {
+ case 0 :
+ PageLeft = (float)atof(val);
+ break;
+ case 1 :
+ PageBottom = (float)atof(val);
+ break;
+ case 2 :
+ PageRight = PageWidth - (float)atof(val);
+ break;
+ case 3 :
+ PageTop = PageLength - (float)atof(val);
+ break;
+ }
+ }
+
+ if ((val = cupsGetOption("page-right", num_options, options)) != NULL)
+ {
+ switch (Orientation & 3)
+ {
+ case 0 :
+ PageRight = PageWidth - (float)atof(val);
+ break;
+ case 1 :
+ PageTop = PageLength - (float)atof(val);
+ break;
+ case 2 :
+ PageLeft = (float)atof(val);
+ break;
+ case 3 :
+ PageBottom = (float)atof(val);
+ break;
+ }
+ }
+
+ if ((val = cupsGetOption("page-bottom", num_options, options)) != NULL)
+ {
+ switch (Orientation & 3)
+ {
+ case 0 :
+ PageBottom = (float)atof(val);
+ break;
+ case 1 :
+ PageLeft = (float)atof(val);
+ break;
+ case 2 :
+ PageTop = PageLength - (float)atof(val);
+ break;
+ case 3 :
+ PageRight = PageWidth - (float)atof(val);
+ break;
+ }
+ }
+
+ if ((val = cupsGetOption("page-top", num_options, options)) != NULL)
+ {
+ switch (Orientation & 3)
+ {
+ case 0 :
+ PageTop = PageLength - (float)atof(val);
+ break;
+ case 1 :
+ PageRight = PageWidth - (float)atof(val);
+ break;
+ case 2 :
+ PageBottom = (float)atof(val);
+ break;
+ case 3 :
+ PageLeft = (float)atof(val);
+ break;
+ }
+ }
+
+ if (change_size)
+ UpdatePageVars();
+
+ if (ppdIsMarked(ppd, "Duplex", "DuplexNoTumble") ||
+ ppdIsMarked(ppd, "Duplex", "DuplexTumble") ||
+ ppdIsMarked(ppd, "JCLDuplex", "DuplexNoTumble") ||
+ ppdIsMarked(ppd, "JCLDuplex", "DuplexTumble") ||
+ ppdIsMarked(ppd, "EFDuplex", "DuplexNoTumble") ||
+ ppdIsMarked(ppd, "EFDuplex", "DuplexTumble") ||
+ ppdIsMarked(ppd, "KD03Duplex", "DuplexNoTumble") ||
+ ppdIsMarked(ppd, "KD03Duplex", "DuplexTumble"))
+ Duplex = 1;
+
+ return (ppd);
+}
+
+
+/*
+ * 'UpdatePageVars()' - Update the page variables for the orientation.
+ */
+
+void
+UpdatePageVars(void)
+{
+ float temp; /* Swapping variable */
+
+
+ switch (Orientation & 3)
+ {
+ case 0 : /* Portait */
+ break;
+
+ case 1 : /* Landscape */
+ temp = PageLeft;
+ PageLeft = PageBottom;
+ PageBottom = temp;
+
+ temp = PageRight;
+ PageRight = PageTop;
+ PageTop = temp;
+
+ temp = PageWidth;
+ PageWidth = PageLength;
+ PageLength = temp;
+ break;
+
+ case 2 : /* Reverse Portrait */
+ temp = PageWidth - PageLeft;
+ PageLeft = PageWidth - PageRight;
+ PageRight = temp;
+
+ temp = PageLength - PageBottom;
+ PageBottom = PageLength - PageTop;
+ PageTop = temp;
+ break;
+
+ case 3 : /* Reverse Landscape */
+ temp = PageWidth - PageLeft;
+ PageLeft = PageWidth - PageRight;
+ PageRight = temp;
+
+ temp = PageLength - PageBottom;
+ PageBottom = PageLength - PageTop;
+ PageTop = temp;
+
+ temp = PageLeft;
+ PageLeft = PageBottom;
+ PageBottom = temp;
+
+ temp = PageRight;
+ PageRight = PageTop;
+ PageTop = temp;
+
+ temp = PageWidth;
+ PageWidth = PageLength;
+ PageLength = temp;
+ break;
+ }
+}
+
+
+/*
+ * 'WriteCommon()' - Write common procedures...
+ */
+
+void
+WriteCommon(void)
+{
+ puts("% x y w h ESPrc - Clip to a rectangle.\n"
+ "userdict/ESPrc/rectclip where{pop/rectclip load}\n"
+ "{{newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
+ "neg 0 rlineto closepath clip newpath}bind}ifelse put");
+ puts("% x y w h ESPrf - Fill a rectangle.\n"
+ "userdict/ESPrf/rectfill where{pop/rectfill load}\n"
+ "{{gsave newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
+ "neg 0 rlineto closepath fill grestore}bind}ifelse put");
+ puts("% x y w h ESPrs - Stroke a rectangle.\n"
+ "userdict/ESPrs/rectstroke where{pop/rectstroke load}\n"
+ "{{gsave newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
+ "neg 0 rlineto closepath stroke grestore}bind}ifelse put");
+}
+
+
+/*
+ * 'WriteLabelProlog()' - Write the prolog with the classification
+ * and page label.
+ */
+
+void
+WriteLabelProlog(const char *label, /* I - Page label */
+ float bottom, /* I - Bottom position in points */
+ float top, /* I - Top position in points */
+ float width) /* I - Width in points */
+{
+ const char *classification; /* CLASSIFICATION environment variable */
+ const char *ptr; /* Temporary string pointer */
+
+
+ /*
+ * First get the current classification...
+ */
+
+ if ((classification = getenv("CLASSIFICATION")) == NULL)
+ classification = "";
+ if (strcmp(classification, "none") == 0)
+ classification = "";
+
+ /*
+ * If there is nothing to show, bind an empty 'write labels' procedure
+ * and return...
+ */
+
+ if (!classification[0] && (label == NULL || !label[0]))
+ {
+ puts("userdict/ESPwl{}bind put");
+ return;
+ }
+
+ /*
+ * Set the classification + page label string...
+ */
+
+ printf("userdict");
+ if (strcmp(classification, "confidential") == 0)
+ printf("/ESPpl(CONFIDENTIAL");
+ else if (strcmp(classification, "classified") == 0)
+ printf("/ESPpl(CLASSIFIED");
+ else if (strcmp(classification, "secret") == 0)
+ printf("/ESPpl(SECRET");
+ else if (strcmp(classification, "topsecret") == 0)
+ printf("/ESPpl(TOP SECRET");
+ else if (strcmp(classification, "unclassified") == 0)
+ printf("/ESPpl(UNCLASSIFIED");
+ else
+ {
+ printf("/ESPpl(");
+
+ for (ptr = classification; *ptr; ptr ++)
+ if (*ptr < 32 || *ptr > 126)
+ printf("\\%03o", *ptr);
+ else if (*ptr == '_')
+ putchar(' ');
+ else
+ {
+ if (*ptr == '(' || *ptr == ')' || *ptr == '\\')
+ putchar('\\');
+
+ putchar(*ptr);
+ }
+ }
+
+ if (label)
+ {
+ if (classification[0])
+ printf(" - ");
+
+ /*
+ * Quote the label string as needed...
+ */
+
+ for (ptr = label; *ptr; ptr ++)
+ if (*ptr < 32 || *ptr > 126)
+ printf("\\%03o", *ptr);
+ else
+ {
+ if (*ptr == '(' || *ptr == ')' || *ptr == '\\')
+ putchar('\\');
+
+ putchar(*ptr);
+ }
+ }
+
+ puts(")put");
+
+ /*
+ * Then get a 14 point Helvetica-Bold font...
+ */
+
+ puts("userdict/ESPpf /Helvetica-Bold findfont 14 scalefont put");
+
+ /*
+ * Finally, the procedure to write the labels on the page...
+ */
+
+ puts("userdict/ESPwl{");
+ puts(" ESPpf setfont");
+ printf(" ESPpl stringwidth pop dup 12 add exch -0.5 mul %.0f add\n",
+ width * 0.5f);
+ puts(" 1 setgray");
+ printf(" dup 6 sub %.0f 3 index 20 ESPrf\n", bottom - 2.0);
+ printf(" dup 6 sub %.0f 3 index 20 ESPrf\n", top - 18.0);
+ puts(" 0 setgray");
+ printf(" dup 6 sub %.0f 3 index 20 ESPrs\n", bottom - 2.0);
+ printf(" dup 6 sub %.0f 3 index 20 ESPrs\n", top - 18.0);
+ printf(" dup %.0f moveto ESPpl show\n", bottom + 2.0);
+ printf(" %.0f moveto ESPpl show\n", top - 14.0);
+ puts("pop");
+ puts("}bind put");
+}
+
+
+/*
+ * 'WriteLabels()' - Write the actual page labels.
+ */
+
+void
+WriteLabels(int orient) /* I - Orientation of the page */
+{
+ float width, /* Width of page */
+ length; /* Length of page */
+
+
+ puts("gsave");
+
+ if ((orient ^ Orientation) & 1)
+ {
+ width = PageLength;
+ length = PageWidth;
+ }
+ else
+ {
+ width = PageWidth;
+ length = PageLength;
+ }
+
+ switch (orient & 3)
+ {
+ case 1 : /* Landscape */
+ printf("%.1f 0.0 translate 90 rotate\n", length);
+ break;
+ case 2 : /* Reverse Portrait */
+ printf("%.1f %.1f translate 180 rotate\n", width, length);
+ break;
+ case 3 : /* Reverse Landscape */
+ printf("0.0 %.1f translate -90 rotate\n", width);
+ break;
+ }
+
+ puts("ESPwl");
+ puts("grestore");
+}
+
+
+/*
+ * 'WriteTextComment()' - Write a DSC text comment.
+ */
+
+void
+WriteTextComment(const char *name, /* I - Comment name ("Title", etc.) */
+ const char *value) /* I - Comment value */
+{
+ int len; /* Current line length */
+
+
+ /*
+ * DSC comments are of the form:
+ *
+ * %%name: value
+ *
+ * The name and value must be limited to 7-bit ASCII for most printers,
+ * so we escape all non-ASCII and ASCII control characters as described
+ * in the Adobe Document Structuring Conventions specification.
+ */
+
+ printf("%%%%%s: (", name);
+ len = 5 + strlen(name);
+
+ while (*value)
+ {
+ if (*value < ' ' || *value >= 127)
+ {
+ /*
+ * Escape this character value...
+ */
+
+ if (len >= 251) /* Keep line < 254 chars */
+ break;
+
+ printf("\\%03o", *value & 255);
+ len += 4;
+ }
+ else if (*value == '\\')
+ {
+ /*
+ * Escape the backslash...
+ */
+
+ if (len >= 253) /* Keep line < 254 chars */
+ break;
+
+ putchar('\\');
+ putchar('\\');
+ len += 2;
+ }
+ else
+ {
+ /*
+ * Put this character literally...
+ */
+
+ if (len >= 254) /* Keep line < 254 chars */
+ break;
+
+ putchar(*value);
+ len ++;
+ }
+
+ value ++;
+ }
+
+ puts(")");
+}
+
diff --git a/filter/common.h b/filter/common.h
new file mode 100644
index 000000000..867710e8d
--- /dev/null
+++ b/filter/common.h
@@ -0,0 +1,72 @@
+/*
+ * Common filter definitions for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1997-2006 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <config.h>
+#include <cups/cups.h>
+#include <cups/ppd.h>
+#include <time.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+
+/*
+ * C++ magic...
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/*
+ * Globals...
+ */
+
+extern int Orientation, /* 0 = portrait, 1 = landscape, etc. */
+ Duplex, /* Duplexed? */
+ LanguageLevel, /* Language level of printer */
+ ColorDevice; /* Do color text? */
+extern float PageLeft, /* Left margin */
+ PageRight, /* Right margin */
+ PageBottom, /* Bottom margin */
+ PageTop, /* Top margin */
+ PageWidth, /* Total page width */
+ PageLength; /* Total page length */
+
+
+/*
+ * Prototypes...
+ */
+
+extern ppd_file_t *SetCommonOptions(int num_options, cups_option_t *options,
+ int change_size);
+extern void UpdatePageVars(void);
+extern void WriteCommon(void);
+extern void WriteLabelProlog(const char *label, float bottom,
+ float top, float width);
+extern void WriteLabels(int orient);
+extern void WriteTextComment(const char *name, const char *value);
+
+
+/*
+ * C++ magic...
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
diff --git a/filter/escp.h b/filter/escp.h
new file mode 100644
index 000000000..0fdedcfd9
--- /dev/null
+++ b/filter/escp.h
@@ -0,0 +1,27 @@
+/*
+ * This file contains model number definitions for the CUPS unified
+ * ESC/P driver.
+ *
+ * Copyright 2007 by Apple Inc.
+ * Copyright 1997-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ */
+
+/* General ESC/P Support */
+#define ESCP_DOTMATRIX 0x1 /* Dot matrix printer? */
+#define ESCP_MICROWEAVE 0x2 /* Use microweave command? */
+#define ESCP_STAGGER 0x4 /* Are color jets staggered? */
+#define ESCP_ESCK 0x8 /* Use print mode command?*/
+#define ESCP_EXT_UNITS 0x10 /* Use extended unit commands? */
+#define ESCP_EXT_MARGINS 0x20 /* Use extended margin command */
+#define ESCP_USB 0x40 /* Send USB packet mode escape? */
+#define ESCP_PAGE_SIZE 0x80 /* Use page size command */
+#define ESCP_RASTER_ESCI 0x100 /* Use ESC i graphics command */
+
+/* Remote mode support */
+#define ESCP_REMOTE 0x1000 /* Use remote mode commands? */
+
diff --git a/filter/foomatic-rip/foomatic-rip.1 b/filter/foomatic-rip/foomatic-rip.1
new file mode 100644
index 000000000..cc0251e08
--- /dev/null
+++ b/filter/foomatic-rip/foomatic-rip.1
@@ -0,0 +1,233 @@
+.\" This -*- nroff -*- source file is part of foomatic.
+
+.hy 0
+.TH FOOMATIC-RIP 1 "2013-11-06" "cups-filters"
+.SH NAME
+foomatic-rip \- Universal print filter/RIP wrapper
+.SH SYNOPSIS
+
+.SS \fRGeneral Options:
+.BI \fBfoomatic-rip\fR\ \fB[-v]\ [-q]\fP \fI\ <mode-specific\ options>
+
+.SS \fRSpooler-less printing filter:
+.BI \fBfoomatic-rip\fR\ \fB[\fB-P\fR \ \fI<printer>\fR \
+| \ \fB--ppd\fR \ \fI<ppdfile>\fR \fB]\fR \ [\fB-J\fR\ \fI<jobtitle>\fR ]
+[\fB-o\fR \ \fI<option>\fB=\fI<value>\fR \ [...]] \ \fB[\fI<files>\fB]\fR
+
+.SS \fRCUPS filter:
+.BI \fBfoomatic-rip\fR\ \fI<jobid>\fR \ \fI<user>\fR \ \fI<jobtitle>\fR \ \fI<numcopies>\fR \ \fI<options>\fR \ \fB[\fI<file>\fB]\fR
+
+.SH DESCRIPTION
+foomatic-rip is a universal print filter which can be used as CUPS filter or
+stand-alone for spooler-less, direct printing. It has the following features:
+
+.TP 2m
+\[bu]
+It translates PostScript and PDF from standard input or a file to the printer's
+native language on standard output.
+
+.TP 2m
+\[bu]
+The translation is done with an external renderer, usually Ghostscript
+(\fBgs(1)\fR). If no translation is needed (PostScript printer) the
+renderer's command line reduces to \fBcat(1)\fR. The way how this
+translation is done is described in a \fBPPD file\fR.
+
+.TP 2m
+\[bu]
+Printer capabilities, how to handle user options, and how to build the
+renderer command line is always described by \fBPPD files\fR, these
+PPD files usually come from \fBFoomatic\fR or can be the ones supplied by
+the manufacturers of PostScript printers. The PPD files are the same
+for both CUPS and direct printing.
+
+.TP 2m
+\[bu]
+foomatic-rip works with \fBCUPS\fR and for direct printing (\fBwithout
+spooler\fR), where the latter is mainly for testing and debugging.
+The mode is selected by the command line options and environment
+variables which are supplied to foomatic-rip.
+
+.TP 2m
+\[bu]
+foomatic-rip does not only apply option settings supplied by the user
+through the command line of the printing command, but also searches
+the entire job for embedded option settings (only PostScript
+jobs). Here not only settings which affect the whole job are taken into
+account, but also settings in the page headers, which are only valid
+for the page where they were found, so applications which produce
+PostScript code with page-specific printer option settings are fully
+supported.
+
+.SH DIRECT, SPOOLER-LESS PRINTING
+
+.SS Options
+
+.TP 10
+.B \-v
+\fRverbose mode for debugging.
+.B WARNING:
+This will create a file in /tmp that contains the debugging information.
+This opens a security loophole and should not be used in production.
+
+.TP 10
+.B \-q
+\fRquiet mode - minimal information output
+
+.TP 10
+.BI \-P \ <printer>
+\fI<printer>\fR is the configured printer which should be used for this job.
+
+.TP 10
+.BI \--ppd \ <ppdfile>
+The PPD file \fI<ppdfile>\fR should be applied for processing this job.
+.TP 10
+.BI \-o \ \fI<option>\fB=\fI<value>\fR
+Option settings for this job.
+.TP 10
+.BI \fI<files>\fR
+The file(s) to be printed.
+
+.P
+\fBfoomatic-rip\fR will print from standard input unless at least one file to
+be printed is specified on the command line.
+If your printer PPD file is stored as \fI/etc/direct/<printer>.ppd\fR
+or \fI~/.foomatic/direct/<printer>.ppd\fR you can use it by simply specifying "-P \fI<printer>\fR".
+
+Put a line
+
+\fB*FoomaticRIPPostPipe: "| \fI<command>\fB"\fR
+.hy 0
+
+into the PPD file, right after \fB*PPD-Adobe: "4.3"\fR, where
+\fI<command>\fR is a command into which you want to re-direct the
+output data. Due to the restrictions of PPD files \fB<\fR, \fB>\fR, and
+\fB"\fR are not allowed in the \fI<command>\fR, replace them as
+follows:
+
+.ie t \
+. sp 0.2v
+.el \
+. sp
+.nf
+.B Character Replacement
+.B ---------------------
+.B < &lt;
+.B > &gt;
+.B " &quot;
+.B ' &apos;
+.B & &amp;
+.fi
+
+This way you can print directly to your printer, use
+
+\fB*FoomaticRIPPostPipe: "| cat &gt; /dev/lp0"\fR
+
+or
+
+\fB*FoomaticRIPPostPipe: "| cat &gt; /dev/usb/lp0"\fR
+
+for local parallel or USB printers. To make normal users able to print
+this way add them to the group \fBlp\fR and make sure that the
+appropriate printer device file \fI/dev/...\fR is group-writable for
+the \fBlp\fR group.
+
+for a TCP/Socket/JetDirect printer with the host name \fBprinter\fR
+listening on port \fB9100\fR you need this:
+
+\fB*FoomaticRIPPostPipe: "| /usr/bin/nc -w 1 printer 9100"\fR
+
+Note the "-w 1" in the "nc" command line, it makes "nc" exiting
+immediately after the data is transferred to the printer.
+
+\fB*FoomaticRIPPostPipe: "| rlpr -Plp@printserver"\fR
+
+directs your jobs to the LPD printer queue \fBlp\fR on the machine
+named \fBprintserver\fR.
+
+See also http://www.openprinting.org/direct-doc.html
+
+.SH "PRINTING WITH SPOOLER"
+
+See the documentation on the OpenPrinting Web site:
+.ft CW
+http://www.openprinting.org/
+\fR
+
+.SH "CONFIGURATION FILE"
+
+The file \fB/etc/cups/foomatic-rip.conf\fR or if it is not
+readable the file \fB/etc/foomatic/filter.conf\fR is read
+whenever foomatic-rip is executed. It allows to configure the behavior
+of foomatic-rip as follows (lines beginning with \fB#\fR are comments
+and therefore get ignored):
+
+.TP 10
+.B debug: 0|1
+\fRTurns on (\fB1\fR) or off (\fB0\fR) the debug mode. This is equivalent to
+supplying the \fB--debug\fR command line option. Default setting is \fB0\fR.
+
+.TP 10
+.BI echo: \ [<path>/]<executable>
+\fRSets the path to an \fBecho(1)\fR executable which supports \fB-n\fR.
+
+.TP 10
+.BI gspath: \ [<path>/]<executable>
+\fRSets the path to the Ghostscript (\fBgs(1)\fR) executable. To be used if
+Ghostscript is at a non-standard location or if an alternative Ghostscript
+should be used.
+
+.TP 10
+.BI execpath: \ <path>[:<path>]...
+\fRSets the \fB$PATH\fR variable to be used by foomatic-rip.
+
+.TP 10
+.BI cupsfilterpath: \ <path>[:<path>]...
+\fRSets the directories (colon-separated) in which foomatic-rip searches for
+CUPS filters.
+
+.TP 10
+.BI preferred_shell: \ [<path>/]<executable>
+\fRSets the preferred shell to use when executing FoomaticRIPCommandLine and
+friends. Several PPD files use shell constructs that require a more
+modern shell like \fBbash\fR, \fBzsh\fR, or \fBksh\fR.
+
+
+.SH FILES
+.PD 0
+.TP 0
+/etc/cups/ppd/<printer>.ppd
+.TP 0
+/etc/direct/<printer>.ppd
+
+The PPD files of the currently defined printers
+
+.TP 0
+/etc/cups/foomatic-rip.conf
+.TP 0
+/etc/foomatic/filter.conf
+
+Configuration file for foomatic-rip
+
+.PD 0
+
+.\".SH SEE ALSO
+.\".IR foomatic-XXX (1),
+
+.SH EXIT STATUS
+.B foomatic-rip
+returns 0 unless something unexpected happens.
+
+.SH AUTHOR
+Till Kamppeter <\fItill.kamppeter@gmail.com\fR> with parts of Manfred
+Wassmanns's <\fImanolo@NCC-1701.B.Shuttle.de\fR> man pages for the
+Foomatic 2.0.x filters.
+
+.SH BUGS
+None so far.
+
+Please send bug reports to the OpenPrinting bug tracker:
+
+http://bugs.linuxfoundation.org/
+
+Use "OpenPrinting" as the product and "cups-filters" as the component.
diff --git a/filter/foomatic-rip/foomatic-rip.1.in b/filter/foomatic-rip/foomatic-rip.1.in
new file mode 100644
index 000000000..bdcfd318f
--- /dev/null
+++ b/filter/foomatic-rip/foomatic-rip.1.in
@@ -0,0 +1,233 @@
+.\" This -*- nroff -*- source file is part of foomatic.
+
+.hy 0
+.TH FOOMATIC-RIP 1 "2013-11-06" "cups-filters"
+.SH NAME
+foomatic-rip \- Universal print filter/RIP wrapper
+.SH SYNOPSIS
+
+.SS \fRGeneral Options:
+.BI \fBfoomatic-rip\fR\ \fB[-v]\ [-q]\fP \fI\ <mode-specific\ options>
+
+.SS \fRSpooler-less printing filter:
+.BI \fBfoomatic-rip\fR\ \fB[\fB-P\fR \ \fI<printer>\fR \
+| \ \fB--ppd\fR \ \fI<ppdfile>\fR \fB]\fR \ [\fB-J\fR\ \fI<jobtitle>\fR ]
+[\fB-o\fR \ \fI<option>\fB=\fI<value>\fR \ [...]] \ \fB[\fI<files>\fB]\fR
+
+.SS \fRCUPS filter:
+.BI \fBfoomatic-rip\fR\ \fI<jobid>\fR \ \fI<user>\fR \ \fI<jobtitle>\fR \ \fI<numcopies>\fR \ \fI<options>\fR \ \fB[\fI<file>\fB]\fR
+
+.SH DESCRIPTION
+foomatic-rip is a universal print filter which can be used as CUPS filter or
+stand-alone for spooler-less, direct printing. It has the following features:
+
+.TP 2m
+\[bu]
+It translates PostScript and PDF from standard input or a file to the printer's
+native language on standard output.
+
+.TP 2m
+\[bu]
+The translation is done with an external renderer, usually Ghostscript
+(\fBgs(1)\fR). If no translation is needed (PostScript printer) the
+renderer's command line reduces to \fBcat(1)\fR. The way how this
+translation is done is described in a \fBPPD file\fR.
+
+.TP 2m
+\[bu]
+Printer capabilities, how to handle user options, and how to build the
+renderer command line is always described by \fBPPD files\fR, these
+PPD files usually come from \fBFoomatic\fR or can be the ones supplied by
+the manufacturers of PostScript printers. The PPD files are the same
+for both CUPS and direct printing.
+
+.TP 2m
+\[bu]
+foomatic-rip works with \fBCUPS\fR and for direct printing (\fBwithout
+spooler\fR), where the latter is mainly for testing and debugging.
+The mode is selected by the command line options and environment
+variables which are supplied to foomatic-rip.
+
+.TP 2m
+\[bu]
+foomatic-rip does not only apply option settings supplied by the user
+through the command line of the printing command, but also searches
+the entire job for embedded option settings (only PostScript
+jobs). Here not only settings which affect the whole job are taken into
+account, but also settings in the page headers, which are only valid
+for the page where they were found, so applications which produce
+PostScript code with page-specific printer option settings are fully
+supported.
+
+.SH DIRECT, SPOOLER-LESS PRINTING
+
+.SS Options
+
+.TP 10
+.B \-v
+\fRverbose mode for debugging.
+.B WARNING:
+This will create a file in /tmp that contains the debugging information.
+This opens a security loophole and should not be used in production.
+
+.TP 10
+.B \-q
+\fRquiet mode - minimal information output
+
+.TP 10
+.BI \-P \ <printer>
+\fI<printer>\fR is the configured printer which should be used for this job.
+
+.TP 10
+.BI \--ppd \ <ppdfile>
+The PPD file \fI<ppdfile>\fR should be applied for processing this job.
+.TP 10
+.BI \-o \ \fI<option>\fB=\fI<value>\fR
+Option settings for this job.
+.TP 10
+.BI \fI<files>\fR
+The file(s) to be printed.
+
+.P
+\fBfoomatic-rip\fR will print from standard input unless at least one file to
+be printed is specified on the command line.
+If your printer PPD file is stored as \fI@sysconfdir@/direct/<printer>.ppd\fR
+or \fI~/.foomatic/direct/<printer>.ppd\fR you can use it by simply specifying "-P \fI<printer>\fR".
+
+Put a line
+
+\fB*FoomaticRIPPostPipe: "| \fI<command>\fB"\fR
+.hy 0
+
+into the PPD file, right after \fB*PPD-Adobe: "4.3"\fR, where
+\fI<command>\fR is a command into which you want to re-direct the
+output data. Due to the restrictions of PPD files \fB<\fR, \fB>\fR, and
+\fB"\fR are not allowed in the \fI<command>\fR, replace them as
+follows:
+
+.ie t \
+. sp 0.2v
+.el \
+. sp
+.nf
+.B Character Replacement
+.B ---------------------
+.B < &lt;
+.B > &gt;
+.B " &quot;
+.B ' &apos;
+.B & &amp;
+.fi
+
+This way you can print directly to your printer, use
+
+\fB*FoomaticRIPPostPipe: "| cat &gt; /dev/lp0"\fR
+
+or
+
+\fB*FoomaticRIPPostPipe: "| cat &gt; /dev/usb/lp0"\fR
+
+for local parallel or USB printers. To make normal users able to print
+this way add them to the group \fBlp\fR and make sure that the
+appropriate printer device file \fI/dev/...\fR is group-writable for
+the \fBlp\fR group.
+
+for a TCP/Socket/JetDirect printer with the host name \fBprinter\fR
+listening on port \fB9100\fR you need this:
+
+\fB*FoomaticRIPPostPipe: "| /usr/bin/nc -w 1 printer 9100"\fR
+
+Note the "-w 1" in the "nc" command line, it makes "nc" exiting
+immediately after the data is transferred to the printer.
+
+\fB*FoomaticRIPPostPipe: "| rlpr -Plp@printserver"\fR
+
+directs your jobs to the LPD printer queue \fBlp\fR on the machine
+named \fBprintserver\fR.
+
+See also http://www.openprinting.org/direct-doc.html
+
+.SH "PRINTING WITH SPOOLER"
+
+See the documentation on the OpenPrinting Web site:
+.ft CW
+http://www.openprinting.org/
+\fR
+
+.SH "CONFIGURATION FILE"
+
+The file \fB@sysconfdir@/cups/foomatic-rip.conf\fR or if it is not
+readable the file \fB@sysconfdir@/foomatic/filter.conf\fR is read
+whenever foomatic-rip is executed. It allows to configure the behavior
+of foomatic-rip as follows (lines beginning with \fB#\fR are comments
+and therefore get ignored):
+
+.TP 10
+.B debug: 0|1
+\fRTurns on (\fB1\fR) or off (\fB0\fR) the debug mode. This is equivalent to
+supplying the \fB--debug\fR command line option. Default setting is \fB0\fR.
+
+.TP 10
+.BI echo: \ [<path>/]<executable>
+\fRSets the path to an \fBecho(1)\fR executable which supports \fB-n\fR.
+
+.TP 10
+.BI gspath: \ [<path>/]<executable>
+\fRSets the path to the Ghostscript (\fBgs(1)\fR) executable. To be used if
+Ghostscript is at a non-standard location or if an alternative Ghostscript
+should be used.
+
+.TP 10
+.BI execpath: \ <path>[:<path>]...
+\fRSets the \fB$PATH\fR variable to be used by foomatic-rip.
+
+.TP 10
+.BI cupsfilterpath: \ <path>[:<path>]...
+\fRSets the directories (colon-separated) in which foomatic-rip searches for
+CUPS filters.
+
+.TP 10
+.BI preferred_shell: \ [<path>/]<executable>
+\fRSets the preferred shell to use when executing FoomaticRIPCommandLine and
+friends. Several PPD files use shell constructs that require a more
+modern shell like \fBbash\fR, \fBzsh\fR, or \fBksh\fR.
+
+
+.SH FILES
+.PD 0
+.TP 0
+@sysconfdir@/cups/ppd/<printer>.ppd
+.TP 0
+@sysconfdir@/direct/<printer>.ppd
+
+The PPD files of the currently defined printers
+
+.TP 0
+@sysconfdir@/cups/foomatic-rip.conf
+.TP 0
+@sysconfdir@/foomatic/filter.conf
+
+Configuration file for foomatic-rip
+
+.PD 0
+
+.\".SH SEE ALSO
+.\".IR foomatic-XXX (1),
+
+.SH EXIT STATUS
+.B foomatic-rip
+returns 0 unless something unexpected happens.
+
+.SH AUTHOR
+Till Kamppeter <\fItill.kamppeter@gmail.com\fR> with parts of Manfred
+Wassmanns's <\fImanolo@NCC-1701.B.Shuttle.de\fR> man pages for the
+Foomatic 2.0.x filters.
+
+.SH BUGS
+None so far.
+
+Please send bug reports to the OpenPrinting bug tracker:
+
+http://bugs.linuxfoundation.org/
+
+Use "OpenPrinting" as the product and "cups-filters" as the component.
diff --git a/filter/foomatic-rip/foomaticrip.c b/filter/foomatic-rip/foomaticrip.c
new file mode 100644
index 000000000..2a642edaf
--- /dev/null
+++ b/filter/foomatic-rip/foomaticrip.c
@@ -0,0 +1,1130 @@
+/* foomaticrip.c
+ *
+ * Copyright (C) 2008 Till Kamppeter <till.kamppeter@gmail.com>
+ * Copyright (C) 2008 Lars Uebernickel <larsuebernickel@gmx.de>
+ *
+ * This file is part of foomatic-rip.
+ *
+ * Foomatic-rip 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Foomatic-rip 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 Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "foomaticrip.h"
+#include "util.h"
+#include "options.h"
+#include "pdf.h"
+#include "postscript.h"
+#include "process.h"
+#include "spooler.h"
+#include "renderer.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <errno.h>
+#include <memory.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <math.h>
+#include <signal.h>
+#include <pwd.h>
+#include <cupsfilters/colormanager.h>
+
+/* Logging */
+FILE* logh = NULL;
+
+void _logv(const char *msg, va_list ap)
+{
+ if (!logh)
+ return;
+ vfprintf(logh, msg, ap);
+ fflush(logh);
+}
+
+void _log(const char* msg, ...)
+{
+ va_list ap;
+ va_start(ap, msg);
+ _logv(msg, ap);
+ va_end(ap);
+}
+
+void close_log()
+{
+ if (logh && logh != stderr)
+ fclose(logh);
+}
+
+int redirect_log_to_stderr()
+{
+ if (dup2(fileno(logh), fileno(stderr)) < 0) {
+ _log("Could not dup logh to stderr\n");
+ return 0;
+ }
+ return 1;
+}
+
+void rip_die(int status, const char *msg, ...)
+{
+ va_list ap;
+
+ _log("Process is dying with \"");
+ va_start(ap, msg);
+ _logv(msg, ap);
+ va_end(ap);
+ _log("\", exit stat %d\n", status);
+
+ _log("Cleaning up...\n");
+ kill_all_processes();
+
+ exit(status);
+}
+
+
+jobparams_t *job = NULL;
+
+jobparams_t * get_current_job()
+{
+ assert(job);
+ return job;
+}
+
+
+dstr_t *postpipe; /* command into which the output of this filter should be piped */
+FILE *postpipe_fh = NULL;
+
+FILE * open_postpipe()
+{
+ const char *p;
+
+ if (postpipe_fh)
+ return postpipe_fh;
+
+ if (isempty(postpipe->data))
+ return stdout;
+
+ /* Delete possible '|' symbol in the beginning */
+ p = skip_whitespace(postpipe->data);
+ if (*p && *p == '|')
+ p += 1;
+
+ if (start_system_process("postpipe", p, &postpipe_fh, NULL) < 0)
+ rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS,
+ "Cannot execute postpipe %s\n", postpipe->data);
+
+ return postpipe_fh;
+}
+
+
+char printer_model[256] = "";
+char attrpath[256] = "";
+
+
+int spooler = SPOOLER_DIRECT;
+int dontparse = 0;
+int jobhasjcl;
+int pdfconvertedtops;
+
+
+/* cm-calibration flag */
+int cm_calibrate = 0;
+
+int cm_disabled = 0;
+
+/* These variables were in 'dat' before */
+char colorprofile [128];
+char cupsfilter[256];
+char **jclprepend = NULL;
+dstr_t *jclappend;
+
+/* Set debug to 1 to enable the debug logfile for this filter; it will
+ * appear as defined by LOG_FILE. It will contain status from this
+ * filter, plus the renderer's stderr output. You can also add a line
+ * "debug: 1" to your /etc/cups/foomatic-rip.conf or
+ * /etc/foomatic/filter.conf to get all your Foomatic filters into
+ * debug mode. WARNING: This logfile is a security hole; do not use
+ * in production. */
+int debug = 0;
+
+/* Path to the GhostScript which foomatic-rip shall use */
+char gspath[PATH_MAX] = "gs";
+
+/* What 'echo' program to use. It needs -e and -n. Linux's builtin
+and regular echo work fine; non-GNU platforms may need to install
+gnu echo and put gecho here or something. */
+char echopath[PATH_MAX] = "echo";
+
+/* CUPS raster drivers are searched here */
+char cupsfilterpath[PATH_MAX] = "/usr/local/lib/cups/filter:"
+ "/usr/local/libexec/cups/filter:"
+ "/opt/cups/filter:"
+ "/usr/lib/cups/filter";
+
+char modern_shell[] = SHELL;
+
+void config_set_option(const char *key, const char *value)
+{
+ if (strcmp(key, "debug") == 0)
+ debug = atoi(value);
+
+ /* What path to use for filter programs and such
+ *
+ * Your printer driver must be in the path, as must be the renderer,
+ * and possibly other stuff. The default path is often fine on Linux,
+ * but may not be on other systems. */
+ else if (strcmp(key, "execpath") == 0 && !isempty(value))
+ setenv("PATH", value, 1);
+
+ else if (strcmp(key, "cupsfilterpath") == 0)
+ strlcpy(cupsfilterpath, value, PATH_MAX);
+ else if (strcmp(key, "preferred_shell") == 0)
+ strlcpy(modern_shell, value, 32);
+ else if (strcmp(key, "gspath") == 0)
+ strlcpy(gspath, value, PATH_MAX);
+ else if (strcmp(key, "echo") == 0)
+ strlcpy(echopath, value, PATH_MAX);
+}
+
+int config_from_file(const char *filename)
+{
+ FILE *fh;
+ char line[256];
+ char *key, *value;
+
+ fh = fopen(filename, "r");
+ if (fh == NULL)
+ return 0;
+
+ while (fgets(line, 256, fh) != NULL)
+ {
+ key = strtok(line, " :\t\r\n");
+ if (key == NULL || key[0] == '#')
+ continue;
+ value = strtok(NULL, " \t\r\n#");
+ config_set_option(key, value);
+ }
+ fclose(fh);
+
+ return 1;
+}
+
+const char * get_modern_shell()
+{
+ return modern_shell;
+}
+
+/* returns position in 'str' after the option */
+char * extract_next_option(char *str, char **pagerange, char **key, char **value)
+{
+ char *p = str;
+ char quotechar;
+
+ *pagerange = NULL;
+ *key = NULL;
+ *value = NULL;
+
+ if (!str)
+ return NULL;
+
+ /* skip whitespace and commas */
+ while (*p && (isspace(*p) || *p == ',')) p++;
+
+ if (!*p)
+ return NULL;
+
+ /* read the pagerange if we have one */
+ if (prefixcmp(p, "even:") == 0 || prefixcmp(p, "odd:") == 0 || isdigit(*p)) {
+ *pagerange = p;
+ p = strchr(p, ':');
+ if (!p)
+ return NULL;
+ *p = '\0';
+ p++;
+ }
+
+ /* read the key */
+ if (*p == '\'' || *p == '\"') {
+ quotechar = *p;
+ *key = p +1;
+ p = strchr(*key, quotechar);
+ if (!p)
+ return NULL;
+ }
+ else {
+ *key = p;
+ while (*p && *p != ':' && *p != '=' && *p != ' ') p++;
+ }
+
+ if (*p != ':' && *p != '=') { /* no value for this option */
+ if (!*p)
+ return NULL;
+ else if (isspace(*p)) {
+ *p = '\0';
+ return p +1;
+ }
+ return p;
+ }
+
+ *p++ = '\0'; /* remove the separator sign */
+
+ if (*p == '\"' || *p == '\'') {
+ quotechar = *p;
+ *value = p +1;
+ p = strchr(*value, quotechar);
+ if (!p)
+ return NULL;
+ *p = '\0';
+ p++;
+ }
+ else {
+ *value = p;
+ while (*p && *p != ' ' && *p != ',') p++;
+ if (*p == '\0')
+ return NULL;
+ *p = '\0';
+ p++;
+ }
+
+ return *p ? p : NULL;
+}
+
+/* processes job->optstr */
+void process_cmdline_options()
+{
+ char *p, *cmdlineopts, *nextopt, *pagerange, *key, *value;
+ option_t *opt, *opt2;
+ int optset;
+ char tmp [256];
+
+ _log("Printing system options:\n");
+ cmdlineopts = strdup(job->optstr->data);
+ for (nextopt = extract_next_option(cmdlineopts, &pagerange, &key, &value);
+ key;
+ nextopt = extract_next_option(nextopt, &pagerange, &key, &value))
+ {
+ /* Consider only options which are not in the PPD file here */
+ if ((opt = find_option(key)) != NULL) continue;
+ if (value)
+ _log("Pondering option '%s=%s'\n", key, value);
+ else
+ _log("Pondering option '%s'\n", key);
+
+ /* "profile" option to supply a color correction profile to a CUPS raster driver */
+ if (!strcmp(key, "profile")) {
+ strlcpy(colorprofile, value, 128);
+ continue;
+ }
+ /* option to set color calibration mode */
+ if (!strcmp(key, "cm-calibration")) {
+ cm_calibrate = 1;
+ continue;
+ }
+ /* Solaris options that have no reason to be */
+ if (!strcmp(key, "nobanner") || !strcmp(key, "dest") || !strcmp(key, "protocol"))
+ continue;
+
+ if (pagerange) {
+ snprintf(tmp, 256, "pages:%s", pagerange);
+ optset = optionset(tmp);
+ }
+ else
+ optset = optionset("userval");
+
+ if (value) {
+ if (strcasecmp(key, "media") == 0) {
+ /* Standard arguments?
+ media=x,y,z
+ sides=one|two-sided-long|short-edge
+
+ Rummage around in the media= option for known media, source,
+ etc types.
+ We ought to do something sensible to make the common manual
+ boolean option work when specified as a media= tray thing.
+
+ Note that this fails miserably when the option value is in
+ fact a number; they all look alike. It's unclear how many
+ drivers do that. We may have to standardize the verbose
+ names to make them work as selections, too. */
+
+ if (value[0] == '\0')
+ continue;
+ p = strtok(value, ",");
+ do {
+ if ((opt = find_option("PageSize")) && option_accepts_value(opt, p))
+ option_set_value(opt, optset, p);
+ else if ((opt = find_option("MediaType")) && option_has_choice(opt, p))
+ option_set_value(opt, optset, p);
+ else if ((opt = find_option("InputSlot")) && option_has_choice(opt, p))
+ option_set_value(opt, optset, p);
+ else if (!strcasecmp(p, "manualfeed")) {
+ /* Special case for our typical boolean manual
+ feeder option if we didn't match an InputSlot above */
+ if ((opt = find_option("ManualFeed")))
+ option_set_value(opt, optset, "1");
+ }
+ else
+ _log("Unknown \"media\" component: \"%s\".\n", p);
+
+ } while ((p = strtok(NULL, ",")));
+ }
+ else if (!strcasecmp(key, "sides")) {
+ /* Handle the standard duplex option, mostly */
+ if (!prefixcasecmp(value, "two-sided")) {
+ if ((opt = find_option("Duplex"))) {
+ /* Default to long-edge binding here, for the case that
+ there is no binding setting */
+ option_set_value(opt, optset, "DuplexNoTumble");
+
+ /* Check the binding: "long edge" or "short edge" */
+ if (strcasestr(value, "long-edge")) {
+ if ((opt2 = find_option("Binding")))
+ option_set_value(opt2, optset, "LongEdge");
+ else
+ option_set_value(opt, optset, "DuplexNoTumble");
+ }
+ else if (strcasestr(value, "short-edge")) {
+ if ((opt2 = find_option("Binding")))
+ option_set_value(opt2, optset, "ShortEdge");
+ else
+ option_set_value(opt, optset, "DuplexNoTumble");
+ }
+ }
+ }
+ else if (!prefixcasecmp(value, "one-sided")) {
+ if ((opt = find_option("Duplex")))
+ option_set_value(opt, optset, "0");
+ }
+
+ /* TODO
+ We should handle the other half of this option - the
+ BindEdge bit. Also, are there well-known ipp/cups options
+ for Collate and StapleLocation? These may be here...
+ */
+ }
+ else
+ _log("Unknown option %s=%s.\n", key, value);
+ }
+ /* Custom paper size */
+ else if ((opt = find_option("PageSize")) && option_set_value(opt, optset, key)) {
+ /* do nothing, if the value could be set, it has been set */
+ }
+ else
+ _log("Unknown boolean option \"%s\".\n", key);
+ }
+ free(cmdlineopts);
+
+ /* We 'clear' the profile if cm-calibration mode was specified */
+ if (cm_calibrate) {
+ colorprofile[0] = '\0';
+ cm_disabled = 1;
+ }
+
+ _log("CM Color Calibration Mode in CUPS: %s\n", cm_calibrate ?
+ "Activated" : "Off");
+
+ _log("Options from the PPD file:\n");
+ cmdlineopts = strdup(job->optstr->data);
+ for (nextopt = extract_next_option(cmdlineopts, &pagerange, &key, &value);
+ key;
+ nextopt = extract_next_option(nextopt, &pagerange, &key, &value))
+ {
+ /* Consider only PPD file options here */
+ if ((opt = find_option(key)) == NULL) continue;
+ if (value)
+ _log("Pondering option '%s=%s'\n", key, value);
+ else
+ _log("Pondering option '%s'\n", key);
+
+ if (pagerange) {
+ snprintf(tmp, 256, "pages:%s", pagerange);
+ optset = optionset(tmp);
+
+ if (opt && (option_get_section(opt) != SECTION_ANYSETUP &&
+ option_get_section(opt) != SECTION_PAGESETUP)) {
+ _log("This option (%s) is not a \"PageSetup\" or \"AnySetup\" option, so it cannot be restricted to a page range.\n", key);
+ continue;
+ }
+ }
+ else
+ optset = optionset("userval");
+
+ if (value) {
+ /* Various non-standard printer-specific options */
+ if (!option_set_value(opt, optset, value)) {
+ _log(" invalid choice \"%s\", using \"%s\" instead\n",
+ value, option_get_value(opt, optset));
+ }
+ }
+ /* Standard bool args:
+ landscape; what to do here?
+ duplex; we should just handle this one OK now? */
+ else if (!prefixcasecmp(key, "no"))
+ option_set_value(opt, optset, "0");
+ else
+ option_set_value(opt, optset, "1");
+ }
+ free(cmdlineopts);
+}
+
+/* Functions to let foomatic-rip fork to do several tasks in parallel.
+
+To do the filtering without loading the whole file into memory we work
+on a data stream, we read the data line by line analyse it to decide what
+filters to use and start the filters if we have found out which we need.
+We buffer the data only as long as we didn't determing which filters to
+use for this piece of data and with which options. There are no temporary
+files used.
+
+foomatic-rip splits into up to 3 parallel processes to do the whole
+filtering (listed in the order of the data flow):
+
+ MAIN: Prepare the job auto-detecting the spooler, reading the PPD,
+ extracting the options from the command line, and parsing
+ the job data itself. It analyses the job data to check
+ whether it is PostScript or PDF, it also stuffs PostScript
+ code from option settings into the PostScript data stream.
+ It starts the renderer (KID3/KID4) as soon as it knows its
+ command line and restarts it when page-specific option
+ settings need another command line or different JCL commands.
+ KID3: The rendering process. In most cases Ghostscript, "cat"
+ for native PostScript printers with their manufacturer's
+ PPD files.
+ KID4: Put together the JCL commands and the renderer's output
+ and send all that either to STDOUT or pipe it into the
+ command line defined with $postpipe. */
+
+
+
+void write_output(void *data, size_t len)
+{
+ const char *p = (const char *)data;
+ size_t left = len;
+ FILE *postpipe = open_postpipe();
+
+ /* Remove leading whitespace */
+ while (isspace(*p++) && left-- > 0)
+ ;
+
+ fwrite_or_die((void *)p, left, 1, postpipe);
+ fflush(postpipe);
+}
+
+enum FileType {
+ UNKNOWN_FILE,
+ PDF_FILE,
+ PS_FILE
+};
+
+int guess_file_type(const char *begin, size_t len, int *startpos)
+{
+ const char * p, * end;
+ p = begin;
+ end = begin + len;
+
+ while (p < end)
+ {
+ p = memchr(p, '%', end - p);
+ if (!p)
+ return UNKNOWN_FILE;
+ *startpos = p - begin;
+ if ((end - p) > 2 && !memcmp(p, "%!", 2))
+ return PS_FILE;
+ else if ((end - p) > 7 && !memcmp(p, "%PDF-1.", 7))
+ return PDF_FILE;
+ ++ p;
+ }
+ *startpos = 0;
+ return UNKNOWN_FILE;
+}
+
+/*
+ * Prints 'filename'. If 'convert' is true, the file will be converted if it is
+ * not postscript or pdf
+ */
+int print_file(const char *filename, int convert)
+{
+ FILE *file;
+ char buf[8192];
+ int type;
+ int startpos;
+ size_t n;
+ int ret;
+
+ if (!strcasecmp(filename, "<STDIN>"))
+ file = stdin;
+ else {
+ file = fopen(filename, "r");
+ if (!file) {
+ _log("Could not open \"%s\" for reading\n", filename);
+ return 0;
+ }
+ }
+
+ n = fread_or_die(buf, 1, sizeof(buf) - 1, file);
+ buf[n] = '\0';
+ type = guess_file_type(buf, n, &startpos);
+ /* We do not use any JCL preceeded to the inputr data, as it is simply
+ the PJL commands from the PPD file, and these commands we can also
+ generate, end we even merge them with PJl from the driver */
+ /*if (startpos > 0) {
+ jobhasjcl = 1;
+ write_output(buf, startpos);
+ }*/
+ if (file != stdin)
+ rewind(file);
+
+ if (convert) pdfconvertedtops = 0;
+
+ switch (type) {
+ case PDF_FILE:
+ _log("Filetype: PDF\n");
+
+ if (!ppd_supports_pdf())
+ {
+ char pdf2ps_cmd[CMDLINE_MAX];
+ FILE *out, *in;
+ int renderer_pid;
+ char tmpfilename[PATH_MAX] = "";
+
+ _log("Driver does not understand PDF input, "
+ "converting to PostScript\n");
+
+ pdfconvertedtops = 1;
+
+ /* If reading from stdin, write everything into a temporary file */
+ if (file == stdin)
+ {
+ int fd;
+ FILE *tmpfile;
+
+ snprintf(tmpfilename, PATH_MAX, "%s/foomatic-XXXXXX", temp_dir());
+ fd = mkstemp(tmpfilename);
+ if (fd < 0) {
+ _log("Could not create temporary file: %s\n", strerror(errno));
+ return EXIT_PRNERR_NORETRY_BAD_SETTINGS;
+ }
+ tmpfile = fdopen(fd, "r+");
+ copy_file(tmpfile, stdin, buf, n);
+ fclose(tmpfile);
+
+ filename = tmpfilename;
+ }
+
+ /* If the spooler is CUPS we use the pdftops filter of CUPS,
+ to have always the same PDF->PostScript conversion method
+ in the whole printing environment, including incompatibility
+ workarounds in the CUPS filter (so this way we also have to
+ maintain all these quirks only once).
+
+ The "-dNOINTERPOLATE" makes Ghostscript rendering
+ significantly faster.
+
+ The "-dNOMEDIAATTRS" makes Ghostscript not checking the
+ page sizes against a list of known sizes and try to
+ correct them.
+
+ Note that Ghostscript's "pswrite" output device turns text
+ into bitmaps and therefore produces huge PostScript files.
+ In addition, this output device is deprecated. Therefore
+ we use "ps2write".
+
+ We give priority to Ghostscript here and use Poppler if
+ Ghostscript is not available. */
+ if (spooler == SPOOLER_CUPS)
+ snprintf(pdf2ps_cmd, CMDLINE_MAX,
+ "pdftops '%s' '%s' '%s' '%s' '%s' '%s'",
+ job->id, job->user, job->title, "1", job->optstr->data,
+ filename);
+ else
+ snprintf(pdf2ps_cmd, CMDLINE_MAX,
+ "gs -q -sstdout=%%stderr -sDEVICE=ps2write -sOutputFile=- "
+ "-dBATCH -dNOPAUSE -dPARANOIDSAFER -dNOINTERPOLATE -dNOMEDIAATTRS -dShowAcroForm %s 2>/dev/null || "
+ "pdftops -level2 -origpagesizes %s - 2>/dev/null",
+ filename, filename);
+
+ renderer_pid = start_system_process("pdf-to-ps", pdf2ps_cmd, &in, &out);
+
+ if (dup2(fileno(out), fileno(stdin)) < 0)
+ rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS,
+ "Couldn't dup stdout of pdf-to-ps\n");
+
+ ret = print_file("<STDIN>", 0);
+
+ wait_for_process(renderer_pid);
+ return ret;
+ }
+
+ if (file == stdin)
+ return print_pdf(stdin, buf, n, filename, startpos);
+ else
+ return print_pdf(file, NULL, 0, filename, startpos);
+
+ case PS_FILE:
+ _log("Filetype: PostScript\n");
+ if (file == stdin)
+ return print_ps(stdin, buf, n, filename);
+ else
+ return print_ps(file, NULL, 0, filename);
+
+ case UNKNOWN_FILE:
+ _log("Cannot process \"%s\": Unknown filetype.\n", filename);
+ return 0;
+ }
+
+ fclose(file);
+ return 1;
+}
+
+void signal_terminate(int signal)
+{
+ rip_die(EXIT_PRINTED, "Caught termination signal: Job canceled\n");
+}
+
+jobparams_t * create_job()
+{
+ jobparams_t *job = calloc(1, sizeof(jobparams_t));
+ struct passwd *passwd;
+
+ job->optstr = create_dstr();
+ job->time = time(NULL);
+ strcpy(job->copies, "1");
+ gethostname(job->host, 128);
+ passwd = getpwuid(getuid());
+ if (passwd)
+ strlcpy(job->user, passwd->pw_name, 128);
+ snprintf(job->title, 2048, "%s@%s", job->user, job->host);
+
+ return job;
+}
+
+void free_job(jobparams_t *job)
+{
+ free_dstr(job->optstr);
+ free(job);
+}
+
+int main(int argc, char** argv)
+{
+ int i;
+ int verbose = 0, quiet = 0;
+ const char* str;
+ char *p, *filename;
+ const char *path;
+ char tmp[1024], gstoraster[256];
+ int havefilter, havegstoraster;
+ dstr_t *filelist;
+ list_t * arglist;
+
+ arglist = list_create_from_array(argc -1, (void**)&argv[1]);
+
+ if (argc == 2 && (arglist_find(arglist, "--version") || arglist_find(arglist, "--help") ||
+ arglist_find(arglist, "-v") || arglist_find(arglist, "-h"))) {
+ printf("foomatic-rip of cups-filters version "VERSION"\n");
+ printf("\"man foomatic-rip\" for help.\n");
+ list_free(arglist);
+ return 0;
+ }
+
+ filelist = create_dstr();
+ job = create_job();
+
+ jclprepend = NULL;
+ jclappend = create_dstr();
+ postpipe = create_dstr();
+
+ options_init();
+
+ signal(SIGTERM, signal_terminate);
+ signal(SIGINT, signal_terminate);
+ signal(SIGPIPE, SIG_IGN);
+
+ /* First try to find a config file in the CUS config directory, like
+ /etc/cups/foomatic-rip.conf */
+ i = 0;
+ if ((str = getenv("CUPS_SERVERROOT")) != NULL) {
+ snprintf(tmp, sizeof(tmp), "%s/foomatic-rip.conf", str);
+ i = config_from_file(tmp);
+ }
+ /* If there is none, fall back to /etc/foomatic/filter.conf */
+ if (i == 0)
+ i = config_from_file(CONFIG_PATH "/filter.conf");
+
+ /* Command line options for verbosity */
+ if (arglist_remove_flag(arglist, "-v"))
+ verbose = 1;
+ if (arglist_remove_flag(arglist, "-q"))
+ quiet = 1;
+ if (arglist_remove_flag(arglist, "--debug"))
+ debug = 1;
+
+ if (debug) {
+#if defined(__UCLIBC__) || defined(__NetBSD__)
+ sprintf(tmp, "%s-log-XXXXXX", LOG_FILE);
+ int fd = mkstemp (tmp);
+#else
+ sprintf(tmp, "%s-XXXXXX.log", LOG_FILE);
+ int fd = mkstemps (tmp, 4);
+#endif
+ if (fd != -1)
+ logh = fdopen(fd, "w");
+ else
+ logh = stderr;
+ } else if (quiet && !verbose)
+ logh = NULL; /* Quiet mode, do not log */
+ else
+ logh = stderr; /* Default: log to stderr */
+
+ /* Start debug logging */
+ if (debug) {
+ /* If we are not in debug mode, we do this later, as we must find out at
+ first which spooler is used. When printing without spooler we
+ suppress logging because foomatic-rip is called directly on the
+ command line and so we avoid logging onto the console. */
+ _log("foomatic-rip version "VERSION" running...\n");
+
+ /* Print the command line only in debug mode, Mac OS X adds very many
+ options so that CUPS cannot handle the output of the command line
+ in its log files. If CUPS encounters a line with more than 1024
+ characters sent into its log files, it aborts the job with an error. */
+ if (spooler != SPOOLER_CUPS) {
+ _log("called with arguments: ");
+ for (i = 1; i < argc -1; i++)
+ _log("\'%s\', ", argv[i]);
+ _log("\'%s\'\n", argv[i]);
+ }
+ }
+
+ if (getenv("PPD")) {
+ strncpy(job->ppdfile, getenv("PPD"), 2048);
+ spooler = SPOOLER_CUPS;
+ if (getenv("CUPS_SERVERBIN"))
+ strncpy(cupsfilterpath, getenv("CUPS_SERVERBIN"),
+ sizeof(cupsfilterpath));
+ }
+
+ /* Check status of printer color management from the color manager */
+ cm_disabled = cmIsPrinterCmDisabled(getenv("PRINTER"));
+
+ /* CUPS calls foomatic-rip only with 5 or 6 positional parameters,
+ not with named options, like for example "-p <string>". */
+ if (spooler != SPOOLER_CUPS) {
+
+ if ((str = arglist_get_value(arglist, "-j")) || (str = arglist_get_value(arglist, "-J"))) {
+ strncpy_omit(job->title, str, 2048, omit_shellescapes);
+ if (!arglist_remove(arglist, "-j"))
+ arglist_remove(arglist, "-J");
+ }
+
+ /* PPD file name given via the command line
+ allow duplicates, and use the last specified one */
+ while ((str = arglist_get_value(arglist, "-p"))) {
+ strncpy(job->ppdfile, str, 2048);
+ arglist_remove(arglist, "-p");
+ }
+ while ((str = arglist_get_value(arglist, "--ppd"))) {
+ strncpy(job->ppdfile, str, 2048);
+ arglist_remove(arglist, "--ppd");
+ }
+
+ /* Options for spooler-less printing */
+ while ((str = arglist_get_value(arglist, "-o"))) {
+ strncpy_omit(tmp, str, 1024, omit_shellescapes);
+ dstrcatf(job->optstr, "%s ", tmp);
+ /* if "-o cm-calibration" was passed, we raise a flag */
+ if (!strcmp(tmp, "cm-calibration")) {
+ cm_calibrate = 1;
+ cm_disabled = 1;
+ }
+ arglist_remove(arglist, "-o");
+ /* We print without spooler */
+ spooler = SPOOLER_DIRECT;
+ }
+
+ /* Printer for spooler-less printing */
+ if ((str = arglist_get_value(arglist, "-d"))) {
+ strncpy_omit(job->printer, str, 256, omit_shellescapes);
+ arglist_remove(arglist, "-d");
+ }
+
+ /* Printer for spooler-less printing */
+ if ((str = arglist_get_value(arglist, "-P"))) {
+ strncpy_omit(job->printer, str, 256, omit_shellescapes);
+ arglist_remove(arglist, "-P");
+ }
+
+ }
+
+ _log("'CM Color Calibration' Mode in SPOOLER-LESS: %s\n", cm_calibrate ?
+ "Activated" : "Off");
+
+ /* spooler specific initialization */
+ switch (spooler) {
+
+ case SPOOLER_CUPS:
+ init_cups(arglist, filelist, job);
+ break;
+
+ case SPOOLER_DIRECT:
+ init_direct(arglist, filelist, job);
+ break;
+ }
+
+ /* Files to be printed (can be more than one for spooler-less printing) */
+ /* Empty file list -> print STDIN */
+ dstrtrim(filelist);
+ if (filelist->len == 0)
+ dstrcpyf(filelist, "<STDIN>");
+
+ /* Check filelist */
+ p = strtok(strdup(filelist->data), " ");
+ while (p) {
+ if (strcmp(p, "<STDIN>") != 0) {
+ if (p[0] == '-')
+ rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "Invalid argument: %s", p);
+ else if (access(p, R_OK) != 0) {
+ _log("File %s does not exist/is not readable\n", p);
+ strclr(p);
+ }
+ }
+ p = strtok(NULL, " ");
+ }
+
+ /* When we print without spooler do not log onto STDERR unless
+ the "-v" ('Verbose') is set or the debug mode is used */
+ if (spooler == SPOOLER_DIRECT && !verbose && !debug) {
+ if (logh && logh != stderr)
+ fclose(logh);
+ logh = NULL;
+ }
+
+ /* If we are in debug mode, we do this earlier. */
+ if (!debug) {
+ _log("foomatic-rip version " VERSION " running...\n");
+ /* Print the command line only in debug mode, Mac OS X adds very many
+ options so that CUPS cannot handle the output of the command line
+ in its log files. If CUPS encounters a line with more than 1024
+ characters sent into its log files, it aborts the job with an error. */
+ if (spooler != SPOOLER_CUPS) {
+ _log("called with arguments: ");
+ for (i = 1; i < argc -1; i++)
+ _log("\'%s\', ", argv[i]);
+ _log("\'%s\'\n", argv[i]);
+ }
+ }
+
+ /* PPD File */
+ /* Load the PPD file and build a data structure for the renderer's
+ command line and the options */
+ if (spooler == SPOOLER_CUPS && job->printer && strlen(job->printer) > 0) {
+ str = cupsGetPPD(job->printer);
+ if (str) {
+ read_ppd_file(str);
+ unlink(str);
+ } else
+ read_ppd_file(job->ppdfile);
+ } else
+ read_ppd_file(job->ppdfile);
+
+ /* We do not need to parse the PostScript job when we don't have
+ any options. If we have options, we must check whether the
+ default settings from the PPD file are valid and correct them
+ if nexessary. */
+ if (option_count() == 0) {
+ /* We don't have any options, so we do not need to parse the
+ PostScript data */
+ dontparse = 1;
+ }
+
+ /* Is our PPD for a CUPS raster driver */
+ if (!isempty(cupsfilter)) {
+ /* Search the filter in cupsfilterpath
+ The %Y is a placeholder for the option settings */
+ havefilter = 0;
+ path = cupsfilterpath;
+ while ((path = strncpy_tochar(tmp, path, 1024, ":"))) {
+ strlcat(tmp, "/", 1024);
+ strlcat(tmp, cupsfilter, 1024);
+ if (access(tmp, X_OK) == 0) {
+ havefilter = 1;
+ strlcpy(cupsfilter, tmp, 256);
+ strlcat(cupsfilter, " 0 '' '' 0 '%Y%X'", 256);
+ break;
+ }
+ }
+
+ if (!havefilter) {
+ /* We do not have the required filter, so we assume that
+ rendering this job is supposed to be done on a remote
+ server. So we do not define a renderer command line and
+ embed only the option settings (as we had a PostScript
+ printer). This way the settings are taken into account
+ when the job is rendered on the server.*/
+ _log("CUPS filter for this PPD file not found - assuming that job will "
+ "be rendered on a remote server. Only the PostScript of the options"
+ "will be inserted into the PostScript data stream.\n");
+ }
+ else {
+ /* use gstoraster filter if available, otherwise run Ghostscript
+ directly */
+ havegstoraster = 0;
+ path = cupsfilterpath;
+ while ((path = strncpy_tochar(tmp, path, 1024, ":"))) {
+ strlcat(tmp, "/gstoraster", 1024);
+ if (access(tmp, X_OK) == 0) {
+ havegstoraster = 1;
+ strlcpy(gstoraster, tmp, 256);
+ strlcat(gstoraster, " 0 '' '' 0 '%X'", 256);
+ break;
+ }
+ }
+ if (!havegstoraster) {
+ const char **qualifier = NULL;
+ const char *icc_profile = NULL;
+
+ if (!cm_disabled) {
+ qualifier = get_ppd_qualifier();
+ _log("INFO: Using qualifer: '%s.%s.%s'\n",
+ qualifier[0], qualifier[1], qualifier[2]);
+
+ cmGetPrinterIccProfile(getenv("PRINTER"),
+ (char **)&icc_profile, 0);
+
+ /* fall back to PPD */
+ if (icc_profile == NULL) {
+ _log("INFO: need to look in PPD for matching qualifer\n");
+ icc_profile = get_icc_profile_for_qualifier(qualifier);
+ }
+ }
+
+ /* ICC profile is specified for Ghostscript unless
+ "cm-calibration" option was passed in foomatic-rip */
+ if (icc_profile != NULL)
+ snprintf(cmd, sizeof(cmd),
+ "-sOutputICCProfile='%s'", icc_profile);
+ else
+ cmd[0] = '\0';
+
+ snprintf(gstoraster, sizeof(gstoraster), "gs -dQUIET -dDEBUG -dPARANOIDSAFER -dNOPAUSE -dBATCH -dNOINTERPOLATE -dNOMEDIAATTRS -sDEVICE=cups -dShowAcroForm %s -sOutputFile=- -", cmd);
+ }
+
+ /* build Ghostscript/CUPS driver command line */
+ snprintf(cmd, 1024, "%s | %s", gstoraster, cupsfilter);
+ _log("INFO: Using command line: %s\n", cmd);
+
+ /* Set environment variables */
+ setenv("PPD", job->ppdfile, 1);
+ }
+ }
+
+ /* Was the RIP command line defined in the PPD file? If not, we assume a PostScript printer
+ and do not render/translate the input data */
+ if (isempty(cmd)) {
+ strcpy(cmd, "cat%A%B%C%D%E%F%G%H%I%J%K%L%M%Z");
+ if (dontparse) {
+ /* No command line, no options, we have a raw queue, don't check
+ whether the input is PostScript, simply pass the input data to
+ the backend.*/
+ dontparse = 2;
+ strcpy(printer_model, "Raw queue");
+ }
+ }
+
+ /* Summary for debugging */
+ _log("\nParameter Summary\n"
+ "-----------------\n\n"
+ "Spooler: %s\n"
+ "Printer: %s\n"
+ "Shell: %s\n"
+ "PPD file: %s\n"
+ "ATTR file: %s\n"
+ "Printer model: %s\n",
+ spooler_name(spooler), job->printer, get_modern_shell(), job->ppdfile, attrpath, printer_model);
+ /* Print the options string only in debug mode, Mac OS X adds very many
+ options so that CUPS cannot handle the output of the option string
+ in its log files. If CUPS encounters a line with more than 1024 characters
+ sent into its log files, it aborts the job with an error.*/
+ if (debug || spooler != SPOOLER_CUPS)
+ _log("Options: %s\n", job->optstr->data);
+ _log("Job title: %s\n", job->title);
+ _log("File(s) to be printed:\n");
+ _log("%s\n\n", filelist->data);
+ if (getenv("GS_LIB"))
+ _log("Ghostscript extra search path ('GS_LIB'): %s\n", getenv("GS_LIB"));
+
+ /* Process options from command line */
+ optionset_copy_values(optionset("default"), optionset("userval"));
+ process_cmdline_options();
+
+ /* no postpipe for CUPS , even if one is defined in the PPD file */
+ if (spooler == SPOOLER_CUPS )
+ dstrclear(postpipe);
+
+ if (postpipe->len)
+ _log("Ouput will be redirected to:\n%s\n", postpipe);
+
+
+ filename = strtok_r(filelist->data, " ", &p);
+ while (filename) {
+ _log("\n================================================\n\n"
+ "File: %s\n\n"
+ "================================================\n\n", filename);
+
+ /* Do we have a raw queue? */
+ if (dontparse == 2) {
+ /* Raw queue, simply pass the input into the postpipe (or to STDOUT
+ when there is no postpipe) */
+ _log("Raw printing, executing \"cat %s\"\n\n");
+ snprintf(tmp, 1024, "cat %s", postpipe->data);
+ run_system_process("raw-printer", tmp);
+ continue;
+ }
+
+ /* First, for arguments with a default, stick the default in as
+ the initial value for the "header" option set, this option set
+ consists of the PPD defaults, the options specified on the
+ command line, and the options set in the header part of the
+ PostScript file (all before the first page begins). */
+ optionset_copy_values(optionset("userval"), optionset("header"));
+
+ if (!print_file(filename, 1))
+ rip_die(EXIT_PRNERR_NORETRY, "Could not print file %s\n", filename);
+ filename = strtok_r(NULL, " ", &p);
+ }
+
+ /* Close the last input file */
+ fclose(stdin);
+
+ /* TODO dump everything in $dat when debug is turned on (necessary?) */
+
+ _log("\nClosing foomatic-rip.\n");
+
+
+ /* Cleanup */
+ free_job(job);
+ free_dstr(filelist);
+ options_free();
+ close_log();
+
+ argv_free(jclprepend);
+ free_dstr(jclappend);
+
+ list_free(arglist);
+
+ return EXIT_PRINTED;
+}
+
diff --git a/filter/foomatic-rip/foomaticrip.h b/filter/foomatic-rip/foomaticrip.h
new file mode 100644
index 000000000..6ed2c007b
--- /dev/null
+++ b/filter/foomatic-rip/foomaticrip.h
@@ -0,0 +1,120 @@
+/* foomaticrip.h
+ *
+ * Copyright (C) 2008 Till Kamppeter <till.kamppeter@gmail.com>
+ * Copyright (C) 2008 Lars Uebernickel <larsuebernickel@gmx.de>
+ *
+ * This file is part of foomatic-rip.
+ *
+ * Foomatic-rip 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Foomatic-rip 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 Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef foomatic_h
+#define foomatic_h
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include "config.h"
+
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <limits.h>
+
+/* This is the location of the debug logfile (and also the copy of the
+ * processed PostScript data) in case you have enabled debugging above.
+ * The logfile will get the extension ".log", the PostScript data ".ps".
+ */
+#ifndef LOG_FILE
+#define LOG_FILE "/tmp/foomatic-rip"
+#endif
+
+
+/* Constants used by this filter
+ *
+ * Error codes, as some spoolers behave different depending on the reason why
+ * the RIP failed, we return an error code.
+ */
+#define EXIT_PRINTED 0 /* file was printed normally */
+#define EXIT_PRNERR 1 /* printer error occured */
+#define EXIT_PRNERR_NORETRY 2 /* printer error with no hope of retry */
+#define EXIT_JOBERR 3 /* job is defective */
+#define EXIT_SIGNAL 4 /* terminated after catching signal */
+#define EXIT_ENGAGED 5 /* printer is otherwise engaged (connection refused) */
+#define EXIT_STARVED 6 /* starved for system resources */
+#define EXIT_PRNERR_NORETRY_ACCESS_DENIED 7 /* bad password? bad port permissions? */
+#define EXIT_PRNERR_NOT_RESPONDING 8 /* just doesn't answer at all (turned off?) */
+#define EXIT_PRNERR_NORETRY_BAD_SETTINGS 9 /* interface settings are invalid */
+#define EXIT_PRNERR_NO_SUCH_ADDRESS 10 /* address lookup failed, may be transient */
+#define EXIT_PRNERR_NORETRY_NO_SUCH_ADDRESS 11 /* address lookup failed, not transient */
+#define EXIT_INCAPABLE 50 /* printer wants (lacks) features or resources */
+
+
+/* Supported spoolers are currently:
+ *
+ * cups - CUPS - Common Unix Printing System
+ * direct - Direct, spooler-less printing
+ */
+#define SPOOLER_CUPS 1
+#define SPOOLER_DIRECT 2
+
+/* The spooler from which foomatic-rip was called. set in main() */
+extern int spooler;
+
+#ifndef PATH_MAX
+#define PATH_MAX 4096
+#endif
+#define CMDLINE_MAX 65536
+
+typedef struct {
+ char printer[256];
+ char id[128];
+ char user[128];
+ char host[128];
+ char title[2048];
+ char ppdfile[2048];
+ char copies[128];
+ int rbinumcopies;
+ struct dstr *optstr;
+ time_t time;
+} jobparams_t;
+
+
+jobparams_t * get_current_job();
+
+void _log(const char* msg, ...);
+int redirect_log_to_stderr();
+void rip_die(int status, const char *msg, ...);
+
+const char * get_modern_shell();
+FILE * open_postpipe();
+
+extern struct dstr *currentcmd;
+extern struct dstr *jclappend;
+extern char **jclprepend;
+extern int jobhasjcl;
+extern char cupsfilterpath[PATH_MAX];
+extern int debug;
+extern int do_docs;
+extern char printer_model[];
+extern int dontparse;
+extern int pdfconvertedtops;
+extern char gspath[PATH_MAX];
+extern char echopath[PATH_MAX];
+
+#endif
+
diff --git a/filter/foomatic-rip/options.c b/filter/foomatic-rip/options.c
new file mode 100644
index 000000000..325a0a626
--- /dev/null
+++ b/filter/foomatic-rip/options.c
@@ -0,0 +1,2264 @@
+/* options.c
+ *
+ * Copyright (C) 2008 Till Kamppeter <till.kamppeter@gmail.com>
+ * Copyright (C) 2008 Lars Uebernickel <larsuebernickel@gmx.de>
+ *
+ * This file is part of foomatic-rip.
+ *
+ * Foomatic-rip 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Foomatic-rip 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 Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "foomaticrip.h"
+#include "options.h"
+#include "util.h"
+#include <stdlib.h>
+#include <ctype.h>
+#include <assert.h>
+#include <regex.h>
+#include <string.h>
+#include <math.h>
+
+/* qualifier -> filename mapping entry */
+typedef struct icc_mapping_entry_s {
+ char *qualifier;
+ char *filename;
+} icc_mapping_entry_t;
+
+/* Values from foomatic keywords in the ppd file */
+char printer_model [256];
+char printer_id [256];
+char driver [128];
+char cmd [4096];
+char cmd_pdf [4096];
+dstr_t *postpipe = NULL; /* command into which the output of this
+ filter should be piped */
+char cupsfilter [256];
+int jobentitymaxlen = 0;
+int userentitymaxlen = 0;
+int hostentitymaxlen = 0;
+int titleentitymaxlen = 0;
+int optionsentitymaxlen = 0;
+
+/* JCL prefix to put before the JCL options
+ (Can be modified by a "*JCLBegin:" keyword in the ppd file): */
+char jclbegin[256] = "\033%-12345X@PJL\n";
+
+/* JCL command to switch the printer to the PostScript interpreter
+ (Can be modified by a "*JCLToPSInterpreter:" keyword in the PPD file): */
+char jcltointerpreter[256] = "";
+
+/* JCL command to close a print job
+ (Can be modified by a "*JCLEnd:" keyword in the PPD file): */
+char jclend[256] = "\033%-12345X@PJL RESET\n";
+
+/* Prefix for starting every JCL command
+ (Can be modified by "*FoomaticJCLPrefix:" keyword in the PPD file): */
+char jclprefix[256] = "@PJL ";
+int jclprefixset = 0;
+
+dstr_t *prologprepend;
+dstr_t *setupprepend;
+dstr_t *pagesetupprepend;
+
+
+list_t *qualifier_data = NULL;
+char **qualifier = NULL;
+
+option_t *optionlist = NULL;
+option_t *optionlist_sorted_by_order = NULL;
+
+int optionset_alloc, optionset_count;
+char **optionsets;
+
+
+const char * get_icc_profile_for_qualifier(const char **qualifier)
+{
+ char tmp[1024];
+ char *profile = NULL;
+ listitem_t *i;
+ icc_mapping_entry_t *entry;
+
+ /* no data */
+ if (qualifier_data == NULL)
+ goto out;
+
+ /* search list for qualifier */
+ snprintf(tmp, sizeof(tmp), "%s.%s.%s",
+ qualifier[0], qualifier[1], qualifier[2]);
+ for (i = qualifier_data->first; i != NULL; i = i->next) {
+ entry = (icc_mapping_entry_t *) i->data;
+ if (strcmp(entry->qualifier, tmp) == 0) {
+ profile = entry->filename;
+ break;
+ }
+ }
+out:
+ return profile;
+}
+
+/* a selector is a general tri-dotted specification.
+ * The 2nd and 3rd elements of the qualifier are optionally modified by
+ * cupsICCQualifier2 and cupsICCQualifier3:
+ *
+ * [Colorspace].[{cupsICCQualifier2}].[{cupsICCQualifier3}]
+ */
+const char **
+get_ppd_qualifier ()
+{
+ return (const char**) qualifier;
+}
+
+const char * type_name(int type)
+{
+ switch (type) {
+ case TYPE_NONE:
+ return "none";
+ case TYPE_ENUM:
+ return "enum";
+ case TYPE_PICKMANY:
+ return "pickmany";
+ case TYPE_BOOL:
+ return "bool";
+ case TYPE_INT:
+ return "int";
+ case TYPE_FLOAT:
+ return "float";
+ case TYPE_STRING:
+ return "string";
+ };
+ _log("type '%d' does not exist\n", type);
+ return NULL;
+}
+
+int type_from_string(const char *typestr)
+{
+ int type = TYPE_NONE;
+
+ /* Official PPD options */
+ if (!strcmp(typestr, "PickOne"))
+ type = TYPE_ENUM;
+ else if (!strcmp(typestr, "PickMany"))
+ type = TYPE_PICKMANY;
+ else if (!strcmp(typestr, "Boolean"))
+ type = TYPE_BOOL;
+
+ /* FoomaticRIPOption */
+ else if (strcasecmp(typestr, "enum") == 0)
+ type = TYPE_ENUM;
+ else if (strcasecmp(typestr, "pickmany") == 0)
+ type = TYPE_PICKMANY;
+ else if (strcasecmp(typestr, "bool") == 0)
+ type = TYPE_BOOL;
+ else if (strcasecmp(typestr, "int") == 0)
+ type = TYPE_INT;
+ else if (strcasecmp(typestr, "float") == 0)
+ type = TYPE_FLOAT;
+ else if (strcasecmp(typestr, "string") == 0)
+ type = TYPE_STRING;
+ else if (strcasecmp(typestr, "password") == 0)
+ type = TYPE_PASSWORD;
+
+ return type;
+}
+
+char style_from_string(const char *style)
+{
+ char r = '\0';
+ if (strcmp(style, "PS") == 0)
+ r = 'G';
+ else if (strcmp(style, "CmdLine") == 0)
+ r = 'C';
+ else if (strcmp(style, "JCL") == 0)
+ r = 'J';
+ else if (strcmp(style, "Composite") == 0)
+ r = 'X';
+ return r;
+}
+
+int section_from_string(const char *value)
+{
+ if (!strcasecmp(value, "AnySetup"))
+ return SECTION_ANYSETUP;
+ else if (!strcasecmp(value, "PageSetup"))
+ return SECTION_PAGESETUP;
+ else if (!strcasecmp(value, "Prolog"))
+ return SECTION_PROLOG;
+ else if (!strcasecmp(value, "DocumentSetup"))
+ return SECTION_DOCUMENTSETUP;
+ else if (!strcasecmp(value, "JCLSetup"))
+ return SECTION_JCLSETUP;
+
+ _log("Unknown section: \"%s\"\n", value);
+ return 0;
+}
+
+void options_init()
+{
+ optionset_alloc = 8;
+ optionset_count = 0;
+ optionsets = calloc(optionset_alloc, sizeof(char *));
+
+ prologprepend = create_dstr();
+ setupprepend = create_dstr();
+ pagesetupprepend = create_dstr();
+}
+
+static void free_param(param_t *param)
+{
+ if (param->allowedchars) {
+ regfree(param->allowedchars);
+ free(param->allowedchars);
+ }
+
+ if (param->allowedregexp) {
+ regfree(param->allowedregexp);
+ free(param->allowedregexp);
+ }
+
+ free(param);
+}
+
+/*
+ * Values
+ */
+
+static void free_value(value_t *val)
+{
+ if (val->value)
+ free(val->value);
+ free(val);
+}
+
+
+/*
+ * Options
+ */
+static void free_option(option_t *opt)
+{
+ choice_t *choice;
+ param_t *param;
+ value_t *value;
+
+ free(opt->custom_command);
+ free(opt->proto);
+
+ while (opt->valuelist) {
+ value = opt->valuelist;
+ opt->valuelist = opt->valuelist->next;
+ free_value(value);
+ }
+ while (opt->choicelist) {
+ choice = opt->choicelist;
+ opt->choicelist = opt->choicelist->next;
+ free(choice);
+ }
+ while (opt->paramlist) {
+ param = opt->paramlist;
+ opt->paramlist = opt->paramlist->next;
+ free_param(param);
+ }
+ if (opt->foomatic_param)
+ free_param(opt->foomatic_param);
+
+ free(opt);
+}
+
+void options_free()
+{
+ option_t *opt;
+ int i;
+ listitem_t *item;
+ icc_mapping_entry_t *entry;
+
+ for (i = 0; i < optionset_count; i++)
+ free(optionsets[i]);
+ free(optionsets);
+ optionsets = NULL;
+ optionset_alloc = 0;
+ optionset_count = 0;
+
+ if (qualifier_data) {
+ for (item = qualifier_data->first; item != NULL; item = item->next) {
+ entry = (icc_mapping_entry_t *) item->data;
+ free(entry->qualifier);
+ free(entry->filename);
+ free(entry);
+ }
+ list_free(qualifier_data);
+ }
+
+ for (i=0; i<3; i++)
+ free(qualifier[i]);
+ free(qualifier);
+
+ while (optionlist) {
+ opt = optionlist;
+ optionlist = optionlist->next;
+ free_option(opt);
+ }
+
+ if (postpipe)
+ free_dstr(postpipe);
+
+ free_dstr(prologprepend);
+ free_dstr(setupprepend);
+ free_dstr(pagesetupprepend);
+}
+
+size_t option_count()
+{
+ option_t *opt;
+ size_t cnt = 0;
+
+ for (opt = optionlist; opt; opt = opt->next)
+ cnt++;
+ return cnt;
+}
+
+option_t * find_option(const char *name)
+{
+ option_t *opt;
+
+ /* PageRegion and PageSize are the same options, just store one of them */
+ if (!strcasecmp(name, "PageRegion"))
+ return find_option("PageSize");
+
+ for (opt = optionlist; opt; opt = opt->next) {
+ if ((!strcasecmp(opt->name, name)) ||
+ ((!strcasecmp(opt->name, &name[2])) &&
+ (!prefixcasecmp(name, "no"))))
+ return opt;
+ }
+ return NULL;
+}
+
+option_t * assure_option(const char *name)
+{
+ option_t *opt, *last;
+
+ if ((opt = find_option(name)))
+ return opt;
+
+ opt = calloc(1, sizeof(option_t));
+
+ /* PageRegion and PageSize are the same options, just store one of them */
+ if (!strcmp(name, "PageRegion"))
+ strlcpy(opt->name, "PageSize", 128);
+ else
+ strlcpy(opt->name, name, 128);
+
+ /* set varname */
+ strcpy(opt->varname, opt->name);
+ strrepl(opt->varname, "-/.", '_');
+
+ /* Default execution style is 'G' (PostScript) since all arguments for
+ which we don't find "*Foomatic..." keywords are usual PostScript options */
+ opt->style = 'G';
+
+ opt->type = TYPE_NONE;
+
+ /* append opt to optionlist */
+ if (optionlist) {
+ for (last = optionlist; last->next; last = last->next);
+ last->next = opt;
+ }
+ else
+ optionlist = opt;
+
+ /* prepend opt to optionlist_sorted_by_order
+ (0 is always at the beginning) */
+ if (optionlist_sorted_by_order) {
+ opt->next_by_order = optionlist_sorted_by_order;
+ optionlist_sorted_by_order = opt;
+ }
+ else {
+ optionlist_sorted_by_order = opt;
+ }
+
+ _log("Added option %s\n", opt->name);
+ return opt;
+}
+
+/* This functions checks if "opt" is named "name", or if it has any
+ alternative names "name" (e.g. PageSize / PageRegion) */
+int option_has_name(option_t *opt, const char *name)
+{
+ if (!strcmp(opt->name, name))
+ return 1;
+
+ if (!strcmp(opt->name, "PageSize") && !strcmp(name, "PageRegion"))
+ return 1;
+
+ return 0;
+}
+
+int option_is_composite(option_t *opt)
+{
+ return opt ? (opt->style == 'X') : 0;
+}
+
+int option_is_ps_command(option_t *opt)
+{
+ return opt->style == 'G';
+}
+
+int option_is_jcl_arg(option_t *opt)
+{
+ return opt->style == 'J';
+}
+
+int option_is_commandline_arg(option_t *opt)
+{
+ return opt->style == 'C';
+}
+
+int option_get_section(option_t *opt)
+{
+ return opt->section;
+}
+
+static value_t * option_find_value(option_t *opt, int optionset)
+{
+ value_t *val;
+
+ if (!opt)
+ return NULL;
+
+ for (val = opt->valuelist; val; val = val->next) {
+ if (val->optionset == optionset)
+ return val;
+ }
+ return NULL;
+}
+
+static value_t * option_assure_value(option_t *opt, int optionset)
+{
+ value_t *val, *last;
+ val = option_find_value(opt, optionset);
+ if (!val) {
+ val = calloc(1, sizeof(value_t));
+ val->optionset = optionset;
+
+ /* append to opt->valuelist */
+ if (opt->valuelist) {
+ for (last = opt->valuelist; last->next; last = last->next);
+ last->next = val;
+ }
+ else
+ opt->valuelist = val;
+ }
+ return val;
+}
+
+static param_t * option_find_param_index(option_t *opt, const char *name, int *idx)
+{
+ param_t *param;
+ int i;
+ for (param = opt->paramlist, i = 0; param; param = param->next, i += 1) {
+ if (!strcasecmp(param->name, name)) {
+ if (idx)
+ *idx = i;
+ return param;
+ }
+ }
+ if (idx)
+ *idx = -1;
+ return 0;
+}
+
+static choice_t * option_find_choice(option_t *opt, const char *name)
+{
+ choice_t *choice;
+ assert(opt && name);
+ for (choice = opt->choicelist; choice; choice = choice->next) {
+ if (!strcasecmp(choice->value, name))
+ return choice;
+ }
+ return NULL;
+}
+
+void free_paramvalues(option_t *opt, char **paramvalues)
+{
+ int i;
+ if (!paramvalues)
+ return;
+ for (i = 0; i < opt->param_count; i++)
+ free(paramvalues[i]);
+ free(paramvalues);
+}
+
+char * get_valid_param_string(option_t *opt, param_t *param, const char *str)
+{
+ char *result;
+ int i, imin, imax;
+ float f, fmin, fmax;
+ size_t len;
+
+ switch (param->type) {
+ case TYPE_INT:
+ i = atoi(str);
+ imin = !isempty(param->min) ? atoi(param->min) : -999999;
+ imax = !isempty(param->max) ? atoi(param->max) : 1000000;
+ if (i < imin) {
+ _log("Value \"%s\" for option \"%s\", parameter \"%s\" is smaller than the minimum value \"%d\"\n",
+ str, opt->name, param->name, imin);
+ return NULL;
+ }
+ else if (i > imax) {
+ _log("Value \"%s\" for option \"%s\", parameter \"%s\" is larger than the maximum value \"%d\"\n",
+ str, opt->name, param->name, imax);
+ return NULL;
+ }
+ result = malloc(32);
+ snprintf(result, 32, "%d", i);
+ return result;
+
+ case TYPE_FLOAT:
+ case TYPE_CURVE:
+ case TYPE_INVCURVE:
+ case TYPE_POINTS:
+ f = atof(str);
+ fmin = !isempty(param->min) ? atof(param->min) : -999999.0;
+ fmax = !isempty(param->max) ? atof(param->max) : 1000000.0;
+ if (f < fmin) {
+ _log("Value \"%s\" for option \"%s\", parameter \"%s\" is smaller than the minimum value \"%d\"\n",
+ str, opt->name, param->name, fmin);
+ return NULL;
+ }
+ else if (f > fmax) {
+ _log("Value \"%s\" for option \"%s\", parameter \"%s\" is larger than the maximum value \"%d\"\n",
+ str, opt->name, param->name, fmax);
+ return NULL;
+ }
+ result = malloc(32);
+ snprintf(result, 32, "%f", f);
+ return result;
+
+ case TYPE_STRING:
+ case TYPE_PASSWORD:
+ case TYPE_PASSCODE:
+ if (param->allowedchars &&
+ regexec(param->allowedchars, str, 0, NULL, 0) != 0) {
+ _log("Custom string \"%s\" for \"%s\", parameter \"%s\" contains illegal characters.\n",
+ str, opt->name, param->name);
+ return NULL;
+ }
+ if (param->allowedregexp &&
+ regexec(param->allowedregexp, str, 0, NULL, 0) != 0) {
+ _log("Custom string \"%s\" for \"%s\", parameter \"%s\" does not match the allowed regexp.\n",
+ str, opt->name, param->name);
+ return NULL;
+ }
+ len = strlen(str);
+ if (!isempty(param->min) && len < atoi(param->min)) {
+ _log("Custom value \"%s\" is too short for option \"%s\", parameter \"%s\".\n",
+ str, opt->name, param->name);
+ return NULL;
+ }
+ if (!isempty(param->max) && len > atoi(param->max)) {
+ _log("Custom value \"%s\" is too long for option \"%s\", parameter \"%s\".\n",
+ str, opt->name, param->name);
+ return NULL;
+ }
+ return strdup(str);
+ }
+ return NULL;
+}
+
+char * get_valid_param_string_int(option_t *opt, param_t *param, int value)
+{
+ char str[20];
+ snprintf(str, 20, "%d", value);
+ return get_valid_param_string(opt, param, str);
+}
+
+char * get_valid_param_string_float(option_t *opt, param_t *param, float value)
+{
+ char str[20];
+ snprintf(str, 20, "%f", value);
+ return get_valid_param_string(opt, param, str);
+}
+
+float convert_to_points(float f, const char *unit)
+{
+ if (!strcasecmp(unit, "pt"))
+ return roundf(f);
+ if (!strcasecmp(unit, "in"))
+ return roundf(f * 72.0);
+ if (!strcasecmp(unit, "cm"))
+ return roundf(f * 72.0 / 2.54);
+ if (!strcasecmp(unit, "mm"))
+ return roundf(f * 72.0 / 25.4);
+
+ _log("Unknown unit: \"%s\"\n", unit);
+ return roundf(f);
+}
+
+static char ** paramvalues_from_string(option_t *opt, const char *str)
+{
+ char ** paramvalues;
+ int n, i;
+ param_t *param;
+ char *copy, *cur, *p;
+ float width, height;
+ char unit[3];
+
+ if (!strcmp(opt->name, "PageSize"))
+ {
+ if (startswith(str, "Custom."))
+ str = &str[7];
+ /* 'unit' is optional, if it is not given, 'pt' is assumed */
+ n = sscanf(str, "%fx%f%2s", &width, &height, unit);
+ if (n > 1) {
+ if (n == 3) {
+ width = convert_to_points(width, unit);
+ height = convert_to_points(height, unit);
+ }
+ paramvalues = calloc(opt->param_count, sizeof(char*));
+ for (param = opt->paramlist, i = 0; param; param = param->next, i++) {
+ if (!strcasecmp(param->name, "width"))
+ paramvalues[i] = get_valid_param_string_int(opt, param, (int)width);
+ else if (!strcasecmp(param->name, "height"))
+ paramvalues[i] = get_valid_param_string_int(opt, param, (int)height);
+ else
+ paramvalues[i] = !isempty(param->min) ? param->min : "-999999";
+ if (!paramvalues[i]) {
+ free_paramvalues(opt, paramvalues);
+ return NULL;
+ }
+ }
+ return paramvalues;
+ }
+ }
+
+ if (opt->param_count == 1) {
+ paramvalues = malloc(sizeof(char*));
+ paramvalues[0] = get_valid_param_string(opt, opt->paramlist,
+ startswith(str, "Custom.") ? &str[7] : str);
+ if (!paramvalues[0]) {
+ free(paramvalues);
+ return NULL;
+ }
+ }
+ else {
+ if (!(p = strchr(str, '{')))
+ return NULL;
+ paramvalues = calloc(opt->param_count, sizeof(char*));
+ copy = strdup(p +1);
+ for (cur = strtok(copy, " \t}"); cur; cur = strtok(NULL, " \t}")) {
+ p = strchr(cur, '=');
+ if (!p)
+ continue;
+ *p++ = '\0';
+ if ((param = option_find_param_index(opt, cur, &i)))
+ paramvalues[i] = get_valid_param_string(opt, param, p);
+ else
+ _log("Could not find param \"%s\" for option \"%s\"\n",
+ cur, opt->name);
+ }
+ free(copy);
+
+ /* check if all params have been set */
+ for (i = 0; i < opt->param_count; i++) {
+ if (!paramvalues[i]) {
+ free_paramvalues(opt, paramvalues);
+ return NULL;
+ }
+ }
+ }
+ return paramvalues;
+}
+
+char * paramvalues_to_string(option_t *opt, char **paramvalues)
+{
+ int i;
+ param_t *param;
+ dstr_t *res = create_dstr();
+ char *data;
+
+ if (opt->param_count < 1) {
+ free (res);
+ return NULL;
+ }
+
+ if (opt->param_count == 1) {
+ param = opt->paramlist;
+ dstrcpyf(res, "Custom.%s", paramvalues[0]);
+ }
+ else {
+ dstrcpyf(res, "{%s=%s", opt->paramlist->name, paramvalues[0]);
+ param = opt->paramlist->next;
+ i = 1;
+ while (param) {
+ dstrcatf(res, " %s=%s", param->name, paramvalues[i]);
+ i++;
+ param = param->next;
+ }
+ dstrcat(res, "}");
+ }
+ /* only free dstr struct, NOT the string data */
+ data = res->data;
+ free(res);
+ return data;
+}
+
+char * get_valid_value_string(option_t *opt, const char *value)
+{
+ char *res;
+ choice_t *choice;
+ char **paramvalues;
+
+ if (!value)
+ return NULL;
+
+ if (startswith(value, "From") && option_is_composite(find_option(&value[4])))
+ return strdup(value);
+
+ if (opt->type == TYPE_BOOL) {
+ if (is_true_string(value))
+ return strdup("1");
+ else if (is_false_string(value))
+ return strdup("0");
+ else {
+ _log("Could not interpret \"%s\" as boolean value for option \"%s\".\n", value, opt->name);
+ return NULL;
+ }
+ }
+
+ /* Check if "value" is a predefined choice (except for "Custom", which is
+ * not really a predefined choice, but an error if used without further
+ * parameters) */
+ if ((strcmp(value, "Custom") != 0 || strcmp(opt->name, "PageSize") == 0) &&
+ (choice = option_find_choice(opt, value)))
+ return strdup(choice->value);
+
+ if (opt->type == TYPE_ENUM) {
+ if (!strcasecmp(value, "none"))
+ return strdup("None");
+
+ /*
+ * CUPS assumes that options with the choices "Yes", "No", "On", "Off",
+ * "True", or "False" are boolean options and maps "-o Option=On" to
+ * "-o Option" and "-o Option=Off" to "-o noOption", which foomatic-rip
+ * maps to "0" and "1". So when "0" or "1" is unavailable in the
+ * option, we try "Yes", "No", "On", "Off", "True", and "False".
+ */
+ if (is_true_string(value)) {
+ for (choice = opt->choicelist; choice; choice = choice->next) {
+ if (is_true_string(choice->value))
+ return strdup(choice->value);
+ }
+ }
+ else if (is_false_string(value)) {
+ for (choice = opt->choicelist; choice; choice = choice->next) {
+ if (is_false_string(choice->value))
+ return strdup(choice->value);
+ }
+ }
+ }
+
+ /* Custom value */
+ if (opt->paramlist) {
+ paramvalues = paramvalues_from_string(opt, value);
+ if (paramvalues) {
+ res = paramvalues_to_string(opt, paramvalues);
+ free(paramvalues);
+ return (startswith(res, "Custom.") ? strdup(&res[7]) : strdup(res));
+ }
+ }
+ else if (opt->foomatic_param)
+ return get_valid_param_string(opt, opt->foomatic_param,
+ startswith(value, "Custom.") ? &value[7] : value);
+
+ /* Return the default value */
+ return NULL;
+}
+
+/* Returns the current value for 'opt' in 'optionset'. */
+const char * option_get_value(option_t *opt, int optionset)
+{
+ value_t *val = option_find_value(opt, optionset);
+ return val ? val->value : NULL;
+}
+
+/* Returns non-zero if the foomatic prototype should be used for that
+ * optionset, otherwise the custom_command will be used */
+int option_use_foomatic_prototype(option_t *opt)
+{
+ /* Only PostScript and JCL options can be CUPS custom options */
+ if (!option_is_ps_command(opt) && !option_is_jcl_arg(opt))
+ return 1;
+
+ /* if only one of them exists, take that one */
+ if (opt->custom_command && !opt->proto)
+ return 0;
+ if (!opt->custom_command && opt->proto)
+ return 1;
+ return 0;
+}
+
+void build_foomatic_custom_command(dstr_t *cmd, option_t *opt, const char *values)
+{
+ if (!opt->proto && !strcmp(opt->name, "PageSize"))
+ {
+ choice_t *choice = option_find_choice(opt, "Custom");
+ char ** paramvalues = paramvalues_from_string(opt, values);
+ char width[30], height[30];
+ int pos;
+
+ assert(choice);
+
+ /* Get rid of the trailing ".00000", it confuses ghostscript */
+ snprintf(width, 20, "%d", atoi(paramvalues[0]));
+ snprintf(height, 20, "%d", atoi(paramvalues[1]));
+
+ dstrcpy(cmd, choice->command);
+
+ if ((pos = dstrreplace(cmd, "%0", width, 0)) < 0)
+ pos = dstrreplace(cmd, "0", width, 0);
+
+ if (dstrreplace(cmd, "%1", height, pos) < 0)
+ dstrreplace(cmd, "0", height, pos);
+
+ free_paramvalues(opt, paramvalues);
+ }
+ else
+ {
+ dstrcpy(cmd, opt->proto);
+ /* use replace instead of printf-style because opt->proto could contain
+ other format strings */
+ dstrreplace(cmd, "%s", values, 0);
+ }
+}
+
+void build_cups_custom_ps_command(dstr_t *cmd, option_t *opt, const char *values)
+{
+ param_t *param;
+ int i;
+ char **paramvalues = paramvalues_from_string(opt, values);
+
+ dstrclear(cmd);
+ for (param = opt->paramlist, i = 0; param; param = param->next, i++)
+ dstrcatf(cmd, "%s ", paramvalues[i]);
+ dstrcat(cmd, opt->custom_command);
+ free_paramvalues(opt, paramvalues);
+}
+
+void build_cups_custom_jcl_command(dstr_t *cmd, option_t *opt, const char *values)
+{
+ param_t *param;
+ int i;
+ char orderstr[8];
+ char **paramvalues = paramvalues_from_string(opt, values);
+
+ dstrcpy(cmd, opt->custom_command);
+ for (param = opt->paramlist, i = 0; param; param = param->next, i++) {
+ snprintf(orderstr, 8, "\\%d", param->order);
+ dstrreplace(cmd, orderstr, paramvalues[i], 0);
+ }
+ free_paramvalues(opt, paramvalues);
+}
+
+int composite_get_command(dstr_t *cmd, option_t *opt, int optionset, int section)
+{
+ char *copy, *cur, *p;
+ option_t *dep;
+ const char * valstr;
+ dstr_t *depcmd;
+
+ dstrclear(cmd);
+ if (!option_is_composite(opt))
+ return 0;
+
+ if (!(valstr = option_get_value(opt, optionset)))
+ return 0;
+
+ depcmd = create_dstr();
+ copy = strdup(valstr);
+ /* Dependent options have been set to the right value in composite_set_values,
+ so just find out which options depend on this composite and get their commands
+ for "optionset" with option_get_command() */
+ for (cur = strtok(copy, " \t"); cur; cur = strtok(NULL, " \t")) {
+ dstrclear(depcmd);
+ if ((p = strchr(cur, '='))) {
+ *p++ = '\0';
+ if ((dep = find_option(cur)))
+ option_get_command(depcmd, dep, optionset, section);
+ }
+ else if (startswith(cur, "no") || startswith(cur, "No")) {
+ if ((dep = find_option(&cur[2])))
+ option_get_command(depcmd, dep, optionset, section);
+ }
+ else {
+ if ((dep = find_option(cur)))
+ option_get_command(depcmd, dep, optionset, section);
+ }
+ if (depcmd->len)
+ dstrcatf(cmd, "%s\n", depcmd->data);
+ }
+ free(copy);
+ free_dstr(depcmd);
+ return cmd->len != 0;
+}
+
+int option_is_in_section(option_t *opt, int section)
+{
+ if (opt->section == section)
+ return 1;
+ if (opt->section == SECTION_ANYSETUP && (section == SECTION_PAGESETUP || section == SECTION_DOCUMENTSETUP))
+ return 1;
+ return 0;
+}
+
+int option_is_custom_value(option_t *opt, const char *value)
+{
+ if (opt->type == TYPE_BOOL || opt->type == TYPE_ENUM)
+ return 0;
+
+ return !option_has_choice(opt, value);
+}
+
+int option_get_command(dstr_t *cmd, option_t *opt, int optionset, int section)
+{
+ const char *valstr;
+ choice_t *choice = NULL;
+
+ dstrclear(cmd);
+
+ if (option_is_composite(opt))
+ return composite_get_command(cmd, opt, optionset, section);
+
+ if (section >= 0 && !option_is_in_section(opt, section))
+ return 1; /* empty command for this section */
+
+ valstr = option_get_value(opt, optionset);
+ if (!valstr)
+ return 0;
+
+ /* If the value is set to a predefined choice */
+ choice = option_find_choice(opt, valstr);
+ if (choice && (*choice->command ||
+ ((opt->type != TYPE_INT) && (opt->type != TYPE_FLOAT)))) {
+ dstrcpy(cmd, choice->command);
+ return 1;
+ }
+
+ /* Consider "None" as the empty string for string and password options */
+ if ((opt->type == TYPE_STRING || opt->type == TYPE_PASSWORD) &&
+ !strcasecmp(valstr, "None"))
+ valstr = "";
+
+ /* Custom value */
+ if (option_use_foomatic_prototype(opt))
+ build_foomatic_custom_command(cmd, opt, valstr);
+ else {
+ dstrcpy(cmd, opt->custom_command);
+ if ((option_get_section(opt) == SECTION_JCLSETUP) ||
+ (opt->style == 'J'))
+ build_cups_custom_jcl_command(cmd, opt, valstr);
+ else
+ build_cups_custom_ps_command(cmd, opt, valstr);
+ }
+
+ return cmd->len != 0;
+}
+
+void composite_set_values(option_t *opt, int optionset, const char *values)
+{
+ char *copy, *cur, *p;
+ option_t *dep;
+ value_t *val;
+
+ copy = strdup(values);
+ for (cur = strtok(copy, " \t"); cur; cur = strtok(NULL, " \t")) {
+ if ((p = strchr(cur, '='))) {
+ *p++ = '\0';
+ if ((dep = find_option(cur))) {
+ val = option_assure_value(dep, optionset);
+ val->fromoption = opt;
+ val->value = get_valid_value_string(dep, p);
+ }
+ else
+ _log("Could not find option \"%s\" (set from composite \"%s\")", cur, opt->name);
+ }
+ else if (startswith(cur, "no") || startswith(cur, "No")) {
+ if ((dep = find_option(&cur[2]))) {
+ val = option_assure_value(dep, optionset);
+ val->fromoption = opt;
+ val->value = get_valid_value_string(dep, "0");
+ }
+ }
+ else {
+ if ((dep = find_option(cur))) {
+ val = option_assure_value(dep, optionset);
+ val->fromoption = opt;
+ val->value = get_valid_value_string(dep, "1");
+ }
+ }
+ }
+ free(copy);
+}
+
+int option_set_value(option_t *opt, int optionset, const char *value)
+{
+ value_t *val = option_assure_value(opt, optionset);
+ char *newvalue;
+ choice_t *choice;
+ option_t *fromopt;
+
+ newvalue = get_valid_value_string(opt, value);
+ if (!newvalue)
+ return 0;
+
+ free(val->value);
+ val->value = NULL;
+
+ if (startswith(newvalue, "From") && (fromopt = find_option(&newvalue[4])) &&
+ option_is_composite(fromopt)) {
+ /* TODO only set the changed option, not all of them */
+ choice = option_find_choice(fromopt,
+ option_get_value(fromopt, optionset));
+
+ composite_set_values(fromopt, optionset, choice->command);
+ }
+ else {
+ val->value = newvalue;
+ }
+
+ if (option_is_composite(opt)) {
+ /* set dependent values */
+ choice = option_find_choice(opt, value);
+ if (choice && !isempty(choice->command))
+ composite_set_values(opt, optionset, choice->command);
+ }
+ return 1;
+}
+
+int option_accepts_value(option_t *opt, const char *value)
+{
+ char *val = get_valid_value_string(opt, value);
+ if (!val)
+ return 0;
+ free(val);
+ return 1;
+}
+
+int option_has_choice(option_t *opt, const char *choice)
+{
+ return option_find_choice(opt, choice) != NULL;
+}
+
+const char * option_text(option_t *opt)
+{
+ if (isempty(opt->text))
+ return opt->text;
+ return opt->text;
+}
+
+int option_type(option_t *opt)
+{
+ return opt->type;
+}
+
+void option_set_order(option_t *opt, double order)
+{
+ option_t *prev;
+
+ /* remove opt from old position */
+ if (opt == optionlist_sorted_by_order)
+ optionlist_sorted_by_order = opt->next_by_order;
+ else {
+ for (prev = optionlist_sorted_by_order;
+ prev && prev->next_by_order != opt;
+ prev = prev->next_by_order);
+ prev->next_by_order = opt->next_by_order;
+ }
+
+ opt->order = order;
+
+ /* insert into new position */
+ if (!optionlist_sorted_by_order)
+ optionlist_sorted_by_order = opt;
+ else if (optionlist_sorted_by_order->order > opt->order) {
+ opt->next_by_order = optionlist_sorted_by_order;
+ optionlist_sorted_by_order = opt;
+ }
+ else {
+ for (prev = optionlist_sorted_by_order;
+ prev->next_by_order && prev->next_by_order->order < opt->order;
+ prev = prev->next_by_order);
+ opt->next_by_order = prev->next_by_order;
+ prev->next_by_order = opt;
+ }
+}
+
+/* Set option from *FoomaticRIPOption keyword */
+void option_set_from_string(option_t *opt, const char *str)
+{
+ char type[32], style[32];
+ double order;
+ int matches;
+
+ matches = sscanf(str, "%31s %31s %c %lf", type, style, &opt->spot, &order);
+ if (matches < 3) {
+ _log("Can't read the value of *FoomaticRIPOption for \"%s\"", opt->name);
+ return;
+ }
+ opt->type = type_from_string(type);
+ opt->style = style_from_string(style);
+
+ if (matches == 4)
+ option_set_order(opt, order);
+}
+
+static choice_t * option_assure_choice(option_t *opt, const char *name)
+{
+ choice_t *choice, *last = NULL;
+
+ for (choice = opt->choicelist; choice; choice = choice->next) {
+ if (!strcasecmp(choice->value, name))
+ return choice;
+ last = choice;
+ }
+ if (!choice) {
+ choice = calloc(1, sizeof(choice_t));
+ if (last)
+ last->next = choice;
+ else
+ opt->choicelist = choice;
+ strlcpy(choice->value, name, 128);
+ }
+ return choice;
+}
+
+static void unhtmlify(char *dest, size_t size, const char *src)
+{
+ jobparams_t *job = get_current_job();
+ char *pdest = dest;
+ const char *psrc = src, *p = NULL;
+ const char *repl;
+ struct tm *t = localtime(&job->time);
+ char tmpstr[10];
+ size_t s, l, n;
+
+ while (*psrc && pdest - dest < size - 1) {
+
+ if (*psrc == '&') {
+ psrc++;
+ repl = NULL;
+ p = NULL;
+ l = 0;
+
+ /* Replace HTML/XML entities by the original characters */
+ if (!prefixcmp(psrc, "apos")) {
+ repl = "\'";
+ p = psrc + 4;
+ } else if (!prefixcmp(psrc, "quot")) {
+ repl = "\"";
+ p = psrc + 4;
+ } else if (!prefixcmp(psrc, "gt")) {
+ repl = ">";
+ p = psrc + 2;
+ } else if (!prefixcmp(psrc, "lt")) {
+ repl = "<";
+ p = psrc + 2;
+ } else if (!prefixcmp(psrc, "amp")) {
+ repl = "&";
+ p = psrc + 3;
+
+ /* Replace special entities by job->data */
+ } else if (!prefixcmp(psrc, "job")) {
+ repl = job->id;
+ p = psrc + 3;
+ if (jobentitymaxlen != 0)
+ l = jobentitymaxlen;
+ } else if (!prefixcmp(psrc, "user")) {
+ repl = job->user;
+ p = psrc + 4;
+ if (userentitymaxlen != 0)
+ l = userentitymaxlen;
+ } else if (!prefixcmp(psrc, "host")) {
+ repl = job->host;
+ p = psrc + 4;
+ if (hostentitymaxlen != 0)
+ l = hostentitymaxlen;
+ } else if (!prefixcmp(psrc, "title")) {
+ repl = job->title;
+ p = psrc + 5;
+ if (titleentitymaxlen != 0)
+ l = titleentitymaxlen;
+ } else if (!prefixcmp(psrc, "copies")) {
+ repl = job->copies;
+ p = psrc + 6;
+ } else if (!prefixcmp(psrc, "rbinumcopies")) {
+ if (job->rbinumcopies > 0) {
+ snprintf(tmpstr, 10, "%d", job->rbinumcopies);
+ repl = tmpstr;
+ }
+ else
+ repl = job->copies;
+ p = psrc + 12;
+ }
+ else if (!prefixcmp(psrc, "options")) {
+ repl = job->optstr->data;
+ p = psrc + 7;
+ if (optionsentitymaxlen != 0)
+ l = optionsentitymaxlen;
+ } else if (!prefixcmp(psrc, "year")) {
+ sprintf(tmpstr, "%04d", t->tm_year + 1900);
+ repl = tmpstr;
+ p = psrc + 4;
+ }
+ else if (!prefixcmp(psrc, "month")) {
+ sprintf(tmpstr, "%02d", t->tm_mon + 1);
+ repl = tmpstr;
+ p = psrc + 5;
+ }
+ else if (!prefixcmp(psrc, "date")) {
+ sprintf(tmpstr, "%02d", t->tm_mday);
+ repl = tmpstr;
+ p = psrc + 4;
+ }
+ else if (!prefixcmp(psrc, "hour")) {
+ sprintf(tmpstr, "%02d", t->tm_hour);
+ repl = tmpstr;
+ p = psrc + 4;
+ }
+ else if (!prefixcmp(psrc, "min")) {
+ sprintf(tmpstr, "%02d", t->tm_min);
+ repl = tmpstr;
+ p = psrc + 3;
+ }
+ else if (!prefixcmp(psrc, "sec")) {
+ sprintf(tmpstr, "%02d", t->tm_sec);
+ repl = tmpstr;
+ p = psrc + 3;
+ }
+ if (p) {
+ n = strtol(p, (char **)(&p), 0);
+ if (n != 0)
+ l = n;
+ if (*p != ';')
+ repl = NULL;
+ } else
+ repl = NULL;
+ if (repl) {
+ if ((l == 0) || (l > strlen(repl)))
+ l = strlen(repl);
+ s = size - (pdest - dest) - 1;
+ strncpy(pdest, repl, s);
+ if (s < l)
+ pdest += s;
+ else
+ pdest += l;
+ psrc = p + 1;
+ }
+ else {
+ *pdest = '&';
+ pdest++;
+ }
+ }
+ else {
+ *pdest = *psrc;
+ pdest++;
+ psrc++;
+ }
+ }
+ *pdest = '\0';
+}
+
+/*
+ * Checks whether 'code' contains active PostScript, i.e. not only comments
+ */
+static int contains_active_postscript(const char *code)
+{
+ char **line, **lines;
+ int contains_ps = 0;
+
+ if (!(lines = argv_split(code, "\n", NULL)))
+ return 0;
+
+ for (line = lines; *line && !contains_ps; line++)
+ contains_ps = !isempty(*line) &&
+ !startswith(skip_whitespace(*line), "%");
+
+ argv_free(lines);
+ return contains_ps;
+}
+
+void option_set_choice(option_t *opt, const char *name, const char *text,
+ const char *code)
+{
+ choice_t *choice;
+
+ if (opt->type == TYPE_BOOL) {
+ if (is_true_string(name))
+ choice = option_assure_choice(opt, "1");
+ else
+ choice = option_assure_choice(opt, "0");
+ }
+ else
+ choice = option_assure_choice(opt, name);
+
+ if (text)
+ strlcpy(choice->text, text, 128);
+
+ if (!code)
+ {
+ _log("Warning: No code for choice \"%s\" of option \"%s\"\n",
+ choice->text, opt->name);
+ return;
+ }
+
+ if (!startswith(code, "%% FoomaticRIPOptionSetting"))
+ unhtmlify(choice->command, 65536, code);
+}
+
+/*
+ * Parameters
+ */
+
+int param_set_allowed_chars(param_t *param, const char *value)
+{
+ char rxstr[128], tmp[128];
+
+ param->allowedchars = malloc(sizeof(regex_t));
+ unhtmlify(tmp, 128, value);
+ snprintf(rxstr, 128, "^[%s]*$", tmp);
+ if (regcomp(param->allowedchars, rxstr, 0) != 0) {
+ regfree(param->allowedchars);
+ param->allowedchars = NULL;
+ return 0;
+ }
+ return 1;
+}
+
+int param_set_allowed_regexp(param_t *param, const char *value)
+{
+ char tmp[128];
+
+ param->allowedregexp = malloc(sizeof(regex_t));
+ unhtmlify(tmp, 128, value);
+ if (regcomp(param->allowedregexp, tmp, 0) != 0) {
+ regfree(param->allowedregexp);
+ param->allowedregexp = NULL;
+ return 0;
+ }
+ return 1;
+}
+
+void option_set_custom_command(option_t *opt, const char *cmd)
+{
+ size_t len = strlen(cmd) + 50;
+ free(opt->custom_command);
+ opt->custom_command = malloc(len);
+ unhtmlify(opt->custom_command, len, cmd);
+}
+
+param_t * option_add_custom_param_from_string(option_t *opt,
+ const char *name, const char *text, const char *str)
+{
+ param_t *param = calloc(1, sizeof(param_t));
+ param_t *p;
+ char typestr[33];
+ int n;
+
+ strlcpy(param->name, name, 128);
+ strlcpy(param->text, text, 128);
+
+ n = sscanf(str, "%d%15s%19s%19s",
+ &param->order, typestr, param->min, param->max);
+
+ if (n != 4) {
+ _log("Could not parse custom parameter for '%s'!\n", opt->name);
+ free(param);
+ return NULL;
+ }
+
+ if (!strcmp(typestr, "curve"))
+ param->type = TYPE_CURVE;
+ else if (!strcmp(typestr, "invcurve"))
+ param->type = TYPE_INVCURVE;
+ else if (!strcmp(typestr, "int"))
+ param->type = TYPE_INT;
+ else if (!strcmp(typestr, "real"))
+ param->type = TYPE_FLOAT;
+ else if (!strcmp(typestr, "passcode"))
+ param->type = TYPE_PASSCODE;
+ else if (!strcmp(typestr, "password"))
+ param->type = TYPE_PASSWORD;
+ else if (!strcmp(typestr, "points"))
+ param->type = TYPE_POINTS;
+ else if (!strcmp(typestr, "string"))
+ param->type = TYPE_STRING;
+ else {
+ _log("Unknown custom parameter type for param '%s' for option '%s'\n", param->name, opt->name);
+ free(param);
+ return NULL;
+ }
+
+ param->next = NULL;
+
+ /* Insert param into opt->paramlist, sorted by order */
+ if (!opt->paramlist)
+ opt->paramlist = param;
+ else if (opt->paramlist->order > param->order) {
+ param->next = opt->paramlist;
+ opt->paramlist = param;
+ }
+ else {
+ for (p = opt->paramlist;
+ p->next && p->next->order < param->order;
+ p = p->next);
+ param->next = p->next;
+ p->next = param;
+ }
+
+ opt->param_count++;
+ return param;
+}
+
+param_t * option_assure_foomatic_param(option_t *opt)
+{
+ param_t *param;
+
+ if (opt->foomatic_param)
+ return opt->foomatic_param;
+
+ param = calloc(1, sizeof(param_t));
+ strcpy(param->name, "foomatic-param");
+ param->order = 0;
+ param->type = opt->type;
+
+ opt->foomatic_param = param;
+ return param;
+}
+
+
+/*
+ * Optionsets
+ */
+
+const char * optionset_name(int idx)
+{
+ if (idx < 0 || idx >= optionset_count) {
+ _log("Optionset with index %d does not exist\n", idx);
+ return NULL;
+ }
+ return optionsets[idx];
+}
+
+int optionset(const char * name)
+{
+ int i;
+
+ for (i = 0; i < optionset_count; i++) {
+ if (!strcmp(optionsets[i], name))
+ return i;
+ }
+
+ if (optionset_count == optionset_alloc) {
+ optionset_alloc *= 2;
+ optionsets = realloc(optionsets, optionset_alloc * sizeof(char *));
+ for (i = optionset_count; i < optionset_alloc; i++)
+ optionsets[i] = NULL;
+ }
+
+ optionsets[optionset_count] = strdup(name);
+ optionset_count++;
+ return optionset_count -1;
+}
+
+void optionset_copy_values(int src_optset, int dest_optset)
+{
+ option_t *opt;
+ value_t *val;
+
+ for (opt = optionlist; opt; opt = opt->next) {
+ for (val = opt->valuelist; val; val = val->next) {
+ if (val->optionset == src_optset) {
+ option_set_value(opt, dest_optset, val->value);
+ break;
+ }
+ }
+ }
+}
+
+void optionset_delete_values(int optionset)
+{
+ option_t *opt;
+ value_t *val, *prev_val;
+
+ for (opt = optionlist; opt; opt = opt->next) {
+ val = opt->valuelist;
+ prev_val = NULL;
+ while (val) {
+ if (val->optionset == optionset) {
+ if (prev_val)
+ prev_val->next = val->next;
+ else
+ opt->valuelist = val->next;
+ free_value(val);
+ val = prev_val ? prev_val->next : opt->valuelist;
+ break;
+ } else {
+ prev_val = val;
+ val = val->next;
+ }
+ }
+ }
+}
+
+int optionset_equal(int optset1, int optset2, int exceptPS)
+{
+ option_t *opt;
+ const char *val1, *val2;
+
+ for (opt = optionlist; opt; opt = opt->next) {
+ if (exceptPS && opt->style == 'G')
+ continue;
+
+ val1 = option_get_value(opt, optset1);
+ val2 = option_get_value(opt, optset2);
+
+ if (val1 && val2) { /* both entries exist */
+ if (strcmp(val1, val2) != 0)
+ return 0; /* but aren't equal */
+ }
+ else if (val1 || val2) /* one entry exists --> can't be equal */
+ return 0;
+ /* If no extry exists, the non-existing entries
+ * are considered as equal */
+ }
+ return 1;
+}
+
+/*
+ * read_ppd_file()
+ */
+void read_ppd_file(const char *filename)
+{
+ FILE *fh;
+ const char *tmp;
+ char *icc_qual2 = NULL;
+ char *icc_qual3 = NULL;
+ char line [256]; /* PPD line length is max 255 (excl. \0) */
+ char *p;
+ char key[128], name[64], text[64];
+ dstr_t *value = create_dstr(); /* value can span multiple lines */
+ double order;
+ value_t *val;
+ option_t *opt, *current_opt = NULL;
+ param_t *param;
+ icc_mapping_entry_t *entry;
+
+ fh = fopen(filename, "r");
+ if (!fh)
+ rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "Unable to open PPD file %s\n", filename);
+ _log("Parsing PPD file ...\n");
+
+ dstrassure(value, 256);
+
+ qualifier_data = list_create();
+ while (!feof(fh)) {
+ tmp = fgets(line, 256, fh);
+
+ if (line[0] != '*' || startswith(line, "*%"))
+ continue;
+
+ /* get the key */
+ if (!(p = strchr(line, ':')))
+ continue;
+ *p = '\0';
+
+ key[0] = name[0] = text[0] = '\0';
+ sscanf(line, "*%127s%*[ \t]%63[^ \t/=)]%*1[/=]%63[^\n]", key, name, text);
+
+ /* get the value */
+ dstrclear(value);
+ sscanf(p +1, " %255[^\r\n]", value->data);
+ value->len = strlen(value->data);
+ if (!value->len)
+ _log("PPD: Missing value for key \"%s\"\n", line);
+
+ while (1) {
+ /* "&&" is the continue-on-next-line marker */
+ if (dstrendswith(value, "&&")) {
+ value->len -= 2;
+ value->data[value->len] = '\0';
+ }
+ /* quoted but quotes are not yet closed */
+ else if (value->data[0] == '\"' && !strchr(value->data +1, '\"'))
+ dstrcat(value, "\n"); /* keep newlines in quoted string*/
+ /* not quoted, or quotes already closed */
+ else
+ break;
+
+ tmp = fgets(line, 256, fh);
+ dstrcat(value, line);
+ dstrremovenewline(value);
+ }
+
+ /* remove quotes */
+ if (value->data[0] == '\"') {
+ memmove(value->data, value->data +1, value->len +1);
+ p = strrchr(value->data, '\"');
+ if (!p) {
+ _log("Invalid line: \"%s: ...\"\n", key);
+ continue;
+ }
+ *p = '\0';
+ }
+ /* remove last newline */
+ dstrremovenewline(value);
+
+ /* remove last whitespace */
+ dstrtrim_right(value);
+
+ /* process key/value pairs */
+ if (strcmp(key, "NickName") == 0) {
+ unhtmlify(printer_model, 256, value->data);
+ }
+ else if (strcmp(key, "FoomaticIDs") == 0) {
+ /* *FoomaticIDs: <printer ID> <driver ID> */
+ sscanf(value->data, "%*[ \t]%127[^ \t]%*[ \t]%127[^ \t\n]",
+ printer_id, driver);
+ }
+ else if (strcmp(key, "FoomaticRIPPostPipe") == 0) {
+ if (!postpipe)
+ postpipe = create_dstr();
+ dstrassure(postpipe, value->len +128);
+ unhtmlify(postpipe->data, postpipe->alloc, value->data);
+ }
+ else if (strcmp(key, "FoomaticRIPCommandLine") == 0) {
+ unhtmlify(cmd, 4096, value->data);
+ }
+ else if (strcmp(key, "FoomaticRIPCommandLinePDF") == 0) {
+ unhtmlify(cmd_pdf, 4096, value->data);
+ }
+ else if (!strcmp(key, "cupsFilter")) {
+ /* cupsFilter: <code> */
+ /* only save the filter for "application/vnd.cups-raster" */
+ if (prefixcmp(value->data, "application/vnd.cups-raster") == 0) {
+ p = strrchr(value->data, ' ');
+ if (p)
+ unhtmlify(cupsfilter, 256, p +1);
+ }
+ }
+ else if (startswith(key, "Custom") && !strcasecmp(name, "true")) {
+ /* Cups custom option: *CustomFoo True: "command" */
+ if (startswith(&key[6], "JCL")) {
+ opt = assure_option(&key[9]);
+ opt->style = 'J';
+ }
+ else
+ opt = assure_option(&key[6]);
+ option_set_custom_command(opt, value->data);
+ if (!strcmp(key, "CustomPageSize"))
+ option_set_custom_command(assure_option("PageRegion"), value->data);
+ }
+ else if (startswith(key, "ParamCustom")) {
+ /* Cups custom parameter:
+ *ParamCustomFoo Name/Text: order type minimum maximum */
+ if (startswith(&key[11], "JCL"))
+ opt = assure_option(&key[14]);
+ else
+ opt = assure_option(&key[11]);
+ option_add_custom_param_from_string(opt, name, text, value->data);
+ }
+ else if (!strcmp(key, "OpenUI") || !strcmp(key, "JCLOpenUI")) {
+ /* "*[JCL]OpenUI *<option>[/<translation>]: <type>" */
+ current_opt = assure_option(&name[1]);
+ if (!isempty(text))
+ strlcpy(current_opt->text, text, 128);
+ if (startswith(key, "JCL"))
+ current_opt->style = 'J';
+ /* Set the argument type only if not defined yet,
+ a definition in "*FoomaticRIPOption" has priority */
+ if (current_opt->type == TYPE_NONE)
+ current_opt->type = type_from_string(value->data);
+ }
+ else if (!strcmp(key, "CloseUI") || !strcmp(key, "JCLCloseUI")) {
+ /* *[JCL]CloseUI: *<option> */
+ if (!current_opt || !option_has_name(current_opt, value->data +1))
+ _log("CloseUI found without corresponding OpenUI (%s).\n", value->data +1);
+ current_opt = NULL;
+ }
+ else if (!strcmp(key, "FoomaticRIPOption")) {
+ /* "*FoomaticRIPOption <option>: <type> <style> <spot> [<order>]"
+ <order> only used for 1-choice enum options */
+ option_set_from_string(assure_option(name), value->data);
+ }
+ else if (!strcmp(key, "FoomaticRIPOptionPrototype")) {
+ /* "*FoomaticRIPOptionPrototype <option>: <code>"
+ Used for numerical and string options only */
+ opt = assure_option(name);
+ opt->proto = malloc(65536);
+ unhtmlify(opt->proto, 65536, value->data);
+ }
+ else if (!strcmp(key, "FoomaticRIPOptionRange")) {
+ /* *FoomaticRIPOptionRange <option>: <min> <max>
+ Used for numerical options only */
+ param = option_assure_foomatic_param(assure_option(name));
+ sscanf(value->data, "%19s %19s", param->min, param->max);
+ }
+ else if (!strcmp(key, "FoomaticRIPOptionMaxLength")) {
+ /* "*FoomaticRIPOptionMaxLength <option>: <length>"
+ Used for string options only */
+ param = option_assure_foomatic_param(assure_option(name));
+ sscanf(value->data, "%19s", param->max);
+ }
+ else if (!strcmp(key, "FoomaticRIPOptionAllowedChars")) {
+ /* *FoomaticRIPOptionAllowedChars <option>: <code>
+ Used for string options only */
+ param = option_assure_foomatic_param(assure_option(name));
+ param_set_allowed_chars(param, value->data);
+ }
+ else if (!strcmp(key, "FoomaticRIPOptionAllowedRegExp")) {
+ /* "*FoomaticRIPOptionAllowedRegExp <option>: <code>"
+ Used for string options only */
+ param = option_assure_foomatic_param(assure_option(name));
+ param_set_allowed_regexp(param, value->data);
+ }
+ else if (!strcmp(key, "OrderDependency")) {
+ /* OrderDependency: <order> <section> *<option> */
+ /* use 'text' to read <section> */
+ sscanf(value->data, "%lf %63s *%63s", &order, text, name);
+ opt = assure_option(name);
+ opt->section = section_from_string(text);
+ option_set_order(opt, order);
+ }
+
+ /* Default options are not yet validated (not all options/choices
+ have been read yet) */
+ else if (!prefixcmp(key, "Default")) {
+ /* Default<option>: <value> */
+
+ opt = assure_option(&key[7]);
+ val = option_assure_value(opt, optionset("default"));
+ free(val->value);
+ val->value = strdup(value->data);
+ }
+ else if (!prefixcmp(key, "FoomaticRIPDefault")) {
+ /* FoomaticRIPDefault<option>: <value>
+ Used for numerical options only */
+ opt = assure_option(&key[18]);
+ val = option_assure_value(opt, optionset("default"));
+ free(val->value);
+ val->value = strdup(value->data);
+ }
+
+ /* Current argument */
+ else if (current_opt && !strcmp(key, current_opt->name)) {
+ /* *<option> <choice>[/translation]: <code> */
+ option_set_choice(current_opt, name, text, value->data);
+ }
+ else if (!strcmp(key, "FoomaticRIPOptionSetting")) {
+ /* "*FoomaticRIPOptionSetting <option>[=<choice>]: <code>
+ For boolean options <choice> is not given */
+ option_set_choice(assure_option(name),
+ isempty(text) ? "true" : text, NULL, value->data);
+ }
+
+ /* "*(Foomatic|)JCL(Begin|ToPSInterpreter|End|Prefix): <code>"
+ The printer supports PJL/JCL when there is such a line */
+ else if (!prefixcmp(key, "JCLBegin") ||
+ !prefixcmp(key, "FoomaticJCLBegin")) {
+ unhexify(jclbegin, 256, value->data);
+ if (!jclprefixset && strstr(jclbegin, "PJL") == NULL)
+ jclprefix[0] = '\0';
+ }
+ else if (!prefixcmp(key, "JCLToPSInterpreter") ||
+ !prefixcmp(key, "FoomaticJCLToPSInterpreter")) {
+ unhexify(jcltointerpreter, 256, value->data);
+ }
+ else if (!prefixcmp(key, "JCLEnd") ||
+ !prefixcmp(key, "FoomaticJCLEnd")) {
+ unhexify(jclend, 256, value->data);
+ }
+ else if (!prefixcmp(key, "JCLPrefix") ||
+ !prefixcmp(key, "FoomaticJCLPrefix")) {
+ unhexify(jclprefix, 256, value->data);
+ jclprefixset = 1;
+ }
+ else if (!prefixcmp(key, "% COMDATA #")) {
+ /* old foomtic 2.0.x PPD file */
+ _log("You are using an old Foomatic 2.0 PPD file, which is no "
+ "longer supported by Foomatic >4.0. Exiting.\n");
+ exit(1); /* TODO exit more gracefully */
+ }
+ else if (!strcmp(key, "FoomaticRIPJobEntityMaxLength")) {
+ /* "*FoomaticRIPJobEntityMaxLength: <length>" */
+ sscanf(value->data, "%d", &jobentitymaxlen);
+ }
+ else if (!strcmp(key, "FoomaticRIPUserEntityMaxLength")) {
+ /* "*FoomaticRIPUserEntityMaxLength: <length>" */
+ sscanf(value->data, "%d", &userentitymaxlen);
+ }
+ else if (!strcmp(key, "FoomaticRIPHostEntityMaxLength")) {
+ /* "*FoomaticRIPHostEntityMaxLength: <length>" */
+ sscanf(value->data, "%d", &hostentitymaxlen);
+ }
+ else if (!strcmp(key, "FoomaticRIPTitleEntityMaxLength")) {
+ /* "*FoomaticRIPTitleEntityMaxLength: <length>" */
+ sscanf(value->data, "%d", &titleentitymaxlen);
+ }
+ else if (!strcmp(key, "FoomaticRIPOptionsEntityMaxLength")) {
+ /* "*FoomaticRIPOptionsEntityMaxLength: <length>" */
+ sscanf(value->data, "%d", &optionsentitymaxlen);
+ }
+ else if (!strcmp(key, "cupsICCProfile")) {
+ /* "*cupsICCProfile: <qualifier/Title> <filename>" */
+ entry = calloc(1, sizeof(icc_mapping_entry_t));
+ entry->qualifier = strdup(name);
+ entry->filename = strdup(value->data);
+ list_append (qualifier_data, entry);
+ }
+ else if (!strcmp(key, "cupsICCQualifier2")) {
+ /* "*cupsICCQualifier2: <value>" */
+ icc_qual2 = strdup(value->data);
+ }
+ else if (!strcmp(key, "cupsICCQualifier3")) {
+ /* "*cupsICCQualifier3: <value>" */
+ icc_qual3 = strdup(value->data);
+ }
+ }
+
+ fclose(fh);
+ free_dstr(value);
+
+ /* Validate default options by resetting them with option_set_value() */
+ for (opt = optionlist; opt; opt = opt->next) {
+ val = option_find_value(opt, optionset("default"));
+ if (val) {
+ /* if fromopt is set, this value has already been validated */
+ if (!val->fromoption)
+ option_set_value(opt, optionset("default"), val->value);
+ }
+ else
+ /* Make sure that this option has a default choice, even if none is
+ defined in the PPD file */
+ option_set_value(opt, optionset("default"), opt->choicelist->value);
+ }
+
+ /* create qualifier for this PPD */
+ qualifier = calloc(4, sizeof(char*));
+
+ /* get colorspace */
+ tmp = option_get_value(find_option("ColorSpace"), optionset("default"));
+ if (tmp == NULL)
+ tmp = option_get_value(find_option("ColorModel"), optionset("default"));
+ if (tmp == NULL)
+ tmp = "";
+ qualifier[0] = strdup(tmp);
+
+ /* get selector2 */
+ if (icc_qual2 == NULL)
+ icc_qual2 = strdup("MediaType");
+ tmp = option_get_value(find_option(icc_qual2), optionset("default"));
+ if (tmp == NULL)
+ tmp = "";
+ qualifier[1] = strdup(tmp);
+
+ /* get selectors */
+ if (icc_qual3 == NULL)
+ icc_qual3 = strdup("Resolution");
+ tmp = option_get_value(find_option(icc_qual3), optionset("default"));
+ if (tmp == NULL)
+ tmp = "";
+ qualifier[2] = strdup(tmp);
+
+ free (icc_qual2);
+ free (icc_qual3);
+}
+
+int ppd_supports_pdf()
+{
+ option_t *opt;
+
+ /* If at least one option inserts PostScript code, we cannot support PDF */
+ for (opt = optionlist; opt; opt = opt->next)
+ {
+ choice_t *choice;
+
+ if (!option_is_ps_command(opt) || option_is_composite(opt) ||
+ (opt->type == TYPE_NONE))
+ continue;
+
+ for (choice = opt->choicelist; choice; choice = choice->next)
+ if (contains_active_postscript(choice->command)) {
+ _log(" PostScript option found: %s=%s: \"%s\"\n",
+ opt->name, choice->value, choice->command);
+ return 0;
+ }
+ }
+
+ if (!isempty(cmd_pdf))
+ return 1;
+
+ /* Ghostscript also accepts PDF, use that if it is in the normal command
+ * line */
+ if (startswith(cmd, "gs"))
+ {
+ strncpy(cmd_pdf, cmd, 4096);
+ return 1;
+ }
+
+ _log(" Neither PDF renderer command line nor Ghostscript-based renderer command line found\n");
+ return 0;
+}
+
+/* build a renderer command line, based on the given option set */
+int build_commandline(int optset, dstr_t *cmdline, int pdfcmdline)
+{
+ option_t *opt;
+ const char *userval;
+ char *s, *p;
+ dstr_t *cmdvar = create_dstr();
+ dstr_t *open = create_dstr();
+ dstr_t *close = create_dstr();
+ char letters[] = "%A %B %C %D %E %F %G %H %I %J %K %L %M %W %X %Y %Z";
+ int jcl = 0;
+
+ dstr_t *local_jclprepend = create_dstr();
+
+ dstrclear(prologprepend);
+ dstrclear(setupprepend);
+ dstrclear(pagesetupprepend);
+
+ if (cmdline)
+ dstrcpy(cmdline, pdfcmdline ? cmd_pdf : cmd);
+
+ for (opt = optionlist_sorted_by_order; opt; opt = opt->next_by_order) {
+ /* composite options have no direct influence, and all their dependents
+ have already been set */
+ if (option_is_composite(opt))
+ continue;
+
+ userval = option_get_value(opt, optset);
+ option_get_command(cmdvar, opt, optset, -1);
+
+ /* Insert the built snippet at the correct place */
+ if (option_is_ps_command(opt)) {
+ /* Place this Postscript command onto the prepend queue
+ for the appropriate section. */
+ if (cmdvar->len) {
+ dstrcpyf(open, "[{\n%%%%BeginFeature: *%s ", opt->name);
+ if (opt->type == TYPE_BOOL)
+ dstrcatf(open, is_true_string(userval) ? "True\n" : "False\n");
+ else
+ dstrcatf(open, "%s\n", userval);
+ dstrcpyf(close, "\n%%%%EndFeature\n} stopped cleartomark\n");
+
+ switch (option_get_section(opt)) {
+ case SECTION_PROLOG:
+ dstrcatf(prologprepend, "%s%s%s", open->data, cmdvar->data, close->data);
+ break;
+
+ case SECTION_ANYSETUP:
+ if (optset != optionset("currentpage"))
+ dstrcatf(setupprepend, "%s%s%s", open->data, cmdvar->data, close->data);
+ else if (strcmp(option_get_value(opt, optionset("header")), userval) != 0)
+ dstrcatf(pagesetupprepend, "%s%s%s", open->data, cmdvar->data, close->data);
+ break;
+
+ case SECTION_DOCUMENTSETUP:
+ dstrcatf(setupprepend, "%s%s%s", open->data, cmdvar->data, close->data);
+ break;
+
+ case SECTION_PAGESETUP:
+ dstrcatf(pagesetupprepend, "%s%s%s", open->data, cmdvar->data, close->data);
+ break;
+
+ case SECTION_JCLSETUP: /* PCL/JCL argument */
+ s = malloc(cmdvar->len +1);
+ unhexify(s, cmdvar->len +1, cmdvar->data);
+ dstrcatf(local_jclprepend, "%s", s);
+ free(s);
+ break;
+
+ default:
+ dstrcatf(setupprepend, "%s%s%s", open->data, cmdvar->data, close->data);
+ }
+ }
+ }
+ else if (option_is_jcl_arg(opt)) {
+ jcl = 1;
+ /* Put JCL commands onto JCL stack */
+ if (cmdvar->len) {
+ char *s = malloc(cmdvar->len +1);
+ unhexify(s, cmdvar->len +1, cmdvar->data);
+ if (!startswith(cmdvar->data, jclprefix))
+ dstrcatf(local_jclprepend, "%s%s\n", jclprefix, s);
+ else
+ dstrcat(local_jclprepend, s);
+ free(s);
+ }
+ }
+ else if (option_is_commandline_arg(opt) && cmdline) {
+ /* Insert the processed argument in the command line
+ just before every occurrence of the spot marker. */
+ p = malloc(3);
+ snprintf(p, 3, "%%%c", opt->spot);
+ s = malloc(cmdvar->len +3);
+ snprintf(s, cmdvar->len +3, "%s%%%c", cmdvar->data, opt->spot);
+ dstrreplace(cmdline, p, s, 0);
+ free(p);
+ free(s);
+ }
+
+ /* Insert option into command line of CUPS raster driver */
+ if (cmdline && strstr(cmdline->data, "%Y")) {
+ if (isempty(userval))
+ continue;
+ s = malloc(strlen(opt->name) + strlen(userval) + 20);
+ sprintf(s, "%s=%s %%Y", opt->name, userval);
+ dstrreplace(cmdline, "%Y", s, 0);
+ free(s);
+ }
+ }
+
+ /* Tidy up after computing option statements for all of P, J, and C types: */
+
+ /* C type finishing */
+ /* Pluck out all of the %n's from the command line prototype */
+ if (cmdline) {
+ s = strtok(letters, " ");
+ do {
+ dstrreplace(cmdline, s, "", 0);
+ } while ((s = strtok(NULL, " ")));
+ }
+
+ /* J type finishing */
+ /* Compute the proper stuff to say around the job */
+ if (jcl && !jobhasjcl) {
+ /* command to switch to the interpreter */
+ dstrcatf(local_jclprepend, "%s", jcltointerpreter);
+
+ /* Arrange for JCL RESET command at the end of job */
+ dstrcpy(jclappend, jclend);
+
+ argv_free(jclprepend);
+ jclprepend = argv_split(local_jclprepend->data, "\r\n", NULL);
+ }
+
+ free_dstr(cmdvar);
+ free_dstr(open);
+ free_dstr(close);
+ free_dstr(local_jclprepend);
+
+ return !isempty(cmd);
+}
+
+/* if "comments" is set, add "%%BeginProlog...%%EndProlog" */
+void append_prolog_section(dstr_t *str, int optset, int comments)
+{
+ /* Start comment */
+ if (comments) {
+ _log("\"Prolog\" section is missing, inserting it.\n");
+ dstrcat(str, "%%BeginProlog\n");
+ }
+
+ /* Generate the option code (not necessary when CUPS is spooler and
+ PostScript data is not converted from PDF) */
+ if ((spooler != SPOOLER_CUPS) || pdfconvertedtops) {
+ _log("Inserting option code into \"Prolog\" section.\n");
+ build_commandline(optset, NULL, 0);
+ dstrcat(str, prologprepend->data);
+ }
+
+ /* End comment */
+ if (comments)
+ dstrcat(str, "%%EndProlog\n");
+}
+
+void append_setup_section(dstr_t *str, int optset, int comments)
+{
+ /* Start comment */
+ if (comments) {
+ _log("\"Setup\" section is missing, inserting it.\n");
+ dstrcat(str, "%%BeginSetup\n");
+ }
+
+ /* Generate the option code (not necessary when CUPS is spooler and
+ PostScript data is not converted from PDF) */
+ if ((spooler != SPOOLER_CUPS) || pdfconvertedtops) {
+ _log("Inserting option code into \"Setup\" section.\n");
+ build_commandline(optset, NULL, 0);
+ dstrcat(str, setupprepend->data);
+ }
+
+ /* End comment */
+ if (comments)
+ dstrcat(str, "%%EndSetup\n");
+}
+
+void append_page_setup_section(dstr_t *str, int optset, int comments)
+{
+ /* Start comment */
+ if (comments) {
+ _log("\"PageSetup\" section is missing, inserting it.\n");
+ dstrcat(str, "%%BeginPageSetup\n");
+ }
+
+ /* Generate the option code (not necessary when CUPS is spooler) */
+ _log("Inserting option code into \"PageSetup\" section.\n");
+ build_commandline(optset, NULL, 0);
+ dstrcat(str, pagesetupprepend->data);
+
+ /* End comment */
+ if (comments)
+ dstrcat(str, "%%EndPageSetup\n");
+}
+
+
+typedef struct page_range {
+ short even, odd;
+ unsigned first, last;
+ struct page_range *next;
+} page_range_t;
+
+static page_range_t * parse_page_ranges(const char *ranges)
+{
+ page_range_t *head = NULL, *tail = NULL;
+ char *tokens, *tok;
+ int cnt;
+
+ tokens = strdup(ranges);
+ for (tok = strtok(tokens, ","); tok; tok = strtok(NULL, ",")) {
+ page_range_t *pr = calloc(1, sizeof(page_range_t));
+
+ if (startswith(tok, "even"))
+ pr->even = 1;
+ else if (startswith(tok, "odd"))
+ pr->odd = 1;
+ else if ((cnt = sscanf(tok, "%u-%u", &pr->first, &pr->last))) {
+ /* If 'last' has not been read, this could mean only one page (no
+ * hyphen) or all pages to the end */
+ if (cnt == 1 && !endswith(tok, "-"))
+ pr->last = pr->first;
+ else if (cnt == 2 && pr->first > pr->last) {
+ unsigned tmp = pr->first;
+ pr->first = pr->last;
+ pr->last = tmp;
+ }
+ }
+ else {
+ printf("Invalid page range: %s\n", tok);
+ free(pr);
+ continue;
+ }
+
+ if (tail) {
+ tail->next = pr;
+ tail = pr;
+ }
+ else
+ tail = head = pr;
+ }
+
+ free(tokens);
+ return head;
+}
+
+static void free_page_ranges(page_range_t *ranges)
+{
+ page_range_t *pr;
+ while (ranges) {
+ pr = ranges;
+ ranges = ranges->next;
+ free(pr);
+ }
+}
+
+/* Parse a string containing page ranges and either check whether a
+ given page is in the ranges or, if the given page number is zero,
+ determine the score how specific this page range string is.*/
+int get_page_score(const char *pages, int page)
+{
+ page_range_t *ranges = parse_page_ranges(pages);
+ page_range_t *pr;
+ int totalscore = 0;
+ int pageinside = 0;
+
+ for (pr = ranges; pr; pr = pr->next) {
+ if (pr->even) {
+ totalscore += 50000;
+ if (page % 2 == 0)
+ pageinside = 1;
+ }
+ else if (pr->odd) {
+ totalscore += 50000;
+ if (page % 2 == 1)
+ pageinside = 1;
+ }
+ else if (pr->first == pr->last) { /* Single page */
+ totalscore += 1;
+ if (page == pr->first)
+ pageinside = 1;
+ }
+ else if (pr->last == 0) { /* To the end of the document */
+ totalscore += 100000;
+ if (page >= pr->first)
+ pageinside = 1;
+ }
+ else { /* Sequence of pages */
+ totalscore += pr->last - pr->first +1;
+ if (page >= pr->first && page <= pr->last)
+ pageinside = 1;
+ }
+ }
+
+ free_page_ranges(ranges);
+
+ if (page == 0 || pageinside)
+ return totalscore;
+
+ return 0;
+}
+
+/* Set the options for a given page */
+void set_options_for_page(int optset, int page)
+{
+ int score, bestscore;
+ option_t *opt;
+ value_t *val, *bestvalue;
+ const char *ranges;
+ const char *optsetname;
+
+ for (opt = optionlist; opt; opt = opt->next) {
+
+ bestscore = 10000000;
+ bestvalue = NULL;
+ for (val = opt->valuelist; val; val = val->next) {
+
+ optsetname = optionset_name(val->optionset);
+ if (!startswith(optsetname, "pages:"))
+ continue;
+
+ ranges = &optsetname[6]; /* after "pages:" */
+ score = get_page_score(ranges, page);
+ if (score && score < bestscore) {
+ bestscore = score;
+ bestvalue = val;
+ }
+ }
+
+ if (bestvalue)
+ option_set_value(opt, optset, bestvalue->value);
+ }
+}
+
diff --git a/filter/foomatic-rip/options.h b/filter/foomatic-rip/options.h
new file mode 100644
index 000000000..9230bac0d
--- /dev/null
+++ b/filter/foomatic-rip/options.h
@@ -0,0 +1,182 @@
+/* options.h
+ *
+ * Copyright (C) 2008 Till Kamppeter <till.kamppeter@gmail.com>
+ * Copyright (C) 2008 Lars Uebernickel <larsuebernickel@gmx.de>
+ *
+ * This file is part of foomatic-rip.
+ *
+ * Foomatic-rip 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Foomatic-rip 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 Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef options_h
+#define options_h
+
+
+#include <stddef.h>
+#include <regex.h>
+#include "util.h"
+
+/* Option types */
+#define TYPE_NONE 0
+#define TYPE_ENUM 1
+#define TYPE_PICKMANY 2
+#define TYPE_BOOL 3
+#define TYPE_INT 4
+#define TYPE_FLOAT 5
+#define TYPE_STRING 6
+#define TYPE_PASSWORD 7
+#define TYPE_CURVE 8
+#define TYPE_INVCURVE 9
+#define TYPE_PASSCODE 10
+#define TYPE_POINTS 11
+
+/* Sections */
+#define SECTION_ANYSETUP 1
+#define SECTION_PAGESETUP 2
+#define SECTION_PROLOG 3
+#define SECTION_DOCUMENTSETUP 4
+#define SECTION_JCLSETUP 5
+
+
+
+typedef struct choice_s {
+ char value [128];
+ char text [128];
+ char command[65536];
+ struct choice_s *next;
+} choice_t;
+
+/* Custom option parameter */
+typedef struct param_s {
+ char name [128];
+ char text [128]; /* formerly comment, changed to 'text' to
+ be consistent with cups */
+ int order;
+
+ int type;
+ char min[20], max[20]; /* contents depend on 'type' */
+
+ regex_t *allowedchars;
+ regex_t *allowedregexp;
+
+ struct param_s *next;
+} param_t;
+
+/* Option */
+typedef struct option_s {
+ char name [128];
+ char text [128];
+ char varname [128]; /* clean version of 'name' (no spaces etc.) */
+ int type;
+ int style;
+ char spot;
+ double order;
+ int section;
+
+ int notfirst; /* TODO remove */
+
+ choice_t *choicelist;
+
+ /* Foomatic PPD extensions */
+ char *proto; /* *FoomaticRIPOptionPrototype: if this is set
+ it will be used with only the first option
+ in paramlist (there should be only one) */
+ param_t *foomatic_param;
+
+ /* CUPS custom options */
+ char *custom_command; /* *CustomFoo */
+ param_t *paramlist; /* for custom values, sorted by stack order */
+ size_t param_count;
+
+ struct value_s *valuelist;
+
+ struct option_s *next;
+ struct option_s *next_by_order;
+} option_t;
+
+
+/* A value for an option */
+typedef struct value_s {
+ int optionset;
+ char *value;
+ option_t *fromoption; /* This is set when this value is set by a composite */
+ struct value_s *next;
+} value_t;
+
+
+extern option_t *optionlist;
+extern option_t *optionlist_sorted_by_order;
+
+extern char jclbegin[256];
+extern char jcltointerpreter[256];
+extern char jclend[256];
+extern char jclprefix[256];
+
+extern char cmd[4096];
+extern char cmd_pdf[4096];
+
+
+int option_is_composite(option_t *opt);
+int option_is_ps_command(option_t *opt);
+int option_is_jcl_arg(option_t *opt);
+int option_is_commandline_arg(option_t *opt);
+
+
+int option_get_section(option_t *opt); /* TODO deprecated */
+
+/* handles ANYSETUP (for (PAGE|DOCUMENT)SETUP) */
+int option_is_in_section(option_t *opt, int section);
+
+void options_init();
+void options_free();
+
+size_t option_count();
+option_t *find_option(const char *name);
+
+void read_ppd_file(const char *filename);
+
+int ppd_supports_pdf();
+
+
+int option_set_value(option_t *opt, int optset, const char *value);
+const char * option_get_value(option_t *opt, int optset);
+
+/* section == -1 for all sections */
+int option_get_command(dstr_t *cmd, option_t *opt, int optset, int section);
+
+int option_accepts_value(option_t *opt, const char *value);
+int option_has_choice(option_t *opt, const char *choice);
+int option_is_custom_value(option_t *opt, const char *value);
+
+
+const char * optionset_name(int idx);
+int optionset(const char * name);
+
+void optionset_copy_values(int src_optset, int dest_optset);
+int optionset_equal(int optset1, int optset2, int exceptPS);
+void optionset_delete_values(int optionset);
+
+void append_prolog_section(dstr_t *str, int optset, int comments);
+void append_setup_section(dstr_t *str, int optset, int comments);
+void append_page_setup_section(dstr_t *str, int optset, int comments);
+int build_commandline(int optset, dstr_t *cmdline, int pdfcmdline);
+
+void set_options_for_page(int optset, int page);
+const char *get_icc_profile_for_qualifier(const char **qualifier);
+const char **get_ppd_qualifier(void);
+
+#endif
+
diff --git a/filter/foomatic-rip/pdf.c b/filter/foomatic-rip/pdf.c
new file mode 100644
index 000000000..9c3979bb2
--- /dev/null
+++ b/filter/foomatic-rip/pdf.c
@@ -0,0 +1,310 @@
+/* pdf.c
+ *
+ * Copyright (C) 2008 Till Kamppeter <till.kamppeter@gmail.com>
+ * Copyright (C) 2008 Lars Uebernickel <larsuebernickel@gmx.de>
+ *
+ * This file is part of foomatic-rip.
+ *
+ * Foomatic-rip 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Foomatic-rip 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 Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "foomaticrip.h"
+#include "util.h"
+#include "options.h"
+#include "process.h"
+#include "renderer.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+
+#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
+
+
+static int wait_for_renderer();
+
+
+static int pdf_count_pages(const char *filename)
+{
+ char gscommand[CMDLINE_MAX];
+ char output[31] = "";
+ int pagecount;
+ size_t bytes;
+
+ snprintf(gscommand, CMDLINE_MAX, "%s -dNODISPLAY -q -c "
+ "'/pdffile (%s) (r) file def pdfdict begin pdffile pdfopen begin "
+ "(PageCount: ) print pdfpagecount == flush currentdict pdfclose "
+ "end end quit'",
+ gspath, filename);
+
+ FILE *pd = popen(gscommand, "r");
+ if (!pd)
+ rip_die(EXIT_STARVED, "Failed to execute ghostscript to determine number of input pages!\n");
+
+ bytes = fread_or_die(output, 1, 31, pd);
+ pclose(pd);
+
+ if (bytes <= 0 || sscanf(output, "PageCount: %d", &pagecount) < 1)
+ pagecount = -1;
+
+ return pagecount;
+}
+
+pid_t kid3 = 0;
+
+
+static int start_renderer(const char *cmd)
+{
+ if (kid3 != 0)
+ wait_for_renderer();
+
+ _log("Starting renderer with command: %s\n", cmd);
+ kid3 = start_process("kid3", exec_kid3, (void *)cmd, NULL, NULL);
+ if (kid3 < 0)
+ rip_die(EXIT_STARVED, "Could not start renderer\n");
+
+ return 1;
+}
+
+static int wait_for_renderer()
+{
+ int status;
+
+ waitpid(kid3, &status, 0);
+
+ if (!WIFEXITED(status)) {
+ _log("Kid3 did not finish normally.\n");
+ exit(EXIT_PRNERR_NORETRY_BAD_SETTINGS);
+ }
+
+ _log("Kid3 exit status: %d\n", WEXITSTATUS(status));
+ if (WEXITSTATUS(status) != 0)
+ exit(EXIT_PRNERR_NORETRY_BAD_SETTINGS);
+
+ kid3 = 0;
+ return 1;
+}
+
+/*
+ * Extract pages 'first' through 'last' from the pdf and write them into a
+ * temporary file.
+ */
+static int pdf_extract_pages(char filename[PATH_MAX],
+ const char *pdffilename,
+ int first,
+ int last)
+{
+ char gscommand[CMDLINE_MAX];
+ char filename_arg[PATH_MAX], first_arg[50], last_arg[50];
+ int fd;
+
+ _log("Extracting pages %d through %d\n", first, last);
+
+ snprintf(filename, PATH_MAX, "%s/foomatic-XXXXXX", temp_dir());
+ if ((fd = mkstemp(filename)) == -1)
+ rip_die(EXIT_STARVED, "Unable to create temporary file!\n");
+ close (fd);
+
+ snprintf(filename_arg, PATH_MAX, "-sOutputFile=%s", filename);
+
+ first_arg[0] = '\0';
+ last_arg[0] = '\0';
+ if (first > 1)
+ {
+ snprintf(first_arg, 50, "-dFirstPage=%d", first);
+ if (last >= first)
+ snprintf(last_arg, 50, "-dLastPage=%d", last);
+ }
+
+ snprintf(gscommand, CMDLINE_MAX, "%s -q -dNOPAUSE -dBATCH -dPARANOIDSAFER -dNOINTERPOLATE -dNOMEDIAATTRS"
+ "-sDEVICE=pdfwrite -dShowAcroForm %s %s %s %s",
+ gspath, filename_arg, first_arg, last_arg, pdffilename);
+
+ FILE *pd = popen(gscommand, "r");
+ if (!pd)
+ rip_die(EXIT_STARVED, "Could not run ghostscript to extract the pages!\n");
+ pclose(pd);
+
+ return 1;
+}
+
+static int render_pages_with_generic_command(dstr_t *cmd,
+ const char *filename,
+ int firstpage,
+ int lastpage)
+{
+ char tmpfile[PATH_MAX];
+ int result;
+
+ /* TODO it might be a good idea to give pdf command lines the possibility
+ * to get the file on the command line rather than piped through stdin
+ * (maybe introduce a &filename; ??) */
+
+ if (lastpage < 0) /* i.e. print the whole document */
+ dstrcatf(cmd, " < %s", filename);
+ else
+ {
+ if (!pdf_extract_pages(tmpfile, filename, firstpage, lastpage))
+ rip_die(EXIT_STARVED, "Could not run ghostscript to extract the pages!\n");
+ dstrcatf(cmd, " < %s", tmpfile);
+ }
+
+ result = start_renderer(cmd->data);
+
+ if (lastpage > 0)
+ unlink(tmpfile);
+
+ return result;
+}
+
+static int render_pages_with_ghostscript(dstr_t *cmd,
+ size_t start_gs_cmd,
+ size_t end_gs_cmd,
+ const char *filename,
+ int firstpage,
+ int lastpage)
+{
+ char *p;
+
+ /* No need to create a temporary file, just give ghostscript the file and
+ * first/last page on the command line */
+
+ /* Some command lines want to read from stdin */
+ for (p = &cmd->data[end_gs_cmd -1]; isspace(*p); p--)
+ ;
+ if (*p == '-')
+ *p = ' ';
+
+ dstrinsertf(cmd, end_gs_cmd, " %s ", filename);
+
+ dstrinsertf(cmd, start_gs_cmd + 2, " -dShowAcroForm ");
+
+ if (firstpage > 1)
+ {
+ if (lastpage >= firstpage)
+ dstrinsertf(cmd, start_gs_cmd +2,
+ " -dFirstPage=%d -dLastPage=%d ",
+ firstpage, lastpage);
+ else
+ dstrinsertf(cmd, start_gs_cmd +2,
+ " -dFirstPage=%d ", firstpage);
+ }
+
+ return start_renderer(cmd->data);
+}
+
+static int render_pages(const char *filename, int firstpage, int lastpage)
+{
+ dstr_t *cmd = create_dstr();
+ size_t start, end;
+ int result;
+
+ build_commandline(optionset("currentpage"), cmd, 1);
+
+ extract_command(&start, &end, cmd->data, "gs");
+ if (start == end)
+ /* command is not Ghostscript */
+ result = render_pages_with_generic_command(cmd,
+ filename,
+ firstpage,
+ lastpage);
+ else
+ /* Ghostscript command, tell it which pages we want to render */
+ result = render_pages_with_ghostscript(cmd,
+ start,
+ end,
+ filename,
+ firstpage,
+ lastpage);
+
+ free_dstr(cmd);
+ return result;
+}
+
+static int print_pdf_file(const char *filename)
+{
+ int page_count, i;
+ int firstpage;
+
+ page_count = pdf_count_pages(filename);
+
+ if (page_count <= 0)
+ rip_die(EXIT_JOBERR, "Unable to determine number of pages, page count: %d\n", page_count);
+ _log("File contains %d pages\n", page_count);
+
+ optionset_copy_values(optionset("header"), optionset("currentpage"));
+ optionset_copy_values(optionset("currentpage"), optionset("previouspage"));
+ firstpage = 1;
+ for (i = 1; i <= page_count; i++)
+ {
+ set_options_for_page(optionset("currentpage"), i);
+ if (!optionset_equal(optionset("currentpage"), optionset("previouspage"), 1))
+ {
+ render_pages(filename, firstpage, i);
+ firstpage = i;
+ }
+ optionset_copy_values(optionset("currentpage"), optionset("previouspage"));
+ }
+ if (firstpage == 1)
+ render_pages(filename, 1, -1); /* Render the whole document */
+ else
+ render_pages(filename, firstpage, page_count);
+
+ wait_for_renderer();
+
+ return 1;
+}
+
+int print_pdf(FILE *s,
+ const char *alreadyread,
+ size_t len,
+ const char *filename,
+ size_t startpos)
+{
+ char tmpfilename[PATH_MAX] = "";
+ int result;
+
+ /* If reading from stdin, write everything into a temporary file */
+ /* TODO don't do this if there aren't any pagerange-limited options */
+ if (s == stdin)
+ {
+ int fd;
+ FILE *tmpfile;
+
+ snprintf(tmpfilename, PATH_MAX, "%s/foomatic-XXXXXX", temp_dir());
+ fd = mkstemp(tmpfilename);
+ if (fd < 0) {
+ _log("Could not create temporary file: %s\n", strerror(errno));
+ return EXIT_PRNERR_NORETRY_BAD_SETTINGS;
+ }
+
+ tmpfile = fdopen(fd, "r+");
+ copy_file(tmpfile, stdin, alreadyread, len);
+ fclose(tmpfile);
+
+ filename = tmpfilename;
+ }
+
+ result = print_pdf_file(filename);
+
+ if (!isempty(tmpfilename))
+ unlink(tmpfilename);
+
+ return result;
+}
+
diff --git a/filter/foomatic-rip/pdf.h b/filter/foomatic-rip/pdf.h
new file mode 100644
index 000000000..aa044453c
--- /dev/null
+++ b/filter/foomatic-rip/pdf.h
@@ -0,0 +1,30 @@
+/* pdf.h
+ *
+ * Copyright (C) 2008 Till Kamppeter <till.kamppeter@gmail.com>
+ * Copyright (C) 2008 Lars Uebernickel <larsuebernickel@gmx.de>
+ *
+ * This file is part of foomatic-rip.
+ *
+ * Foomatic-rip 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Foomatic-rip 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 Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef pdf_h
+#define pdf_h
+
+int print_pdf(FILE *s, const char *alreadyread, size_t len, const char *filename, size_t startpos);
+
+#endif
+
diff --git a/filter/foomatic-rip/postscript.c b/filter/foomatic-rip/postscript.c
new file mode 100644
index 000000000..75070d2b9
--- /dev/null
+++ b/filter/foomatic-rip/postscript.c
@@ -0,0 +1,1207 @@
+/* postscript.c
+ *
+ * Copyright (C) 2008 Till Kamppeter <till.kamppeter@gmail.com>
+ * Copyright (C) 2008 Lars Uebernickel <larsuebernickel@gmx.de>
+ *
+ * This file is part of foomatic-rip.
+ *
+ * Foomatic-rip 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Foomatic-rip 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 Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "foomaticrip.h"
+#include "util.h"
+#include "options.h"
+#include "renderer.h"
+#include "process.h"
+
+#include <errno.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+void get_renderer_handle(const dstr_t *prepend, FILE **fd, pid_t *pid);
+int close_renderer_handle(FILE *rendererhandle, pid_t rendererpid);
+
+#define LT_BEGIN_FEATURE 1
+#define LT_FOOMATIC_RIP_OPTION_SETTING 2
+int line_type(const char *line)
+{
+ const char *p;
+ if (startswith(line, "%%BeginFeature:"))
+ return LT_BEGIN_FEATURE;
+ p = line;
+ while (*p && isspace(*p)) p++;
+ if (!startswith(p, "%%"))
+ return 0;
+ p += 2;
+ while (*p && isspace(*p)) p++;
+ if (startswith(p, "FoomaticRIPOptionSetting:"))
+ return LT_FOOMATIC_RIP_OPTION_SETTING;
+ return 0;
+}
+
+
+/* Next, examine the PostScript job for traces of command-line and
+ JCL options. PPD-aware applications and spoolers stuff option
+ settings directly into the file, they do not necessarily send
+ PPD options by the command line. Also stuff in PostScript code
+ to apply option settings given by the command line and to set
+ the defaults given in the PPD file.
+
+ Examination strategy: read lines from STDIN until the first
+ %%Page: comment appears and save them as @psheader. This is the
+ page-independent header part of the PostScript file. The
+ PostScript interpreter (renderer) must execute this part once
+ before rendering any assortment of pages. Then pages can be
+ printed in any arbitrary selection or order. All option
+ settings we find here will be collected in the default option
+ set for the RIP command line.
+
+ Now the pages will be read and sent to the renderer, one after
+ the other. Every page is read into memory until the
+ %%EndPageSetup comment appears (or a certain amount of lines was
+ read). So we can get option settings only valid for this
+ page. If we have such settings we set them in the modified
+ command set for this page.
+
+ If the renderer is not running yet (first page) we start it with
+ the command line built from the current modified command set and
+ send the first page to it, in the end we leave the renderer
+ running and keep input and output pipes open, so that it can
+ accept further pages. If the renderer is still running from
+ the previous page and the current modified command set is the
+ same as the one for the previous page, we send the page. If
+ the command set is different, we close the renderer, re-start
+ it with the command line built from the new modified command
+ set, send the header again, and then the page.
+
+ After the last page the trailer (%%Trailer) is sent.
+
+ The output pipe of this program stays open all the time so that
+ the spooler does not assume that the job has finished when the
+ renderer is re-started.
+
+ Non DSC-conforming documents will be read until a certain line
+ number is reached. Command line or JCL options inserted later
+ will be ignored.
+
+ If options are implemented by PostScript code supposed to be
+ stuffed into the job's PostScript data we stuff the code for all
+ these options into our job data, So all default settings made in
+ the PPD file (the user can have edited the PPD file to change
+ them) are taken care of and command line options get also
+ applied. To give priority to settings made by applications we
+ insert the options's code in the beginnings of their respective
+ sections, so that sommething, which is already inserted, gets
+ executed after our code. Missing sections are automatically
+ created. In non-DSC-conforming files we insert the option code
+ in the beginning of the file. This is the same policy as used by
+ the "pstops" filter of CUPS.
+
+ If CUPS is the spooler, the option settings were already
+ inserted by the "pstops" filter, so we don't insert them
+ again. The only thing we do is correcting settings of numerical
+ options when they were set to a value not available as choice in
+ the PPD file, As "pstops" does not support "real" numerical
+ options, it sees these settings as an invalid choice and stays
+ with the default setting. In this case we correct the setting in
+ the first occurence of the option's code, as this one is the one
+ added by CUPS, later occurences come from applications and
+ should not be touched.
+
+ If the input is not PostScript (if there is no "%!" after
+ $maxlinestopsstart lines) we will abort the document with an error.
+*/
+
+/* PostScript sections */
+#define PS_SECTION_JCLSETUP 1
+#define PS_SECTION_PROLOG 2
+#define PS_SECTION_SETUP 3
+#define PS_SECTION_PAGESETUP 4
+
+#define MAX_NON_DSC_LINES_IN_HEADER 1000
+#define MAX_LINES_FOR_PAGE_OPTIONS 200
+
+typedef struct {
+ size_t pos;
+
+ FILE *file;
+ const char *alreadyread;
+ size_t len;
+} stream_t;
+
+void _print_ps(stream_t *stream);
+
+int stream_next_line(dstr_t *line, stream_t *s)
+{
+ int c;
+ size_t cnt = 0;
+
+ dstrclear(line);
+ while (s->pos < s->len) {
+ c = s->alreadyread[s->pos++];
+ dstrputc(line, c);
+ cnt++;
+ if (c == '\n')
+ return cnt;
+ }
+
+ while ((c = fgetc(s->file)) != EOF) {
+ dstrputc(line, c);
+ cnt++;
+ if (c == '\n')
+ return cnt;
+ }
+ return cnt;
+}
+
+int print_ps(FILE *file, const char *alreadyread, size_t len, const char *filename)
+{
+ stream_t stream;
+
+ if (file != stdin && (dup2(fileno(file), fileno(stdin)) < 0)) {
+ _log("Could not dup %s to stdin.\n", filename);
+ return 0;
+ }
+
+ stream.pos = 0;
+ stream.file = stdin;
+ stream.alreadyread = alreadyread;
+ stream.len = len;
+ _print_ps(&stream);
+ return 1;
+}
+
+void _print_ps(stream_t *stream)
+{
+ char *p;
+
+ int maxlines = 1000; /* Maximum number of lines to be read when the
+ documenent is not DSC-conforming.
+ "$maxlines = 0" means that all will be read and
+ examined. If it is discovered that the input
+ file is DSC-conforming, this will be set to 0. */
+
+ int maxlinestopsstart = 200; /* That many lines are allowed until the
+ "%!" indicating PS comes. These
+ additional lines in the
+ beginning are usually JCL
+ commands. The lines will be
+ ignored by our parsing but
+ passed through. */
+
+ int printprevpage = 0; /* We set this when encountering "%%Page:" and the
+ previous page is not printed yet. Then it will
+ be printed and the new page will be prepared in
+ the next run of the loop (we don't read a new
+ line and don't increase the $linect then). */
+
+ int linect = 0; /* how many lines have we examined */
+ int nonpslines = 0; /* lines before "%!" found yet. */
+ int more_stuff = 1; /* there is more stuff in stdin */
+ int saved = 0; /* DSC line not precessed yet */
+ int isdscjob = 0; /* is the job dsc conforming */
+ int inheader = 1; /* Are we still in the header, before first
+ "%%Page:" comment= */
+
+ int optionsalsointoheader = 0; /* 1: We are in a "%%BeginSetup...
+ %%EndSetup" section after the first
+ "%%Page:..." line (OpenOffice.org
+ does this and intends the options here
+ apply to the whole document and not
+ only to the current page). We have to
+ add all lines also to the end of the
+ @psheader now and we have to set
+ non-PostScript options also in the
+ "header" optionset. 0: otherwise. */
+
+ int insertoptions = 1; /* If we find out that a file with a DSC magic
+ string ("%!PS-Adobe-") is not really DSC-
+ conforming, we insert the options directly
+ after the line with the magic string. We use
+ this variable to store the number of the line
+ with the magic string */
+
+ int prologfound = 0; /* Did we find the
+ "%%BeginProlog...%%EndProlog" section? */
+ int setupfound = 0; /* Did we find the
+ %%BeginSetup...%%EndSetup" section? */
+ int pagesetupfound = 0; /* special page setup handling needed */
+
+ int inprolog = 0; /* We are between "%%BeginProlog" and "%%EndProlog" */
+ int insetup = 0; /* We are between "%%BeginSetup" and "%%EndSetup" */
+ int infeature = 0; /* We are between "%%BeginFeature" and "%%EndFeature" */
+
+ int optionreplaced = 0; /* Will be set to 1 when we are in an
+ option ("%%BeginFeature...
+ %%EndFeature") which we have replaced. */
+
+ int postscriptsection = PS_SECTION_JCLSETUP; /* In which section of the PostScript file
+ are we currently ? */
+
+ int nondsclines = 0; /* Number of subsequent lines found which are at a
+ non-DSC-conforming place, between the sections
+ of the header.*/
+
+ int nestinglevel = 0; /* Are we in the main document (0) or in an
+ embedded document bracketed by "%%BeginDocument"
+ and "%%EndDocument" (>0) We do not parse the
+ PostScript in an embedded document. */
+
+ int inpageheader = 0; /* Are we in the header of a page,
+ between "%%BeginPageSetup" and
+ "%%EndPageSetup" (1) or not (0). */
+
+ int passthru = 0; /* 0: write data into psfifo,
+ 1: pass data directly to the renderer */
+
+ int lastpassthru = 0; /* State of 'passthru' in previous line
+ (to allow debug output when $passthru
+ switches. */
+
+ int ignorepageheader = 0; /* Will be set to 1 as soon as active
+ code (not between "%%BeginPageSetup"
+ and "%%EndPageSetup") appears after a
+ "%%Page:" comment. In this case
+ "%%BeginPageSetup" and
+ "%%EndPageSetup" is not allowed any
+ more on this page and will be ignored.
+ Will be set to 0 when a new "%%Page:"
+ comment appears. */
+
+ int optset = optionset("header"); /* Where do the option settings which
+ we have found go? */
+
+ /* current line */
+ dstr_t *line = create_dstr();
+
+ dstr_t *onelinebefore = create_dstr();
+ dstr_t *twolinesbefore = create_dstr();
+
+ /* The header of the PostScript file, to be send after each start of the renderer */
+ dstr_t *psheader = create_dstr();
+
+ /* The input FIFO, data which we have pulled from stdin for examination,
+ but not send to the renderer yet */
+ dstr_t *psfifo = create_dstr();
+
+ int ignoreline;
+
+ int ooo110 = 0; /* Flag to work around an application bug */
+
+ int currentpage = 0; /* The page which we are currently printing */
+
+ option_t *o;
+ const char *val;
+
+ int linetype;
+
+ dstr_t *linesafterlastbeginfeature = create_dstr(); /* All codelines after the last "%%BeginFeature" */
+
+ char optionname [128];
+ char value [128];
+ int fromcomposite = 0;
+
+ dstr_t *pdest;
+
+ double width, height;
+
+ pid_t rendererpid = 0;
+ FILE *rendererhandle = NULL;
+
+ int retval;
+
+ dstr_t *tmp = create_dstr();
+ jobhasjcl = 0;
+
+ /* We do not parse the PostScript to find Foomatic options, we check
+ only whether we have PostScript. */
+ if (dontparse)
+ maxlines = 1;
+
+ _log("Reading PostScript input ...\n");
+
+ do {
+ ignoreline = 0;
+
+ if (printprevpage || saved || stream_next_line(line, stream)) {
+ saved = 0;
+ if (linect == nonpslines) {
+ /* In the beginning should be the postscript leader,
+ sometimes after some JCL commands */
+ if ( !(line->data[0] == '%' && line->data[1] == '!') &&
+ !(line->data[1] == '%' && line->data[2] == '!')) /* There can be a Windows control character before "%!" */
+ {
+ nonpslines++;
+ if (maxlines == nonpslines)
+ maxlines ++;
+ jobhasjcl = 1;
+
+ if (nonpslines > maxlinestopsstart) {
+ /* This is not a PostScript job, abort it */
+ _log("Job does not start with \"%%!\", is it Postscript?\n");
+ rip_die(EXIT_JOBERR, "Unknown data format.\n");
+ }
+ }
+ else {
+ /* Do we have a DSC-conforming document? */
+ if ((line->data[0] == '%' && startswith(line->data, "%!PS-Adobe-")) ||
+ (line->data[1] == '%' && startswith(line->data, "%!PS-Adobe-")))
+ {
+ /* Do not stop parsing the document */
+ if (!dontparse) {
+ maxlines = 0;
+ isdscjob = 1;
+ insertoptions = linect + 1;
+ /* We have written into psfifo before, now we continue in
+ psheader and move over the data which is already in psfifo */
+ dstrcat(psheader, psfifo->data);
+ dstrclear(psfifo);
+ }
+ _log("--> This document is DSC-conforming!\n");
+ }
+ else {
+ /* Job is not DSC-conforming, stick in all PostScript
+ option settings in the beginning */
+ append_prolog_section(line, optset, 1);
+ append_setup_section(line, optset, 1);
+ append_page_setup_section(line, optset, 1);
+ prologfound = 1;
+ setupfound = 1;
+ pagesetupfound = 1;
+ }
+ }
+ }
+ else {
+ if (startswith(line->data, "%")) {
+ if (startswith(line->data, "%%BeginDocument")) {
+ /* Beginning of an embedded document
+ Note that Adobe Acrobat has a bug and so uses
+ "%%BeginDocument " instead of "%%BeginDocument:" */
+ nestinglevel++;
+ _log("Embedded document, nesting level now: %d\n", nestinglevel);
+ }
+ else if (nestinglevel > 0 && startswith(line->data, "%%EndDocument")) {
+ /* End of an embedded document */
+ nestinglevel--;
+ _log("End of embedded document, nesting level now: %d\n", nestinglevel);
+ }
+ else if (nestinglevel == 0 && startswith(line->data, "%%Creator")) {
+ /* Here we set flags to treat particular bugs of the
+ PostScript produced by certain applications */
+ p = strstr(line->data, "%%Creator") + 9;
+ while (*p && (isspace(*p) || *p == ':')) p++;
+ if (!strcmp(p, "OpenOffice.org")) {
+ p += 14;
+ while (*p && isspace(*p)) p++;
+ if (sscanf(p, "1.1.%d", &ooo110) == 1) {
+ _log("Document created with OpenOffice.org 1.1.x\n");
+ ooo110 = 1;
+ }
+ } else if (!strcmp(p, "StarOffice 8")) {
+ p += 12;
+ _log("Document created with StarOffice 8\n");
+ ooo110 = 1;
+ }
+ }
+ else if (nestinglevel == 0 && startswith(line->data, "%%BeginProlog")) {
+ /* Note: Below is another place where a "Prolog" section
+ start will be considered. There we assume start of the
+ "Prolog" if the job is DSC-Conformimg, but an arbitrary
+ comment starting with "%%Begin", but not a comment
+ explicitly treated here, is found. This is done because
+ many "dvips" (TeX/LaTeX) files miss the "%%BeginProlog"
+ comment.
+ Beginning of Prolog */
+ _log("\n-----------\nFound: %%%%BeginProlog\n");
+ inprolog = 1;
+ if (inheader)
+ postscriptsection = PS_SECTION_PROLOG;
+ nondsclines = 0;
+ /* Insert options for "Prolog" */
+ if (!prologfound) {
+ append_prolog_section(line, optset, 0);
+ prologfound = 1;
+ }
+ }
+ else if (nestinglevel == 0 && startswith(line->data, "%%EndProlog")) {
+ /* End of Prolog */
+ _log("Found: %%%%EndProlog\n");
+ inprolog = 0;
+ insertoptions = linect +1;
+ }
+ else if (nestinglevel == 0 && startswith(line->data, "%%BeginSetup")) {
+ /* Beginning of Setup */
+ _log("\n-----------\nFound: %%%%BeginSetup\n");
+ insetup = 1;
+ nondsclines = 0;
+ /* We need to distinguish with the $inheader variable
+ here whether we are in the header or on a page, as
+ OpenOffice.org inserts a "%%BeginSetup...%%EndSetup"
+ section after the first "%%Page:..." line and assumes
+ this section to be valid for all pages. */
+ if (inheader) {
+ postscriptsection = PS_SECTION_SETUP;
+ /* If there was no "Prolog" but there are
+ options for the "Prolog", push a "Prolog"
+ with these options onto the psfifo here */
+ if (!prologfound) {
+ dstrclear(tmp);
+ append_prolog_section(tmp, optset, 1);
+ dstrprepend(line, tmp->data);
+ prologfound = 1;
+ }
+ /* Insert options for "DocumentSetup" or "AnySetup" */
+ if (spooler != SPOOLER_CUPS && !setupfound) {
+ /* For non-CUPS spoolers or no spooler at all,
+ we leave everythnig as it is */
+ append_setup_section(line, optset, 0);
+ setupfound = 1;
+ }
+ }
+ else {
+ /* Found option settings must be stuffed into both
+ the header and the currrent page now. They will
+ be written into both the "header" and the
+ "currentpage" optionsets and the PostScript code
+ lines of this section will not only go into the
+ output stream, but also added to the end of the
+ @psheader, so that they get repeated (to preserve
+ the embedded PostScript option settings) on a
+ restart of the renderer due to command line
+ option changes */
+ optionsalsointoheader = 1;
+ _log("\"%%%%BeginSetup\" in page header\n");
+ }
+ }
+ else if (nestinglevel == 0 && startswith(line->data, "%%EndSetup")) {
+ /* End of Setup */
+ _log("Found: %%%%EndSetup\n");
+ insetup = 0;
+ if (inheader)
+ insertoptions = linect +1;
+ else {
+ /* The "%%BeginSetup...%%EndSetup" which
+ OpenOffice.org has inserted after the first
+ "%%Page:..." line ends here, so the following
+ options go only onto the current page again */
+ optionsalsointoheader = 0;
+ }
+ }
+ else if (nestinglevel == 0 && startswith(line->data, "%%Page:")) {
+ if (!lastpassthru && !inheader) {
+ /* In the last line we were not in passthru mode,
+ so the last page is not printed. Prepare to do
+ it now. */
+ printprevpage = 1;
+ passthru = 1;
+ _log("New page found but previous not printed, print it now.\n");
+ }
+ else {
+ /* the previous page is printed, so we can prepare
+ the current one */
+ _log("\n-----------\nNew page: %s", line->data);
+ printprevpage = 0;
+ currentpage++;
+ /* We consider the beginning of the page already as
+ page setup section, as some apps do not use
+ "%%PageSetup" tags. */
+ postscriptsection = PS_SECTION_PAGESETUP;
+
+ /* TODO can this be removed?
+ Save PostScript state before beginning the page
+ $line .= "/foomatic-saved-state save def\n"; */
+
+ /* Here begins a new page */
+ if (inheader) {
+ build_commandline(optset, NULL, 0);
+ /* Here we add some stuff which still
+ belongs into the header */
+ dstrclear(tmp);
+
+ /* If there was no "Setup" but there are
+ options for the "Setup", push a "Setup"
+ with these options onto the @psfifo here */
+ if (!setupfound) {
+ append_setup_section(tmp, optset, 1);
+ setupfound = 1;
+ }
+ /* If there was no "Prolog" but there are
+ options for the "Prolog", push a "Prolog"
+ with these options onto the @psfifo here */
+ if (!prologfound) {
+ append_prolog_section(tmp, optset, 1);
+ prologfound = 1;
+ }
+ /* Now we push this into the header */
+ dstrcat(psheader, tmp->data);
+
+ /* The first page starts, so header ends */
+ inheader = 0;
+ nondsclines = 0;
+ /* Option setting should go into the page
+ specific option set now */
+ optset = optionset("currentpage");
+ }
+ else {
+ /* Restore PostScript state after completing the
+ previous page:
+
+ foomatic-saved-state restore
+ %%Page: ...
+ /foomatic-saved-state save def
+
+ Print this directly, so that if we need to
+ restart the renderer for this page due to
+ a command line change this is done under the
+ old instance of the renderer
+ rint $rendererhandle
+ "foomatic-saved-state restore\n"; */
+
+ /* Save the option settings of the previous page */
+ optionset_copy_values(optionset("currentpage"), optionset("previouspage"));
+ optionset_delete_values(optionset("currentpage"));
+ }
+ /* Initialize the option set */
+ optionset_copy_values(optionset("header"), optionset("currentpage"));
+
+ /* Set the command line options which apply only
+ to given pages */
+ set_options_for_page(optionset("currentpage"), currentpage);
+ pagesetupfound = 0;
+ if (spooler == SPOOLER_CUPS) {
+ /* Remove the "notfirst" flag from all options
+ forseen for the "PageSetup" section, because
+ when these are numerical options for CUPS.
+ they have to be set to the correct value
+ for every page */
+ for (o = optionlist; o; o = o->next) {
+ if (option_get_section(o ) == SECTION_PAGESETUP)
+ o->notfirst = 0;
+ }
+ }
+ /* Now the page header comes, so buffer the data,
+ because we must perhaps shut down and restart
+ the renderer */
+ passthru = 0;
+ ignorepageheader = 0;
+ optionsalsointoheader = 0;
+ }
+ }
+ else if (nestinglevel == 0 && !ignorepageheader &&
+ startswith(line->data, "%%BeginPageSetup")) {
+ /* Start of the page header, up to %%EndPageSetup
+ nothing of the page will be drawn, page-specific
+ option settngs (as letter-head paper for page 1)
+ go here*/
+ _log("\nFound: %%%%BeginPageSetup\n");
+ passthru = 0;
+ inpageheader = 1;
+ postscriptsection = PS_SECTION_PAGESETUP;
+ optionsalsointoheader = (ooo110 && currentpage == 1) ? 1 : 0;
+ /* Insert PostScript option settings
+ (options for section "PageSetup") */
+ if (isdscjob) {
+ append_page_setup_section(line, optset, 0);
+ pagesetupfound = 1;
+ }
+ }
+ else if (nestinglevel == 0 && !ignorepageheader &&
+ startswith(line->data, "%%BeginPageSetup")) {
+ /* End of the page header, the page is ready to be printed */
+ _log("Found: %%%%EndPageSetup\n");
+ _log("End of page header\n");
+ /* We cannot for sure say that the page header ends here
+ OpenOffice.org puts (due to a bug) a "%%BeginSetup...
+ %%EndSetup" section after the first "%%Page:...". It
+ is possible that CUPS inserts a "%%BeginPageSetup...
+ %%EndPageSetup" before this section, which means that
+ the options in the "%%BeginSetup...%%EndSetup"
+ section are after the "%%EndPageSetup", so we
+ continue for searching options up to the buffer size
+ limit $maxlinesforpageoptions. */
+ passthru = 0;
+ inpageheader = 0;
+ optionsalsointoheader = 0;
+ }
+ else if (nestinglevel == 0 && !optionreplaced && (!passthru || !isdscjob) &&
+ ((linetype = line_type(line->data)) &&
+ (linetype == LT_BEGIN_FEATURE || linetype == LT_FOOMATIC_RIP_OPTION_SETTING))) {
+
+ /* parse */
+ if (linetype == LT_BEGIN_FEATURE) {
+ dstrcpy(tmp, line->data);
+ p = strtok(tmp->data, " \t"); /* %%BeginFeature: */
+ p = strtok(NULL, " \t="); /* Option */
+ if (*p == '*') p++;
+ strlcpy(optionname, p, 128);
+ p = strtok(NULL, " \t\r\n"); /* value */
+ fromcomposite = 0;
+ strlcpy(value, p, 128);
+ }
+ else { /* LT_FOOMATIC_RIP_OPTION_SETTING */
+ dstrcpy(tmp, line->data);
+ p = strstr(tmp->data, "FoomaticRIPOptionSetting:");
+ p = strtok(p, " \t"); /* FoomaticRIPOptionSetting */
+ p = strtok(NULL, " \t="); /* Option */
+ strlcpy(optionname, p, 128);
+ p = strtok(NULL, " \t\r\n"); /* value */
+ if (*p == '@') { /* fromcomposite */
+ p++;
+ fromcomposite = 1;
+ }
+ else
+ fromcomposite = 0;
+ strlcpy(value, p, 128);
+ }
+
+ /* Mark that we are in a "Feature" section */
+ if (linetype == LT_BEGIN_FEATURE) {
+ infeature = 1;
+ dstrclear(linesafterlastbeginfeature);
+ }
+
+ /* OK, we have an option. If it's not a
+ Postscript-style option (ie, it's command-line or
+ JCL) then we should note that fact, since the
+ attribute-to-filter option passing in CUPS is kind of
+ funky, especially wrt boolean options. */
+ _log("Found: %s", line->data);
+ if ((o = find_option(optionname)) &&
+ (o->type != TYPE_NONE)) {
+ _log(" Option: %s=%s%s\n", optionname, fromcomposite ? "From" : "", value);
+ if (spooler == SPOOLER_CUPS &&
+ linetype == LT_BEGIN_FEATURE &&
+ !option_get_value(o, optionset("notfirst")) &&
+ strcmp((val = option_get_value(o, optset)) ? val : "", value) != 0 &&
+ (inheader || option_get_section(o) == SECTION_PAGESETUP)) {
+
+ /* We have the first occurence of an option
+ setting and the spooler is CUPS, so this
+ setting is inserted by "pstops" or
+ "imagetops". The value from the command
+ line was not inserted by "pstops" or
+ "imagetops" so it seems to be not under
+ the choices in the PPD. Possible
+ reasons:
+
+ - "pstops" and "imagetops" ignore settings
+ of numerical or string options which are
+ not one of the choices in the PPD file,
+ and inserts the default value instead.
+
+ - On the command line an option was applied
+ only to selected pages:
+ "-o <page ranges>:<option>=<values>
+ This is not supported by CUPS, so not
+ taken care of by "pstops".
+
+ We must fix this here by replacing the
+ setting inserted by "pstops" or "imagetops"
+ with the exact setting given on the command
+ line. */
+
+ /* $arg->{$optionset} is already
+ range-checked, so do not check again here
+ Insert DSC comment */
+ pdest = (inheader && isdscjob) ? psheader : psfifo;
+ if (option_is_ps_command(o)) {
+ /* PostScript option, insert the code */
+
+ option_get_command(tmp, o, optset, -1);
+ if (!(val = option_get_value(o, optset)))
+ val = "";
+
+ /* Boolean and enumerated choice options can only be set in the
+ * PageSetup section */
+ if ((inheader && option_is_custom_value(o, val)) || !inheader)
+ {
+ if (o->type == TYPE_BOOL)
+ dstrcatf(pdest, "%%%%BeginFeature: *%s %s\n", o->name,
+ val && !strcmp(val, "1") ? "True" : "False");
+ else
+ dstrcatf(pdest, "%%%%BeginFeature: *%s %s\n", o->name, val);
+
+ dstrcatf(pdest, "%s\n", tmp->data);
+
+ /* We have replaced this option on the FIFO */
+ optionreplaced = 1;
+ }
+ }
+ else { /* Command line or JCL option */
+ val = option_get_value(o, optset);
+
+ if (!inheader || option_is_custom_value(o, val)) {
+ dstrcatf(pdest, "%%%% FoomaticRIPOptionSetting: %s=%s\n",
+ o->name, val ? val : "");
+ optionreplaced = 1;
+ }
+ }
+
+ if (optionreplaced) {
+ val = option_get_value(o, optset);
+ _log(" --> Correcting numerical/string option to %s=%s (Command line argument)\n",
+ o->name, val ? val : "");
+ }
+ }
+
+ /* Mark that we have already found this option */
+ o->notfirst = 1;
+ if (!optionreplaced) {
+ if (o->style != 'G') {
+ /* Controlled by '<Composite>' setting of
+ a member option of a composite option */
+ if (fromcomposite) {
+ dstrcpyf(tmp, "From%s", value);
+ strlcpy(value, tmp->data, 128);
+ }
+
+ /* Non PostScript option
+ Check whether it is valid */
+ if (option_set_value(o, optset, value)) {
+ _log("Setting option\n");
+ strlcpy(value, option_get_value(o, optset), 128);
+ if (optionsalsointoheader)
+ option_set_value(o, optionset("header"), value);
+ if (o->type == TYPE_ENUM &&
+ (!strcmp(o->name, "PageSize") || !strcmp(o->name, "PageRegion")) &&
+ startswith(value, "Custom") &&
+ linetype == LT_FOOMATIC_RIP_OPTION_SETTING) {
+ /* Custom Page size */
+ width = height = 0.0;
+ p = linesafterlastbeginfeature->data;
+ while (*p && isspace(*p)) p++;
+ width = strtod(p, &p);
+ while (*p && isspace(*p)) p++;
+ height = strtod(p, &p);
+ if (width && height) {
+ dstrcpyf(tmp, "%s.%fx%f", value, width, height);
+ strlcpy(value, tmp->data, 128);
+ option_set_value(o, optset, value);
+ if (optionsalsointoheader)
+ option_set_value(o, optionset("header"), value);
+ }
+ }
+ /* For a composite option insert the
+ code from the member options with
+ current setting "From<composite>"
+ The code from the member options
+ is chosen according to the setting
+ of the composite option. */
+ if (option_is_composite(o) && linetype == LT_FOOMATIC_RIP_OPTION_SETTING) {
+ build_commandline(optset, NULL, 0); /* TODO can this be removed? */
+
+ /* TODO merge section and ps_section */
+ if (postscriptsection == PS_SECTION_JCLSETUP)
+ option_get_command(tmp, o, optset, SECTION_JCLSETUP);
+ else if (postscriptsection == PS_SECTION_PROLOG)
+ option_get_command(tmp, o, optset, SECTION_PROLOG);
+ else if (postscriptsection == PS_SECTION_SETUP)
+ option_get_command(tmp, o, optset, SECTION_DOCUMENTSETUP);
+ else if (postscriptsection == PS_SECTION_PAGESETUP)
+ option_get_command(tmp, o, optset, SECTION_PAGESETUP);
+ dstrcat(line, tmp->data);
+ }
+ }
+ else
+ _log(" --> Invalid option setting found in job\n");
+ }
+ else if (fromcomposite) {
+ /* PostScript option, but we have to look up
+ the PostScript code to be inserted from
+ the setting of a composite option, as
+ this option is set to "Controlled by
+ '<Composite>'". */
+ /* Set the option */
+ dstrcpyf(tmp, "From%s", value);
+ strlcpy(value, tmp->data, 128);
+ if (option_set_value(o, optset, value)) {
+ _log(" --> Looking up setting in composite option %s\n", value);
+ if (optionsalsointoheader)
+ option_set_value(o, optionset("header"), value);
+ /* update composite options */
+ build_commandline(optset, NULL, 0);
+ /* Substitute PostScript comment by the real code */
+ /* TODO what exactly is the next line doing? */
+ /* dstrcpy(line, o->compositesubst->data); */
+ }
+ else
+ _log(" --> Invalid option setting found in job\n");
+ }
+ else
+ /* it is a PostScript style option with
+ the code readily inserted, no option
+ for the renderer command line/JCL to set,
+ no lookup of a composite option needed,
+ so nothing to do here... */
+ _log(" --> Option will be set by PostScript interpreter\n");
+ }
+ }
+ else
+ /* This option is unknown to us, WTF? */
+ _log("Unknown option %s=%s found in the job\n", optionname, value);
+ }
+ else if (nestinglevel == 0 && startswith(line->data, "%%EndFeature")) {
+ /* End of feature */
+ infeature = 0;
+ /* If the option setting was replaced, it ends here,
+ too, and the next option is not necessarily also replaced */
+ optionreplaced = 0;
+ dstrclear(linesafterlastbeginfeature);
+ }
+ else if (nestinglevel == 0 && isdscjob && !prologfound &&
+ startswith(line->data, "%%Begin")) {
+ /* In some PostScript files (especially when generated
+ by "dvips" of TeX/LaTeX) the "%%BeginProlog" is
+ missing, so assume that it was before the current
+ line (the first line starting with "%%Begin". */
+ _log("Job claims to be DSC-conforming, but \"%%%%BeginProlog\" "
+ "was missing before first line with another"
+ "\"%%%%BeginProlog\" comment (is this a TeX/LaTeX/dvips-generated"
+ " PostScript file?). Assuming start of \"Prolog\" here.\n");
+ /* Beginning of Prolog */
+ inprolog = 1;
+ nondsclines = 0;
+ /* Insert options for "Prolog" before the current line */
+ dstrcpyf(tmp, "%%%%BeginProlog\n");
+ append_prolog_section(tmp, optset, 0);
+ dstrprepend(line, tmp->data);
+ prologfound = 1;
+ }
+ else if (nestinglevel == 0 && (
+ startswith(line->data, "%RBINumCopies:") ||
+ startswith(line->data, "%%RBINumCopies:"))) {
+ p = strchr(line->data, ':') +1;
+ get_current_job()->rbinumcopies = atoi(p);
+ _log("Found %RBINumCopies: %d\n", get_current_job()->rbinumcopies);
+ }
+ else if (startswith(skip_whitespace(line->data), "%") ||
+ startswith(skip_whitespace(line->data), "$"))
+ /* This is an unknown PostScript comment or a blank
+ line, no active code */
+ ignoreline = 1;
+ }
+ else {
+ /* This line is active PostScript code */
+ if (infeature)
+ /* Collect coe in a "%%BeginFeature: ... %%EndFeature"
+ section, to get the values for a custom option
+ setting */
+ dstrcat(linesafterlastbeginfeature, line->data);
+
+ if (inheader) {
+ if (!inprolog && !insetup) {
+ /* Outside the "Prolog" and "Setup" section
+ a correct DSC-conforming document has no
+ active PostScript code, so consider the
+ file as non-DSC-conforming when there are
+ too many of such lines. */
+ nondsclines++;
+ if (nondsclines > MAX_NON_DSC_LINES_IN_HEADER) {
+ /* Consider document as not DSC-conforming */
+ _log("This job seems not to be DSC-conforming, "
+ "DSC-comment for next section not found, "
+ "stopping to parse the rest, passing it "
+ "directly to the renderer.\n");
+ /* Stop scanning for further option settings */
+ maxlines = 1;
+ isdscjob = 0;
+ /* Insert defaults and command line settings in
+ the beginning of the job or after the last valid
+ section */
+ dstrclear(tmp);
+ if (prologfound)
+ append_prolog_section(tmp, optset, 1);
+ if (setupfound)
+ append_setup_section(tmp, optset, 1);
+ if (pagesetupfound)
+ append_page_setup_section(tmp, optset, 1);
+ dstrinsert(psheader, line_start(psheader->data, insertoptions), tmp->data);
+
+ prologfound = 1;
+ setupfound = 1;
+ pagesetupfound = 1;
+ }
+ }
+ }
+ else if (!inpageheader) {
+ /* PostScript code inside a page, but not between
+ "%%BeginPageSetup" and "%%EndPageSetup", so
+ we are perhaps already drawing onto a page now */
+ if (startswith(onelinebefore->data, "%%Page"))
+ _log("No page header or page header not DSC-conforming\n");
+ /* Stop buffering lines to search for options
+ placed not DSC-conforming */
+ if (line_count(psfifo->data) >= MAX_LINES_FOR_PAGE_OPTIONS) {
+ _log("Stopping search for page header options\n");
+ passthru = 1;
+ /* If there comes a page header now, ignore it */
+ ignorepageheader = 1;
+ optionsalsointoheader = 0;
+ }
+ /* Insert PostScript option settings (options for the
+ * section "PageSetup" */
+ if (isdscjob && !pagesetupfound) {
+ append_page_setup_section(psfifo, optset, 1);
+ pagesetupfound = 1;
+ }
+ }
+ }
+ }
+
+ /* Debug Info */
+ if (lastpassthru != passthru) {
+ if (passthru)
+ _log("Found: %s --> Output goes directly to the renderer now.\n\n", line->data);
+ else
+ _log("Found: %s --> Output goes to the FIFO buffer now.\n\n", line->data);
+ }
+
+ /* We are in an option which was replaced, do not output the current line */
+ if (optionreplaced)
+ dstrclear(line);
+
+ /* If we are in a "%%BeginSetup...%%EndSetup" section after
+ the first "%%Page:..." and the current line belongs to
+ an option setting, we have to copy the line also to the
+ @psheader. */
+ if (optionsalsointoheader && (infeature || startswith(line->data, "%%EndFeature")))
+ dstrcat(psheader, line->data);
+
+ /* Store or send the current line */
+ if (inheader && isdscjob) {
+ /* We are still in the PostScript header, collect all lines
+ in @psheader */
+ dstrcat(psheader, line->data);
+ }
+ else {
+ if (passthru && isdscjob) {
+ if (!lastpassthru) {
+ /*
+ * We enter passthru mode with this line, so the
+ * command line can have changed, check it and close
+ * the renderer if needed
+ */
+ if (rendererpid && !optionset_equal(optionset("currentpage"), optionset("previouspage"), 0)) {
+ _log("Command line/JCL options changed, restarting renderer\n");
+ retval = close_renderer_handle(rendererhandle, rendererpid);
+ if (retval != EXIT_PRINTED)
+ rip_die(retval, "Error closing renderer\n");
+ rendererpid = 0;
+ }
+ }
+
+ /* Flush psfifo and send line directly to the renderer */
+ if (!rendererpid) {
+ /* No renderer running, start it */
+ dstrcpy(tmp, psheader->data);
+ dstrcat(tmp, psfifo->data);
+ get_renderer_handle(tmp, &rendererhandle, &rendererpid);
+ /* psfifo is sent out, flush it */
+ dstrclear(psfifo);
+ }
+
+ if (!isempty(psfifo->data)) {
+ /* Send psfifo to renderer */
+ fwrite_or_die(psfifo->data, psfifo->len, 1, rendererhandle);
+ /* flush psfifo */
+ dstrclear(psfifo);
+ }
+
+ /* Send line to renderer */
+ if (!printprevpage) {
+ fwrite_or_die(line->data, line->len, 1, rendererhandle);
+
+ while (stream_next_line(line, stream) > 0) {
+ if (startswith(line->data, "%%")) {
+ _log("Found: %s", line->data);
+ _log(" --> Continue DSC parsing now.\n\n");
+ saved = 1;
+ break;
+ }
+ else {
+ fwrite_or_die(line->data, line->len, 1, rendererhandle);
+ linect++;
+ }
+ }
+ }
+ }
+ else {
+ /* Push the line onto the stack to split up later */
+ dstrcat(psfifo, line->data);
+ }
+ }
+
+ if (!printprevpage)
+ linect++;
+ }
+ else {
+ /* EOF! */
+ more_stuff = 0;
+
+ /* No PostScript header in the whole file? Then it's not
+ PostScript, convert it.
+ We open the file converter here when the file has less
+ lines than the amount which we search for the PostScript
+ header ($maxlinestopsstart). */
+ if (linect <= nonpslines) {
+ /* This is not a PostScript job, abort it */
+ _log("Job does not start with \"%%!\", is it Postscript?\n");
+ rip_die(EXIT_JOBERR, "Unknown data format.\n");
+ }
+ }
+
+ lastpassthru = passthru;
+
+ if (!ignoreline && !printprevpage) {
+ dstrcpy(twolinesbefore, onelinebefore->data);
+ dstrcpy(onelinebefore, line->data);
+ }
+
+ } while ((maxlines == 0 || linect < maxlines) && more_stuff != 0);
+
+ /* Some buffer still containing data? Send it out to the renderer */
+ if (more_stuff || inheader || !isempty(psfifo->data)) {
+ /* Flush psfifo and send the remaining data to the renderer, this
+ only happens with non-DSC-conforming jobs or non-Foomatic PPDs */
+ if (more_stuff)
+ _log("Stopped parsing the PostScript data, "
+ "sending rest directly to the renderer.\n");
+ else
+ _log("Flushing FIFO.\n");
+
+ if (inheader) {
+ build_commandline(optset, NULL, 0);
+ /* No page initialized yet? Copy the "header" option set into the
+ "currentpage" option set, so that the renderer will find the
+ options settings. */
+ optionset_copy_values(optionset("header"), optionset("currentpage"));
+ optset = optionset("currentpage");
+
+ /* If not done yet, insert defaults and command line settings
+ in the beginning of the job or after the last valid section */
+ dstrclear(tmp);
+ if (prologfound)
+ append_prolog_section(tmp, optset, 1);
+ if (setupfound)
+ append_setup_section(tmp, optset, 1);
+ if (pagesetupfound)
+ append_page_setup_section(tmp, optset, 1);
+ dstrinsert(psheader, line_start(psheader->data, insertoptions), tmp->data);
+
+ prologfound = 1;
+ setupfound = 1;
+ pagesetupfound = 1;
+ }
+
+ if (rendererpid > 0 && !optionset_equal(optionset("currentpage"), optionset("previouspage"), 0)) {
+ _log("Command line/JCL options changed, restarting renderer\n");
+ retval = close_renderer_handle(rendererhandle, rendererpid);
+ if (retval != EXIT_PRINTED)
+ rip_die(retval, "Error closing renderer\n");
+ rendererpid = 0;
+ }
+
+ if (!rendererpid) {
+ dstrcpy(tmp, psheader->data);
+ dstrcat(tmp, psfifo->data);
+ get_renderer_handle(tmp, &rendererhandle, &rendererpid);
+ /* We have sent psfifo now */
+ dstrclear(psfifo);
+ }
+
+ if (psfifo->len) {
+ /* Send psfifo to the renderer */
+ fwrite_or_die(psfifo->data, psfifo->len, 1, rendererhandle);
+ dstrclear(psfifo);
+ }
+
+ /* Print the rest of the input data */
+ if (more_stuff) {
+ while (stream_next_line(tmp, stream))
+ fwrite_or_die(tmp->data, tmp->len, 1, rendererhandle);
+ }
+ }
+
+ /* At every "%%Page:..." comment we have saved the PostScript state
+ and we have increased the page number. So if the page number is
+ non-zero we had at least one "%%Page:..." comment and so we have
+ to give a restore the PostScript state.
+ if ($currentpage > 0) {
+ print $rendererhandle "foomatic-saved-state restore\n";
+ } */
+
+ /* Close the renderer */
+ if (rendererpid) {
+ retval = close_renderer_handle(rendererhandle, rendererpid);
+ if (retval != EXIT_PRINTED)
+ rip_die(retval, "Error closing renderer\n");
+ rendererpid = 0;
+ }
+
+ free_dstr(line);
+ free_dstr(onelinebefore);
+ free_dstr(twolinesbefore);
+ free_dstr(psheader);
+ free_dstr(psfifo);
+ free_dstr(tmp);
+}
+
+/*
+ * Run the renderer command line (and if defined also the postpipe) and returns
+ * a file handle for stuffing in the PostScript data.
+ */
+void get_renderer_handle(const dstr_t *prepend, FILE **fd, pid_t *pid)
+{
+ pid_t kid3;
+ FILE *kid3in;
+ dstr_t *cmdline = create_dstr();
+
+ /* Build the command line and get the JCL commands */
+ build_commandline(optionset("currentpage"), cmdline, 0);
+ massage_gs_commandline(cmdline);
+
+ _log("\nStarting renderer with command: \"%s\"\n", cmdline->data);
+ kid3 = start_process("kid3", exec_kid3, (void *)cmdline->data, &kid3in, NULL);
+ if (kid3 < 0)
+ rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "Cannot fork for kid3\n");
+
+ /* Feed the PostScript header and the FIFO contents */
+ if (prepend)
+ fwrite_or_die(prepend->data, prepend->len, 1, kid3in);
+
+ /* We are the parent, return glob to the file handle */
+ *fd = kid3in;
+ *pid = kid3;
+
+ free_dstr(cmdline);
+}
+
+/* Close the renderer process and wait until all kid processes finish */
+int close_renderer_handle(FILE *rendererhandle, pid_t rendererpid)
+{
+ int status;
+
+ _log("\nClosing renderer\n");
+ fclose(rendererhandle);
+
+ status = wait_for_process(rendererpid);
+ if (WIFEXITED(status))
+ return WEXITSTATUS(status);
+ else
+ return EXIT_PRNERR_NORETRY_BAD_SETTINGS;
+}
+
diff --git a/filter/foomatic-rip/postscript.h b/filter/foomatic-rip/postscript.h
new file mode 100644
index 000000000..cb6c52581
--- /dev/null
+++ b/filter/foomatic-rip/postscript.h
@@ -0,0 +1,30 @@
+/* postscript.h
+ *
+ * Copyright (C) 2008 Till Kamppeter <till.kamppeter@gmail.com>
+ * Copyright (C) 2008 Lars Uebernickel <larsuebernickel@gmx.de>
+ *
+ * This file is part of foomatic-rip.
+ *
+ * Foomatic-rip 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Foomatic-rip 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 Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef postscript_h
+#define postscript_h
+
+int print_ps(FILE *s, const char *alreadyread, size_t len, const char *filename);
+
+#endif
+
diff --git a/filter/foomatic-rip/process.c b/filter/foomatic-rip/process.c
new file mode 100644
index 000000000..a91289a25
--- /dev/null
+++ b/filter/foomatic-rip/process.c
@@ -0,0 +1,229 @@
+/* process.c
+ *
+ * Copyright (C) 2008 Till Kamppeter <till.kamppeter@gmail.com>
+ * Copyright (C) 2008 Lars Uebernickel <larsuebernickel@gmx.de>
+ *
+ * This file is part of foomatic-rip.
+ *
+ * Foomatic-rip 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Foomatic-rip 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 Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "foomaticrip.h"
+#include "process.h"
+#include <unistd.h>
+#include "util.h"
+#include <sys/wait.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <signal.h>
+
+int kidgeneration = 0;
+
+struct process {
+ char name[64];
+ pid_t pid;
+ int isgroup;
+};
+
+#define MAX_CHILDS 4
+struct process procs[MAX_CHILDS] = {
+ { "", -1, 0 },
+ { "", -1, 0 },
+ { "", -1, 0 },
+ { "", -1, 0 }
+};
+
+void add_process(const char *name, int pid, int isgroup)
+{
+ int i;
+ for (i = 0; i < MAX_CHILDS; i++) {
+ if (procs[i].pid == -1) {
+ strlcpy(procs[i].name, name, 64);
+ procs[i].pid = pid;
+ procs[i].isgroup = isgroup;
+ return;
+ }
+ }
+ rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "Didn't think there would be that many child processes... Exiting.\n");
+}
+
+int find_process(int pid)
+{
+ int i;
+ for (i = 0; i < MAX_CHILDS; i++)
+ if (procs[i].pid == pid)
+ return i;
+ return -1;
+}
+
+void clear_proc_list()
+{
+ int i;
+ for (i = 0; i < MAX_CHILDS; i++)
+ procs[i].pid = -1;
+}
+
+void kill_all_processes()
+{
+ int i;
+
+ for (i = 0; i < MAX_CHILDS; i++) {
+ if (procs[i].pid == -1)
+ continue;
+ _log("Killing %s\n", procs[i].name);
+ kill(procs[i].isgroup ? -procs[i].pid : procs[i].pid, 15);
+ sleep(1 << (3 - kidgeneration));
+ kill(procs[i].isgroup ? -procs[i].pid : procs[i].pid, 9);
+ }
+ clear_proc_list();
+}
+
+static pid_t _start_process(const char *name,
+ int (*proc_func)(FILE *, FILE *, void *),
+ void *user_arg, FILE **pipe_in, FILE **pipe_out,
+ int createprocessgroup)
+{
+ pid_t pid;
+ int pfdin[2], pfdout[2];
+ int ret;
+ FILE *in, *out;
+
+ if (pipe_in)
+ if (pipe(pfdin) < 0)
+ return -1;
+ if (pipe_out)
+ if (pipe(pfdout) < 0)
+ return -1;
+
+ _log("Starting process \"%s\" (generation %d)\n", name, kidgeneration +1);
+
+ pid = fork();
+ if (pid < 0) {
+ _log("Could not fork for %s\n", name);
+ if (pipe_in) {
+ close(pfdin[0]);
+ close(pfdin[1]);
+ }
+ if (pipe_out) {
+ close(pfdout[0]);
+ close(pfdout[1]);
+ }
+ return -1;
+ }
+
+ if (pid == 0) { /* Child */
+
+ // Reset sigpipe behavior to default for all children
+ signal(SIGPIPE, SIG_DFL);
+
+ if (pipe_in) {
+ close(pfdin[1]);
+ in = fdopen(pfdin[0], "r");
+ }
+ else
+ in = NULL;
+
+ if (pipe_out) {
+ close(pfdout[0]);
+ out = fdopen(pfdout[1], "w");
+ }
+ else
+ out = NULL;
+
+ if (createprocessgroup)
+ setpgid(0, 0);
+
+ kidgeneration++;
+
+ /* The subprocess list is only valid for the parent. Clear it. */
+ clear_proc_list();
+
+ ret = proc_func(in, out, user_arg);
+ exit(ret);
+ }
+
+ /* Parent */
+ if (pipe_in) {
+ close(pfdin[0]);
+ *pipe_in = fdopen(pfdin[1], "w");
+ if (!*pipe_in)
+ _log("fdopen: %s\n", strerror(errno));
+ }
+ if (pipe_out) {
+ close(pfdout[1]);
+ *pipe_out = fdopen(pfdout[0], "r");
+ if (!*pipe_out)
+ _log("fdopen: %s\n", strerror(errno));
+ }
+
+ /* Add the child process to the list of open processes (to be able to kill
+ * them in case of a signal. */
+ add_process(name, pid, createprocessgroup);
+
+ return pid;
+}
+
+int exec_command(FILE *in, FILE *out, void *cmd)
+{
+ if (in && dup2(fileno(in), fileno(stdin)) < 0)
+ rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "%s: Could not dup stdin\n", (const char *)cmd);
+ if (out && dup2(fileno(out), fileno(stdout)) < 0)
+ rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS, "%s: Could not dup stdout\n", (const char *)cmd);
+
+ execl(get_modern_shell(), get_modern_shell(), "-e", "-c", (const char *)cmd, (char *)NULL);
+
+ _log("Error: Executing \"%s -c %s\" failed (%s).\n", get_modern_shell(), (const char *)cmd, strerror(errno));
+ return EXIT_PRNERR_NORETRY_BAD_SETTINGS;
+}
+
+pid_t start_system_process(const char *name, const char *command, FILE **fdin, FILE **fdout)
+{
+ return _start_process(name, exec_command, (void*)command, fdin, fdout, 1);
+}
+
+pid_t start_process(const char *name, int (*proc_func)(FILE *, FILE *, void *), void *user_arg, FILE **fdin, FILE **fdout)
+{
+ return _start_process(name, proc_func, user_arg, fdin, fdout, 0);
+}
+
+int wait_for_process(int pid)
+{
+ int i;
+ int status;
+
+ i = find_process(pid);
+ if (i < 0) {
+ _log("No such process \"%d\"", pid);
+ return -1;
+ }
+
+ waitpid(procs[i].pid, &status, 0);
+ if (WIFEXITED(status))
+ _log("%s exited with status %d\n", procs[i].name, WEXITSTATUS(status));
+ else if (WIFSIGNALED(status))
+ _log("%s received signal %d\n", procs[i].name, WTERMSIG(status));
+
+ /* remove from process list */
+ procs[i].pid = -1;
+ return status;
+}
+
+int run_system_process(const char *name, const char *command)
+{
+ int pid = start_system_process(name, command, NULL, NULL);
+ return wait_for_process(pid);
+}
+
diff --git a/filter/foomatic-rip/process.h b/filter/foomatic-rip/process.h
new file mode 100644
index 000000000..b95dcb4da
--- /dev/null
+++ b/filter/foomatic-rip/process.h
@@ -0,0 +1,48 @@
+/* process.h
+ *
+ * Copyright (C) 2008 Till Kamppeter <till.kamppeter@gmail.com>
+ * Copyright (C) 2008 Lars Uebernickel <larsuebernickel@gmx.de>
+ *
+ * This file is part of foomatic-rip.
+ *
+ * Foomatic-rip 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Foomatic-rip 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 Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef process_h
+#define process_h
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+pid_t start_process(const char *name, int (*proc_func)(), void *user_arg, FILE **fdin, FILE **fdout);
+pid_t start_system_process(const char *name, const char *command, FILE **fdin, FILE **fdout);
+
+/* returns command's return status (see waitpid(2)) */
+int run_system_process(const char *name, const char *command);
+
+pid_t create_pipe_process(const char *name,
+ FILE *src,
+ FILE *dest,
+ const char *alreadyread,
+ size_t alreadyread_len);
+
+int wait_for_process(int pid);
+
+void kill_all_processes();
+
+#endif
+
diff --git a/filter/foomatic-rip/renderer.c b/filter/foomatic-rip/renderer.c
new file mode 100644
index 000000000..2fd3c689f
--- /dev/null
+++ b/filter/foomatic-rip/renderer.c
@@ -0,0 +1,491 @@
+/* renderer.c
+ *
+ * Copyright (C) 2008 Till Kamppeter <till.kamppeter@gmail.com>
+ * Copyright (C) 2008 Lars Uebernickel <larsuebernickel@gmx.de>
+ *
+ * This file is part of foomatic-rip.
+ *
+ * Foomatic-rip 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Foomatic-rip 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 Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <config.h>
+#include <signal.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "foomaticrip.h"
+#include "util.h"
+#include "process.h"
+#include "options.h"
+
+/*
+ * Check whether we have a Ghostscript version with redirection of the standard
+ * output of the PostScript programs via '-sstdout=%stderr'
+ */
+int test_gs_output_redirection()
+{
+ char gstestcommand[CMDLINE_MAX];
+ char output[10] = "";
+ int bytes;
+
+ snprintf(gstestcommand, CMDLINE_MAX,
+ "%s -dQUIET -dPARANOIDSAFER -dNOPAUSE "
+ "-dBATCH -dNOMEDIAATTRS -sDEVICE=ps2write -sstdout=%%stderr "
+ "-sOutputFile=/dev/null -c '(hello\n) print flush' 2>&1", gspath);
+
+ FILE *pd = popen(gstestcommand, "r");
+ if (!pd) {
+ _log("Failed to execute ghostscript!\n");
+ return 0;
+ }
+
+ bytes = fread_or_die(output, 1, 10, pd);
+ pclose(pd);
+
+ if (bytes > 0 && startswith(output, "hello"))
+ return 1;
+
+ return 0;
+}
+
+/*
+ * Massage arguments to make ghostscript execute properly as a filter, with
+ * output on stdout and errors on stderr etc. (This function does what
+ * foomatic-gswrapper used to do)
+ */
+void massage_gs_commandline(dstr_t *cmd)
+{
+ int gswithoutputredirection = test_gs_output_redirection();
+ size_t start, end;
+ dstr_t *gscmd, *cmdcopy;
+
+ extract_command(&start, &end, cmd->data, "gs");
+ if (start == end) /* cmd doesn't call ghostscript */
+ return;
+
+ gscmd = create_dstr();
+ dstrncpy(gscmd, &cmd->data[start], end - start);
+
+ /* If Ghostscript does not support redirecting the standard output
+ of the PostScript program to standard error with '-sstdout=%stderr', sen
+ the job output data to fd 3; errors will be on 2(stderr) and job ps
+ program interpreter output on 1(stdout). */
+ if (gswithoutputredirection)
+ dstrreplace(gscmd, "-sOutputFile=- ", "-sOutputFile=%stdout ", 0);
+ else
+ dstrreplace(gscmd, "-sOutputFile=- ", "-sOutputFile=/dev/fd/3 ", 0);
+
+ /* Use always buffered input. This works around a Ghostscript
+ bug which prevents printing encrypted PDF files with Adobe Reader 8.1.1
+ and Ghostscript built as shared library (Ghostscript bug #689577, Ubuntu
+ bug #172264) */
+ if (dstrendswith(gscmd, " -"))
+ dstrcat(gscmd, "_");
+ else
+ dstrreplace(gscmd, " - ", " -_ ", 0);
+ dstrreplace(gscmd, " /dev/fd/0", " -_ ", 0);
+
+ /* Turn *off* -q (quiet!); now that stderr is useful! :) */
+ dstrreplace(gscmd, " -q ", " ", 0);
+
+ /* Escape any quotes, and then quote everything just to be sure...
+ Escaping a single quote inside single quotes is a bit complex as the
+ shell takes everything literal there. So we have to assemble it by
+ concatinating different quoted strings. Finally we get e.g.: 'x'"'"'y'
+ or ''"'"'xy' or 'xy'"'"'' or ... */
+ /* dstrreplace(cmd, "'", "'\"'\"'"); TODO tbd */
+
+ dstrremove(gscmd, 0, 2); /* Remove 'gs' */
+ if (gswithoutputredirection)
+ {
+ dstrprepend(gscmd, " -sstdout=%stderr ");
+ dstrprepend(gscmd, gspath);
+ }
+ else
+ {
+ dstrprepend(gscmd, gspath);
+ dstrcat(gscmd, " 3>&1 1>&2");
+ }
+
+ /* put gscmd back into cmd, between 'start' and 'end' */
+ cmdcopy = create_dstr();
+ dstrcpy(cmdcopy, cmd->data);
+
+ dstrncpy(cmd, cmdcopy->data, start);
+ dstrcat(cmd, gscmd->data);
+ dstrcat(cmd, &cmdcopy->data[end]);
+
+ free_dstr(gscmd);
+ free_dstr(cmdcopy);
+
+ /* If the renderer command line contains the "echo" command, replace the
+ * "echo" by the user-chosen $myecho (important for non-GNU systems where
+ * GNU echo is in a special path */
+ dstrreplace(cmd, "echo", echopath, 0); /* TODO search for \wecho\w */
+}
+
+char * read_line(FILE *stream, size_t *readbytes)
+{
+ char *line;
+ size_t alloc = 64, len = 0;
+ int c;
+
+ line = malloc(alloc);
+
+ while ((c = fgetc(stream)) != EOF) {
+ if (len >= alloc -1) {
+ alloc *= 2;
+ line = realloc(line, alloc);
+ }
+ line[len] = (char)c;
+ len++;
+ if (c == '\n')
+ break;
+ }
+
+ line[len] = '\0';
+ *readbytes = len;
+ return line;
+}
+
+void write_binary_data(FILE *stream, const char *data, size_t bytes)
+{
+ int i;
+ for (i=0; i < bytes; i++)
+ {
+ fputc(data[i], stream);
+ }
+}
+
+/*
+ * Read all lines containing 'jclstr' from 'stream' (actually, one more) and
+ * return them in a zero terminated array.
+ */
+static char ** read_jcl_lines(FILE *stream, const char *jclstr,
+ size_t *readbinarybytes)
+{
+ char *line;
+ char **result;
+ size_t alloc = 8, cnt = 0;
+
+ result = malloc(alloc * sizeof(char *));
+
+ /* read from the renderer output until the first non-JCL line appears */
+ while ((line = read_line(stream, readbinarybytes)))
+ {
+ if (cnt >= alloc -1)
+ {
+ alloc *= 2;
+ result = realloc(result, alloc * sizeof(char *));
+ }
+ result[cnt] = line;
+ if (!strstr(line, jclstr))
+ break;
+ /* Remove newline from the end of a line containing JCL */
+ result[cnt][*readbinarybytes - 1] = '\0';
+ cnt++;
+ }
+
+ cnt++;
+ result[cnt] = NULL;
+ return result;
+}
+
+static int jcl_keywords_equal(const char *jclline1, const char *jclline2,
+ const char *jclstr)
+{
+ char *j1, *j2, *p1, *p2;
+
+ j1 = strstr(jclline1, jclstr);
+ if (!j1) return 0;
+ if (!(p1 = strchr(skip_whitespace(j1), '=')))
+ p1 = j1 + strlen(j1);
+ p1--;
+ while (p1 > j1 && isspace(*p1))
+ p1--;
+
+ j2 = strstr(jclline2, jclstr);
+ if (!j2) return 0;
+ if (!(p2 = strchr(skip_whitespace(j2), '=')))
+ p2 = j2 + strlen(j2);
+ p2--;
+ while (p2 > j2 && isspace(*p2))
+ p2--;
+
+ if (p1 - j1 != p2 - j2) return 0;
+ return strncmp(j1, j2, p1 - j1 + 1) == 0;
+}
+
+/*
+ * Finds the keyword of line in opts
+ */
+static const char * jcl_options_find_keyword(char **opts, const char *line,
+ const char *jclstr)
+{
+ if (!opts)
+ return NULL;
+
+ while (*opts)
+ {
+ if (jcl_keywords_equal(*opts, line, jclstr))
+ return *opts;
+ opts++;
+ }
+ return NULL;
+}
+
+static void argv_write(FILE *stream, char **argv, const char *sep)
+{
+ if (!argv)
+ return;
+
+ while (*argv)
+ fprintf(stream, "%s%s", *argv++, sep);
+}
+
+/*
+ * Merges 'original_opts' and 'pref_opts' and writes them to 'stream'. Header /
+ * footer is taken from 'original_opts'. If both have the same options, the one
+ * from 'pref_opts' is preferred
+ * Returns true, if original_opts was not empty
+ */
+static int write_merged_jcl_options(FILE *stream,
+ char **original_opts,
+ char **opts,
+ size_t readbinarybytes,
+ const char *jclstr)
+{
+ char *p = strstr(original_opts[0], jclstr);
+ char header[128];
+ char **optsp1 = NULL, **optsp2 = NULL;
+
+ /* No JCL options in original_opts, just prepend opts */
+ if (argv_count(original_opts) == 1)
+ {
+ fprintf(stream, "%s", jclbegin);
+ argv_write(stream, opts, "\n");
+ write_binary_data(stream, original_opts[0], readbinarybytes);
+ return 0;
+ }
+
+ if (argv_count(original_opts) == 2)
+ {
+ /* If we have only one line of JCL it is probably something like the
+ * "@PJL ENTER LANGUAGE=..." line which has to be in the end, but it
+ * also contains the "<esc>%-12345X" which has to be in the beginning
+ * of the job */
+ if (p)
+ fwrite_or_die(original_opts[0], 1, p - original_opts[0], stream);
+ else
+ fprintf(stream, "%s\n", original_opts[0]);
+
+ argv_write(stream, opts, "\n");
+
+ if (p)
+ fprintf(stream, "%s\n", p);
+
+ write_binary_data(stream, original_opts[1], readbinarybytes);
+ return 1;
+ }
+
+ /* Write jcl header */
+ strncpy(header, original_opts[0], p - original_opts[0]);
+ header[p - original_opts[0]] = '\0';
+ fprintf(stream, "%s", header);
+
+ /* Insert the JCL commands from the PPD file right before the first
+ "@PJL SET ..." line from the, if there are no "@PJL SET ..." lines,
+ directly before "@PJL ENTER LANGUAGE ...", otherwise after the JCL
+ commands from the driver */
+ for (optsp1 = original_opts; *(optsp1 + 1); optsp1++) {
+ if (optsp2 == NULL &&
+ ((strstr(*optsp1, "ENTER LANGUAGE") != NULL) ||
+ (strncasecmp(*optsp1, "@PJL SET ", 9) == 0))) {
+ for (optsp2 = opts; *optsp2; optsp2++)
+ if (!jcl_options_find_keyword(original_opts, *optsp2, jclstr))
+ fprintf(stream, "%s\n", *optsp2);
+ }
+ if (optsp1 != original_opts) p = *optsp1;
+ if (!p)
+ _log("write_merged_jcl_options() dereferences NULL pointer p\n");
+ if (jcl_options_find_keyword(opts, p, jclstr))
+ fprintf(stream, "%s\n", jcl_options_find_keyword(opts, p, jclstr));
+ else
+ fprintf(stream, "%s\n", p);
+ }
+ if (optsp2 == NULL)
+ for (optsp2 = opts; *optsp2; optsp2++)
+ if (!jcl_options_find_keyword(original_opts, *optsp2, jclstr))
+ fprintf(stream, "%s\n", *optsp2);
+
+ write_binary_data(stream, *optsp1, readbinarybytes);
+
+ return 1;
+}
+
+void log_jcl()
+{
+ char **opt;
+
+ _log("JCL: %s", jclbegin);
+ if (jclprepend)
+ for (opt = jclprepend; *opt; opt++)
+ _log("%s\n", *opt);
+
+ _log("<job data> %s\n\n", jclappend->data);
+}
+
+int exec_kid4(FILE *in, FILE *out, void *user_arg)
+{
+ FILE *fileh = open_postpipe();
+ int driverjcl = 0;
+ size_t readbinarybytes;
+
+ log_jcl();
+
+ /* wrap the JCL around the job data, if there are any options specified...
+ * Should the driver already have inserted JCL commands we merge our JCL
+ * header with the one from the driver */
+ if (argv_count(jclprepend) > 0)
+ {
+ if (!isspace(jclprepend[0][0]))
+ {
+ char *jclstr, **jclheader;
+ size_t pos;
+
+ pos = strcspn(jclprepend[0], " \t\n\r");
+ jclstr = malloc(pos +1);
+ strncpy(jclstr, jclprepend[0], pos);
+ jclstr[pos] = '\0';
+
+ jclheader = read_jcl_lines(in, jclstr, &readbinarybytes);
+
+ driverjcl = write_merged_jcl_options(fileh,
+ jclheader,
+ jclprepend,
+ readbinarybytes,
+ jclstr);
+
+ free(jclstr);
+ argv_free(jclheader);
+ }
+ else
+ /* No merging of JCL header possible, simply prepend it */
+ argv_write(fileh, jclprepend, "\n");
+ }
+
+ /* The job data */
+ copy_file(fileh, in, NULL, 0);
+
+ /* A JCL trailer */
+ if (argv_count(jclprepend) > 0 && !driverjcl)
+ fwrite_or_die(jclappend->data, jclappend->len, 1, fileh);
+
+ fclose(in);
+ if (fclose(fileh) != 0)
+ {
+ _log("error closing postpipe\n");
+ return EXIT_PRNERR_NORETRY_BAD_SETTINGS;
+ }
+
+ return EXIT_PRINTED;
+}
+
+int exec_kid3(FILE *in, FILE *out, void *user_arg)
+{
+ dstr_t *commandline;
+ int kid4;
+ FILE *kid4in;
+ int status;
+
+ commandline = create_dstr();
+ dstrcpy(commandline, (const char *)user_arg);
+
+ kid4 = start_process("kid4", exec_kid4, NULL, &kid4in, NULL);
+ if (kid4 < 0) {
+ free_dstr(commandline);
+ return EXIT_PRNERR_NORETRY_BAD_SETTINGS;
+ }
+
+ if (in && dup2(fileno(in), fileno(stdin)) < 0) {
+ _log("kid3: Could not dup stdin\n");
+ fclose(kid4in);
+ free_dstr(commandline);
+ return EXIT_PRNERR_NORETRY_BAD_SETTINGS;
+ }
+ if (dup2(fileno(kid4in), fileno(stdout)) < 0) {
+ _log("kid3: Could not dup stdout to kid4\n");
+ fclose(kid4in);
+ free_dstr(commandline);
+ return EXIT_PRNERR_NORETRY_BAD_SETTINGS;
+ }
+ if (debug)
+ {
+ if (!redirect_log_to_stderr()) {
+ fclose(kid4in);
+ free_dstr(commandline);
+ return EXIT_PRNERR_NORETRY_BAD_SETTINGS;
+ }
+
+ /* Save the data supposed to be fed into the renderer also into a file*/
+ dstrprepend(commandline, "tee $(mktemp " LOG_FILE "-XXXXXX.ps) | ( ");
+ dstrcat(commandline, ")");
+ }
+
+ /* Actually run the thing */
+ status = run_system_process("renderer", commandline->data);
+
+ if (in)
+ fclose(in);
+ fclose(kid4in);
+ fclose(stdin);
+ fclose(stdout);
+ free_dstr(commandline);
+
+ if (WIFEXITED(status)) {
+ switch (WEXITSTATUS(status)) {
+ case 0: /* Success! */
+ /* wait for postpipe/output child */
+ wait_for_process(kid4);
+ _log("kid3 finished\n");
+ return EXIT_PRINTED;
+ case 1:
+ _log("Possible error on renderer command line or PostScript error. Check options.");
+ return EXIT_JOBERR;
+ case 139:
+ _log("The renderer may have dumped core.");
+ return EXIT_JOBERR;
+ case 141:
+ _log("A filter used in addition to the renderer itself may have failed.");
+ return EXIT_PRNERR;
+ case 243:
+ case 255: /* PostScript error? */
+ return EXIT_JOBERR;
+ }
+ }
+ else if (WIFSIGNALED(status)) {
+ switch (WTERMSIG(status)) {
+ case SIGUSR1:
+ return EXIT_PRNERR;
+ case SIGUSR2:
+ return EXIT_PRNERR_NORETRY;
+ case SIGTTIN:
+ return EXIT_ENGAGED;
+ }
+ }
+ return EXIT_PRNERR;
+}
+
diff --git a/filter/foomatic-rip/renderer.h b/filter/foomatic-rip/renderer.h
new file mode 100644
index 000000000..298f67b5c
--- /dev/null
+++ b/filter/foomatic-rip/renderer.h
@@ -0,0 +1,31 @@
+/* renderer.h
+ *
+ * Copyright (C) 2008 Till Kamppeter <till.kamppeter@gmail.com>
+ * Copyright (C) 2008 Lars Uebernickel <larsuebernickel@gmx.de>
+ *
+ * This file is part of foomatic-rip.
+ *
+ * Foomatic-rip 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Foomatic-rip 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 Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef renderer_h
+#define renderer_h
+
+void massage_gs_commandline(dstr_t *cmd);
+int exec_kid3(FILE *in, FILE *out, void *user_arg);
+
+#endif
+
diff --git a/filter/foomatic-rip/spooler.c b/filter/foomatic-rip/spooler.c
new file mode 100644
index 000000000..236551f7f
--- /dev/null
+++ b/filter/foomatic-rip/spooler.c
@@ -0,0 +1,225 @@
+/* spooler.c
+ *
+ * Copyright (C) 2008 Till Kamppeter <till.kamppeter@gmail.com>
+ * Copyright (C) 2008 Lars Uebernickel <larsuebernickel@gmx.de>
+ *
+ * This file is part of foomatic-rip.
+ *
+ * Foomatic-rip 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Foomatic-rip 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 Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "spooler.h"
+#include "foomaticrip.h"
+#include "util.h"
+#include "options.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+
+const char *spooler_name(int spooler)
+{
+ switch (spooler) {
+ case SPOOLER_CUPS: return "cups";
+ case SPOOLER_DIRECT: return "direct";
+ };
+ return "<unknown>";
+}
+
+void init_cups(list_t *arglist, dstr_t *filelist, jobparams_t *job)
+{
+ char path [PATH_MAX] = "";
+ char cups_jobid [128];
+ char cups_user [128];
+ char cups_jobtitle [2048];
+ char cups_copies [128];
+ int cups_options_len;
+ char *cups_options;
+ char cups_filename [256];
+
+ if (getenv("CUPS_FONTPATH"))
+ strncpy(path, getenv("CUPS_FONTPATH"), PATH_MAX - 1);
+ else if (getenv("CUPS_DATADIR")) {
+ strncpy(path, getenv("CUPS_DATADIR"), PATH_MAX - 1);
+ strncat(path, "/fonts", PATH_MAX - strlen(path) - 1);
+ }
+ if (getenv("GS_LIB")) {
+ strncat(path, ":", PATH_MAX - strlen(path) - 1);
+ strncat(path, getenv("GS_LIB"), PATH_MAX - strlen(path) - 1);
+ }
+ setenv("GS_LIB", path, 1);
+
+ /* Get all command line parameters */
+ strncpy_omit(cups_jobid, arglist_get(arglist, 0), 128, omit_shellescapes);
+ strncpy_omit(cups_user, arglist_get(arglist, 1), 128, omit_shellescapes);
+ strncpy_omit(cups_jobtitle, arglist_get(arglist, 2), 2048,
+ omit_shellescapes);
+ strncpy_omit(cups_copies, arglist_get(arglist, 3), 128, omit_shellescapes);
+
+ cups_options_len = strlen(arglist_get(arglist, 4));
+ cups_options = malloc(cups_options_len + 1);
+ strncpy_omit(cups_options, arglist_get(arglist, 4), cups_options_len + 1,
+ omit_shellescapes);
+
+ /* Common job parameters */
+ strcpy(job->id, cups_jobid);
+ strcpy(job->title, cups_jobtitle);
+ strcpy(job->user, cups_user);
+ strcpy(job->copies, cups_copies);
+ dstrcatf(job->optstr, " %s", cups_options);
+
+ /* Check for and handle inputfile vs stdin */
+ if (list_item_count(arglist) > 4) {
+ strncpy_omit(cups_filename, arglist_get(arglist, 5), 256, omit_shellescapes);
+ if (cups_filename[0] != '-') {
+ /* We get input from a file */
+ dstrcatf(filelist, "%s ", cups_filename);
+ _log("Getting input from file %s\n", cups_filename);
+ }
+ }
+
+ /* On which queue are we printing?
+ CUPS puts the print queue name into the PRINTER environment variable
+ when calling filters. */
+ strncpy(job->printer, getenv("PRINTER"), 256);
+
+ free(cups_options);
+}
+
+/* used by init_direct to find a ppd file */
+int find_ppdfile(const char *user_default_path, jobparams_t *job)
+{
+ /* Search also common spooler-specific locations, this way a printer
+ configured under a certain spooler can also be used without spooler */
+
+ strcpy(job->ppdfile, job->printer);
+ if (access(job->ppdfile, R_OK) == 0)
+ return 1;
+
+ snprintf(job->ppdfile, 2048, "%s.ppd", job->printer); /* current dir */
+ if (access(job->ppdfile, R_OK) == 0)
+ return 1;
+ snprintf(job->ppdfile, 2048, "%s/%s.ppd", user_default_path, job->printer); /* user dir */
+ if (access(job->ppdfile, R_OK) == 0)
+ return 1;
+ snprintf(job->ppdfile, 2048, "%s/direct/%s.ppd", CONFIG_PATH, job->printer); /* system dir */
+ if (access(job->ppdfile, R_OK) == 0)
+ return 1;
+ snprintf(job->ppdfile, 2048, "%s/%s.ppd", CONFIG_PATH, job->printer); /* system dir */
+ if (access(job->ppdfile, R_OK) == 0)
+ return 1;
+ snprintf(job->ppdfile, 2048, "/etc/cups/ppd/%s.ppd", job->printer); /* CUPS config dir */
+ if (access(job->ppdfile, R_OK) == 0)
+ return 1;
+ snprintf(job->ppdfile, 2048, "/usr/local/etc/cups/ppd/%s.ppd", job->printer); /* CUPS config dir */
+ if (access(job->ppdfile, R_OK) == 0)
+ return 1;
+
+ /* nothing found */
+ job->ppdfile[0] = '\0';
+ return 0;
+}
+
+/* search 'configfile' for 'key', copy value into dest, return success */
+int configfile_find_option(const char *configfile, const char *key, char *dest, size_t destsize)
+{
+ FILE *fh;
+ char line [1024];
+ char *p;
+
+ dest[0] = '\0';
+
+ if (!(fh = fopen(configfile, "r")))
+ return 0;
+
+ while (fgets(line, 1024, fh)) {
+ if (!prefixcmp(line, "default")) {
+ p = strchr(line, ':');
+ if (p) {
+ strncpy_omit(dest, p + 1, destsize, omit_whitespace_newline);
+ if (dest[0])
+ break;
+ }
+ }
+ }
+ fclose(fh);
+ return dest[0] != '\0';
+}
+
+/* tries to find a default printer name in various config files and copies the
+ * result into the global var 'printer'. Returns success */
+int find_default_printer(const char *user_default_path, jobparams_t *job)
+{
+ char configfile [1024];
+ char *key = "default";
+
+ if (configfile_find_option("./.directconfig", key, job->printer, 256))
+ return 1;
+ if (configfile_find_option("./directconfig", key, job->printer, 256))
+ return 1;
+ if (configfile_find_option("./.config", key, job->printer, 256))
+ return 1;
+ strlcpy(configfile, user_default_path, 1024);
+ strlcat(configfile, "/direct/.config", 1024);
+ if (configfile_find_option(configfile, key, job->printer, 256))
+ return 1;
+ strlcpy(configfile, user_default_path, 1024);
+ strlcat(configfile, "/direct.conf", 1024);
+ if (configfile_find_option(configfile, key, job->printer, 256))
+ return 1;
+ if (configfile_find_option(CONFIG_PATH "/direct/.config", key, job->printer, 256))
+ return 1;
+ if (configfile_find_option(CONFIG_PATH "/direct.conf", key, job->printer, 256))
+ return 1;
+
+ return 0;
+}
+
+void init_direct(list_t *arglist, dstr_t *filelist, jobparams_t *job)
+{
+ char tmp [1024];
+ listitem_t *i;
+ char user_default_path [PATH_MAX];
+
+ strlcpy(user_default_path, getenv("HOME"), 256);
+ strlcat(user_default_path, "/.foomatic/", 256);
+
+ /* Which files do we want to print? */
+ for (i = arglist->first; i; i = i->next) {
+ strncpy_omit(tmp, (char*)i->data, 1024, omit_shellescapes);
+ dstrcatf(filelist, "%s ", tmp);
+ }
+
+ if (job->ppdfile[0] == '\0') {
+ if (job->printer[0] == '\0') {
+ /* No printer definition file selected, check whether we have a
+ default printer defined */
+ find_default_printer(user_default_path, job);
+ }
+
+ /* Neither in a config file nor on the command line a printer was selected */
+ if (!job->printer[0]) {
+ _log("No printer definition (option \"-P <name>\") specified!\n");
+ exit(EXIT_PRNERR_NORETRY_BAD_SETTINGS);
+ }
+
+ /* Search for the PPD file */
+ if (!find_ppdfile(user_default_path, job)) {
+ _log("There is no readable PPD file for the printer %s, is it configured?\n", job->printer);
+ exit(EXIT_PRNERR_NORETRY_BAD_SETTINGS);
+ }
+ }
+}
+
diff --git a/filter/foomatic-rip/spooler.h b/filter/foomatic-rip/spooler.h
new file mode 100644
index 000000000..7025ccaf7
--- /dev/null
+++ b/filter/foomatic-rip/spooler.h
@@ -0,0 +1,35 @@
+/* spooler.h
+ *
+ * Copyright (C) 2008 Till Kamppeter <till.kamppeter@gmail.com>
+ * Copyright (C) 2008 Lars Uebernickel <larsuebernickel@gmx.de>
+ *
+ * This file is part of foomatic-rip.
+ *
+ * Foomatic-rip 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Foomatic-rip 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 Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef SPOOLER_H
+#define SPOOLER_H
+
+#include "foomaticrip.h"
+#include "util.h"
+
+const char *spooler_name(int spooler);
+void init_cups(list_t *arglist, dstr_t *filelist, jobparams_t *job);
+void init_direct(list_t *arglist, dstr_t *filelist, jobparams_t *job);
+
+#endif
+
diff --git a/filter/foomatic-rip/util.c b/filter/foomatic-rip/util.c
new file mode 100644
index 000000000..9038f9010
--- /dev/null
+++ b/filter/foomatic-rip/util.c
@@ -0,0 +1,1143 @@
+/* util.c
+ *
+ * Copyright (C) 2008 Till Kamppeter <till.kamppeter@gmail.com>
+ * Copyright (C) 2008 Lars Uebernickel <larsuebernickel@gmx.de>
+ *
+ * This file is part of foomatic-rip.
+ *
+ * Foomatic-rip 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Foomatic-rip 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 Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "util.h"
+#include "foomaticrip.h"
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <errno.h>
+
+
+const char* shellescapes = "|;<>&!$\'\"`#*?()[]{}";
+
+const char * temp_dir()
+{
+ static const char *tmpdir = NULL;
+
+ if (!tmpdir)
+ {
+ const char *dirs[] = { getenv("TMPDIR"), P_tmpdir, "/tmp" };
+ int i;
+
+ for (i = 0; i < (sizeof(dirs) / sizeof(dirs[0])); i++) {
+ if (access(dirs[i], W_OK) == 0) {
+ tmpdir = dirs[i];
+ break;
+ }
+ }
+ if (tmpdir)
+ {
+ _log("Storing temporary files in %s\n", tmpdir);
+ setenv("TMPDIR", tmpdir, 1); /* for child processes */
+ }
+ else
+ rip_die(EXIT_PRNERR_NORETRY_BAD_SETTINGS,
+ "Cannot find a writable temp dir.");
+ }
+
+ return tmpdir;
+}
+
+int prefixcmp(const char *str, const char *prefix)
+{
+ return strncmp(str, prefix, strlen(prefix));
+}
+
+int prefixcasecmp(const char *str, const char *prefix)
+{
+ return strncasecmp(str, prefix, strlen(prefix));
+}
+
+int startswith(const char *str, const char *prefix)
+{
+ return str ? (strncmp(str, prefix, strlen(prefix)) == 0) : 0;
+}
+
+int endswith(const char *str, const char *postfix)
+{
+ int slen = strlen(str);
+ int plen = strlen(postfix);
+ const char *pstr;
+
+ if (slen < plen)
+ return 0;
+
+ pstr = &str[slen - plen];
+ return strcmp(pstr, postfix) == 0;
+}
+
+const char * skip_whitespace(const char *str)
+{
+ while (*str && isspace(*str))
+ str++;
+ return str;
+}
+
+void strlower(char *dest, size_t destlen, const char *src)
+{
+ char *pdest = dest;
+ const char *psrc = src;
+ while (*psrc && --destlen > 0)
+ {
+ *pdest = tolower(*psrc);
+ pdest++;
+ psrc++;
+ }
+ *pdest = '\0';
+}
+
+int isempty(const char *string)
+{
+ return !string || string[0] == '\0';
+}
+
+const char * strncpy_omit(char* dest, const char* src, size_t n, int (*omit_func)(int))
+{
+ const char* psrc = src;
+ char* pdest = dest;
+ int cnt = n -1;
+ if (!pdest)
+ return NULL;
+ if (psrc) {
+ while (*psrc != 0 && cnt > 0) {
+ if (!omit_func(*psrc)) {
+ *pdest = *psrc;
+ pdest++;
+ cnt--;
+ }
+ psrc++;
+ }
+ }
+ *pdest = '\0';
+ return psrc;
+}
+int omit_unprintables(int c) { return c>= '\x00' && c <= '\x1f'; }
+int omit_shellescapes(int c) { return strchr(shellescapes, c) != NULL; }
+int omit_specialchars(int c) { return omit_unprintables(c) || omit_shellescapes(c); }
+int omit_whitespace(int c) { return c == ' ' || c == '\t'; }
+int omit_whitespace_newline(int c) { return omit_whitespace(c) || c == '\n'; }
+
+#ifndef HAVE_STRCASESTR
+char *
+strcasestr (const char *haystack, const char *needle)
+{
+ char *p, *startn = 0, *np = 0;
+
+ for (p = haystack; *p; p++) {
+ if (np) {
+ if (toupper(*p) == toupper(*np)) {
+ if (!*++np)
+ return startn;
+ } else
+ np = 0;
+ } else if (toupper(*p) == toupper(*needle)) {
+ np = needle + 1;
+ startn = p;
+ }
+ }
+
+ return 0;
+}
+#endif
+
+#ifndef __OpenBSD__
+#ifndef HAVE_STRLCPY
+size_t strlcpy(char *dest, const char *src, size_t size)
+{
+ char *pdest = dest;
+ const char *psrc = src;
+
+ if (!src) {
+ dest[0] = '\0';
+ return 0;
+ }
+
+ if (size) {
+ while (--size && (*pdest++ = *psrc++) != '\0');
+ *pdest = '\0';
+ }
+ if (!size)
+ while (*psrc++);
+ return (psrc - src -1);
+}
+#endif /* ! HAVE_STRLCPY */
+
+#ifndef HAVE_STRLCAT
+size_t strlcat(char *dest, const char *src, size_t size)
+{
+ char *pdest = dest;
+ const char *psrc = src;
+ size_t i = size;
+ size_t len;
+
+ while (--i && *pdest)
+ pdest++;
+ len = pdest - dest;
+
+ if (!i)
+ return strlen(src) + len;
+
+ while (i-- && *psrc)
+ *pdest++ = *psrc++;
+ *pdest = '\0';
+
+ return len + (psrc - src);
+}
+#endif /* ! HAVE_STRLCAT */
+#endif /* ! __OpenBSD__ */
+
+void strrepl(char *str, const char *chars, char repl)
+{
+ char *p = str;
+
+ while (*p) {
+ if (strchr(chars, *p))
+ *p = repl;
+ p++;
+ }
+}
+
+void strrepl_nodups(char *str, const char *chars, char repl)
+{
+ char *pstr = str;
+ char *p = str;
+ int prev = 0;
+
+ while (*pstr) {
+ if (strchr(chars, *pstr) || *pstr == repl) {
+ if (!prev) {
+ *p = repl;
+ p++;
+ prev = 1;
+ }
+ }
+ else {
+ *p = *pstr;
+ p++;
+ prev = 0;
+ }
+ pstr++;
+ }
+ *p = '\0';
+}
+
+void strclr(char *str)
+{
+ while (*str) {
+ *str = '\0';
+ str++;
+ }
+}
+
+char * strnchr(const char *str, int c, size_t n)
+{
+ char *p = (char*)str;
+
+ while (*p && --n > 0) {
+ if (*p == (char)c)
+ return p;
+ p++;
+ }
+ return p;
+}
+
+void escapechars(char *dest, size_t size, const char *src, const char *esc_chars)
+{
+ const char *psrc = src;
+
+ while (*psrc && --size > 0) {
+ if (strchr(esc_chars, *psrc))
+ *dest++ = '\\';
+ *dest++ = *psrc++;
+ }
+}
+
+const char * strncpy_tochar(char *dest, const char *src, size_t max, const char *stopchars)
+{
+ const char *psrc = src;
+ char *pdest = dest;
+ if (isempty(psrc)) {
+ return NULL;
+ }
+ while (*psrc && --max > 0 && !strchr(stopchars, *psrc)) {
+ *pdest = *psrc;
+ pdest++;
+ psrc++;
+ }
+ *pdest = '\0';
+ return psrc +1;
+}
+
+size_t fwrite_or_die(const void* ptr, size_t size, size_t count, FILE* stream) {
+ size_t res = fwrite(ptr, size, count, stream);
+ if (ferror(stream))
+ rip_die(EXIT_PRNERR, "Encountered error %s during fwrite", strerror(errno));
+
+ return res;
+}
+
+size_t fread_or_die(void* ptr, size_t size, size_t count, FILE* stream) {
+ size_t res = fread(ptr, size, count, stream);
+ if (ferror(stream))
+ rip_die(EXIT_PRNERR, "Encountered error %s during fread", strerror(errno));
+
+ return res;
+}
+
+int find_in_path(const char *progname, const char *paths, char *found_in)
+{
+ char *pathscopy;
+ char *path;
+ char filepath[PATH_MAX];
+
+ if (access(progname, X_OK) == 0)
+ return 1;
+
+ pathscopy = strdup(paths);
+ for (path = strtok(pathscopy, ":"); path; path = strtok(NULL, ":")) {
+ strlcpy(filepath, path, PATH_MAX);
+ strlcat(filepath, "/", PATH_MAX);
+ strlcat(filepath, progname, PATH_MAX);
+
+ if (access(filepath, X_OK) == 0) {
+ if (found_in)
+ strlcpy(found_in, path, PATH_MAX);
+ free(pathscopy);
+ return 1;
+ }
+ }
+
+ if (found_in)
+ found_in[0] = '\0';
+ free(pathscopy);
+ return 0;
+}
+
+void file_basename(char *dest, const char *path, size_t dest_size)
+{
+ const char *p = strrchr(path, '/');
+ char *pdest = dest;
+ if (!pdest)
+ return;
+ if (p)
+ p += 1;
+ else
+ p = path;
+ while (*p != 0 && *p != '.' && --dest_size > 0) {
+ *pdest++ = *p++;
+ }
+ *pdest = '\0';
+}
+
+void make_absolute_path(char *path, int len)
+{
+ char *tmp, *cwd;
+
+ if (path[0] != '/') {
+ tmp = malloc(len +1);
+ strlcpy(tmp, path, len);
+
+ cwd = malloc(len);
+ if (getcwd(cwd, len) != NULL) {
+ strlcpy(path, cwd, len);
+ strlcat(path, "/", len);
+ strlcat(path, tmp, len);
+ }
+
+ free(tmp);
+ free(cwd);
+ }
+}
+
+int is_true_string(const char *str)
+{
+ return str && (!strcmp(str, "1") || !strcasecmp(str, "Yes") ||
+ !strcasecmp(str, "On") || !strcasecmp(str, "True"));
+}
+
+int is_false_string(const char *str)
+{
+ return str && (!strcmp(str, "0") || !strcasecmp(str, "No") ||
+ !strcasecmp(str, "Off") || !strcasecmp(str, "False") ||
+ !strcasecmp(str, "None"));
+}
+
+int digit(char c)
+{
+ if (c >= '0' && c <= '9')
+ return (int)c - (int)'0';
+ return -1;
+}
+
+static const char * next_token(const char *string, const char *separators)
+{
+ if (!string)
+ return NULL;
+
+ while (*string && !strchr(separators, *string))
+ string++;
+
+ while (*string && strchr(separators, *string))
+ string++;
+
+ return string;
+}
+
+static unsigned count_separators(const char *string, const char *separators)
+{
+ const char *p;
+ unsigned cnt = 0;
+
+ if (!string)
+ return 0;
+
+ for (p = string; *p; p = next_token(p, separators))
+ cnt++;
+
+ return cnt;
+}
+
+/*
+ * Returns a zero terminated array of strings
+ */
+char ** argv_split(const char *string, const char *separators, int *cntp)
+{
+ unsigned cnt;
+ int i;
+ char **argv;
+
+ if (!string)
+ return NULL;
+
+ if ((cnt = count_separators(string, separators)) == 0)
+ return NULL;
+
+ argv = malloc((cnt +1) * sizeof(char *));
+ argv[cnt] = NULL;
+
+ for (i = 0; i < cnt; i++)
+ {
+ size_t len = strcspn(string, separators);
+ char *s;
+ s = malloc(len + 1);
+ strncpy(s, string, len);
+ s[len] = '\0';
+ argv[i] = s;
+ string = next_token(string, separators);
+ }
+
+ if (cntp)
+ *cntp = cnt;
+ return argv;
+}
+
+size_t argv_count(char **argv)
+{
+ size_t cnt = 0;
+
+ if (!argv)
+ return 0;
+
+ while (*argv++)
+ cnt++;
+
+ return cnt;
+}
+
+void argv_free(char **argv)
+{
+ char **p;
+
+ if (!argv)
+ return;
+
+ for (p = argv; *p; p++)
+ free(*p);
+
+ free(argv);
+}
+
+int line_count(const char *str)
+{
+ int cnt = 0;
+ while (*str) {
+ if (*str == '\n')
+ cnt++;
+ str++;
+ }
+ return cnt;
+}
+
+int line_start(const char *str, int line_number)
+{
+ const char *p = str;
+ while (*p && line_number > 0) {
+ if (*p == '\n')
+ line_number--;
+ p++;
+ }
+ return p - str;
+}
+
+void unhexify(char *dest, size_t size, const char *src)
+{
+ char *pdest = dest;
+ const char *psrc = src;
+ char cstr[3];
+
+ cstr[2] = '\0';
+
+ while (*psrc && pdest - dest < size -1) {
+ if (*psrc == '<') {
+ psrc++;
+ do {
+ cstr[0] = *psrc++;
+ cstr[1] = *psrc++;
+ if (!isxdigit(cstr[0]) || !isxdigit(cstr[1])) {
+ printf("Error replacing hex notation in %s!\n", src);
+ break;
+ }
+ *pdest++ = (char)strtol(cstr, NULL, 16);
+ } while (*psrc != '>');
+ psrc++;
+ }
+ else
+ *pdest++ = *psrc++;
+ }
+ *pdest = '\0';
+}
+
+void extract_command(size_t *start, size_t *end, const char *cmdline, const char *cmd)
+{
+ char *copy = strdup(cmdline);
+ char *tok = NULL;
+ const char *delim = "|;";
+
+ *start = *end = 0;
+ for (tok = strtok(copy, delim); tok; tok = strtok(NULL, delim)) {
+ while (*tok && isspace(*tok))
+ tok++;
+ if (startswith(tok, cmd)) {
+ *start = tok - copy;
+ *end = tok + strlen(tok) - copy;
+ break;
+ }
+ }
+
+ free(copy);
+}
+
+int contains_command(const char *cmdline, const char *cmd)
+{
+ size_t start = 0, end = 0;
+
+ extract_command(&start, &end, cmdline, cmd);
+ if (start == 0 && end == 0)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Dynamic strings
+ */
+dstr_t * create_dstr()
+{
+ dstr_t *ds = malloc(sizeof(dstr_t));
+ ds->len = 0;
+ ds->alloc = 32;
+ ds->data = malloc(ds->alloc);
+ ds->data[0] = '\0';
+ return ds;
+}
+
+void free_dstr(dstr_t *ds)
+{
+ free(ds->data);
+ free(ds);
+}
+
+void dstrclear(dstr_t *ds)
+{
+ ds->len = 0;
+ ds->data[0] = '\0';
+}
+
+void dstrassure(dstr_t *ds, size_t alloc)
+{
+ if (ds->alloc < alloc) {
+ ds->alloc = alloc;
+ ds->data = realloc(ds->data, ds->alloc);
+ }
+}
+
+void dstrcpy(dstr_t *ds, const char *src)
+{
+ size_t srclen;
+
+ if (!src) {
+ ds->len = 0;
+ ds->data[0] = '\0';
+ return;
+ }
+
+ srclen = strlen(src);
+
+ if (srclen >= ds->alloc) {
+ do {
+ ds->alloc *= 2;
+ } while (srclen >= ds->alloc);
+ ds->data = realloc(ds->data, ds->alloc);
+ }
+
+ strcpy(ds->data, src);
+ ds->len = srclen;
+}
+
+void dstrncpy(dstr_t *ds, const char *src, size_t n)
+{
+ if (n >= ds->alloc) {
+ do {
+ ds->alloc *= 2;
+ } while (n >= ds->alloc);
+ ds->data = realloc(ds->data, ds->alloc);
+ }
+
+ strncpy(ds->data, src, n);
+ ds->len = n;
+ ds->data[ds->len] = '\0';
+}
+
+void dstrncat(dstr_t *ds, const char *src, size_t n)
+{
+ size_t needed = ds->len + n;
+
+ if (needed >= ds->alloc) {
+ do {
+ ds->alloc *= 2;
+ } while (needed >= ds->alloc);
+ ds->data = realloc(ds->data, ds->alloc);
+ }
+
+ strncpy(&ds->data[ds->len], src, n);
+ ds->len = needed;
+ ds->data[ds->len] = '\0';
+}
+
+void dstrcpyf(dstr_t *ds, const char *src, ...)
+{
+ va_list ap;
+ size_t srclen;
+
+ va_start(ap, src);
+ srclen = vsnprintf(ds->data, ds->alloc, src, ap);
+ va_end(ap);
+
+ if (srclen >= ds->alloc) {
+ do {
+ ds->alloc *= 2;
+ } while (srclen >= ds->alloc);
+ ds->data = realloc(ds->data, ds->alloc);
+
+ va_start(ap, src);
+ vsnprintf(ds->data, ds->alloc, src, ap);
+ va_end(ap);
+ }
+
+ ds->len = srclen;
+}
+
+void dstrputc(dstr_t *ds, int c)
+{
+ if (ds->len +1 >= ds->alloc) {
+ ds->alloc *= 2;
+ ds->data = realloc(ds->data, ds->alloc);
+ }
+ ds->data[ds->len++] = c;
+ ds->data[ds->len] = '\0';
+}
+
+void dstrcat(dstr_t *ds, const char *src)
+{
+ size_t srclen = strlen(src);
+ size_t newlen = ds->len + srclen;
+
+ if (newlen >= ds->alloc) {
+ do {
+ ds->alloc *= 2;
+ } while (newlen >= ds->alloc);
+ ds->data = realloc(ds->data, ds->alloc);
+ }
+
+ memcpy(&ds->data[ds->len], src, srclen +1);
+ ds->len = newlen;
+}
+
+void dstrcatf(dstr_t *ds, const char *src, ...)
+{
+ va_list ap;
+ size_t restlen = ds->alloc - ds->len;
+ size_t srclen;
+
+ va_start(ap, src);
+ srclen = vsnprintf(&ds->data[ds->len], restlen, src, ap);
+ va_end(ap);
+
+ if (srclen >= restlen) {
+ do {
+ ds->alloc *= 2;
+ restlen = ds->alloc - ds->len;
+ } while (srclen >= restlen);
+ ds->data = realloc(ds->data, ds->alloc);
+
+ va_start(ap, src);
+ srclen = vsnprintf(&ds->data[ds->len], restlen, src, ap);
+ va_end(ap);
+ }
+
+ ds->len += srclen;
+}
+
+size_t fgetdstr(dstr_t *ds, FILE *stream)
+{
+ int c;
+ size_t cnt = 0;
+
+ ds->len = 0;
+ if (ds->alloc == 0) {
+ ds->alloc = 256;
+ ds->data = malloc(ds->alloc);
+ }
+
+ while ((c = fgetc(stream)) != EOF) {
+ if (ds->len +1 == ds->alloc) {
+ ds->alloc *= 2;
+ ds->data = realloc(ds->data, ds->alloc);
+ }
+ ds->data[ds->len++] = (char)c;
+ cnt ++;
+ if (c == '\n')
+ break;
+ }
+ ds->data[ds->len] = '\0';
+ return cnt;
+}
+
+/*
+ * Replace the first occurrence of 'find' after the index 'start' with 'repl'
+ * Returns the position right after the replaced string
+ */
+int dstrreplace(dstr_t *ds, const char *find, const char *repl, int start)
+{
+ char *p;
+ dstr_t *copy = create_dstr();
+ int end = -1;
+
+ dstrcpy(copy, ds->data);
+
+ if ((p = strstr(&copy->data[start], find)))
+ {
+ dstrncpy(ds, copy->data, p - copy->data);
+ dstrcatf(ds, "%s", repl);
+ end = ds->len;
+ dstrcatf(ds, "%s", p + strlen(find));
+ }
+
+ free_dstr(copy);
+ return end;
+}
+
+void dstrprepend(dstr_t *ds, const char *str)
+{
+ dstr_t *copy = create_dstr();
+ dstrcpy(copy, ds->data);
+ dstrcpy(ds, str);
+ dstrcatf(ds, "%s", copy->data);
+ free_dstr(copy);
+}
+
+void dstrinsert(dstr_t *ds, int idx, const char *str)
+{
+ char * copy = strdup(ds->data);
+ size_t len = strlen(str);
+
+ if (idx >= ds->len)
+ idx = ds->len;
+ else if (idx < 0)
+ idx = 0;
+
+ if (ds->len + len >= ds->alloc) {
+ do {
+ ds->alloc *= 2;
+ } while (ds->len + len >= ds->alloc);
+ free(ds->data);
+ ds->data = malloc(ds->alloc);
+ }
+
+ strncpy(ds->data, copy, idx);
+ ds->data[idx] = '\0';
+ strcat(ds->data, str);
+ strcat(ds->data, &copy[idx]);
+ ds->len += len;
+ free(copy);
+}
+
+void dstrinsertf(dstr_t *ds, int idx, const char *str, ...)
+{
+ va_list ap;
+ char *strf;
+ size_t len;
+
+ va_start(ap, str);
+ len = vsnprintf(NULL, 0, str, ap);
+ va_end(ap);
+
+ strf = malloc(len +1);
+ va_start(ap, str);
+ vsnprintf(strf, len +1, str, ap);
+ va_end(ap);
+
+ dstrinsert(ds, idx, strf);
+
+ free(strf);
+}
+
+void dstrremove(dstr_t *ds, int idx, size_t count)
+{
+ char *p1, *p2;
+
+ if (idx + count >= ds->len)
+ return;
+
+ p1 = &ds->data[idx];
+ p2 = &ds->data[idx + count];
+
+ while (*p2) {
+ *p1 = *p2;
+ p1++;
+ p2++;
+ }
+ *p1 = '\0';
+}
+
+static inline int isnewline(int c)
+{
+ return c == '\n' || c == '\r';
+}
+
+void dstrcatline(dstr_t *ds, const char *str)
+{
+ size_t eol = strcspn(str, "\n\r");
+ if (isnewline(str[eol]))
+ eol++;
+ dstrncat(ds, str, eol);
+}
+
+int dstrendswith(dstr_t *ds, const char *str)
+{
+ int len = strlen(str);
+ char *pstr;
+
+ if (ds->len < len)
+ return 0;
+ pstr = &ds->data[ds->len - len];
+ return strcmp(pstr, str) == 0;
+
+}
+
+void dstrfixnewlines(dstr_t *ds)
+{
+ if (ds->data[ds->len -1] == '\r') {
+ ds->data[ds->len -1] = '\n';
+ }
+ else if (ds->data[ds->len -2] == '\r') {
+ ds->data[ds->len -1] = '\n';
+ ds->data[ds->len -2] = '\0';
+ ds->len -= 1;
+ }
+}
+
+void dstrremovenewline(dstr_t *ds)
+{
+ if (!ds->len)
+ return;
+
+ if (ds->data[ds->len -1] == '\r' || ds->data[ds->len -1] == '\n') {
+ ds->data[ds->len -1] = '\0';
+ ds->len -= 1;
+ }
+
+ if (ds->len < 2)
+ return;
+
+ if (ds->data[ds->len -2] == '\r') {
+ ds->data[ds->len -2] = '\0';
+ ds->len -= 2;
+ }
+}
+
+void dstrtrim(dstr_t *ds)
+{
+ int pos = 0;
+
+ while (pos < ds->len && isspace(ds->data[pos]))
+ pos++;
+
+ if (pos > 0) {
+ ds->len -= pos;
+ memmove(ds->data, &ds->data[pos], ds->len +1);
+ }
+}
+
+void dstrtrim_right(dstr_t *ds)
+{
+ if (!ds->len)
+ return;
+
+ while (isspace(ds->data[ds->len -1]))
+ ds->len -= 1;
+ ds->data[ds->len] = '\0';
+}
+
+
+
+/*
+ * LIST
+ */
+
+list_t * list_create()
+{
+ list_t *l = malloc(sizeof(list_t));
+ l->first = NULL;
+ l->last = NULL;
+ return l;
+}
+
+list_t * list_create_from_array(int count, void ** data)
+{
+ int i;
+ list_t *l = list_create();
+
+ for (i = 0; i < count; i++)
+ list_append(l, data[i]);
+
+ return l;
+}
+
+void list_free(list_t *list)
+{
+ listitem_t *i = list->first, *tmp;
+ while (i) {
+ tmp = i->next;
+ free(i);
+ i = tmp;
+ }
+}
+
+size_t list_item_count(list_t *list)
+{
+ size_t cnt = 0;
+ listitem_t *i;
+ for (i = list->first; i; i = i->next)
+ cnt++;
+ return cnt;
+}
+
+list_t * list_copy(list_t *list)
+{
+ list_t *l = list_create();
+ listitem_t *i;
+
+ for (i = list->first; i; i = i->next)
+ list_append(l, i->data);
+ return l;
+}
+
+void list_prepend(list_t *list, void *data)
+{
+ listitem_t *item;
+
+ assert(list);
+
+ item = malloc(sizeof(listitem_t));
+ item->data = data;
+ item->prev = NULL;
+
+ if (list->first) {
+ item->next = list->first;
+ list->first->next = item;
+ list->first = item;
+ }
+ else {
+ item->next = NULL;
+ list->first = item;
+ list->last = item;
+ }
+}
+
+void list_append(list_t *list, void *data)
+{
+ listitem_t *item;
+
+ assert(list);
+
+ item = malloc(sizeof(listitem_t));
+ item->data = data;
+ item->next = NULL;
+
+ if (list->last) {
+ item->prev = list->last;
+ list->last->next = item;
+ list->last = item;
+ }
+ else {
+ item->prev = NULL;
+ list->first = item;
+ list->last = item;
+ }
+}
+
+void list_remove(list_t *list, listitem_t *item)
+{
+ assert(item);
+
+ if (item->prev)
+ item->prev->next = item->next;
+ if (item->next)
+ item->next->prev = item->prev;
+ if (item == list->first)
+ list->first = item->next;
+ if (item == list->last)
+ list->last = item->prev;
+
+ free(item);
+}
+
+listitem_t * list_get(list_t *list, int idx)
+{
+ listitem_t *i;
+ for (i = list->first; i && idx; i = i->next)
+ idx--;
+ return i;
+}
+
+listitem_t * arglist_find(list_t *list, const char *name)
+{
+ listitem_t *i;
+ for (i = list->first; i; i = i->next) {
+ if (!strcmp((const char*)i->data, name))
+ return i;
+ }
+ return NULL;
+}
+
+listitem_t * arglist_find_prefix(list_t *list, const char *name)
+{
+ listitem_t *i;
+ for (i = list->first; i; i= i->next) {
+ if (!prefixcmp((const char*)i->data, name))
+ return i;
+ }
+ return NULL;
+}
+
+
+char * arglist_get_value(list_t *list, const char *name)
+{
+ listitem_t *i;
+ char *p;
+
+ for (i = list->first; i; i = i->next) {
+ if (i->next && !strcmp(name, (char*)i->data))
+ return (char*)i->next->data;
+ else if (!prefixcmp((char*)i->data, name)) {
+ p = &((char*)i->data)[strlen(name)];
+ return *p == '=' ? p +1 : p;
+ }
+ }
+ return NULL;
+}
+
+char * arglist_get(list_t *list, int idx)
+{
+ listitem_t *i = list_get(list, idx);
+ return i ? (char*)i->data : NULL;
+}
+
+int arglist_remove(list_t *list, const char *name)
+{
+ listitem_t *i;
+ char *i_name;
+
+ for (i = list->first; i; i = i->next) {
+ i_name = (char*)i->data;
+ if (i->next && !strcmp(name, i_name)) {
+ list_remove(list, i->next);
+ list_remove(list, i);
+ return 1;
+ }
+ else if (!prefixcmp(i_name, name)) {
+ list_remove(list, i);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int arglist_remove_flag(list_t *list, const char *name)
+{
+ listitem_t *i = arglist_find(list, name);
+ if (i) {
+ list_remove(list, i);
+ return 1;
+ }
+ return 0;
+}
+
+int copy_file(FILE *dest,
+ FILE *src,
+ const char *alreadyread,
+ size_t alreadyread_len)
+{
+ char buf[8192];
+ size_t bytes;
+
+ if (alreadyread && alreadyread_len)
+ {
+ if (fwrite_or_die(alreadyread, 1, alreadyread_len, dest) < alreadyread_len)
+ {
+ _log("Could not write to temp file\n");
+ return 0;
+ }
+ }
+
+ while ((bytes = fread_or_die(buf, 1, 8192, src)))
+ fwrite_or_die(buf, 1, bytes, dest);
+
+ return !ferror(src) && !ferror(dest);
+}
+
diff --git a/filter/foomatic-rip/util.h b/filter/foomatic-rip/util.h
new file mode 100644
index 000000000..33e3c8700
--- /dev/null
+++ b/filter/foomatic-rip/util.h
@@ -0,0 +1,216 @@
+/* util.h
+ *
+ * Copyright (C) 2008 Till Kamppeter <till.kamppeter@gmail.com>
+ * Copyright (C) 2008 Lars Uebernickel <larsuebernickel@gmx.de>
+ *
+ * This file is part of foomatic-rip.
+ *
+ * Foomatic-rip 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Foomatic-rip 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 Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef util_h
+#define util_h
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include "config.h"
+#include <string.h>
+#include <stdio.h>
+
+
+extern const char* shellescapes;
+
+int isempty(const char *string);
+const char * temp_dir();
+int prefixcmp(const char *str, const char *prefix);
+int prefixcasecmp(const char *str, const char *prefix);
+
+int startswith(const char *str, const char *prefix);
+int endswith(const char *str, const char *postfix);
+
+const char * skip_whitespace(const char *str);
+
+void strlower(char *dest, size_t destlen, const char *src);
+
+/*
+ * Like strncpy, but omits characters for which omit_func returns true
+ * It also assures that dest is zero terminated.
+ * Returns a pointer to the position in 'src' right after the last byte that has been copied.
+ */
+const char * strncpy_omit(char* dest, const char* src, size_t n, int (*omit_func)(int));
+
+int omit_unprintables(int c);
+int omit_shellescapes(int c);
+int omit_specialchars(int c);
+int omit_whitespace(int c);
+int omit_whitespace_newline(int c);
+
+#ifndef HAVE_STRCASESTR
+/* strcasestr() is not available under Solaris */
+char * strcasestr (const char *haystack, const char *needle);
+#endif
+
+/* TODO check for platforms which already have strlcpy and strlcat */
+
+/* Copy at most size-1 characters from src to dest
+ dest will always be \0 terminated (unless size == 0)
+ returns strlen(src) */
+#ifndef HAVE_STRLCPY
+size_t strlcpy(char *dest, const char *src, size_t size);
+#endif /* ! HAVE_STRLCPY */
+#ifndef HAVE_STRLCAT
+size_t strlcat(char *dest, const char *src, size_t size);
+#endif /* ! HAVE_STRLCAT */
+
+/* Replace all occurences of each of the characters in 'chars' by 'repl' */
+void strrepl(char *str, const char *chars, char repl);
+
+/* Replace all occurences of each of the characters in 'chars' by 'repl',
+ but do not allow consecutive 'repl' chars */
+void strrepl_nodups(char *str, const char *chars, char repl);
+
+/* clears 'str' with \0s */
+void strclr(char *str);
+
+char * strnchr(const char *str, int c, size_t n);
+
+void escapechars(char *dest, size_t size, const char *src, const char *esc_chars);
+
+/* copies characters from 'src' to 'dest', until 'src' contains a character from 'stopchars'
+ will not copy more than 'max' chars
+ dest will be zero terminated in either case
+ returns a pointer to the position right after the last byte that has been copied
+*/
+const char * strncpy_tochar(char *dest, const char *src, size_t max, const char *stopchars);
+
+/* "safe" versions of standard <cstdio> fwrite and fread that will cause the
+ * program to exit gracefully when a write/read fails */
+size_t fwrite_or_die(const void* ptr, size_t size, size_t count, FILE* stream);
+size_t fread_or_die(void* ptr, size_t size, size_t count, FILE* stream);
+
+/* 'paths' is a colon seperated list of paths (like $PATH)
+ * 'found_in' may be NULL if it is not needed */
+int find_in_path(const char *progname, const char *paths, char *found_in);
+
+/* extracts the base name of 'path', i.e. only the filename, without path or extension */
+void file_basename(char *dest, const char *path, size_t dest_size);
+
+/* if 'path' is relative, prepend cwd */
+void make_absolute_path(char *path, int len);
+
+int is_true_string(const char *str); /* "1", "Yes", "On", "True" */
+int is_false_string(const char *str); /* "0", "No", "Off", "False", "None" */
+
+int digit(char c); /* returns 0-9 if c is a digit, otherwise -1 */
+
+int line_count(const char *str);
+
+/* returns the index of the beginning of the line_number'th line in str */
+int line_start(const char *str, int line_number);
+
+/* Replace hex notation for unprintable characters in PPD files
+ by the actual characters ex: "<0A>" --> chr(hex("0A")) */
+void unhexify(char *dest, size_t size, const char *src);
+
+void extract_command(size_t *start, size_t *end, const char *cmdline, const char *cmd);
+
+char ** argv_split(const char *string, const char *separators, int *cntp);
+size_t argv_count(char **argv);
+void argv_free(char **argv);
+
+/*
+ * Returns non-zero if 'cmdline' calls 'cmd' in some way
+ */
+int contains_command(const char *cmdline, const char *cmd);
+
+int copy_file(FILE *dest, FILE *src, const char *alreadyread, size_t alreadyread_len);
+
+/* Dynamic string */
+typedef struct dstr {
+ char *data;
+ size_t len;
+ size_t alloc;
+} dstr_t;
+
+dstr_t * create_dstr();
+void free_dstr(dstr_t *ds);
+void dstrclear(dstr_t *ds);
+void dstrassure(dstr_t *ds, size_t alloc);
+void dstrcpy(dstr_t *ds, const char *src);
+void dstrncpy(dstr_t *ds, const char *src, size_t n);
+void dstrncat(dstr_t *ds, const char *src, size_t n);
+void dstrcpyf(dstr_t *ds, const char *src, ...);
+void dstrcat(dstr_t *ds, const char *src);
+void dstrcatf(dstr_t *ds, const char *src, ...);
+void dstrputc(dstr_t *ds, int c);
+size_t fgetdstr(dstr_t *ds, FILE *stream); /* returns number of characters read */
+int dstrreplace(dstr_t *ds, const char *find, const char *repl, int start);
+void dstrprepend(dstr_t *ds, const char *str);
+void dstrinsert(dstr_t *ds, int idx, const char *str);
+void dstrinsertf(dstr_t *ds, int idx, const char *str, ...);
+void dstrremove(dstr_t *ds, int idx, size_t count);
+void dstrcatline(dstr_t *ds, const char *str); /* appends the first line from str to ds (incl. \n) */
+
+int dstrendswith(dstr_t *ds, const char *str);
+void dstrfixnewlines(dstr_t *ds);
+void dstrremovenewline(dstr_t *ds);
+void dstrtrim(dstr_t *ds);
+void dstrtrim_right(dstr_t *ds);
+
+
+/* Doubly linked list of void pointers */
+typedef struct listitem_s {
+ void *data;
+ struct listitem_s *prev, *next;
+} listitem_t;
+
+typedef struct {
+ listitem_t *first, *last;
+} list_t;
+
+list_t * list_create();
+list_t * list_create_from_array(int count, void ** data); /* array values are NOT copied */
+void list_free(list_t *list);
+
+size_t list_item_count(list_t *list);
+
+list_t * list_copy(list_t *list);
+
+void list_prepend(list_t *list, void *data);
+void list_append(list_t *list, void *data);
+void list_remove(list_t *list, listitem_t *item);
+
+listitem_t * list_get(list_t *list, int idx);
+
+
+/* Argument values may be seperated from their keys in the following ways:
+ - with whitespace (i.e. it is in the next list entry)
+ - with a '='
+ - not at all
+*/
+listitem_t * arglist_find(list_t *list, const char *name);
+listitem_t * arglist_find_prefix(list_t *list, const char *name);
+
+char * arglist_get_value(list_t *list, const char *name);
+char * arglist_get(list_t *list, int idx);
+
+int arglist_remove(list_t *list, const char *name);
+int arglist_remove_flag(list_t *list, const char *name);
+
+#endif
+
diff --git a/filter/getline.c b/filter/getline.c
new file mode 100644
index 000000000..1f55f6ead
--- /dev/null
+++ b/filter/getline.c
@@ -0,0 +1,122 @@
+/* getline.c -- Replacement for GNU C library function getline
+
+Copyright (C) 1993 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2 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, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Written by Jan Brittenson, bson@gnu.ai.mit.edu. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <stdio.h>
+#define NDEBUG
+#include <assert.h>
+
+#include <stdlib.h>
+
+/* Always add at least this many bytes when extending the buffer. */
+#define MIN_CHUNK 64
+
+/* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR
+ + OFFSET (and null-terminate it). *LINEPTR is a pointer returned from
+ malloc (or NULL), pointing to *N characters of space. It is realloc'd
+ as necessary. Return the number of characters read (not including the
+ null terminator), or -1 on error or EOF. */
+
+int
+getstr (lineptr, n, stream, terminator, offset)
+ char **lineptr;
+ size_t *n;
+ FILE *stream;
+ char terminator;
+ int offset;
+{
+ int nchars_avail; /* Allocated but unused chars in *LINEPTR. */
+ char *read_pos; /* Where we're reading into *LINEPTR. */
+ int ret;
+
+ if (!lineptr || !n || !stream)
+ return -1;
+
+ if (!*lineptr)
+ {
+ *n = MIN_CHUNK;
+ *lineptr = malloc (*n);
+ if (!*lineptr)
+ return -1;
+ }
+
+ nchars_avail = *n - offset;
+ read_pos = *lineptr + offset;
+
+ for (;;)
+ {
+ register int c = getc (stream);
+
+ /* We always want at least one char left in the buffer, since we
+ always (unless we get an error while reading the first char)
+ NUL-terminate the line buffer. */
+
+ assert(*n - nchars_avail == read_pos - *lineptr);
+ if (nchars_avail < 1)
+ {
+ if (*n > MIN_CHUNK)
+ *n *= 2;
+ else
+ *n += MIN_CHUNK;
+
+ nchars_avail = *n + *lineptr - read_pos;
+ *lineptr = realloc (*lineptr, *n);
+ if (!*lineptr)
+ return -1;
+ read_pos = *n - nchars_avail + *lineptr;
+ assert(*n - nchars_avail == read_pos - *lineptr);
+ }
+
+ if (c == EOF || ferror (stream))
+ {
+ /* Return partial line, if any. */
+ if (read_pos == *lineptr)
+ return -1;
+ else
+ break;
+ }
+
+ *read_pos++ = c;
+ nchars_avail--;
+
+ if (c == terminator)
+ /* Return the line. */
+ break;
+ }
+
+ /* Done - NUL terminate and return the number of chars read. */
+ *read_pos = '\0';
+
+ ret = read_pos - (*lineptr + offset);
+ return ret;
+}
+
+int
+getline (lineptr, n, stream)
+ char **lineptr;
+ size_t *n;
+ FILE *stream;
+{
+ return getstr (lineptr, n, stream, '\n', 0);
+}
diff --git a/filter/gstopdf b/filter/gstopdf
new file mode 100644
index 000000000..d261cf8d6
--- /dev/null
+++ b/filter/gstopdf
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gstopdf - Ghostscript-based PDF filter for CUPS
+#
+# Note: This is only a wrapper filter, the real work is done by gstoraster
+#
+# (C) 2012 Till Kamppeter <till.kamppeter@gmail.com>
+#
+# Released under GPL 2 or later
+#
+
+echo "DEBUG: gstopdf argv[$#] = $@" >&2
+echo "DEBUG: PPD: $PPD" >&2
+
+if [ $# -lt 5 -o $# -gt 6 ]; then
+ echo "ERROR: gstopdf job-id user title copies options [file]" >&2
+ exit 1
+fi
+
+# Read from given file.
+if [ -n "$6" ]; then
+ exec <"$6"
+fi
+
+OUTFORMAT=PDF $CUPS_SERVERBIN/filter/gstoraster "$1" "$2" "$3" "$4" "$5"
diff --git a/filter/gstopxl b/filter/gstopxl
new file mode 100644
index 000000000..984d959cf
--- /dev/null
+++ b/filter/gstopxl
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gstopxl - Ghostscript-based PCL-XL filter for CUPS
+#
+# Note: This is only a wrapper filter, the real work is done by gstoraster
+#
+# (C) 2012 Till Kamppeter <till.kamppeter@gmail.com>
+#
+# Released under GPL 2 or later
+#
+
+echo "DEBUG: gstopxl argv[$#] = $@" >&2
+echo "DEBUG: PPD: $PPD" >&2
+
+if [ $# -lt 5 -o $# -gt 6 ]; then
+ echo "ERROR: gstopxl job-id user title copies options [file]" >&2
+ exit 1
+fi
+
+# Read from given file.
+if [ -n "$6" ]; then
+ exec <"$6"
+fi
+
+OUTFORMAT=PXL $CUPS_SERVERBIN/filter/gstoraster "$1" "$2" "$3" "$4" "$5"
diff --git a/filter/gstoraster.c b/filter/gstoraster.c
new file mode 100644
index 000000000..e3113d420
--- /dev/null
+++ b/filter/gstoraster.c
@@ -0,0 +1,971 @@
+/*
+
+Copyright (c) 2008-2016, Till Kamppeter
+Copyright (c) 2011, Tim Waugh
+Copyright (c) 2011-2013, Richard Hughes
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+MIT Open Source License - http://www.opensource.org/
+
+*/
+
+
+/* PS/PDF to CUPS Raster filter based on Ghostscript */
+
+#include <config.h>
+#include <cups/cups.h>
+#if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 6)
+#define HAVE_CUPS_1_7 1
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <cups/raster.h>
+#include <cupsfilters/colormanager.h>
+#include <cupsfilters/raster.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <errno.h>
+
+#define PDF_MAX_CHECK_COMMENT_LINES 20
+
+typedef enum {
+ GS_DOC_TYPE_PDF,
+ GS_DOC_TYPE_PS,
+ GS_DOC_TYPE_UNKNOWN
+} GsDocType;
+
+typedef enum {
+ OUTPUT_FORMAT_RASTER,
+ OUTPUT_FORMAT_PDF,
+ OUTPUT_FORMAT_PXL
+} OutFormatType;
+
+#ifdef CUPS_RASTER_SYNCv1
+typedef cups_page_header2_t gs_page_header;
+#else
+typedef cups_page_header_t gs_page_header;
+#endif /* CUPS_RASTER_SYNCv1 */
+
+static GsDocType
+parse_doc_type(FILE *fp)
+{
+ char buf[5];
+ GsDocType doc_type;
+ char *rc;
+
+ /* get the first few bytes of the file */
+ doc_type = GS_DOC_TYPE_UNKNOWN;
+ rewind(fp);
+ rc = fgets(buf,sizeof(buf),fp);
+ if (rc == NULL)
+ goto out;
+
+ /* is PDF */
+ if (strncmp(buf,"%PDF",4) == 0) {
+ doc_type = GS_DOC_TYPE_PDF;
+ goto out;
+ }
+
+ /* is PS */
+ if (strncmp(buf,"%!",2) == 0) {
+ doc_type = GS_DOC_TYPE_PS;
+ goto out;
+ }
+out:
+ return doc_type;
+}
+
+static void
+parse_pdf_header_options(FILE *fp, gs_page_header *h)
+{
+ char buf[4096];
+ int i;
+
+ rewind(fp);
+ /* skip until PDF start header */
+ while (fgets(buf,sizeof(buf),fp) != 0) {
+ if (strncmp(buf,"%PDF",4) == 0) {
+ break;
+ }
+ }
+ for (i = 0;i < PDF_MAX_CHECK_COMMENT_LINES;i++) {
+ if (fgets(buf,sizeof(buf),fp) == 0) break;
+ if (strncmp(buf,"%%PDFTOPDFNumCopies",19) == 0) {
+ char *p;
+
+ p = strchr(buf+19,':');
+ h->NumCopies = atoi(p+1);
+ } else if (strncmp(buf,"%%PDFTOPDFCollate",17) == 0) {
+ char *p;
+
+ p = strchr(buf+17,':');
+ while (*p == ' ' || *p == '\t') p++;
+ if (strncasecmp(p,"true",4) == 0) {
+ h->Collate = CUPS_TRUE;
+ } else {
+ h->Collate = CUPS_FALSE;
+ }
+ }
+ }
+}
+
+static void
+add_pdf_header_options(gs_page_header *h, cups_array_t *gs_args,
+ OutFormatType outformat, int pxlcolor)
+{
+ int i;
+ char tmpstr[1024];
+
+ /* Simple boolean, enumerated choice, numerical, and string parameters */
+ if (outformat == OUTPUT_FORMAT_RASTER) {
+ if (h->MediaClass[0] |= '\0') {
+ snprintf(tmpstr, sizeof(tmpstr), "-sMediaClass=%s", h->MediaClass);
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ if (h->MediaColor[0] |= '\0') {
+ snprintf(tmpstr, sizeof(tmpstr), "-sMediaColor=%s", h->MediaColor);
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ if (h->MediaType[0] |= '\0') {
+ snprintf(tmpstr, sizeof(tmpstr), "-sMediaType=%s", h->MediaType);
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ if (h->OutputType[0] |= '\0') {
+ snprintf(tmpstr, sizeof(tmpstr), "-sOutputType=%s", h->OutputType);
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ if (h->AdvanceDistance) {
+ snprintf(tmpstr, sizeof(tmpstr), "-dAdvanceDistance=%d",
+ (unsigned)(h->AdvanceDistance));
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ if (h->AdvanceMedia) {
+ snprintf(tmpstr, sizeof(tmpstr), "-dAdvanceMedia=%d",
+ (unsigned)(h->AdvanceMedia));
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ if (h->Collate) {
+ cupsArrayAdd(gs_args, strdup("-dCollate"));
+ }
+ if (h->CutMedia) {
+ snprintf(tmpstr, sizeof(tmpstr), "-dCutMedia=%d",
+ (unsigned)(h->CutMedia));
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ }
+ if (outformat == OUTPUT_FORMAT_RASTER ||
+ outformat == OUTPUT_FORMAT_PXL) {
+ /* PDF output is only for turning PostScript input data into PDF
+ not for sending PDF to a PDF printer (this is done by pdftopdf)
+ therefore we do not apply duplex/tumble here. */
+ if (h->Duplex) {
+ cupsArrayAdd(gs_args, strdup("-dDuplex"));
+ }
+ }
+ if ((h->HWResolution[0] != 100) || (h->HWResolution[1] != 100))
+ snprintf(tmpstr, sizeof(tmpstr), "-r%dx%d",
+ (unsigned)(h->HWResolution[0]), (unsigned)(h->HWResolution[1]));
+ else
+ snprintf(tmpstr, sizeof(tmpstr), "-r100x100");
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ if (outformat == OUTPUT_FORMAT_RASTER) {
+ if (h->InsertSheet) {
+ cupsArrayAdd(gs_args, strdup("-dInsertSheet"));
+ }
+ if (h->Jog) {
+ snprintf(tmpstr, sizeof(tmpstr), "-dJog=%d",
+ (unsigned)(h->Jog));
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ if (h->LeadingEdge) {
+ snprintf(tmpstr, sizeof(tmpstr), "-dLeadingEdge=%d",
+ (unsigned)(h->LeadingEdge));
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ if (h->ManualFeed) {
+ cupsArrayAdd(gs_args, strdup("-dManualFeed"));
+ }
+ }
+ if (outformat == OUTPUT_FORMAT_RASTER ||
+ outformat == OUTPUT_FORMAT_PXL) {
+ if (h->MediaPosition) {
+ int mediapos;
+ if (outformat == OUTPUT_FORMAT_PXL) {
+ /* Convert PWG MediaPosition values to PXL-ones */
+ if (h->MediaPosition == 1) /* Main */
+ mediapos = 4;
+ else if (h->MediaPosition == 2) /* Alternate */
+ mediapos = 5;
+ else if (h->MediaPosition == 3) /* Large Capacity */
+ mediapos = 7;
+ else if (h->MediaPosition == 4) /* Manual */
+ mediapos = 2;
+ else if (h->MediaPosition == 5) /* Envelope */
+ mediapos = 6;
+ else if (h->MediaPosition == 11) /* Top */
+ mediapos = 4;
+ else if (h->MediaPosition == 12) /* Middle */
+ mediapos = 5;
+ else if (h->MediaPosition == 13) /* Bottom */
+ mediapos = 7;
+ else if (h->MediaPosition == 19) /* Bypass */
+ mediapos = 3;
+ else if (h->MediaPosition == 20) /* Tray 1 */
+ mediapos = 3;
+ else if (h->MediaPosition == 21) /* Tray 2 */
+ mediapos = 4;
+ else if (h->MediaPosition == 22) /* Tray 3 */
+ mediapos = 5;
+ else if (h->MediaPosition == 23) /* Tray 4 */
+ mediapos = 7;
+ else
+ mediapos = 0;
+ } else
+ mediapos = h->MediaPosition;
+ snprintf(tmpstr, sizeof(tmpstr), "-dMediaPosition=%d",
+ (unsigned)(mediapos));
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ }
+ if (outformat == OUTPUT_FORMAT_RASTER) {
+ if (h->MediaWeight) {
+ snprintf(tmpstr, sizeof(tmpstr), "-dMediaWeight=%d",
+ (unsigned)(h->MediaWeight));
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ if (h->MirrorPrint) {
+ cupsArrayAdd(gs_args, strdup("-dMirrorPrint"));
+ }
+ if (h->NegativePrint) {
+ cupsArrayAdd(gs_args, strdup("-dNegativePrint"));
+ }
+ if (h->NumCopies != 1) {
+ snprintf(tmpstr, sizeof(tmpstr), "-dNumCopies=%d",
+ (unsigned)(h->NumCopies));
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ if (h->Orientation) {
+ snprintf(tmpstr, sizeof(tmpstr), "-dOrientation=%d",
+ (unsigned)(h->Orientation));
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ if (h->OutputFaceUp) {
+ cupsArrayAdd(gs_args, strdup("-dOutputFaceUp"));
+ }
+ }
+ if (h->PageSize[0] != 612)
+ snprintf(tmpstr, sizeof(tmpstr), "-dDEVICEWIDTHPOINTS=%d",
+ (unsigned)(h->PageSize[0]));
+ else
+ snprintf(tmpstr, sizeof(tmpstr), "-dDEVICEWIDTHPOINTS=612");
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ if (h->PageSize[1] != 792)
+ snprintf(tmpstr, sizeof(tmpstr), "-dDEVICEHEIGHTPOINTS=%d",
+ (unsigned)(h->PageSize[1]));
+ else
+ snprintf(tmpstr, sizeof(tmpstr), "-dDEVICEHEIGHTPOINTS=792");
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ if (outformat == OUTPUT_FORMAT_RASTER) {
+ if (h->Separations) {
+ cupsArrayAdd(gs_args, strdup("-dSeparations"));
+ }
+ if (h->TraySwitch) {
+ cupsArrayAdd(gs_args, strdup("-dTraySwitch"));
+ }
+ }
+ if (outformat == OUTPUT_FORMAT_RASTER ||
+ outformat == OUTPUT_FORMAT_PXL) {
+ /* PDF output is only for turning PostScript input data into PDF
+ not for sending PDF to a PDF printer (this is done by pdftopdf)
+ therefore we do not apply duplex/tumble here. */
+ if (h->Tumble) {
+ cupsArrayAdd(gs_args, strdup("-dTumble"));
+ }
+ }
+ if (outformat == OUTPUT_FORMAT_RASTER) {
+ if (h->cupsMediaType) {
+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsMediaType=%d",
+ (unsigned)(h->cupsMediaType));
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ if (h->cupsBitsPerColor != 1)
+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsBitsPerColor=%d",
+ (unsigned)(h->cupsBitsPerColor));
+ else
+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsBitsPerColor=1");
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ if (h->cupsColorOrder != CUPS_ORDER_CHUNKED)
+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsColorOrder=%d",
+ (unsigned)(h->cupsColorOrder));
+ else
+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsColorOrder=%d",
+ CUPS_ORDER_CHUNKED);
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ if (outformat == OUTPUT_FORMAT_RASTER) {
+ if (h->cupsColorSpace != CUPS_CSPACE_K)
+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsColorSpace=%d",
+ (unsigned)(h->cupsColorSpace));
+ else
+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsColorSpace=%d",
+ CUPS_CSPACE_K);
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+
+ if (outformat == OUTPUT_FORMAT_PXL) {
+ if (h->cupsColorSpace == CUPS_CSPACE_W ||
+ h->cupsColorSpace == CUPS_CSPACE_K ||
+ h->cupsColorSpace == CUPS_CSPACE_WHITE ||
+ h->cupsColorSpace == CUPS_CSPACE_GOLD ||
+ h->cupsColorSpace == CUPS_CSPACE_SILVER ||
+ h->cupsColorSpace == CUPS_CSPACE_SW ||
+ h->cupsColorSpace == CUPS_CSPACE_ICC1 ||
+ h->cupsColorSpace == CUPS_CSPACE_DEVICE1)
+ /* Monochrome color spaces -> use "pxlmono" device */
+ pxlcolor = 0;
+ if (pxlcolor == 1)
+ cupsArrayAdd(gs_args, strdup("-sDEVICE=pxlcolor"));
+ else
+ cupsArrayAdd(gs_args, strdup("-sDEVICE=pxlmono"));
+ }
+ if (outformat == OUTPUT_FORMAT_RASTER) {
+ if (h->cupsCompression) {
+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsCompression=%d",
+ (unsigned)(h->cupsCompression));
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ if (h->cupsRowCount) {
+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsRowCount=%d",
+ (unsigned)(h->cupsRowCount));
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ if (h->cupsRowFeed) {
+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsRowFeed=%d",
+ (unsigned)(h->cupsRowFeed));
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ if (h->cupsRowStep) {
+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsRowStep=%d",
+ (unsigned)(h->cupsRowStep));
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ }
+#ifdef CUPS_RASTER_SYNCv1
+ if (outformat == OUTPUT_FORMAT_RASTER) {
+ if (h->cupsBorderlessScalingFactor != 1.0f) {
+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsBorderlessScalingFactor=%.4f",
+ h->cupsBorderlessScalingFactor);
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ for (i=0; i <= 15; i ++)
+ if (h->cupsInteger[i]) {
+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsInteger%d=%d",
+ i, (unsigned)(h->cupsInteger[i]));
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ for (i=0; i <= 15; i ++)
+ if (h->cupsReal[i]) {
+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsReal%d=%.4f",
+ i, h->cupsReal[i]);
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ for (i=0; i <= 15; i ++)
+ if (h->cupsString[i][0] != '\0') {
+ snprintf(tmpstr, sizeof(tmpstr), "-scupsString%d=%s",
+ i, h->cupsString[i]);
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ if (h->cupsMarkerType[0] != '\0') {
+ snprintf(tmpstr, sizeof(tmpstr), "-scupsMarkerType=%s",
+ h->cupsMarkerType);
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ if (h->cupsRenderingIntent[0] != '\0') {
+ snprintf(tmpstr, sizeof(tmpstr), "-scupsRenderingIntent=%s",
+ h->cupsRenderingIntent);
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ if (h->cupsPageSizeName[0] != '\0') {
+ snprintf(tmpstr, sizeof(tmpstr), "-scupsPageSizeName=%s",
+ h->cupsPageSizeName);
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+ }
+#endif /* CUPS_RASTER_SYNCv1 */
+}
+
+static int
+gs_spawn (const char *filename,
+ cups_array_t *gs_args,
+ char **envp,
+ FILE *fp)
+{
+ char *argument;
+ char buf[BUFSIZ];
+ char **gsargv;
+ const char* apos;
+ int fds[2];
+ int i;
+ int n;
+ int numargs;
+ int pid;
+ int status = 65536;
+ int wstatus;
+
+ /* Put Ghostscript command line argument into an array for the "exec()"
+ call */
+ numargs = cupsArrayCount(gs_args);
+ gsargv = calloc(numargs + 1, sizeof(char *));
+ for (argument = (char *)cupsArrayFirst(gs_args), i = 0; argument;
+ argument = (char *)cupsArrayNext(gs_args), i++) {
+ gsargv[i] = argument;
+ }
+ gsargv[i] = NULL;
+
+ /* Debug output: Full Ghostscript command line and environment variables */
+ fprintf(stderr, "DEBUG: Ghostscript command line:");
+ for (i = 0; gsargv[i]; i ++) {
+ if ((strchr(gsargv[i],' ')) || (strchr(gsargv[i],'\t')))
+ apos = "'";
+ else
+ apos = "";
+ fprintf(stderr, " %s%s%s", apos, gsargv[i], apos);
+ }
+ fprintf(stderr, "\n");
+
+ for (i = 0; envp[i]; i ++)
+ fprintf(stderr, "DEBUG: envp[%d]=\"%s\"\n", i, envp[i]);
+
+ /* Create a pipe for feeding the job into Ghostscript */
+ if (pipe(fds))
+ {
+ fds[0] = -1;
+ fds[1] = -1;
+ fprintf(stderr, "ERROR: Unable to establish pipe for Ghostscript call\n");
+ goto out;
+ }
+
+ /* Set the "close on exec" flag on each end of the pipe... */
+ if (fcntl(fds[0], F_SETFD, fcntl(fds[0], F_GETFD) | FD_CLOEXEC))
+ {
+ close(fds[0]);
+ close(fds[1]);
+ fds[0] = -1;
+ fds[1] = -1;
+ fprintf(stderr, "ERROR: Unable to set \"close on exec\" flag on read end of the pipe for Ghostscript call\n");
+ goto out;
+ }
+ if (fcntl(fds[1], F_SETFD, fcntl(fds[1], F_GETFD) | FD_CLOEXEC))
+ {
+ close(fds[0]);
+ close(fds[1]);
+ fprintf(stderr, "ERROR: Unable to set \"close on exec\" flag on write end of the pipe for Ghostscript call\n");
+ goto out;
+ }
+
+ if ((pid = fork()) == 0)
+ {
+ /* Couple pipe with STDIN of Ghostscript process */
+ if (fds[0] != 0) {
+ close(0);
+ if (fds[0] > 0) {
+ if (dup(fds[0]) < 0) {
+ fprintf(stderr, "ERROR: Unable to couple pipe with STDIN of Ghostscript process\n");
+ goto out;
+ }
+ } else {
+ fprintf(stderr, "ERROR: Unable to couple pipe with STDIN of Ghostscript process\n");
+ goto out;
+ }
+ }
+
+ /* Execute Ghostscript command line ... */
+ execvpe(filename, gsargv, envp);
+ perror(filename);
+ goto out;
+ }
+
+ /* Feed job data into Ghostscript */
+ while ((n = fread(buf, 1, BUFSIZ, fp)) > 0) {
+ int count;
+retry_write:
+ count = write(fds[1], buf, n);
+ if (count != n) {
+ if (count == -1) {
+ if (errno == EINTR)
+ goto retry_write;
+ fprintf(stderr, "ERROR: write failed: %s\n", strerror(errno));
+ }
+ fprintf(stderr, "ERROR: Can't feed job data into Ghostscript\n");
+ goto out;
+ }
+ }
+ close (fds[1]);
+
+retry_wait:
+ if (waitpid (pid, &wstatus, 0) == -1) {
+ if (errno == EINTR)
+ goto retry_wait;
+ perror ("gs");
+ goto out;
+ }
+
+ /* How did Ghostscript terminate */
+ if (WIFEXITED(wstatus))
+ /* Via exit() anywhere or return() in the main() function */
+ status = WEXITSTATUS(wstatus);
+ else if (WIFSIGNALED(wstatus))
+ /* Via signal */
+ status = 256 * WTERMSIG(wstatus);
+
+out:
+ free(gsargv);
+ return status;
+}
+
+#if 0
+static char *
+get_ppd_icc_fallback (ppd_file_t *ppd, char **qualifier)
+{
+ char full_path[1024];
+ char *icc_profile = NULL;
+ char qualifer_tmp[1024];
+ const char *profile_key;
+ ppd_attr_t *attr;
+ char *datadir;
+
+ /* get profile attr, falling back to CUPS */
+ profile_key = "APTiogaProfile";
+ attr = ppdFindAttr(ppd, profile_key, NULL);
+ if (attr == NULL) {
+ profile_key = "cupsICCProfile";
+ attr = ppdFindAttr(ppd, profile_key, NULL);
+ }
+
+ /* create a string for a quick comparion */
+ snprintf(qualifer_tmp, sizeof(qualifer_tmp),
+ "%s.%s.%s",
+ qualifier[0],
+ qualifier[1],
+ qualifier[2]);
+
+ /* neither */
+ if (attr == NULL) {
+ fprintf(stderr, "INFO: no profiles specified in PPD\n");
+ goto out;
+ }
+
+ if ((datadir = getenv("CUPS_DATADIR")) == NULL)
+ datadir = CUPS_DATADIR;
+
+ /* try to find a profile that matches the qualifier exactly */
+ for (;attr != NULL; attr = ppdFindNextAttr(ppd, profile_key, NULL)) {
+ fprintf(stderr, "INFO: found profile %s in PPD with qualifier '%s'\n",
+ attr->value, attr->spec);
+
+ /* invalid entry */
+ if (attr->spec == NULL || attr->value == NULL)
+ continue;
+
+ /* expand to a full path if not already specified */
+ if (attr->value[0] != '/')
+ snprintf(full_path, sizeof(full_path),
+ "%s/profiles/%s", datadir, attr->value);
+ else
+ strncpy(full_path, attr->value, sizeof(full_path));
+
+ /* check the file exists */
+ if (access(full_path, 0)) {
+ fprintf(stderr, "INFO: found profile %s in PPD that does not exist\n",
+ full_path);
+ continue;
+ }
+
+ /* matches the qualifier */
+ if (strcmp(qualifer_tmp, attr->spec) == 0) {
+ icc_profile = strdup(full_path);
+ goto out;
+ }
+ }
+
+ /* no match */
+ if (attr == NULL) {
+ fprintf(stderr, "INFO: no profiles in PPD for qualifier '%s'\n",
+ qualifer_tmp);
+ goto out;
+ }
+
+out:
+ return icc_profile;
+}
+#endif
+
+int
+main (int argc, char **argv, char *envp[])
+{
+ char *outformat_env = NULL;
+ OutFormatType outformat;
+ char buf[BUFSIZ];
+ char *icc_profile = NULL;
+ /*char **qualifier = NULL;*/
+ char *tmp;
+ char tmpstr[1024];
+ const char *t = NULL;
+ cups_array_t *gs_args = NULL;
+ cups_option_t *options = NULL;
+ FILE *fp = NULL;
+ GsDocType doc_type;
+ gs_page_header h;
+ int fd;
+ int cm_disabled;
+ int n;
+ int num_options;
+ int status = 1;
+ ppd_file_t *ppd = NULL;
+ struct sigaction sa;
+ cm_calibration_t cm_calibrate;
+ int pxlcolor = 1;
+#ifdef HAVE_CUPS_1_7
+ int pwgraster = 0;
+ ppd_attr_t *attr;
+#endif /* HAVE_CUPS_1_7 */
+
+ if (argc < 6 || argc > 7) {
+ fprintf(stderr, "ERROR: %s job-id user title copies options [file]\n",
+ argv[0]);
+ goto out;
+ }
+
+ memset(&sa, 0, sizeof(sa));
+ /* Ignore SIGPIPE and have write return an error instead */
+ sa.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &sa, NULL);
+
+ /* Determine the output format via an environment variable set by a wrapper
+ script */
+ outformat_env = getenv("OUTFORMAT");
+ if (outformat_env == NULL || strcasestr(outformat_env, "raster"))
+ outformat = OUTPUT_FORMAT_RASTER;
+ else if (strcasestr(outformat_env, "pdf"))
+ outformat = OUTPUT_FORMAT_PDF;
+ else if (strcasestr(outformat_env, "xl"))
+ outformat = OUTPUT_FORMAT_PXL;
+ else {
+ fprintf(stderr, "ERROR: OUTFORMAT=\"%s\", cannot determine output format\n",
+ outformat_env);
+ goto out;
+ }
+ fprintf(stderr, "DEBUG: OUTFORMAT=\"%s\", so output format will be %s\n",
+ outformat_env,
+ (outformat == OUTPUT_FORMAT_RASTER ? "CUPS/PWG Raster" :
+ (outformat == OUTPUT_FORMAT_PDF ? "PDF" :
+ "PCL XL")));
+
+ num_options = cupsParseOptions(argv[5], 0, &options);
+
+ t = getenv("PPD");
+ if (t && t[0] != '\0')
+ if ((ppd = ppdOpenFile(t)) == NULL) {
+ fprintf(stderr, "ERROR: Failed to open PPD: %s\n", t);
+ }
+
+ if (ppd) {
+ ppdMarkDefaults (ppd);
+ cupsMarkOptions (ppd, num_options, options);
+ }
+
+ if (argc == 6) {
+ /* stdin */
+
+ fd = cupsTempFd(buf,BUFSIZ);
+ if (fd < 0) {
+ fprintf(stderr, "ERROR: Can't create temporary file\n");
+ goto out;
+ }
+ /* remove name */
+ unlink(buf);
+
+ /* copy stdin to the tmp file */
+ while ((n = read(0,buf,BUFSIZ)) > 0) {
+ if (write(fd,buf,n) != n) {
+ fprintf(stderr, "ERROR: Can't copy stdin to temporary file\n");
+ close(fd);
+ goto out;
+ }
+ }
+ if (lseek(fd,0,SEEK_SET) < 0) {
+ fprintf(stderr, "ERROR: Can't rewind temporary file\n");
+ close(fd);
+ goto out;
+ }
+
+ if ((fp = fdopen(fd,"rb")) == 0) {
+ fprintf(stderr, "ERROR: Can't fdopen temporary file\n");
+ close(fd);
+ goto out;
+ }
+ } else {
+ /* argc == 7 filename is specified */
+
+ if ((fp = fopen(argv[6],"rb")) == 0) {
+ fprintf(stderr, "ERROR: Can't open input file %s\n",argv[6]);
+ goto out;
+ }
+ }
+
+ /* find out file type */
+ doc_type = parse_doc_type(fp);
+ if (doc_type == GS_DOC_TYPE_UNKNOWN) {
+ fprintf(stderr, "ERROR: Can't detect file type\n");
+ goto out;
+ }
+
+ /* Check status of color management in CUPS */
+ cm_calibrate = cmGetCupsColorCalibrateMode(options, num_options);
+
+ if (cm_calibrate == CM_CALIBRATION_ENABLED)
+ cm_disabled = 1;
+ else
+ cm_disabled = cmIsPrinterCmDisabled(getenv("PRINTER"));
+
+ if (!cm_disabled)
+ cmGetPrinterIccProfile(getenv("PRINTER"), &icc_profile, ppd);
+
+ /* Ghostscript parameters */
+ gs_args = cupsArrayNew(NULL, NULL);
+ if (!gs_args) {
+ fprintf(stderr, "ERROR: Unable to allocate memory for Ghostscript arguments array\n");
+ goto out;
+ }
+
+ /* Part of Ghostscript command line which is not dependent on the job and/or
+ the driver */
+ snprintf(tmpstr, sizeof(tmpstr), "%s", CUPS_GHOSTSCRIPT);
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ cupsArrayAdd(gs_args, strdup("-dQUIET"));
+ /*cupsArrayAdd(gs_args, strdup("-dDEBUG"));*/
+ cupsArrayAdd(gs_args, strdup("-dPARANOIDSAFER"));
+ cupsArrayAdd(gs_args, strdup("-dNOPAUSE"));
+ cupsArrayAdd(gs_args, strdup("-dBATCH"));
+ cupsArrayAdd(gs_args, strdup("-dNOINTERPOLATE"));
+ cupsArrayAdd(gs_args, strdup("-dNOMEDIAATTRS"));
+ if (cm_disabled)
+ cupsArrayAdd(gs_args, strdup("-dUseFastColor"));
+ if (doc_type == GS_DOC_TYPE_PDF)
+ cupsArrayAdd(gs_args, strdup("-dShowAcroForm"));
+ cupsArrayAdd(gs_args, strdup("-sstdout=%stderr"));
+ cupsArrayAdd(gs_args, strdup("-sOutputFile=%stdout"));
+
+ /* Ghostscript output device */
+ if (outformat == OUTPUT_FORMAT_RASTER)
+ cupsArrayAdd(gs_args, strdup("-sDEVICE=cups"));
+ else if (outformat == OUTPUT_FORMAT_PDF)
+ cupsArrayAdd(gs_args, strdup("-sDEVICE=pdfwrite"));
+ /* In case of PCL XL output we determine later whether we will have
+ to use the "pxlmono" or "pxlcolor" output device */
+
+ /* Special Ghostscript options for PDF output */
+ if (outformat == OUTPUT_FORMAT_PDF) {
+ cupsArrayAdd(gs_args, strdup("-dCompatibilityLevel=1.3"));
+ cupsArrayAdd(gs_args, strdup("-dAutoRotatePages=/None"));
+ cupsArrayAdd(gs_args, strdup("-dAutoFilterColorImages=false"));
+ cupsArrayAdd(gs_args, strdup("-dNOPLATFONTS"));
+ cupsArrayAdd(gs_args, strdup("-dColorImageFilter=/FlateEncode"));
+ cupsArrayAdd(gs_args, strdup("-dPDFSETTINGS=/printer"));
+ cupsArrayAdd(gs_args, strdup("-dColorConversionStrategy=/LeaveColorUnchanged"));
+ }
+
+#ifdef HAVE_CUPS_1_7
+ if (outformat == OUTPUT_FORMAT_RASTER)
+ {
+ t = getenv("FINAL_CONTENT_TYPE");
+ if (t && strcasestr(t, "pwg"))
+ pwgraster = 1;
+ }
+#endif /* HAVE_CUPS_1_7 */
+
+ if (ppd)
+ {
+ cupsRasterInterpretPPD(&h,ppd,num_options,options,0);
+#ifdef HAVE_CUPS_1_7
+ if (outformat == OUTPUT_FORMAT_RASTER)
+ {
+ if ((attr = ppdFindAttr(ppd,"PWGRaster",0)) != 0 &&
+ (!strcasecmp(attr->value, "true") ||
+ !strcasecmp(attr->value, "on") ||
+ !strcasecmp(attr->value, "yes")))
+ pwgraster = 1;
+ if (pwgraster == 1)
+ cupsRasterParseIPPOptions(&h, num_options, options, pwgraster, 0);
+ }
+#endif /* HAVE_CUPS_1_7 */
+ if (outformat == OUTPUT_FORMAT_PXL)
+ {
+ if ((attr = ppdFindAttr(ppd,"ColorDevice",0)) != 0 &&
+ (!strcasecmp(attr->value, "false") ||
+ !strcasecmp(attr->value, "off") ||
+ !strcasecmp(attr->value, "no")))
+ /* Monochrome PCL XL printer, according to PPD */
+ pxlcolor = 0;
+ }
+ }
+ else
+ {
+#ifdef HAVE_CUPS_1_7
+ if (outformat == OUTPUT_FORMAT_RASTER)
+ {
+ pwgraster = 1;
+ t = cupsGetOption("media-class", num_options, options);
+ if (t == NULL)
+ t = cupsGetOption("MediaClass", num_options, options);
+ if (t != NULL)
+ {
+ if (strcasestr(t, "pwg"))
+ pwgraster = 1;
+ else
+ pwgraster = 0;
+ }
+ }
+ cupsRasterParseIPPOptions(&h, num_options, options, pwgraster, 1);
+#else
+ fprintf(stderr, "ERROR: No PPD file specified.\n");
+ goto out;
+#endif /* HAVE_CUPS_1_7 */
+ }
+
+ if ((h.HWResolution[0] == 100) && (h.HWResolution[1] == 100)) {
+ /* No "Resolution" option */
+ if (ppd && (attr = ppdFindAttr(ppd, "DefaultResolution", 0)) != NULL) {
+ /* "*DefaultResolution" keyword in the PPD */
+ const char *p = attr->value;
+ h.HWResolution[0] = atoi(p);
+ if ((p = strchr(p, 'x')) != NULL)
+ h.HWResolution[1] = atoi(p);
+ else
+ h.HWResolution[1] = h.HWResolution[0];
+ if (h.HWResolution[0] <= 0)
+ h.HWResolution[0] = 300;
+ if (h.HWResolution[1] <= 0)
+ h.HWResolution[1] = h.HWResolution[0];
+ } else {
+ h.HWResolution[0] = 300;
+ h.HWResolution[1] = 300;
+ }
+ h.cupsWidth = h.HWResolution[0] * h.PageSize[0] / 72;
+ h.cupsHeight = h.HWResolution[1] * h.PageSize[1] / 72;
+ }
+
+ /* set PDF-specific options */
+ if (doc_type == GS_DOC_TYPE_PDF) {
+ parse_pdf_header_options(fp, &h);
+ }
+
+ /* fixed other values that pdftopdf handles */
+ h.MirrorPrint = CUPS_FALSE;
+ h.Orientation = CUPS_ORIENT_0;
+
+ /* get all the data from the header and pass it to ghostscript */
+ add_pdf_header_options (&h, gs_args, outformat, pxlcolor);
+
+ /* CUPS font path */
+ if ((t = getenv("CUPS_FONTPATH")) == NULL)
+ t = CUPS_FONTPATH;
+ snprintf(tmpstr, sizeof(tmpstr), "-I%s", t);
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+
+ /* set the device output ICC profile */
+ if(icc_profile != NULL && icc_profile[0] != '\0') {
+ snprintf(tmpstr, sizeof(tmpstr), "-sOutputICCProfile=%s", icc_profile);
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+
+ /* Switch to taking PostScript commands on the Ghostscript command line */
+ cupsArrayAdd(gs_args, strdup("-c"));
+
+ /* Set margins if we have a bounding box defined */
+ if (h.cupsImagingBBox[3] > 0.0) {
+ snprintf(tmpstr, sizeof(tmpstr),
+ "<</.HWMargins[%f %f %f %f] /Margins[0 0]>>setpagedevice",
+ h.cupsImagingBBox[0], h.cupsImagingBBox[1],
+ h.cupsPageSize[0] - h.cupsImagingBBox[2],
+ h.cupsPageSize[1] - h.cupsImagingBBox[3]);
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+
+ if ((t = cupsGetOption("profile", num_options, options)) != NULL) {
+ snprintf(tmpstr, sizeof(tmpstr), "<</cupsProfile(%s)>>setpagedevice", t);
+ cupsArrayAdd(gs_args, strdup(tmpstr));
+ }
+
+ /* Do we have a "center-of-pixel" command line option or
+ "CenterOfPixel" PPD option set to "true"? In this case let
+ Ghostscript use the center-of-pixel rule instead of the
+ PostScript-standard any-part-of-pixel rule when filling a
+ path. This improves the accuracy of graphics (like bar codes for
+ example) on low-resolution printers (like label printers with
+ typically 203 dpi). See
+ https://bugs.linuxfoundation.org/show_bug.cgi?id=1373 */
+ if (((t = cupsGetOption("CenterOfPixel", num_options, options)) == NULL &&
+ (t = cupsGetOption("center-of-pixel", num_options, options)) == NULL &&
+ ppd && (attr = ppdFindAttr(ppd,"DefaultCenterOfPixel", NULL)) != NULL &&
+ (!strcasecmp(attr->value, "true") ||
+ !strcasecmp(attr->value, "on") ||
+ !strcasecmp(attr->value, "yes"))) ||
+ (t && (!strcasecmp(t, "true") || !strcasecmp(t, "on") ||
+ !strcasecmp(t, "yes")))) {
+ fprintf(stderr, "DEBUG: Ghostscript using Center-of-Pixel method to fill paths.\n");
+ cupsArrayAdd(gs_args, strdup("0 .setfilladjust"));
+ } else
+ fprintf(stderr, "DEBUG: Ghostscript using Any-Part-of-Pixel method to fill paths.\n");
+
+ /* Mark the end of PostScript commands supplied on the Ghostscript command
+ line (with the "-c" option), so that we can supply the input file name */
+ cupsArrayAdd(gs_args, strdup("-f"));
+
+ /* Let Ghostscript read from STDIN */
+ cupsArrayAdd(gs_args, strdup("-_"));
+
+ /* Execute Ghostscript command line ... */
+ snprintf(tmpstr, sizeof(tmpstr), "%s", CUPS_GHOSTSCRIPT);
+
+ /* call Ghostscript */
+ rewind(fp);
+ status = gs_spawn (tmpstr, gs_args, envp, fp);
+ if (status != 0) status = 1;
+out:
+ if (fp)
+ fclose(fp);
+ if (gs_args) {
+ while ((tmp = cupsArrayFirst(gs_args)) != NULL) {
+ cupsArrayRemove(gs_args,tmp);
+ free(tmp);
+ }
+ cupsArrayDelete(gs_args);
+ }
+ free(icc_profile);
+ if (ppd)
+ ppdClose(ppd);
+ return status;
+}
diff --git a/filter/imagetopdf.c b/filter/imagetopdf.c
new file mode 100644
index 000000000..658e1131a
--- /dev/null
+++ b/filter/imagetopdf.c
@@ -0,0 +1,1820 @@
+/*
+ * Image file to PDF filter for the Common UNIX Printing System (CUPS).
+ * developped by BBR Inc. 2006-2007
+ *
+ * This is based on imagetops.c of CUPS
+ *
+ * imagetops.c copyright notice is follows
+ *
+ * Copyright 1993-2006 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "COPYING" which should have been included with this file.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "config.h"
+#include "common.h"
+#include <cupsfilters/image.h>
+#include <cupsfilters/raster.h>
+#include <math.h>
+#include <ctype.h>
+
+#if CUPS_VERSION_MAJOR < 1 \
+ || (CUPS_VERSION_MAJOR == 1 && CUPS_VERSION_MINOR < 2)
+#ifndef CUPS_1_1
+#error Installed libs and specified source Version mismatch \
+ Libs >= 1.2 && Source < 1.2
+#define CUPS_1_1
+#endif
+#else
+#ifdef CUPS_1_1
+#error Installed libs and specified source Version mismatch \
+ Libs < 1.2 && Source >= 1.2
+#undef CUPS_1_1
+#endif
+#endif
+
+#define USE_CONVERT_CMD
+//#define OUT_AS_HEX
+//#define OUT_AS_ASCII85
+
+/*
+ * Globals...
+ */
+
+int Flip = 0, /* Flip/mirror pages */
+ XPosition = 0, /* Horizontal position on page */
+ YPosition = 0, /* Vertical position on page */
+ Collate = 0, /* Collate copies? */
+ Copies = 1, /* Number of copies */
+ Reverse = 0, /* Output order */
+ EvenDuplex = 0; /* cupsEvenDuplex */
+
+#ifdef CUPS_1_1
+#define cups_ib_t ib_t
+#define cups_image_t image_t
+#define CUPS_IMAGE_CMYK IMAGE_CMYK
+#define CUPS_IMAGE_WHITE IMAGE_WHITE
+#define CUPS_IMAGE_RGB IMAGE_RGB
+#define CUPS_IMAGE_RGB_CMYK IMAGE_RGB_CMYK
+#define cupsImageOpen ImageOpen
+#define cupsImageClose ImageClose
+#define cupsImageGetColorSpace(img) (img->colorspace)
+#define cupsImageGetXPPI(img) (img->xppi)
+#define cupsImageGetYPPI(img) (img->yppi)
+#define cupsImageGetWidth(img) (img->xsize)
+#define cupsImageGetHeight(img) (img->ysize)
+#define cupsImageGetRow ImageGetRow
+#endif
+
+/*
+ * Local functions...
+ */
+
+#ifdef OUT_AS_HEX
+static void out_hex(cups_ib_t *, int, int);
+#else
+#ifdef OUT_AS_ASCII85
+static void out_ascii85(cups_ib_t *, int, int);
+#else
+static void out_bin(cups_ib_t *, int, int);
+#endif
+#endif
+static void outPdf(const char *str);
+static void putcPdf(char c);
+static int newObj(void);
+static void freeAllObj(void);
+static void outXref(void);
+static void outTrailer(void);
+static void outString(const char *s);
+static void outPrologue(int nPages);
+static void allocPageObjects(int noPages);
+static void setOffset(int obj);
+static void outPageObject(int pageObj, int contentsObj, int imgObj);
+static void outPageContents(int contentsObj);
+static void outImage(int imgObj);
+
+struct pdfObject {
+ int offset;
+};
+
+static struct pdfObject *objects = NULL;
+static int currentObjectNo = 0;
+static int allocatedObjectNum = 0;
+static int currentOffset = 0;
+static int xrefOffset;
+static int *pageObjects = NULL;
+static int catalogObj;
+static int pagesObj;
+static const char *title;
+static int xpages, /* # x pages */
+ ypages, /* # y pages */
+ xpage, /* Current x page */
+ ypage, /* Current y page */
+ page; /* Current page number */
+static int xc0, yc0, /* Corners of the page in image coords */
+ xc1, yc1;
+static float left, top; /* Left and top of image */
+static float xprint, /* Printable area */
+ yprint,
+ xinches, /* Total size in inches */
+ yinches;
+static float xsize, /* Total size in points */
+ ysize,
+ xsize2,
+ ysize2;
+static float aspect; /* Aspect ratio */
+static cups_image_t *img; /* Image to print */
+static int colorspace; /* Output colorspace */
+static cups_ib_t *row; /* Current row */
+static float gammaval = 1.0; /* Gamma correction value */
+static float brightness = 1.0; /* Gamma correction value */
+static ppd_file_t *ppd; /* PPD file */
+
+#define N_OBJECT_ALLOC 100
+#define LINEBUFSIZE 1024
+
+static char linebuf[LINEBUFSIZE];
+
+void emitJCLOptions(FILE *fp, int copies)
+{
+ int section;
+ ppd_choice_t **choices;
+ int i;
+ char buf[1024];
+ ppd_attr_t *attr;
+ int pdftoopvp = 0;
+ int datawritten = 0;
+
+ if (ppd == 0) return;
+ if ((attr = ppdFindAttr(ppd,"pdftopdfJCLBegin",NULL)) != NULL) {
+ int n = strlen(attr->value);
+ pdftoopvp = 1;
+ for (i = 0;i < n;i++) {
+ if (attr->value[i] == '\r' || attr->value[i] == '\n') {
+ /* skip new line */
+ continue;
+ }
+ fputc(attr->value[i],fp);
+ datawritten = 1;
+ }
+ }
+
+ snprintf(buf,sizeof(buf),"%d",copies);
+ if (ppdFindOption(ppd,"Copies") != NULL) {
+ ppdMarkOption(ppd,"Copies",buf);
+ } else {
+ if ((attr = ppdFindAttr(ppd,"pdftopdfJCLCopies",buf)) != NULL) {
+ fputs(attr->value,fp);
+ datawritten = 1;
+ } else if (pdftoopvp) {
+ fprintf(fp,"Copies=%d;",copies);
+ datawritten = 1;
+ }
+ }
+ for (section = (int)PPD_ORDER_ANY;
+ section <= (int)PPD_ORDER_PROLOG;section++) {
+ int n;
+
+ n = ppdCollect(ppd,(ppd_section_t)section,&choices);
+ for (i = 0;i < n;i++) {
+ snprintf(buf,sizeof(buf),"pdftopdfJCL%s",
+ ((ppd_option_t *)(choices[i]->option))->keyword);
+ if ((attr = ppdFindAttr(ppd,buf,choices[i]->choice)) != NULL) {
+ fputs(attr->value,fp);
+ datawritten = 1;
+ } else if (pdftoopvp) {
+ fprintf(fp,"%s=%s;",
+ ((ppd_option_t *)(choices[i]->option))->keyword,
+ choices[i]->choice);
+ datawritten = 1;
+ }
+ }
+ }
+ if (datawritten) fputc('\n',fp);
+}
+
+
+static void setOffset(int obj)
+{
+ objects[obj].offset = currentOffset;
+}
+
+static void allocPageObjects(int nPages)
+{
+ int i;
+
+ if ((pageObjects = malloc(sizeof(int)*nPages)) == NULL)
+ {
+ fprintf(stderr,"ERROR: Can't allocate pageObjects\n");
+ exit(2);
+ }
+ for (i = 0;i < nPages;i++)
+ {
+ pageObjects[i] = newObj();
+ }
+}
+
+static int newObj(void)
+{
+ if (objects == NULL)
+ {
+ if ((objects = malloc(sizeof(struct pdfObject)*N_OBJECT_ALLOC))
+ == NULL)
+ {
+ fprintf(stderr,"ERROR: Can't allocate objects\n");
+ exit(2);
+ }
+ allocatedObjectNum = N_OBJECT_ALLOC;
+ }
+ if (currentObjectNo >= allocatedObjectNum)
+ {
+ if ((objects = realloc(objects,
+ sizeof(struct pdfObject)*(allocatedObjectNum+N_OBJECT_ALLOC)))
+ == NULL)
+ {
+ fprintf(stderr,"ERROR: Can't allocate objects\n");
+ exit(2);
+ }
+ allocatedObjectNum += N_OBJECT_ALLOC;
+ }
+ objects[currentObjectNo].offset = currentOffset;
+ return currentObjectNo++;
+}
+
+static void freeAllObj(void)
+{
+ if (objects != NULL)
+ {
+ free(objects);
+ objects = NULL;
+ }
+}
+
+static void putcPdf(char c)
+{
+ fputc(c,stdout);
+ currentOffset++;
+}
+
+static void outPdf(const char *str)
+{
+ unsigned long len = strlen(str);
+
+ fputs(str,stdout);
+ currentOffset += len;
+}
+
+static void outXref(void)
+{
+ char buf[21];
+ int i;
+
+ xrefOffset = currentOffset;
+ outPdf("xref\n");
+ snprintf(buf,21,"0 %d\n",currentObjectNo);
+ outPdf(buf);
+ outPdf("0000000000 65535 f \n");
+ for (i = 1;i < currentObjectNo;i++)
+ {
+ snprintf(buf,21,"%010d 00000 n \n",objects[i].offset);
+ outPdf(buf);
+ }
+}
+
+static void outString(const char *s)
+{
+ char c;
+
+ putcPdf('(');
+ for (;(c = *s) != '\0';s++) {
+ if (c == '\\' || c == '(' || c == ')') {
+ putcPdf('\\');
+ }
+ putcPdf(c);
+ }
+ putcPdf(')');
+}
+
+static void outTrailer(void)
+{
+ time_t curtime;
+ struct tm *curtm;
+ char curdate[255];
+
+ curtime = time(NULL);
+ curtm = localtime(&curtime);
+ strftime(curdate, sizeof(curdate),"D:%Y%m%d%H%M%S%z", curtm);
+
+ outPdf("trailer\n");
+ snprintf(linebuf, LINEBUFSIZE,"<</Size %d ",currentObjectNo);
+ outPdf(linebuf);
+ outPdf("/Root 1 0 R\n");
+ outPdf("/Info << /Title ");
+ outString(title);
+ putcPdf(' ');
+ snprintf(linebuf,LINEBUFSIZE,"/CreationDate (%s) ",curdate);
+ outPdf(linebuf);
+ snprintf(linebuf,LINEBUFSIZE,"/ModDate (%s) ",curdate);
+ outPdf(linebuf);
+ outPdf("/Producer (imagetopdf) ");
+ outPdf("/Trapped /False >>\n");
+ outPdf(">>\n");
+ outPdf("startxref\n");
+ snprintf(linebuf,LINEBUFSIZE,"%d\n",xrefOffset);
+ outPdf(linebuf);
+ outPdf("%%EOF\n");
+}
+
+static void outPrologue(int nPages)
+{
+ int i;
+
+ /* out header */
+ newObj(); /* dummy for no 0 object */
+ outPdf("%PDF-1.3\n");
+ /* out binary for transfer program */
+ linebuf[0] = '%';
+ linebuf[1] = (char)129;
+ linebuf[2] = (char)130;
+ linebuf[3] = (char)131;
+ linebuf[4] = (char)132;
+ linebuf[5] = '\n';
+ linebuf[6] = (char)0;
+ outPdf(linebuf);
+ outPdf("% This file was generated by imagetopdf\n");
+
+ catalogObj = newObj();
+ pagesObj = newObj();
+ allocPageObjects(nPages);
+
+ /* out catalog */
+ snprintf(linebuf,LINEBUFSIZE,
+ "%d 0 obj <</Type/Catalog /Pages %d 0 R ",catalogObj,pagesObj);
+ outPdf(linebuf);
+ outPdf(">> endobj\n");
+
+ /* out Pages */
+ setOffset(pagesObj);
+ snprintf(linebuf,LINEBUFSIZE,
+ "%d 0 obj <</Type/Pages /Kids [ ",pagesObj);
+ outPdf(linebuf);
+ if (Reverse) {
+ for (i = nPages-1;i >= 0;i--)
+ {
+ snprintf(linebuf,LINEBUFSIZE,"%d 0 R ",pageObjects[i]);
+ outPdf(linebuf);
+ }
+ } else {
+ for (i = 0;i < nPages;i++)
+ {
+ snprintf(linebuf,LINEBUFSIZE,"%d 0 R ",pageObjects[i]);
+ outPdf(linebuf);
+ }
+ }
+ outPdf("] ");
+ snprintf(linebuf,LINEBUFSIZE,"/Count %d >> endobj\n",nPages);
+ outPdf(linebuf);
+}
+
+static void outPageObject(int pageObj, int contentsObj, int imgObj)
+{
+ int trfuncObj;
+ int lengthObj;
+ int startOffset;
+ int length;
+ int outTrfunc = (gammaval != 1.0 || brightness != 1.0);
+
+ /* out Page Object */
+ setOffset(pageObj);
+ snprintf(linebuf,LINEBUFSIZE,
+ "%d 0 obj <</Type/Page /Parent %d 0 R ",
+ pageObj,pagesObj);
+ outPdf(linebuf);
+ snprintf(linebuf,LINEBUFSIZE,
+ "/MediaBox [ 0 0 %f %f ] ",PageWidth,PageLength);
+ outPdf(linebuf);
+ snprintf(linebuf,LINEBUFSIZE,
+ "/TrimBox [ 0 0 %f %f ] ",PageWidth,PageLength);
+ outPdf(linebuf);
+ snprintf(linebuf,LINEBUFSIZE,
+ "/CropBox [ 0 0 %f %f ] ",PageWidth,PageLength);
+ outPdf(linebuf);
+ if (contentsObj >= 0) {
+ snprintf(linebuf,LINEBUFSIZE,
+ "/Contents %d 0 R ",contentsObj);
+ outPdf(linebuf);
+ snprintf(linebuf,LINEBUFSIZE,
+ "/Resources <</ProcSet [/PDF] "
+ "/XObject << /Im %d 0 R >>\n",imgObj);
+ outPdf(linebuf);
+ } else {
+ /* empty page */
+ snprintf(linebuf,LINEBUFSIZE,
+ "/Resources <</ProcSet [/PDF] \n");
+ outPdf(linebuf);
+ }
+ if (outTrfunc) {
+ trfuncObj = newObj();
+ lengthObj = newObj();
+ snprintf(linebuf,LINEBUFSIZE,
+ "/ExtGState << /GS1 << /TR %d 0 R >> >>\n",trfuncObj);
+ outPdf(linebuf);
+ }
+ outPdf(" >>\n>>\nendobj\n");
+
+ if (outTrfunc) {
+ /* out translate function */
+ setOffset(trfuncObj);
+ snprintf(linebuf,LINEBUFSIZE,
+ "%d 0 obj <</FunctionType 4 /Domain [0 1.0]"
+ " /Range [0 1.0] /Length %d 0 R >>\n",
+ trfuncObj,lengthObj);
+ outPdf(linebuf);
+ outPdf("stream\n");
+ startOffset = currentOffset;
+ snprintf(linebuf,LINEBUFSIZE,
+ "{ neg 1 add dup 0 lt { pop 1 } { %.3f exp neg 1 add } "
+ "ifelse %.3f mul }\n", gammaval, brightness);
+ outPdf(linebuf);
+ length = currentOffset - startOffset;
+ snprintf(linebuf,LINEBUFSIZE,
+ "endstream\nendobj\n");
+ outPdf(linebuf);
+
+ /* out length object */
+ setOffset(lengthObj);
+ snprintf(linebuf,LINEBUFSIZE,
+ "%d 0 obj %d endobj\n",lengthObj,length);
+ outPdf(linebuf);
+ }
+}
+
+static void outPageContents(int contentsObj)
+{
+ int startOffset;
+ int lengthObj;
+ int length;
+
+ setOffset(contentsObj);
+ lengthObj = newObj();
+ snprintf(linebuf,LINEBUFSIZE,
+ "%d 0 obj <</Length %d 0 R >> stream\n",contentsObj,lengthObj);
+ outPdf(linebuf);
+ startOffset = currentOffset;
+
+ if (gammaval != 1.0 || brightness != 1.0)
+ outPdf("/GS1 gs\n");
+ if (Flip)
+ {
+ snprintf(linebuf,LINEBUFSIZE,
+ "-1 0 0 1 %.0f 0 cm\n",PageWidth);
+ outPdf(linebuf);
+ }
+
+ switch (Orientation)
+ {
+ case 1:
+ snprintf(linebuf,LINEBUFSIZE,
+ "0 1 -1 0 %.0f 0 cm\n",PageWidth);
+ outPdf(linebuf);
+ break;
+ case 2:
+ snprintf(linebuf,LINEBUFSIZE,
+ "-1 0 0 -1 %.0f %.0f cm\n",PageWidth, PageLength);
+ outPdf(linebuf);
+ break;
+ case 3:
+ snprintf(linebuf,LINEBUFSIZE,
+ "0 -1 1 0 0 %.0f cm\n",PageLength);
+ outPdf(linebuf);
+ break;
+ }
+
+ xc0 = cupsImageGetWidth(img) * xpage / xpages;
+ xc1 = cupsImageGetWidth(img) * (xpage + 1) / xpages - 1;
+ yc0 = cupsImageGetHeight(img) * ypage / ypages;
+ yc1 = cupsImageGetHeight(img) * (ypage + 1) / ypages - 1;
+
+ snprintf(linebuf,LINEBUFSIZE,
+ "1 0 0 1 %.1f %.1f cm\n",left,top);
+ outPdf(linebuf);
+
+ snprintf(linebuf,LINEBUFSIZE,
+ "%.3f 0 0 %.3f 0 0 cm\n",
+ xprint * 72.0, yprint * 72.0);
+ outPdf(linebuf);
+ outPdf("/Im Do\n");
+ length = currentOffset - startOffset - 1;
+ outPdf("endstream\nendobj\n");
+
+ /* out length object */
+ setOffset(lengthObj);
+ snprintf(linebuf,LINEBUFSIZE,
+ "%d 0 obj %d endobj\n",lengthObj,length);
+ outPdf(linebuf);
+}
+
+static void outImage(int imgObj)
+{
+ int y; /* Current Y coordinate in image */
+#ifdef OUT_AS_ASCII85
+ int out_offset; /* Offset into output buffer */
+#endif
+ int out_length; /* Length of output buffer */
+ int startOffset;
+ int lengthObj;
+ int length;
+
+ setOffset(imgObj);
+ lengthObj = newObj();
+ snprintf(linebuf,LINEBUFSIZE,
+ "%d 0 obj << /Length %d 0 R /Type /XObject "
+ "/Subtype /Image /Name /Im"
+#ifdef OUT_AS_HEX
+ "/Filter /ASCIIHexDecode "
+#else
+#ifdef OUT_AS_ASCII85
+ "/Filter /ASCII85Decode "
+#endif
+#endif
+ ,imgObj,lengthObj);
+ outPdf(linebuf);
+ snprintf(linebuf,LINEBUFSIZE,
+ "/Width %d /Height %d /BitsPerComponent 8 ",
+ xc1 - xc0 + 1, yc1 - yc0 + 1);
+ outPdf(linebuf);
+
+ switch (colorspace)
+ {
+ case CUPS_IMAGE_WHITE :
+ outPdf("/ColorSpace /DeviceGray ");
+ outPdf("/Decode[0 1] ");
+ break;
+ case CUPS_IMAGE_RGB :
+ outPdf("/ColorSpace /DeviceRGB ");
+ outPdf("/Decode[0 1 0 1 0 1] ");
+ break;
+ case CUPS_IMAGE_CMYK :
+ outPdf("/ColorSpace /DeviceCMYK ");
+ outPdf("/Decode[0 1 0 1 0 1 0 1] ");
+ break;
+ }
+ if (((xc1 - xc0 + 1) / xprint) < 100.0)
+ outPdf("/Interpolate true ");
+
+ outPdf(">>\n");
+ outPdf("stream\n");
+ startOffset = currentOffset;
+
+#ifdef OUT_AS_ASCII85
+ /* out ascii85 needs multiple of 4bytes */
+ for (y = yc0, out_offset = 0; y <= yc1; y ++)
+ {
+ cupsImageGetRow(img, xc0, y, xc1 - xc0 + 1, row + out_offset);
+
+ out_length = (xc1 - xc0 + 1) * abs(colorspace) + out_offset;
+ out_offset = out_length & 3;
+
+ out_ascii85(row, out_length, y == yc1);
+
+ if (out_offset > 0)
+ memcpy(row, row + out_length - out_offset, out_offset);
+ }
+#else
+ for (y = yc0; y <= yc1; y ++)
+ {
+ cupsImageGetRow(img, xc0, y, xc1 - xc0 + 1, row);
+
+ out_length = (xc1 - xc0 + 1) * abs(colorspace);
+
+#ifdef OUT_AS_HEX
+ out_hex(row, out_length, y == yc1);
+#else
+ out_bin(row, out_length, y == yc1);
+#endif
+ }
+#endif
+ length = currentOffset - startOffset;
+ outPdf("\nendstream\nendobj\n");
+
+ /* out length object */
+ setOffset(lengthObj);
+ snprintf(linebuf,LINEBUFSIZE,
+ "%d 0 obj %d endobj\n",lengthObj,length);
+ outPdf(linebuf);
+}
+
+/*
+ * Copied ppd_decode() from CUPS which is not exported to the API
+ */
+
+static int /* O - Length of decoded string */
+ppd_decode(char *string) /* I - String to decode */
+{
+ char *inptr, /* Input pointer */
+ *outptr; /* Output pointer */
+
+
+ inptr = string;
+ outptr = string;
+
+ while (*inptr != '\0')
+ if (*inptr == '<' && isxdigit(inptr[1] & 255))
+ {
+ /*
+ * Convert hex to 8-bit values...
+ */
+
+ inptr ++;
+ while (isxdigit(*inptr & 255))
+ {
+ if (isalpha(*inptr))
+ *outptr = (tolower(*inptr) - 'a' + 10) << 4;
+ else
+ *outptr = (*inptr - '0') << 4;
+
+ inptr ++;
+
+ if (!isxdigit(*inptr & 255))
+ break;
+
+ if (isalpha(*inptr))
+ *outptr |= tolower(*inptr) - 'a' + 10;
+ else
+ *outptr |= *inptr - '0';
+
+ inptr ++;
+ outptr ++;
+ }
+
+ while (*inptr != '>' && *inptr != '\0')
+ inptr ++;
+ while (*inptr == '>')
+ inptr ++;
+ }
+ else
+ *outptr++ = *inptr++;
+
+ *outptr = '\0';
+
+ return ((int)(outptr - string));
+}
+
+/*
+ * 'main()' - Main entry...
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ cups_page_header2_t h; /* CUPS Raster page header, to */
+ /* accommodate results of command */
+ /* line parsing for PPD-less queue */
+ ppd_choice_t *choice; /* PPD option choice */
+ int num_options; /* Number of print options */
+ cups_option_t *options; /* Print options */
+ const char *val; /* Option value */
+ float zoom; /* Zoom facter */
+ int xppi, yppi; /* Pixels-per-inch */
+ int hue, sat; /* Hue and saturation adjustment */
+ int emit_jcl;
+ int pdf_printer = 0;
+ char filename[1024]; /* Name of file to print */
+ int deviceCopies = 1;
+ int deviceCollate = 0;
+ int deviceReverse = 0;
+ ppd_attr_t *attr;
+ int pl,pr;
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc < 6 || argc > 7)
+ {
+ fputs("ERROR: imagetopdf job-id user title copies options [file]\n", stderr);
+ return (1);
+ }
+
+ title = argv[3];
+ fprintf(stderr, "INFO: %s %s %s %s %s %s %s\n", argv[0], argv[1], argv[2],
+ argv[3], argv[4], argv[5], argv[6] ? argv[6] : "(null)");
+
+ /*
+ * Copy stdin as needed...
+ */
+
+ if (argc == 6)
+ {
+ int fd; /* File to write to */
+ char buffer[8192]; /* Buffer to read into */
+ int bytes; /* # of bytes to read */
+
+
+ if ((fd = cupsTempFd(filename, sizeof(filename))) < 0)
+ {
+ perror("ERROR: Unable to copy image file");
+ return (1);
+ }
+
+ fprintf(stderr, "DEBUG: imagetopdf - copying to temp print file \"%s\"\n",
+ filename);
+
+ while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
+ if (write(fd, buffer, bytes) == -1)
+ fprintf(stderr,
+ "DEBUG: imagetopdf - write error on temp print file \"%s\"\n",
+ filename);
+
+ close(fd);
+ }
+ else
+ {
+ strncpy(filename, argv[6], sizeof(filename));
+ }
+
+ /*
+ * Process command-line options and write the prolog...
+ */
+
+ zoom = 1.0;
+ xppi = 0;
+ yppi = 0;
+ hue = 0;
+ sat = 100;
+
+ Copies = atoi(argv[4]);
+
+ options = NULL;
+ num_options = cupsParseOptions(argv[5], 0, &options);
+
+ ppd = SetCommonOptions(num_options, options, 0);
+ if (!ppd) {
+ cupsRasterParseIPPOptions(&h, num_options, options, 0, 1);
+ Orientation = h.Orientation;
+ Duplex = h.Duplex;
+ ColorDevice = h.cupsNumColors <= 1 ? 0 : 1;
+ PageWidth = h.cupsPageSize[0] != 0.0 ? h.cupsPageSize[0] :
+ (float)h.PageSize[0];
+ PageLength = h.cupsPageSize[1] != 0.0 ? h.cupsPageSize[1] :
+ (float)h.PageSize[1];
+ PageLeft = h.cupsImagingBBox[0] != 0.0 ? h.cupsImagingBBox[0] :
+ (float)h.ImagingBoundingBox[0];
+ PageBottom = h.cupsImagingBBox[1] != 0.0 ? h.cupsImagingBBox[1] :
+ (float)h.ImagingBoundingBox[1];
+ PageRight = h.cupsImagingBBox[2] != 0.0 ? h.cupsImagingBBox[2] :
+ (float)h.ImagingBoundingBox[2];
+ PageTop = h.cupsImagingBBox[3] != 0.0 ? h.cupsImagingBBox[3] :
+ (float)h.ImagingBoundingBox[3];
+ Flip = h.MirrorPrint ? 1 : 0;
+ Collate = h.Collate ? 1 : 0;
+ Copies = h.NumCopies;
+ }
+
+ if (Copies == 1
+ && (choice = ppdFindMarkedChoice(ppd,"Copies")) != NULL) {
+ Copies = atoi(choice->choice);
+ }
+ if (Copies == 0) Copies = 1;
+ if ((val = cupsGetOption("Duplex",num_options,options)) != 0 &&
+ (!strcasecmp(val, "true") || !strcasecmp(val, "on") ||
+ !strcasecmp(val, "yes"))) {
+ /* for compatiblity */
+ if (ppdFindOption(ppd,"Duplex") != NULL) {
+ ppdMarkOption(ppd,"Duplex","True");
+ ppdMarkOption(ppd,"Duplex","On");
+ Duplex = 1;
+ }
+ } else if ((val = cupsGetOption("sides",num_options,options)) != 0 &&
+ (!strcasecmp(val, "two-sided-long-edge") ||
+ !strcasecmp(val, "two-sided-short-edge"))) {
+ /* for compatiblity */
+ if (ppdFindOption(ppd,"Duplex") != NULL) {
+ ppdMarkOption(ppd,"Duplex","True");
+ ppdMarkOption(ppd,"Duplex","On");
+ Duplex = 1;
+ }
+ }
+
+
+ if ((val = cupsGetOption("OutputOrder",num_options,options)) != 0) {
+ if (!strcasecmp(val, "Reverse")) {
+ Reverse = 1;
+ }
+ } else if (ppd) {
+ /*
+ * Figure out the right default output order from the PPD file...
+ */
+
+ if ((choice = ppdFindMarkedChoice(ppd,"OutputOrder")) != 0) {
+ Reverse = !strcasecmp(choice->choice,"Reverse");
+ } else if ((choice = ppdFindMarkedChoice(ppd,"OutputBin")) != 0 &&
+ (attr = ppdFindAttr(ppd,"PageStackOrder",choice->choice)) != 0 &&
+ attr->value) {
+ Reverse = !strcasecmp(attr->value,"Reverse");
+ } else if ((attr = ppdFindAttr(ppd,"DefaultOutputOrder",0)) != 0 &&
+ attr->value) {
+ Reverse = !strcasecmp(attr->value,"Reverse");
+ }
+ }
+
+ /* adjust to even page when duplex */
+ if (((val = cupsGetOption("cupsEvenDuplex",num_options,options)) != 0 &&
+ (!strcasecmp(val, "true") || !strcasecmp(val, "on") ||
+ !strcasecmp(val, "yes"))) ||
+ ((attr = ppdFindAttr(ppd,"cupsEvenDuplex",0)) != 0 &&
+ (!strcasecmp(attr->value, "true")
+ || !strcasecmp(attr->value, "on") ||
+ !strcasecmp(attr->value, "yes")))) {
+ EvenDuplex = 1;
+ }
+
+ if ((val = cupsGetOption("multiple-document-handling", num_options, options)) != NULL)
+ {
+ /*
+ * This IPP attribute is unnecessarily complicated...
+ *
+ * single-document, separate-documents-collated-copies, and
+ * single-document-new-sheet all require collated copies.
+ *
+ * separate-documents-uncollated-copies allows for uncollated copies.
+ */
+
+ Collate = strcasecmp(val, "separate-documents-uncollated-copies") != 0;
+ }
+
+ if ((val = cupsGetOption("Collate", num_options, options)) != NULL) {
+ if (strcasecmp(val, "True") == 0) {
+ Collate = 1;
+ }
+ } else {
+ if ((choice = ppdFindMarkedChoice(ppd,"Collate")) != NULL
+ && (!strcasecmp(choice->choice,"true")
+ || !strcasecmp(choice->choice, "on")
+ || !strcasecmp(choice->choice, "yes"))) {
+ Collate = 1;
+ }
+ }
+
+ if ((val = cupsGetOption("gamma", num_options, options)) != NULL)
+ gammaval = atoi(val) * 0.001f;
+
+ if ((val = cupsGetOption("brightness", num_options, options)) != NULL)
+ brightness = atoi(val) * 0.01f;
+
+ if ((val = cupsGetOption("scaling", num_options, options)) != NULL)
+ zoom = atoi(val) * 0.01;
+ else if (((val =
+ cupsGetOption("fit-to-page", num_options, options)) != NULL) ||
+ ((val = cupsGetOption("fitplot", num_options, options)) != NULL))
+ {
+ if (!strcasecmp(val, "yes") || !strcasecmp(val, "on") ||
+ !strcasecmp(val, "true"))
+ zoom = 1.0;
+ else
+ zoom = 0.0;
+ }
+ else if ((val = cupsGetOption("natural-scaling", num_options, options)) != NULL)
+ zoom = 0.0;
+
+ if ((val = cupsGetOption("ppi", num_options, options)) != NULL)
+ {
+ if (sscanf(val, "%dx%d", &xppi, &yppi) < 2)
+ yppi = xppi;
+ zoom = 0.0;
+ }
+
+ if ((val = cupsGetOption("position", num_options, options)) != NULL)
+ {
+ if (strcasecmp(val, "center") == 0)
+ {
+ XPosition = 0;
+ YPosition = 0;
+ }
+ else if (strcasecmp(val, "top") == 0)
+ {
+ XPosition = 0;
+ YPosition = 1;
+ }
+ else if (strcasecmp(val, "left") == 0)
+ {
+ XPosition = -1;
+ YPosition = 0;
+ }
+ else if (strcasecmp(val, "right") == 0)
+ {
+ XPosition = 1;
+ YPosition = 0;
+ }
+ else if (strcasecmp(val, "top-left") == 0)
+ {
+ XPosition = -1;
+ YPosition = 1;
+ }
+ else if (strcasecmp(val, "top-right") == 0)
+ {
+ XPosition = 1;
+ YPosition = 1;
+ }
+ else if (strcasecmp(val, "bottom") == 0)
+ {
+ XPosition = 0;
+ YPosition = -1;
+ }
+ else if (strcasecmp(val, "bottom-left") == 0)
+ {
+ XPosition = -1;
+ YPosition = -1;
+ }
+ else if (strcasecmp(val, "bottom-right") == 0)
+ {
+ XPosition = 1;
+ YPosition = -1;
+ }
+ }
+
+ if ((val = cupsGetOption("saturation", num_options, options)) != NULL)
+ sat = atoi(val);
+
+ if ((val = cupsGetOption("hue", num_options, options)) != NULL)
+ hue = atoi(val);
+
+ if ((val = cupsGetOption("mirror", num_options, options)) != NULL &&
+ strcasecmp(val, "True") == 0)
+ Flip = 1;
+
+ if ((val = cupsGetOption("emit-jcl", num_options, options)) != NULL &&
+ (!strcasecmp(val, "false") || !strcasecmp(val, "off") ||
+ !strcasecmp(val, "no") || !strcmp(val, "0")))
+ emit_jcl = 0;
+ else
+ emit_jcl = 1;
+
+
+
+ /*
+ * Open the input image to print...
+ */
+
+ colorspace = ColorDevice ? CUPS_IMAGE_RGB_CMYK : CUPS_IMAGE_WHITE;
+
+ img = cupsImageOpen(filename, colorspace, CUPS_IMAGE_WHITE, sat, hue, NULL);
+
+#if defined(USE_CONVERT_CMD) && defined(CONVERT_CMD)
+ if (img == NULL) {
+ char filename2[1024];
+ int fd2;
+
+ if ((fd2 = cupsTempFd(filename2, sizeof(filename2))) < 0)
+ {
+ perror("ERROR: Unable to copy image file");
+ return (1);
+ }
+ close(fd2);
+ snprintf(linebuf,LINEBUFSIZE,
+ CONVERT_CMD
+ " %s png:%s",filename, filename2);
+ if (system(linebuf) != 0) {
+ unlink(filename2);
+ perror("ERROR: Unable to copy image file");
+ return (1);
+ }
+ img = cupsImageOpen(filename2, colorspace,
+ CUPS_IMAGE_WHITE, sat, hue, NULL);
+ unlink(filename2);
+ }
+#endif
+ if (argc == 6)
+ unlink(filename);
+
+ if (img == NULL)
+ {
+ fputs("ERROR: Unable to open image file for printing!\n", stderr);
+ ppdClose(ppd);
+ return (1);
+ }
+
+ colorspace = cupsImageGetColorSpace(img);
+
+ /*
+ * Scale as necessary...
+ */
+
+ if (zoom == 0.0 && xppi == 0)
+ {
+ xppi = cupsImageGetXPPI(img);
+ yppi = cupsImageGetYPPI(img);
+ }
+
+ if (yppi == 0)
+ yppi = xppi;
+
+ fprintf(stderr, "DEBUG: Before scaling: xppi=%d, yppi=%d, zoom=%.2f\n",
+ xppi, yppi, zoom);
+
+ if (xppi > 0)
+ {
+ /*
+ * Scale the image as neccesary to match the desired pixels-per-inch.
+ */
+
+ if (Orientation & 1)
+ {
+ xprint = (PageTop - PageBottom) / 72.0;
+ yprint = (PageRight - PageLeft) / 72.0;
+ }
+ else
+ {
+ xprint = (PageRight - PageLeft) / 72.0;
+ yprint = (PageTop - PageBottom) / 72.0;
+ }
+
+ fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
+ xprint, yprint);
+
+ xinches = (float)cupsImageGetWidth(img) / (float)xppi;
+ yinches = (float)cupsImageGetHeight(img) / (float)yppi;
+
+ fprintf(stderr, "DEBUG: Image size is %.1f x %.1f inches...\n",
+ xinches, yinches);
+
+ if ((val = cupsGetOption("natural-scaling", num_options, options)) != NULL)
+ {
+ xinches = xinches * atoi(val) / 100;
+ yinches = yinches * atoi(val) / 100;
+ }
+
+ if (cupsGetOption("orientation-requested", num_options, options) == NULL &&
+ cupsGetOption("landscape", num_options, options) == NULL)
+ {
+ /*
+ * Rotate the image if it will fit landscape but not portrait...
+ */
+
+ fputs("DEBUG: Auto orientation...\n", stderr);
+
+ if ((xinches > xprint || yinches > yprint) &&
+ xinches <= yprint && yinches <= xprint)
+ {
+ /*
+ * Rotate the image as needed...
+ */
+
+ fputs("DEBUG: Using landscape orientation...\n", stderr);
+
+ Orientation = (Orientation + 1) & 3;
+ xsize = yprint;
+ yprint = xprint;
+ xprint = xsize;
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Scale percentage of page size...
+ */
+
+ xprint = (PageRight - PageLeft) / 72.0;
+ yprint = (PageTop - PageBottom) / 72.0;
+ aspect = (float)cupsImageGetYPPI(img) / (float)cupsImageGetXPPI(img);
+
+ fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
+ xprint, yprint);
+
+ fprintf(stderr, "DEBUG: cupsImageGetXPPI(img) = %d, cupsImageGetYPPI(img) = %d, aspect = %f\n",
+ cupsImageGetXPPI(img), cupsImageGetYPPI(img), aspect);
+
+ xsize = xprint * zoom;
+ ysize = xsize * cupsImageGetHeight(img) / cupsImageGetWidth(img) / aspect;
+
+ if (ysize > (yprint * zoom))
+ {
+ ysize = yprint * zoom;
+ xsize = ysize * cupsImageGetWidth(img) * aspect / cupsImageGetHeight(img);
+ }
+
+ xsize2 = yprint * zoom;
+ ysize2 = xsize2 * cupsImageGetHeight(img) / cupsImageGetWidth(img) / aspect;
+
+ if (ysize2 > (xprint * zoom))
+ {
+ ysize2 = xprint * zoom;
+ xsize2 = ysize2 * cupsImageGetWidth(img) * aspect / cupsImageGetHeight(img);
+ }
+
+ fprintf(stderr, "DEBUG: Portrait size is %.2f x %.2f inches\n", xsize, ysize);
+ fprintf(stderr, "DEBUG: Landscape size is %.2f x %.2f inches\n", xsize2, ysize2);
+
+ if (cupsGetOption("orientation-requested", num_options, options) == NULL &&
+ cupsGetOption("landscape", num_options, options) == NULL)
+ {
+ /*
+ * Choose the rotation with the largest area, but prefer
+ * portrait if they are equal...
+ */
+
+ fputs("DEBUG: Auto orientation...\n", stderr);
+
+ if ((xsize * ysize) < (xsize2 * xsize2))
+ {
+ /*
+ * Do landscape orientation...
+ */
+
+ fputs("DEBUG: Using landscape orientation...\n", stderr);
+
+ Orientation = 1;
+ xinches = xsize2;
+ yinches = ysize2;
+ xprint = (PageTop - PageBottom) / 72.0;
+ yprint = (PageRight - PageLeft) / 72.0;
+ }
+ else
+ {
+ /*
+ * Do portrait orientation...
+ */
+
+ fputs("DEBUG: Using portrait orientation...\n", stderr);
+
+ Orientation = 0;
+ xinches = xsize;
+ yinches = ysize;
+ }
+ }
+ else if (Orientation & 1)
+ {
+ fputs("DEBUG: Using landscape orientation...\n", stderr);
+
+ xinches = xsize2;
+ yinches = ysize2;
+ xprint = (PageTop - PageBottom) / 72.0;
+ yprint = (PageRight - PageLeft) / 72.0;
+ }
+ else
+ {
+ fputs("DEBUG: Using portrait orientation...\n", stderr);
+
+ xinches = xsize;
+ yinches = ysize;
+ xprint = (PageRight - PageLeft) / 72.0;
+ yprint = (PageTop - PageBottom) / 72.0;
+ }
+ }
+
+ /*
+ * Compute the number of pages to print and the size of the image on each
+ * page...
+ */
+
+ if (zoom == 1.0) {
+ /* If fitplot is specified, make xpages, ypages 1 forcedly.
+ Because calculation error may be caused and
+ result of ceil function may be larger than 1.
+ */
+ xpages = ypages = 1;
+ } else {
+ xpages = ceil(xinches / xprint);
+ ypages = ceil(yinches / yprint);
+ }
+
+ xprint = xinches / xpages;
+ yprint = yinches / ypages;
+
+ fprintf(stderr, "DEBUG: xpages = %dx%.2fin, ypages = %dx%.2fin\n",
+ xpages, xprint, ypages, yprint);
+
+ /*
+ * Update the page size for custom sizes...
+ */
+
+ if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) != NULL &&
+ strcasecmp(choice->choice, "Custom") == 0)
+ {
+ float width, /* New width in points */
+ length; /* New length in points */
+ char s[255]; /* New custom page size... */
+
+
+ /*
+ * Use the correct width and length for the current orientation...
+ */
+
+ if (Orientation & 1)
+ {
+ width = yprint * 72.0;
+ length = xprint * 72.0;
+ }
+ else
+ {
+ width = xprint * 72.0;
+ length = yprint * 72.0;
+ }
+
+ /*
+ * Add margins to page size...
+ */
+
+ width += ppd->custom_margins[0] + ppd->custom_margins[2];
+ length += ppd->custom_margins[1] + ppd->custom_margins[3];
+
+ /*
+ * Enforce minimums...
+ */
+
+ if (width < ppd->custom_min[0])
+ width = ppd->custom_min[0];
+
+ if (length < ppd->custom_min[1])
+ length = ppd->custom_min[1];
+
+ fprintf(stderr, "DEBUG: Updated custom page size to %.2f x %.2f inches...\n",
+ width / 72.0, length / 72.0);
+
+ /*
+ * Set the new custom size...
+ */
+
+ sprintf(s, "Custom.%.0fx%.0f", width, length);
+ ppdMarkOption(ppd, "PageSize", s);
+
+ /*
+ * Update page variables...
+ */
+
+ PageWidth = width;
+ PageLength = length;
+ PageLeft = ppd->custom_margins[0];
+ PageRight = width - ppd->custom_margins[2];
+ PageBottom = ppd->custom_margins[1];
+ PageTop = length - ppd->custom_margins[3];
+ }
+
+ if (Copies == 1) {
+ /* collate is not needed */
+ Collate = 0;
+ ppdMarkOption(ppd,"Collate","False");
+ }
+ if (!Duplex) {
+ /* evenDuplex is not needed */
+ EvenDuplex = 0;
+ }
+
+ /* check collate device */
+ if (Collate) {
+ if ((choice = ppdFindMarkedChoice(ppd,"Collate")) != NULL &&
+ !strcasecmp(choice->choice,"true")) {
+ ppd_option_t *opt;
+
+ if ((opt = ppdFindOption(ppd,"Collate")) != NULL &&
+ !opt->conflicted) {
+ deviceCollate = 1;
+ } else {
+ ppdMarkOption(ppd,"Collate","False");
+ }
+ }
+ }
+ /* check OutputOrder device */
+ if (Reverse) {
+ if (ppdFindOption(ppd,"OutputOrder") != NULL) {
+ deviceReverse = 1;
+ }
+ }
+ if (ppd != NULL &&
+ !ppd->manual_copies && Collate && !deviceCollate) {
+ /* Copying by device , software collate is impossible */
+ /* Enable software copying */
+ ppd->manual_copies = 1;
+ }
+ if (Copies > 1 && (ppd == NULL || ppd->manual_copies)
+ && Duplex) {
+ /* Enable software collate , or same pages are printed in both sides */
+ Collate = 1;
+ if (deviceCollate) {
+ deviceCollate = 0;
+ ppdMarkOption(ppd,"Collate","False");
+ }
+ }
+ if (Duplex && Collate && !deviceCollate) {
+ /* Enable evenDuplex or the first page may be printed other side of the
+ end of precedings */
+ EvenDuplex = 1;
+ }
+ if (Duplex && Reverse && !deviceReverse) {
+ /* Enable evenDuplex or the first page may be empty. */
+ EvenDuplex = 1;
+ }
+ /* change feature for software */
+ if (deviceCollate) {
+ Collate = 0;
+ }
+ if (deviceReverse) {
+ Reverse = 0;
+ }
+ if (ppd != NULL) {
+ if (ppd->manual_copies) {
+ /* sure disable hardware copying */
+ ppdMarkOption(ppd,"Copies","1");
+ ppdMarkOption(ppd,"JCLCopies","1");
+ } else {
+ /* change for hardware copying */
+ deviceCopies = Copies;
+ Copies = 1;
+ }
+ }
+
+ /*
+ * See if we need to collate, and if so how we need to do it...
+ */
+
+ if (xpages == 1 && ypages == 1
+ && (Collate || deviceCollate) && !EvenDuplex) {
+ /* collate is not needed, disable it */
+ deviceCollate = 0;
+ Collate = 0;
+ ppdMarkOption(ppd,"Collate","False");
+ }
+
+ if (((xpages*ypages) % 2) == 0) {
+ /* even pages, disable EvenDuplex */
+ EvenDuplex = 0;
+ }
+
+ /*
+ * Write any "exit server" options that have been selected...
+ */
+
+ ppdEmit(ppd, stdout, PPD_ORDER_EXIT);
+
+ /*
+ * Write any JCL commands that are needed to print PostScript code...
+ */
+
+ if (ppd && emit_jcl) {
+ /* pdftopdf only adds JCL to the job if the printer is a native PDF
+ printer and the PPD is for this mode, having the "*JCLToPDFInterpreter:"
+ keyword. We need to read this keyword manually from the PPD and replace
+ the content of ppd->jcl_ps by the value of this keyword, so that
+ ppdEmitJCL() actalually adds JCL based on the presence on
+ "*JCLToPDFInterpreter:". */
+ ppd_attr_t *attr;
+ char buf[1024];
+ int devicecopies_done = 0;
+ char *old_jcl_ps = ppd->jcl_ps;
+ /* If there is a "Copies" option in the PPD file, assure that hardware
+ copies are implemented as described by this option */
+ if (ppdFindOption(ppd,"Copies") != NULL && deviceCopies > 1)
+ {
+ snprintf(buf,sizeof(buf),"%d",deviceCopies);
+ ppdMarkOption(ppd,"Copies",buf);
+ devicecopies_done = 1;
+ }
+ if ((attr = ppdFindAttr(ppd,"JCLToPDFInterpreter",NULL)) != NULL)
+ {
+ if (deviceCopies > 1 && devicecopies_done == 0 && /* HW copies */
+ strncmp(ppd->jcl_begin, "\033%-12345X@", 10) == 0) /* PJL */
+ {
+ /* Add a PJL command to implement the hardware copies */
+ const size_t size = strlen(attr->value) + 1 + 30;
+ ppd->jcl_ps = (char *)malloc(size * sizeof(char));
+ if (deviceCollate)
+ {
+ snprintf(ppd->jcl_ps, size, "@PJL SET QTY=%d\n%s",
+ deviceCopies, attr->value);
+ }
+ else
+ {
+ snprintf(ppd->jcl_ps, size, "@PJL SET COPIES=%d\n%s",
+ deviceCopies, attr->value);
+ }
+ }
+ else
+ ppd->jcl_ps = strdup(attr->value);
+ ppd_decode(ppd->jcl_ps);
+ pdf_printer = 1;
+ }
+ else
+ {
+ ppd->jcl_ps = NULL;
+ pdf_printer = 0;
+ }
+ ppdEmitJCL(ppd, stdout, atoi(argv[1]), argv[2], argv[3]);
+ emitJCLOptions(stdout,deviceCopies);
+ free(ppd->jcl_ps);
+ ppd->jcl_ps = old_jcl_ps; /* cups uses pool allocator, not free() */
+ }
+
+ /*
+ * Start sending the document with any commands needed...
+ */
+
+ outPrologue(Copies*xpages*ypages+(EvenDuplex ? 1 : 0));
+
+ /*
+ * Output the pages...
+ */
+
+ row = malloc(cupsImageGetWidth(img) * abs(colorspace) + 3);
+
+ fprintf(stderr, "DEBUG: XPosition=%d, YPosition=%d, Orientation=%d\n",
+ XPosition, YPosition, Orientation);
+ fprintf(stderr, "DEBUG: xprint=%.0f, yprint=%.0f\n", xprint, yprint);
+ fprintf(stderr, "DEBUG: PageLeft=%.0f, PageRight=%.0f, PageWidth=%.0f\n",
+ PageLeft, PageRight, PageWidth);
+ fprintf(stderr, "DEBUG: PageBottom=%.0f, PageTop=%.0f, PageLength=%.0f\n",
+ PageBottom, PageTop, PageLength);
+
+ if (Flip) {
+ pr = PageWidth - PageLeft;
+ pl = PageWidth - PageRight;
+ } else {
+ pr = PageRight;
+ pl = PageLeft;
+ }
+
+ switch (Orientation)
+ {
+ default :
+ switch (XPosition)
+ {
+ case -1 :
+ left = pl;
+ break;
+ default :
+ left = (pr + pl - xprint * 72) / 2;
+ break;
+ case 1 :
+ left = pr - xprint * 72;
+ break;
+ }
+
+ switch (YPosition)
+ {
+ case -1 :
+ top = PageBottom;
+ break;
+ default :
+ top = (PageTop + PageBottom - yprint * 72) / 2;
+ break;
+ case 1 :
+ top = PageTop - yprint * 72;;
+ break;
+ }
+ break;
+
+ case 1 :
+ switch (XPosition)
+ {
+ case -1 :
+ left = PageBottom;
+ break;
+ default :
+ left = (PageTop + PageBottom - xprint * 72) / 2;
+ break;
+ case 1 :
+ left = PageTop - xprint * 72;
+ break;
+ }
+
+ switch (YPosition)
+ {
+ case -1 :
+ top = pl;
+ break;
+ default :
+ top = (pr + pl - yprint * 72) / 2;
+ break;
+ case 1 :
+ top = pr - yprint * 72;;
+ break;
+ }
+ break;
+
+ case 2 :
+ switch (XPosition)
+ {
+ case -1 :
+ left = pr - xprint * 72;
+ break;
+ default :
+ left = (pr + pl - xprint * 72) / 2;
+ break;
+ case 1 :
+ left = pl;
+ break;
+ }
+
+ switch (YPosition)
+ {
+ case -1 :
+ top = PageTop - yprint * 72;
+ break;
+ default :
+ top = (PageTop + PageBottom - yprint * 72) / 2;
+ break;
+ case 1 :
+ top = PageBottom;
+ break;
+ }
+ break;
+
+ case 3 :
+ switch (XPosition)
+ {
+ case -1 :
+ left = PageTop - xprint * 72;
+ break;
+ default :
+ left = (PageTop + PageBottom - xprint * 72) / 2;
+ break;
+ case 1 :
+ left = PageBottom;
+ break;
+ }
+
+ switch (YPosition)
+ {
+ case -1 :
+ top = pr - yprint * 72;;
+ break;
+ default :
+ top = (pr + pl - yprint * 72) / 2;
+ break;
+ case 1 :
+ top = pl;
+ break;
+ }
+ break;
+ }
+
+ fprintf(stderr, "DEBUG: left=%.2f, top=%.2f\n", left, top);
+
+ if (Collate)
+ {
+ int *contentsObjs;
+ int *imgObjs;
+
+ if ((contentsObjs = malloc(sizeof(int)*xpages*ypages)) == NULL)
+ {
+ fprintf(stderr,"ERROR: Can't allocate contentsObjs\n");
+ exit(2);
+ }
+ if ((imgObjs = malloc(sizeof(int)*xpages*ypages)) == NULL)
+ {
+ fprintf(stderr,"ERROR: Can't allocate imgObjs\n");
+ exit(2);
+ }
+ for (xpage = 0; xpage < xpages; xpage ++)
+ for (ypage = 0; ypage < ypages; ypage ++)
+ {
+ int imgObj;
+ int contentsObj;
+
+ contentsObj = contentsObjs[ypages*xpage+ypage] = newObj();
+ imgObj = imgObjs[ypages*xpage+ypage] = newObj();
+
+ /* out contents object */
+ outPageContents(contentsObj);
+
+ /* out image object */
+ outImage(imgObj);
+ }
+ for (page = 0; Copies > 0 ; Copies --) {
+ for (xpage = 0; xpage < xpages; xpage ++)
+ for (ypage = 0; ypage < ypages; ypage ++, page ++)
+ {
+ /* out Page Object */
+ outPageObject(pageObjects[page],
+ contentsObjs[ypages*xpage+ypage],
+ imgObjs[ypages*xpage+ypage]);
+ if (pdf_printer)
+ fprintf(stderr, "PAGE: %d %d\n", page+1, 1);
+ }
+ if (EvenDuplex) {
+ /* out empty page */
+ outPageObject(pageObjects[page],-1,-1);
+ if (pdf_printer)
+ fprintf(stderr, "PAGE: %d %d\n", page+1, 1);
+ }
+ }
+ free(contentsObjs);
+ free(imgObjs);
+ }
+ else {
+ for (page = 0, xpage = 0; xpage < xpages; xpage ++)
+ for (ypage = 0; ypage < ypages; ypage ++)
+ {
+ int imgObj;
+ int contentsObj;
+ int p;
+
+ imgObj = newObj();
+ contentsObj = newObj();
+
+ /* out contents object */
+ outPageContents(contentsObj);
+
+ /* out image object */
+ outImage(imgObj);
+
+ for (p = 0;p < Copies;p++, page++)
+ {
+ /* out Page Object */
+ outPageObject(pageObjects[page],contentsObj,imgObj);
+ if (pdf_printer)
+ fprintf(stderr, "PAGE: %d %d\n", page+1, 1);
+ }
+ }
+ if (EvenDuplex) {
+ /* out empty pages */
+ int p;
+
+ for (p = 0;p < Copies;p++, page++)
+ {
+ outPageObject(pageObjects[page],-1,-1);
+ if (pdf_printer)
+ fprintf(stderr, "PAGE: %d %d\n", page+1, 1);
+ }
+ }
+ }
+
+ outXref();
+ outTrailer();
+ freeAllObj();
+ /*
+ * Close files...
+ */
+
+#ifndef CUPS_1_1
+ if (emit_jcl)
+ {
+ if (ppd && ppd->jcl_end)
+ ppdEmitJCLEnd(ppd, stdout);
+ }
+#endif
+
+ cupsImageClose(img);
+ ppdClose(ppd);
+
+ return (0);
+}
+
+#ifdef OUT_AS_HEX
+/*
+ * 'out_hex()' - Print binary data as a series of hexadecimal numbers.
+ */
+
+static void
+out_hex(cups_ib_t *data, /* I - Data to print */
+ int length, /* I - Number of bytes to print */
+ int last_line) /* I - Last line of raster data? */
+{
+ static int col = 0; /* Current column */
+ static char *hex = "0123456789ABCDEF";
+ /* Hex digits */
+
+
+ while (length > 0)
+ {
+ /*
+ * Put the hex chars out to the file; note that we don't use printf()
+ * for speed reasons...
+ */
+
+ putcPdf(hex[*data >> 4]);
+ putcPdf(hex[*data & 15]);
+
+ data ++;
+ length --;
+
+ col += 2;
+ if (col > 78)
+ {
+ putcPdf('\n');
+ col = 0;
+ }
+ }
+
+ if (last_line && col)
+ {
+ putcPdf('\n');
+ col = 0;
+ }
+}
+#else
+
+#ifdef OUT_AS_ASCII85
+/*
+ * 'out_ascii85()' - Print binary data as a series of base-85 numbers.
+ */
+
+static void
+out_ascii85(cups_ib_t *data, /* I - Data to print */
+ int length, /* I - Number of bytes to print */
+ int last_line) /* I - Last line of raster data? */
+{
+ unsigned b; /* Binary data word */
+ unsigned char c[6]; /* ASCII85 encoded chars */
+ static int col = 0; /* Current column */
+
+
+ c[5] = '\0'; /* end mark */
+ while (length > 3)
+ {
+ b = (((((data[0] << 8) | data[1]) << 8) | data[2]) << 8) | data[3];
+
+ if (b == 0)
+ {
+ putcPdf('z');
+ col ++;
+ }
+ else
+ {
+ c[4] = (b % 85) + '!';
+ b /= 85;
+ c[3] = (b % 85) + '!';
+ b /= 85;
+ c[2] = (b % 85) + '!';
+ b /= 85;
+ c[1] = (b % 85) + '!';
+ b /= 85;
+ c[0] = b + '!';
+
+ outPdf(c);
+ col += 5;
+ }
+
+ data += 4;
+ length -= 4;
+
+ if (col >= 75)
+ {
+ putcPdf('\n');
+ col = 0;
+ }
+ }
+
+ if (last_line)
+ {
+ if (length > 0)
+ {
+ memset(data + length, 0, 4 - length);
+ b = (((((data[0] << 8) | data[1]) << 8) | data[2]) << 8) | data[3];
+
+ c[4] = (b % 85) + '!';
+ b /= 85;
+ c[3] = (b % 85) + '!';
+ b /= 85;
+ c[2] = (b % 85) + '!';
+ b /= 85;
+ c[1] = (b % 85) + '!';
+ b /= 85;
+ c[0] = b + '!';
+
+ c[length+1] = '\0';
+ outPdf(c);
+ }
+
+ outPdf("~>");
+ col = 0;
+ }
+}
+#else
+/*
+ * 'out_bin()' - Print binary data as binary.
+ */
+
+static void
+out_bin(cups_ib_t *data, /* I - Data to print */
+ int length, /* I - Number of bytes to print */
+ int last_line) /* I - Last line of raster data? */
+{
+ while (length > 0)
+ {
+ putcPdf(*data);
+ data ++;
+ length --;
+ }
+
+ if (last_line)
+ {
+ putcPdf('\n');
+ }
+}
+#endif
+#endif
diff --git a/filter/imagetops b/filter/imagetops
new file mode 100644
index 000000000..c67ca526a
--- /dev/null
+++ b/filter/imagetops
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+# imagetops - This is a Image-to-PostScript filter for CUPS
+#
+# Note: This wrapper filter is only included for backward compatibility with
+# certan custom configurations. It is not mentioned in any of the .convs
+# files included in this package and therefore never used with the default
+# configuration. It makes sure that third-party PPD files referring to
+# imagetops explicitly or custom configurations (in /etc/cups/*.convs files)
+# will not break.
+#
+# DO NOT create new PPD or .convs files using this filter! imagetops is
+# DEPRECATED!
+
+# (C) 2012 Till Kamppeter <till.kamppeter@gmail.com>
+#
+# Released under GPL 2 or later
+#
+
+PDF2PS=`which pdf2ps`
+
+echo "DEBUG: imagetops argv[$#] = $@" >&2
+echo "DEBUG: PPD: $PPD" >&2
+
+if [ $# -lt 5 -o $# -gt 6 ]; then
+ echo "ERROR: $0 job-id user title copies options [file]" >&2
+ exit 1
+fi
+
+# Read from given file.
+if [ -n "$6" ]; then
+ exec <"$6"
+fi
+
+$CUPS_SERVERBIN/filter/imagetopdf "$1" "$2" "$3" "$4" "$5" | $PDF2PS - -
diff --git a/filter/imagetoraster.c b/filter/imagetoraster.c
new file mode 100644
index 000000000..67876f389
--- /dev/null
+++ b/filter/imagetoraster.c
@@ -0,0 +1,4393 @@
+/*
+ * Image file to raster filter for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2007 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * main() - Main entry...
+ * blank_line() - Clear a line buffer to the blank value...
+ * format_CMY() - Convert image data to CMY.
+ * format_CMYK() - Convert image data to CMYK.
+ * format_K() - Convert image data to black.
+ * format_KCMY() - Convert image data to KCMY.
+ * format_KCMYcm() - Convert image data to KCMYcm.
+ * format_RGBA() - Convert image data to RGBA/RGBW.
+ * format_W() - Convert image data to luminance.
+ * format_YMC() - Convert image data to YMC.
+ * format_YMCK() - Convert image data to YMCK.
+ * make_lut() - Make a lookup table given gamma and brightness values.
+ * raster_cb() - Validate the page header.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "common.h"
+#include <cupsfilters/raster.h>
+#include <cupsfilters/colormanager.h>
+#include <cupsfilters/image-private.h>
+#include <unistd.h>
+#include <math.h>
+#include <signal.h>
+#include <string.h>
+
+
+/*
+ * Globals...
+ */
+
+int Flip = 0, /* Flip/mirror pages */
+ XPosition = 0, /* Horizontal position on page */
+ YPosition = 0, /* Vertical position on page */
+ Collate = 0, /* Collate copies? */
+ Copies = 1; /* Number of copies */
+int Floyd16x16[16][16] = /* Traditional Floyd ordered dither */
+ {
+ { 0, 128, 32, 160, 8, 136, 40, 168,
+ 2, 130, 34, 162, 10, 138, 42, 170 },
+ { 192, 64, 224, 96, 200, 72, 232, 104,
+ 194, 66, 226, 98, 202, 74, 234, 106 },
+ { 48, 176, 16, 144, 56, 184, 24, 152,
+ 50, 178, 18, 146, 58, 186, 26, 154 },
+ { 240, 112, 208, 80, 248, 120, 216, 88,
+ 242, 114, 210, 82, 250, 122, 218, 90 },
+ { 12, 140, 44, 172, 4, 132, 36, 164,
+ 14, 142, 46, 174, 6, 134, 38, 166 },
+ { 204, 76, 236, 108, 196, 68, 228, 100,
+ 206, 78, 238, 110, 198, 70, 230, 102 },
+ { 60, 188, 28, 156, 52, 180, 20, 148,
+ 62, 190, 30, 158, 54, 182, 22, 150 },
+ { 252, 124, 220, 92, 244, 116, 212, 84,
+ 254, 126, 222, 94, 246, 118, 214, 86 },
+ { 3, 131, 35, 163, 11, 139, 43, 171,
+ 1, 129, 33, 161, 9, 137, 41, 169 },
+ { 195, 67, 227, 99, 203, 75, 235, 107,
+ 193, 65, 225, 97, 201, 73, 233, 105 },
+ { 51, 179, 19, 147, 59, 187, 27, 155,
+ 49, 177, 17, 145, 57, 185, 25, 153 },
+ { 243, 115, 211, 83, 251, 123, 219, 91,
+ 241, 113, 209, 81, 249, 121, 217, 89 },
+ { 15, 143, 47, 175, 7, 135, 39, 167,
+ 13, 141, 45, 173, 5, 133, 37, 165 },
+ { 207, 79, 239, 111, 199, 71, 231, 103,
+ 205, 77, 237, 109, 197, 69, 229, 101 },
+ { 63, 191, 31, 159, 55, 183, 23, 151,
+ 61, 189, 29, 157, 53, 181, 21, 149 },
+ { 254, 127, 223, 95, 247, 119, 215, 87,
+ 253, 125, 221, 93, 245, 117, 213, 85 }
+ };
+int Floyd8x8[8][8] =
+ {
+ { 0, 32, 8, 40, 2, 34, 10, 42 },
+ { 48, 16, 56, 24, 50, 18, 58, 26 },
+ { 12, 44, 4, 36, 14, 46, 6, 38 },
+ { 60, 28, 52, 20, 62, 30, 54, 22 },
+ { 3, 35, 11, 43, 1, 33, 9, 41 },
+ { 51, 19, 59, 27, 49, 17, 57, 25 },
+ { 15, 47, 7, 39, 13, 45, 5, 37 },
+ { 63, 31, 55, 23, 61, 29, 53, 21 }
+ };
+int Floyd4x4[4][4] =
+ {
+ { 0, 8, 2, 10 },
+ { 12, 4, 14, 6 },
+ { 3, 11, 1, 9 },
+ { 15, 7, 13, 5 }
+ };
+
+cups_ib_t OnPixels[256], /* On-pixel LUT */
+ OffPixels[256]; /* Off-pixel LUT */
+
+
+/*
+ * Local functions...
+ */
+
+static void blank_line(cups_page_header2_t *header, unsigned char *row);
+static void format_CMY(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
+static void format_CMYK(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
+static void format_K(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
+static void format_KCMYcm(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
+static void format_KCMY(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
+#define format_RGB format_CMY
+static void format_RGBA(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
+static void format_W(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
+static void format_YMC(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
+static void format_YMCK(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
+static void make_lut(cups_ib_t *, int, float, float);
+static int raster_cb(cups_page_header2_t *header, int preferred_bits);
+
+
+/*
+ * 'main()' - Main entry...
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i; /* Looping var */
+ cups_image_t *img; /* Image to print */
+ float xprint, /* Printable area */
+ yprint,
+ xinches, /* Total size in inches */
+ yinches;
+ float xsize, /* Total size in points */
+ ysize,
+ xsize2,
+ ysize2;
+ float aspect; /* Aspect ratio */
+ int xpages, /* # x pages */
+ ypages, /* # y pages */
+ xpage, /* Current x page */
+ ypage, /* Current y page */
+ xtemp, /* Bitmap width in pixels */
+ ytemp, /* Bitmap height in pixels */
+ page; /* Current page number */
+ int xc0, yc0, /* Corners of the page in image coords */
+ xc1, yc1;
+ ppd_file_t *ppd; /* PPD file */
+ ppd_choice_t *choice; /* PPD option choice */
+ char *resolution, /* Output resolution */
+ *media_type; /* Media type */
+ ppd_profile_t *profile; /* Color profile */
+ ppd_profile_t userprofile; /* User-specified profile */
+ cups_raster_t *ras; /* Raster stream */
+ cups_page_header2_t header; /* Page header */
+ int num_options; /* Number of print options */
+ cups_option_t *options; /* Print options */
+ const char *val; /* Option value */
+ int slowcollate, /* Collate copies the slow way */
+ slowcopies; /* Make copies the "slow" way? */
+ float g; /* Gamma correction value */
+ float b; /* Brightness factor */
+ float zoom; /* Zoom facter */
+ int xppi, yppi; /* Pixels-per-inch */
+ int hue, sat; /* Hue and saturation adjustment */
+ cups_izoom_t *z; /* Image zoom buffer */
+ cups_iztype_t zoom_type; /* Image zoom type */
+ int primary, /* Primary image colorspace */
+ secondary; /* Secondary image colorspace */
+ cups_ib_t *row, /* Current row */
+ *r0, /* Top row */
+ *r1; /* Bottom row */
+ int y, /* Current Y coordinate on page */
+ iy, /* Current Y coordinate in image */
+ last_iy, /* Previous Y coordinate in image */
+ yerr0, /* Top Y error value */
+ yerr1; /* Bottom Y error value */
+ cups_ib_t lut[256]; /* Gamma/brightness LUT */
+ int plane, /* Current color plane */
+ num_planes; /* Number of color planes */
+ char filename[1024]; /* Name of file to print */
+ cm_calibration_t cm_calibrate; /* Are we color calibrating the device? */
+ int cm_disabled; /* Color management disabled? */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Ignore broken pipe signals...
+ */
+
+ signal(SIGPIPE, SIG_IGN);
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc < 6 || argc > 7)
+ {
+ fprintf(stderr, "Usage: %s job-id user title copies options [file]\n",
+ argv[0]);
+ return (1);
+ }
+
+ /*
+ * See if we need to use the imagetops and pstoraster filters instead...
+ */
+
+ options = NULL;
+ num_options = cupsParseOptions(argv[5], 0, &options);
+
+ if (getenv("CLASSIFICATION") ||
+ cupsGetOption("page-label", num_options, options))
+ {
+ /*
+ * Yes, fork a copy of pstoraster and then transfer control to imagetops...
+ */
+
+ int mypipes[2]; /* New pipes for imagetops | pstoraster */
+ int pid; /* PID of pstoraster */
+
+
+ cupsFreeOptions(num_options, options);
+
+ if (pipe(mypipes))
+ {
+ perror("ERROR: Unable to create pipes for filters");
+ return (errno);
+ }
+
+ if ((pid = fork()) == 0)
+ {
+ /*
+ * Child process for pstoraster... Assign new pipe input to pstoraster...
+ */
+
+ dup2(mypipes[0], 0);
+ close(mypipes[0]);
+ close(mypipes[1]);
+
+ execlp("pstoraster", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
+ NULL);
+ return (errno);
+ }
+ else if (pid < 0)
+ {
+ /*
+ * Error!
+ */
+
+ perror("ERROR: Unable to fork filter");
+ return (errno);
+ }
+
+ /*
+ * Update stdout so it points at the new pstoraster...
+ */
+
+ dup2(mypipes[1], 1);
+ close(mypipes[0]);
+ close(mypipes[1]);
+
+ /*
+ * Run imagetops to get the classification or page labeling that was
+ * requested...
+ */
+
+ execlp("imagetops", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
+ argv[6], NULL);
+ return (errno);
+ }
+
+ /*
+ * Copy stdin as needed...
+ */
+
+ if (argc == 6)
+ {
+ int fd; /* File to write to */
+ char buffer[8192]; /* Buffer to read into */
+ int bytes; /* # of bytes to read */
+
+
+ if ((fd = cupsTempFd(filename, sizeof(filename))) < 0)
+ {
+ perror("ERROR: Unable to copy print file");
+ return (1);
+ }
+
+ fprintf(stderr,
+ "DEBUG: imagetoraster - copying to temp print file \"%s\".\n",
+ filename);
+
+ while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
+ bytes = write(fd, buffer, bytes);
+
+ close(fd);
+ }
+ else
+ {
+ strncpy(filename, argv[6], sizeof(filename) - 1);
+ filename[sizeof(filename) - 1] = '\0';
+ }
+
+ /*
+ * Process command-line options and write the prolog...
+ */
+
+ zoom = 1.0;
+ xppi = 0;
+ yppi = 0;
+ hue = 0;
+ sat = 100;
+ g = 1.0;
+ b = 1.0;
+
+ Copies = atoi(argv[4]);
+
+ ppd = SetCommonOptions(num_options, options, 0);
+
+ if ((val = cupsGetOption("multiple-document-handling", num_options, options)) != NULL)
+ {
+ /*
+ * This IPP attribute is unnecessarily complicated...
+ *
+ * single-document, separate-documents-collated-copies, and
+ * single-document-new-sheet all require collated copies.
+ *
+ * separate-documents-collated-copies allows for uncollated copies.
+ */
+
+ Collate = strcasecmp(val, "separate-documents-collated-copies") != 0;
+ }
+
+ if ((val = cupsGetOption("Collate", num_options, options)) != NULL &&
+ strcasecmp(val, "True") == 0)
+ Collate = 1;
+
+ if ((val = cupsGetOption("gamma", num_options, options)) != NULL)
+ {
+ /*
+ * Get gamma value from 1 to 10000...
+ */
+
+ g = atoi(val) * 0.001f;
+
+ if (g < 0.001f)
+ g = 0.001f;
+ else if (g > 10.0f)
+ g = 10.0f;
+ }
+
+ if ((val = cupsGetOption("brightness", num_options, options)) != NULL)
+ {
+ /*
+ * Get brightness value from 10 to 1000.
+ */
+
+ b = atoi(val) * 0.01f;
+
+ if (b < 0.1f)
+ b = 0.1f;
+ else if (b > 10.0f)
+ b = 10.0f;
+ }
+
+ if ((val = cupsGetOption("scaling", num_options, options)) != NULL)
+ zoom = atoi(val) * 0.01;
+ else if (((val =
+ cupsGetOption("fit-to-page", num_options, options)) != NULL) ||
+ ((val = cupsGetOption("fitplot", num_options, options)) != NULL))
+ {
+ if (!strcasecmp(val, "yes") || !strcasecmp(val, "on") ||
+ !strcasecmp(val, "true"))
+ zoom = 1.0;
+ else
+ zoom = 0.0;
+ }
+ else if ((val = cupsGetOption("natural-scaling", num_options, options)) != NULL)
+ zoom = 0.0;
+
+ if ((val = cupsGetOption("ppi", num_options, options)) != NULL)
+ {
+ if (sscanf(val, "%dx%d", &xppi, &yppi) < 2)
+ yppi = xppi;
+ zoom = 0.0;
+ }
+
+ if ((val = cupsGetOption("position", num_options, options)) != NULL)
+ {
+ if (strcasecmp(val, "center") == 0)
+ {
+ XPosition = 0;
+ YPosition = 0;
+ }
+ else if (strcasecmp(val, "top") == 0)
+ {
+ XPosition = 0;
+ YPosition = 1;
+ }
+ else if (strcasecmp(val, "left") == 0)
+ {
+ XPosition = -1;
+ YPosition = 0;
+ }
+ else if (strcasecmp(val, "right") == 0)
+ {
+ XPosition = 1;
+ YPosition = 0;
+ }
+ else if (strcasecmp(val, "top-left") == 0)
+ {
+ XPosition = -1;
+ YPosition = 1;
+ }
+ else if (strcasecmp(val, "top-right") == 0)
+ {
+ XPosition = 1;
+ YPosition = 1;
+ }
+ else if (strcasecmp(val, "bottom") == 0)
+ {
+ XPosition = 0;
+ YPosition = -1;
+ }
+ else if (strcasecmp(val, "bottom-left") == 0)
+ {
+ XPosition = -1;
+ YPosition = -1;
+ }
+ else if (strcasecmp(val, "bottom-right") == 0)
+ {
+ XPosition = 1;
+ YPosition = -1;
+ }
+ }
+
+ if ((val = cupsGetOption("saturation", num_options, options)) != NULL)
+ sat = atoi(val);
+
+ if ((val = cupsGetOption("hue", num_options, options)) != NULL)
+ hue = atoi(val);
+
+ if ((choice = ppdFindMarkedChoice(ppd, "MirrorPrint")) != NULL)
+ {
+ val = choice->choice;
+ choice->marked = 0;
+ }
+ else
+ val = cupsGetOption("mirror", num_options, options);
+
+ if (val && (!strcasecmp(val, "true") || !strcasecmp(val, "on") ||
+ !strcasecmp(val, "yes")))
+ Flip = 1;
+
+ /*
+ * Set the needed options in the page header...
+ */
+
+ if (cupsRasterInterpretPPD(&header, ppd, num_options, options, raster_cb))
+ {
+ fputs("ERROR: The page setup information was not valid.\n", stderr);
+ fprintf(stderr, "DEBUG: %s\n", cupsRasterErrorString());
+ return (1);
+ }
+
+ /*
+ * Get the media type and resolution that have been chosen...
+ */
+
+ if ((choice = ppdFindMarkedChoice(ppd, "MediaType")) != NULL)
+ media_type = choice->choice;
+ else
+ media_type = "";
+
+ if ((choice = ppdFindMarkedChoice(ppd, "Resolution")) != NULL)
+ resolution = choice->choice;
+ else
+ resolution = "";
+
+ /* support the "cm-calibration" option */
+ cm_calibrate = cmGetCupsColorCalibrateMode(options, num_options);
+
+ if (cm_calibrate == CM_CALIBRATION_ENABLED)
+ cm_disabled = 1;
+ else
+ cm_disabled = cmIsPrinterCmDisabled(getenv("PRINTER"));
+
+ /*
+ * Choose the appropriate colorspace...
+ */
+
+ switch (header.cupsColorSpace)
+ {
+ case CUPS_CSPACE_W :
+ case CUPS_CSPACE_SW :
+ if (header.cupsBitsPerColor >= 8)
+ {
+ primary = CUPS_IMAGE_WHITE;
+ secondary = CUPS_IMAGE_WHITE;
+ }
+ else
+ {
+ primary = CUPS_IMAGE_BLACK;
+ secondary = CUPS_IMAGE_BLACK;
+ }
+ break;
+
+ default :
+ case CUPS_CSPACE_RGB :
+ case CUPS_CSPACE_RGBA :
+ case CUPS_CSPACE_RGBW :
+ case CUPS_CSPACE_SRGB :
+ case CUPS_CSPACE_ADOBERGB :
+ if (header.cupsBitsPerColor >= 8)
+ {
+ primary = CUPS_IMAGE_RGB;
+ secondary = CUPS_IMAGE_RGB;
+ }
+ else
+ {
+ primary = CUPS_IMAGE_CMY;
+ secondary = CUPS_IMAGE_CMY;
+ }
+ break;
+
+ case CUPS_CSPACE_K :
+ case CUPS_CSPACE_WHITE :
+ case CUPS_CSPACE_GOLD :
+ case CUPS_CSPACE_SILVER :
+ primary = CUPS_IMAGE_BLACK;
+ secondary = CUPS_IMAGE_BLACK;
+ break;
+
+ case CUPS_CSPACE_CMYK :
+ case CUPS_CSPACE_YMCK :
+ case CUPS_CSPACE_KCMY :
+ case CUPS_CSPACE_KCMYcm :
+ case CUPS_CSPACE_GMCK :
+ case CUPS_CSPACE_GMCS :
+ if (header.cupsBitsPerColor == 1)
+ {
+ primary = CUPS_IMAGE_CMY;
+ secondary = CUPS_IMAGE_CMY;
+ }
+ else
+ {
+ primary = CUPS_IMAGE_CMYK;
+ secondary = CUPS_IMAGE_CMYK;
+ }
+ break;
+
+ case CUPS_CSPACE_CMY :
+ case CUPS_CSPACE_YMC :
+ primary = CUPS_IMAGE_CMY;
+ secondary = CUPS_IMAGE_CMY;
+ break;
+
+ case CUPS_CSPACE_CIEXYZ :
+ case CUPS_CSPACE_CIELab :
+ case CUPS_CSPACE_ICC1 :
+ case CUPS_CSPACE_ICC2 :
+ case CUPS_CSPACE_ICC3 :
+ case CUPS_CSPACE_ICC4 :
+ case CUPS_CSPACE_ICC5 :
+ case CUPS_CSPACE_ICC6 :
+ case CUPS_CSPACE_ICC7 :
+ case CUPS_CSPACE_ICC8 :
+ case CUPS_CSPACE_ICC9 :
+ case CUPS_CSPACE_ICCA :
+ case CUPS_CSPACE_ICCB :
+ case CUPS_CSPACE_ICCC :
+ case CUPS_CSPACE_ICCD :
+ case CUPS_CSPACE_ICCE :
+ case CUPS_CSPACE_ICCF :
+ case CUPS_CSPACE_DEVICE1 :
+ case CUPS_CSPACE_DEVICE2 :
+ case CUPS_CSPACE_DEVICE3 :
+ case CUPS_CSPACE_DEVICE4 :
+ case CUPS_CSPACE_DEVICE5 :
+ case CUPS_CSPACE_DEVICE6 :
+ case CUPS_CSPACE_DEVICE7 :
+ case CUPS_CSPACE_DEVICE8 :
+ case CUPS_CSPACE_DEVICE9 :
+ case CUPS_CSPACE_DEVICEA :
+ case CUPS_CSPACE_DEVICEB :
+ case CUPS_CSPACE_DEVICEC :
+ case CUPS_CSPACE_DEVICED :
+ case CUPS_CSPACE_DEVICEE :
+ case CUPS_CSPACE_DEVICEF :
+ fprintf(stderr, "DEBUG: Colorspace %d not supported.\n",
+ header.cupsColorSpace);
+ exit(1);
+ break;
+ }
+
+ /*
+ * Find a color profile matching the current options...
+ */
+
+ if ((val = cupsGetOption("profile", num_options, options)) != NULL &&
+ !cm_disabled)
+ {
+ profile = &userprofile;
+ sscanf(val, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f",
+ &(userprofile.density), &(userprofile.gamma),
+ userprofile.matrix[0] + 0, userprofile.matrix[0] + 1,
+ userprofile.matrix[0] + 2,
+ userprofile.matrix[1] + 0, userprofile.matrix[1] + 1,
+ userprofile.matrix[1] + 2,
+ userprofile.matrix[2] + 0, userprofile.matrix[2] + 1,
+ userprofile.matrix[2] + 2);
+
+ userprofile.density *= 0.001f;
+ userprofile.gamma *= 0.001f;
+ userprofile.matrix[0][0] *= 0.001f;
+ userprofile.matrix[0][1] *= 0.001f;
+ userprofile.matrix[0][2] *= 0.001f;
+ userprofile.matrix[1][0] *= 0.001f;
+ userprofile.matrix[1][1] *= 0.001f;
+ userprofile.matrix[1][2] *= 0.001f;
+ userprofile.matrix[2][0] *= 0.001f;
+ userprofile.matrix[2][1] *= 0.001f;
+ userprofile.matrix[2][2] *= 0.001f;
+ }
+ else if (ppd != NULL && !cm_disabled)
+ {
+ fprintf(stderr, "DEBUG: Searching for profile \"%s/%s\"...\n",
+ resolution, media_type);
+
+ for (i = 0, profile = ppd->profiles; i < ppd->num_profiles; i ++, profile ++)
+ {
+ fprintf(stderr, "DEBUG: \"%s/%s\" = ", profile->resolution,
+ profile->media_type);
+
+ if ((strcmp(profile->resolution, resolution) == 0 ||
+ profile->resolution[0] == '-') &&
+ (strcmp(profile->media_type, media_type) == 0 ||
+ profile->media_type[0] == '-'))
+ {
+ fputs("MATCH\n", stderr);
+ break;
+ }
+ else
+ fputs("no.\n", stderr);
+ }
+
+ /*
+ * If we found a color profile, use it!
+ */
+
+ if (i >= ppd->num_profiles)
+ profile = NULL;
+ }
+ else
+ profile = NULL;
+
+ if (profile)
+ cupsImageSetProfile(profile->density, profile->gamma, profile->matrix);
+
+ cupsImageSetRasterColorSpace(header.cupsColorSpace);
+
+ /*
+ * Create a gamma/brightness LUT...
+ */
+
+ make_lut(lut, primary, g, b);
+
+ /*
+ * Open the input image to print...
+ */
+
+ fputs("INFO: Loading print file.\n", stderr);
+
+ if (header.cupsColorSpace == CUPS_CSPACE_CIEXYZ ||
+ header.cupsColorSpace == CUPS_CSPACE_CIELab ||
+ header.cupsColorSpace >= CUPS_CSPACE_ICC1)
+ img = cupsImageOpen(filename, primary, secondary, sat, hue, NULL);
+ else
+ img = cupsImageOpen(filename, primary, secondary, sat, hue, lut);
+
+ if (argc == 6)
+ unlink(filename);
+
+ if (img == NULL)
+ {
+ fputs("ERROR: The print file could not be opened.\n", stderr);
+ ppdClose(ppd);
+ return (1);
+ }
+
+ /*
+ * Scale as necessary...
+ */
+
+ if (zoom == 0.0 && xppi == 0)
+ {
+ xppi = img->xppi;
+ yppi = img->yppi;
+ }
+
+ if (yppi == 0)
+ yppi = xppi;
+
+ fprintf(stderr, "DEBUG: Before scaling: xppi=%d, yppi=%d, zoom=%.2f\n",
+ xppi, yppi, zoom);
+
+ if (xppi > 0)
+ {
+ /*
+ * Scale the image as neccesary to match the desired pixels-per-inch.
+ */
+
+ if (Orientation & 1)
+ {
+ xprint = (PageTop - PageBottom) / 72.0;
+ yprint = (PageRight - PageLeft) / 72.0;
+ }
+ else
+ {
+ xprint = (PageRight - PageLeft) / 72.0;
+ yprint = (PageTop - PageBottom) / 72.0;
+ }
+
+ fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
+ xprint, yprint);
+
+ xinches = (float)img->xsize / (float)xppi;
+ yinches = (float)img->ysize / (float)yppi;
+
+ fprintf(stderr, "DEBUG: Image size is %.1f x %.1f inches...\n",
+ xinches, yinches);
+
+ if ((val = cupsGetOption("natural-scaling", num_options, options)) != NULL)
+ {
+ xinches = xinches * atoi(val) / 100;
+ yinches = yinches * atoi(val) / 100;
+ }
+
+ if (cupsGetOption("orientation-requested", num_options, options) == NULL &&
+ cupsGetOption("landscape", num_options, options) == NULL)
+ {
+ /*
+ * Rotate the image if it will fit landscape but not portrait...
+ */
+
+ fputs("DEBUG: Auto orientation...\n", stderr);
+
+ if ((xinches > xprint || yinches > yprint) &&
+ xinches <= yprint && yinches <= xprint)
+ {
+ /*
+ * Rotate the image as needed...
+ */
+
+ fputs("DEBUG: Using landscape orientation...\n", stderr);
+
+ Orientation = (Orientation + 1) & 3;
+ xsize = yprint;
+ yprint = xprint;
+ xprint = xsize;
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Scale percentage of page size...
+ */
+
+ xprint = (PageRight - PageLeft) / 72.0;
+ yprint = (PageTop - PageBottom) / 72.0;
+ aspect = (float)img->yppi / (float)img->xppi;
+
+ fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
+ xprint, yprint);
+
+ fprintf(stderr, "DEBUG: img->xppi = %d, img->yppi = %d, aspect = %f\n",
+ img->xppi, img->yppi, aspect);
+
+ xsize = xprint * zoom;
+ ysize = xsize * img->ysize / img->xsize / aspect;
+
+ if (ysize > (yprint * zoom))
+ {
+ ysize = yprint * zoom;
+ xsize = ysize * img->xsize * aspect / img->ysize;
+ }
+
+ xsize2 = yprint * zoom;
+ ysize2 = xsize2 * img->ysize / img->xsize / aspect;
+
+ if (ysize2 > (xprint * zoom))
+ {
+ ysize2 = xprint * zoom;
+ xsize2 = ysize2 * img->xsize * aspect / img->ysize;
+ }
+
+ fprintf(stderr, "DEBUG: Portrait size is %.2f x %.2f inches\n", xsize, ysize);
+ fprintf(stderr, "DEBUG: Landscape size is %.2f x %.2f inches\n", xsize2, ysize2);
+
+ if (cupsGetOption("orientation-requested", num_options, options) == NULL &&
+ cupsGetOption("landscape", num_options, options) == NULL)
+ {
+ /*
+ * Choose the rotation with the largest area, but prefer
+ * portrait if they are equal...
+ */
+
+ fputs("DEBUG: Auto orientation...\n", stderr);
+
+ if ((xsize * ysize) < (xsize2 * ysize2))
+ {
+ /*
+ * Do landscape orientation...
+ */
+
+ fputs("DEBUG: Using landscape orientation...\n", stderr);
+
+ Orientation = 1;
+ xinches = xsize2;
+ yinches = ysize2;
+ xprint = (PageTop - PageBottom) / 72.0;
+ yprint = (PageRight - PageLeft) / 72.0;
+ }
+ else
+ {
+ /*
+ * Do portrait orientation...
+ */
+
+ fputs("DEBUG: Using portrait orientation...\n", stderr);
+
+ Orientation = 0;
+ xinches = xsize;
+ yinches = ysize;
+ }
+ }
+ else if (Orientation & 1)
+ {
+ fputs("DEBUG: Using landscape orientation...\n", stderr);
+
+ xinches = xsize2;
+ yinches = ysize2;
+ xprint = (PageTop - PageBottom) / 72.0;
+ yprint = (PageRight - PageLeft) / 72.0;
+ }
+ else
+ {
+ fputs("DEBUG: Using portrait orientation...\n", stderr);
+
+ xinches = xsize;
+ yinches = ysize;
+ xprint = (PageRight - PageLeft) / 72.0;
+ yprint = (PageTop - PageBottom) / 72.0;
+ }
+ }
+
+ /*
+ * Compute the number of pages to print and the size of the image on each
+ * page...
+ */
+
+ xpages = ceil(xinches / xprint);
+ ypages = ceil(yinches / yprint);
+
+ xprint = xinches / xpages;
+ yprint = yinches / ypages;
+
+ fprintf(stderr, "DEBUG: xpages = %dx%.2fin, ypages = %dx%.2fin\n",
+ xpages, xprint, ypages, yprint);
+
+ /*
+ * Compute the bitmap size...
+ */
+
+ if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) != NULL &&
+ strcasecmp(choice->choice, "Custom") == 0)
+ {
+ float width, /* New width in points */
+ length; /* New length in points */
+
+
+ /*
+ * Use the correct width and length for the current orientation...
+ */
+
+ if (Orientation & 1)
+ {
+ width = yprint * 72.0;
+ length = xprint * 72.0;
+ }
+ else
+ {
+ width = xprint * 72.0;
+ length = yprint * 72.0;
+ }
+
+ /*
+ * Add margins to page size...
+ */
+
+ width += ppd->custom_margins[0] + ppd->custom_margins[2];
+ length += ppd->custom_margins[1] + ppd->custom_margins[3];
+
+ /*
+ * Enforce minimums...
+ */
+
+ if (width < ppd->custom_min[0])
+ width = ppd->custom_min[0];
+
+ if (length < ppd->custom_min[1])
+ length = ppd->custom_min[1];
+
+ fprintf(stderr, "DEBUG: Updated custom page size to %.2f x %.2f inches...\n",
+ width / 72.0, length / 72.0);
+
+ /*
+ * Set the new custom size...
+ */
+
+ strcpy(header.cupsPageSizeName, "Custom");
+
+ header.cupsPageSize[0] = width + 0.5;
+ header.cupsPageSize[1] = length + 0.5;
+ header.PageSize[0] = width + 0.5;
+ header.PageSize[1] = length + 0.5;
+
+ /*
+ * Update page variables...
+ */
+
+ PageWidth = width;
+ PageLength = length;
+ PageLeft = ppd->custom_margins[0];
+ PageRight = width - ppd->custom_margins[2];
+ PageBottom = ppd->custom_margins[1];
+ PageTop = length - ppd->custom_margins[3];
+
+ /*
+ * Remove margins from page size...
+ */
+
+ width -= ppd->custom_margins[0] + ppd->custom_margins[2];
+ length -= ppd->custom_margins[1] + ppd->custom_margins[3];
+
+ /*
+ * Set the bitmap size...
+ */
+
+ header.cupsWidth = width * header.HWResolution[0] / 72.0;
+ header.cupsHeight = length * header.HWResolution[1] / 72.0;
+ } else {
+ /*
+ * Set the bitmap size...
+ */
+
+ header.cupsWidth = (Orientation & 1 ? yprint : xprint) *
+ header.HWResolution[0];
+ header.cupsHeight = (Orientation & 1 ? xprint : yprint) *
+ header.HWResolution[1];
+ }
+ header.cupsBytesPerLine = (header.cupsBitsPerPixel *
+ header.cupsWidth + 7) / 8;
+
+ if (header.cupsColorOrder == CUPS_ORDER_BANDED)
+ header.cupsBytesPerLine *= header.cupsNumColors;
+
+ header.Margins[0] = PageLeft;
+ header.Margins[1] = PageBottom;
+
+ fprintf(stderr, "DEBUG: PageSize = [%d %d]\n", header.PageSize[0],
+ header.PageSize[1]);
+ fprintf(stderr, "DEBUG: PageLeft = %f, PageRight = %f, PageBottom = %f, PageTop = %f\n",
+ PageLeft, PageRight, PageBottom, PageTop);
+
+ switch (Orientation)
+ {
+ default :
+ switch (XPosition)
+ {
+ case -1 :
+ header.cupsImagingBBox[0] = PageLeft;
+ header.cupsImagingBBox[2] = PageLeft + xprint * 72;
+ break;
+ default :
+ header.cupsImagingBBox[0] = (PageRight + PageLeft - xprint * 72) / 2;
+ header.cupsImagingBBox[2] = (PageRight + PageLeft + xprint * 72) / 2;
+ break;
+ case 1 :
+ header.cupsImagingBBox[0] = PageRight - xprint * 72;
+ header.cupsImagingBBox[2] = PageRight;
+ break;
+ }
+
+ switch (YPosition)
+ {
+ case -1 :
+ header.cupsImagingBBox[1] = PageBottom;
+ header.cupsImagingBBox[3] = PageBottom + yprint * 72;
+ break;
+ default :
+ header.cupsImagingBBox[1] = (PageTop + PageBottom - yprint * 72) / 2;
+ header.cupsImagingBBox[3] = (PageTop + PageBottom + yprint * 72) / 2;
+ break;
+ case 1 :
+ header.cupsImagingBBox[1] = PageTop - yprint * 72;
+ header.cupsImagingBBox[3] = PageTop;
+ break;
+ }
+ break;
+
+ case 1 :
+ switch (XPosition)
+ {
+ case -1 :
+ header.cupsImagingBBox[0] = PageLeft;
+ header.cupsImagingBBox[2] = PageLeft + yprint * 72;
+ break;
+ default :
+ header.cupsImagingBBox[0] = (PageRight + PageLeft - yprint * 72) / 2;
+ header.cupsImagingBBox[2] = (PageRight + PageLeft + yprint * 72) / 2;
+ break;
+ case 1 :
+ header.cupsImagingBBox[0] = PageRight - yprint * 72;
+ header.cupsImagingBBox[2] = PageRight;
+ break;
+ }
+
+ switch (YPosition)
+ {
+ case -1 :
+ header.cupsImagingBBox[1] = PageBottom;
+ header.cupsImagingBBox[3] = PageBottom + xprint * 72;
+ break;
+ default :
+ header.cupsImagingBBox[1] = (PageTop + PageBottom - xprint * 72) / 2;
+ header.cupsImagingBBox[3] = (PageTop + PageBottom + xprint * 72) / 2;
+ break;
+ case 1 :
+ header.cupsImagingBBox[1] = PageTop - xprint * 72;
+ header.cupsImagingBBox[3] = PageTop;
+ break;
+ }
+ break;
+
+ case 2 :
+ switch (XPosition)
+ {
+ case 1 :
+ header.cupsImagingBBox[0] = PageLeft;
+ header.cupsImagingBBox[2] = PageLeft + xprint * 72;
+ break;
+ default :
+ header.cupsImagingBBox[0] = (PageRight + PageLeft - xprint * 72) / 2;
+ header.cupsImagingBBox[2] = (PageRight + PageLeft + xprint * 72) / 2;
+ break;
+ case -1 :
+ header.cupsImagingBBox[0] = PageRight - xprint * 72;
+ header.cupsImagingBBox[2] = PageRight;
+ break;
+ }
+
+ switch (YPosition)
+ {
+ case 1 :
+ header.cupsImagingBBox[1] = PageBottom;
+ header.cupsImagingBBox[3] = PageBottom + yprint * 72;
+ break;
+ default :
+ header.cupsImagingBBox[1] = (PageTop + PageBottom - yprint * 72) / 2;
+ header.cupsImagingBBox[3] = (PageTop + PageBottom + yprint * 72) / 2;
+ break;
+ case -1 :
+ header.cupsImagingBBox[1] = PageTop - yprint * 72;
+ header.cupsImagingBBox[3] = PageTop;
+ break;
+ }
+ break;
+
+ case 3 :
+ switch (XPosition)
+ {
+ case 1 :
+ header.cupsImagingBBox[0] = PageLeft;
+ header.cupsImagingBBox[2] = PageLeft + yprint * 72;
+ break;
+ default :
+ header.cupsImagingBBox[0] = (PageRight + PageLeft - yprint * 72) / 2;
+ header.cupsImagingBBox[2] = (PageRight + PageLeft + yprint * 72) / 2;
+ break;
+ case -1 :
+ header.cupsImagingBBox[0] = PageRight - yprint * 72;
+ header.cupsImagingBBox[2] = PageRight;
+ break;
+ }
+
+ switch (YPosition)
+ {
+ case 1 :
+ header.cupsImagingBBox[1] = PageBottom;
+ header.cupsImagingBBox[3] = PageBottom + xprint * 72;
+ break;
+ default :
+ header.cupsImagingBBox[1] = (PageTop + PageBottom - xprint * 72) / 2;
+ header.cupsImagingBBox[3] = (PageTop + PageBottom + xprint * 72) / 2;
+ break;
+ case -1 :
+ header.cupsImagingBBox[1] = PageTop - xprint * 72;
+ header.cupsImagingBBox[3] = PageTop;
+ break;
+ }
+ break;
+ }
+
+ header.ImagingBoundingBox[0] = header.cupsImagingBBox[0];
+ header.ImagingBoundingBox[1] = header.cupsImagingBBox[1];
+ header.ImagingBoundingBox[2] = header.cupsImagingBBox[2];
+ header.ImagingBoundingBox[3] = header.cupsImagingBBox[3];
+
+ fprintf(stderr, "DEBUG: Orientation: %d, XPosition: %d, YPosition: %d, ImagingBoundingBox = [%d %d %d %d]\n",
+ Orientation, XPosition, YPosition,
+ header.ImagingBoundingBox[0], header.ImagingBoundingBox[1],
+ header.ImagingBoundingBox[2], header.ImagingBoundingBox[3]);
+
+ if (header.cupsColorOrder == CUPS_ORDER_PLANAR)
+ num_planes = header.cupsNumColors;
+ else
+ num_planes = 1;
+
+ if (header.cupsBitsPerColor >= 8)
+ zoom_type = CUPS_IZOOM_NORMAL;
+ else
+ zoom_type = CUPS_IZOOM_FAST;
+
+ /*
+ * See if we need to collate, and if so how we need to do it...
+ */
+
+ if (xpages == 1 && ypages == 1)
+ Collate = 0;
+
+ slowcollate = Collate && ppdFindOption(ppd, "Collate") == NULL;
+ if (ppd != NULL)
+ slowcopies = ppd->manual_copies;
+ else
+ slowcopies = 1;
+
+ if (Copies > 1 && !slowcollate && !slowcopies)
+ {
+ header.Collate = (cups_bool_t)Collate;
+ header.NumCopies = Copies;
+
+ Copies = 1;
+ }
+ else
+ header.NumCopies = 1;
+
+ /*
+ * Create the dithering lookup tables...
+ */
+
+ OnPixels[0] = 0x00;
+ OnPixels[255] = 0xff;
+ OffPixels[0] = 0x00;
+ OffPixels[255] = 0xff;
+
+ switch (header.cupsBitsPerColor)
+ {
+ case 2 :
+ for (i = 1; i < 255; i ++)
+ {
+ OnPixels[i] = 0x55 * (i / 85 + 1);
+ OffPixels[i] = 0x55 * (i / 64);
+ }
+ break;
+ case 4 :
+ for (i = 1; i < 255; i ++)
+ {
+ OnPixels[i] = 17 * (i / 17 + 1);
+ OffPixels[i] = 17 * (i / 16);
+ }
+ break;
+ }
+
+ /*
+ * Output the pages...
+ */
+
+ fprintf(stderr, "DEBUG: cupsWidth = %d\n", header.cupsWidth);
+ fprintf(stderr, "DEBUG: cupsHeight = %d\n", header.cupsHeight);
+ fprintf(stderr, "DEBUG: cupsBitsPerColor = %d\n", header.cupsBitsPerColor);
+ fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d\n", header.cupsBitsPerPixel);
+ fprintf(stderr, "DEBUG: cupsBytesPerLine = %d\n", header.cupsBytesPerLine);
+ fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", header.cupsColorOrder);
+ fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", header.cupsColorSpace);
+ fprintf(stderr, "DEBUG: img->colorspace = %d\n", img->colorspace);
+
+ row = malloc(2 * header.cupsBytesPerLine);
+ ras = cupsRasterOpen(1, CUPS_RASTER_WRITE);
+
+ for (i = 0, page = 1; i < Copies; i ++)
+ for (xpage = 0; xpage < xpages; xpage ++)
+ for (ypage = 0; ypage < ypages; ypage ++, page ++)
+ {
+ fprintf(stderr, "INFO: Formatting page %d.\n", page);
+
+ if (Orientation & 1)
+ {
+ xc0 = img->xsize * ypage / ypages;
+ xc1 = img->xsize * (ypage + 1) / ypages - 1;
+ yc0 = img->ysize * xpage / xpages;
+ yc1 = img->ysize * (xpage + 1) / xpages - 1;
+
+ xtemp = header.HWResolution[0] * yprint;
+ ytemp = header.HWResolution[1] * xprint;
+ }
+ else
+ {
+ xc0 = img->xsize * xpage / xpages;
+ xc1 = img->xsize * (xpage + 1) / xpages - 1;
+ yc0 = img->ysize * ypage / ypages;
+ yc1 = img->ysize * (ypage + 1) / ypages - 1;
+
+ xtemp = header.HWResolution[0] * xprint;
+ ytemp = header.HWResolution[1] * yprint;
+ }
+
+ cupsRasterWriteHeader2(ras, &header);
+
+ for (plane = 0; plane < num_planes; plane ++)
+ {
+ /*
+ * Initialize the image "zoom" engine...
+ */
+
+ if (Flip)
+ z = _cupsImageZoomNew(img, xc0, yc0, xc1, yc1, -xtemp, ytemp,
+ Orientation & 1, zoom_type);
+ else
+ z = _cupsImageZoomNew(img, xc0, yc0, xc1, yc1, xtemp, ytemp,
+ Orientation & 1, zoom_type);
+
+ /*
+ * Write leading blank space as needed...
+ */
+
+ if (header.cupsHeight > z->ysize && YPosition <= 0)
+ {
+ blank_line(&header, row);
+
+ y = header.cupsHeight - z->ysize;
+ if (YPosition == 0)
+ y /= 2;
+
+ fprintf(stderr, "DEBUG: Writing %d leading blank lines...\n", y);
+
+ for (; y > 0; y --)
+ {
+ if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) <
+ header.cupsBytesPerLine)
+ {
+ fputs("ERROR: Unable to send raster data to the driver.\n",
+ stderr);
+ cupsImageClose(img);
+ exit(1);
+ }
+ }
+ }
+
+ /*
+ * Then write image data...
+ */
+
+ for (y = z->ysize, yerr0 = 0, yerr1 = z->ysize, iy = 0, last_iy = -2;
+ y > 0;
+ y --)
+ {
+ if (iy != last_iy)
+ {
+ if (zoom_type != CUPS_IZOOM_FAST && (iy - last_iy) > 1)
+ _cupsImageZoomFill(z, iy);
+
+ _cupsImageZoomFill(z, iy + z->yincr);
+
+ last_iy = iy;
+ }
+
+ /*
+ * Format this line of raster data for the printer...
+ */
+
+ blank_line(&header, row);
+
+ r0 = z->rows[z->row];
+ r1 = z->rows[1 - z->row];
+
+ switch (header.cupsColorSpace)
+ {
+ case CUPS_CSPACE_W :
+ format_W(&header, row, y, plane, z->xsize, z->ysize,
+ yerr0, yerr1, r0, r1);
+ break;
+ default :
+ case CUPS_CSPACE_RGB :
+ format_RGB(&header, row, y, plane, z->xsize, z->ysize,
+ yerr0, yerr1, r0, r1);
+ break;
+ case CUPS_CSPACE_RGBA :
+ case CUPS_CSPACE_RGBW :
+ format_RGBA(&header, row, y, plane, z->xsize, z->ysize,
+ yerr0, yerr1, r0, r1);
+ break;
+ case CUPS_CSPACE_K :
+ case CUPS_CSPACE_WHITE :
+ case CUPS_CSPACE_GOLD :
+ case CUPS_CSPACE_SILVER :
+ format_K(&header, row, y, plane, z->xsize, z->ysize,
+ yerr0, yerr1, r0, r1);
+ break;
+ case CUPS_CSPACE_CMY :
+ format_CMY(&header, row, y, plane, z->xsize, z->ysize,
+ yerr0, yerr1, r0, r1);
+ break;
+ case CUPS_CSPACE_YMC :
+ format_YMC(&header, row, y, plane, z->xsize, z->ysize,
+ yerr0, yerr1, r0, r1);
+ break;
+ case CUPS_CSPACE_CMYK :
+ format_CMYK(&header, row, y, plane, z->xsize, z->ysize,
+ yerr0, yerr1, r0, r1);
+ break;
+ case CUPS_CSPACE_YMCK :
+ case CUPS_CSPACE_GMCK :
+ case CUPS_CSPACE_GMCS :
+ format_YMCK(&header, row, y, plane, z->xsize, z->ysize,
+ yerr0, yerr1, r0, r1);
+ break;
+ case CUPS_CSPACE_KCMYcm :
+ if (header.cupsBitsPerColor == 1)
+ {
+ format_KCMYcm(&header, row, y, plane, z->xsize, z->ysize,
+ yerr0, yerr1, r0, r1);
+ break;
+ }
+ case CUPS_CSPACE_KCMY :
+ format_KCMY(&header, row, y, plane, z->xsize, z->ysize,
+ yerr0, yerr1, r0, r1);
+ break;
+ }
+
+ /*
+ * Write the raster data to the driver...
+ */
+
+ if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) <
+ header.cupsBytesPerLine)
+ {
+ fputs("ERROR: Unable to send raster data to the driver.\n",
+ stderr);
+ cupsImageClose(img);
+ exit(1);
+ }
+
+ /*
+ * Compute the next scanline in the image...
+ */
+
+ iy += z->ystep;
+ yerr0 += z->ymod;
+ yerr1 -= z->ymod;
+ if (yerr1 <= 0)
+ {
+ yerr0 -= z->ysize;
+ yerr1 += z->ysize;
+ iy += z->yincr;
+ }
+ }
+
+ /*
+ * Write trailing blank space as needed...
+ */
+
+ if (header.cupsHeight > z->ysize && YPosition >= 0)
+ {
+ blank_line(&header, row);
+
+ y = header.cupsHeight - z->ysize;
+ if (YPosition == 0)
+ y = y - y / 2;
+
+ fprintf(stderr, "DEBUG: Writing %d trailing blank lines...\n", y);
+
+ for (; y > 0; y --)
+ {
+ if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) <
+ header.cupsBytesPerLine)
+ {
+ fputs("ERROR: Unable to send raster data to the driver.\n",
+ stderr);
+ cupsImageClose(img);
+ exit(1);
+ }
+ }
+ }
+
+ /*
+ * Free memory used for the "zoom" engine...
+ */
+
+ _cupsImageZoomDelete(z);
+ }
+ }
+
+ /*
+ * Close files...
+ */
+
+ free(row);
+ cupsRasterClose(ras);
+ cupsImageClose(img);
+ ppdClose(ppd);
+
+ return (0);
+}
+
+
+/*
+ * 'blank_line()' - Clear a line buffer to the blank value...
+ */
+
+static void
+blank_line(cups_page_header2_t *header, /* I - Page header */
+ unsigned char *row) /* I - Row buffer */
+{
+ int count; /* Remaining bytes */
+
+
+ count = header->cupsBytesPerLine;
+
+ switch (header->cupsColorSpace)
+ {
+ case CUPS_CSPACE_CIEXYZ :
+ while (count > 2)
+ {
+ *row++ = 242;
+ *row++ = 255;
+ *row++ = 255;
+ count -= 3;
+ }
+ break;
+
+ case CUPS_CSPACE_CIELab :
+ case CUPS_CSPACE_ICC1 :
+ case CUPS_CSPACE_ICC2 :
+ case CUPS_CSPACE_ICC3 :
+ case CUPS_CSPACE_ICC4 :
+ case CUPS_CSPACE_ICC5 :
+ case CUPS_CSPACE_ICC6 :
+ case CUPS_CSPACE_ICC7 :
+ case CUPS_CSPACE_ICC8 :
+ case CUPS_CSPACE_ICC9 :
+ case CUPS_CSPACE_ICCA :
+ case CUPS_CSPACE_ICCB :
+ case CUPS_CSPACE_ICCC :
+ case CUPS_CSPACE_ICCD :
+ case CUPS_CSPACE_ICCE :
+ case CUPS_CSPACE_ICCF :
+ while (count > 2)
+ {
+ *row++ = 255;
+ *row++ = 128;
+ *row++ = 128;
+ count -= 3;
+ }
+ break;
+
+ case CUPS_CSPACE_K :
+ case CUPS_CSPACE_CMY :
+ case CUPS_CSPACE_CMYK :
+ case CUPS_CSPACE_YMC :
+ case CUPS_CSPACE_YMCK :
+ case CUPS_CSPACE_KCMY :
+ case CUPS_CSPACE_KCMYcm :
+ case CUPS_CSPACE_GMCK :
+ case CUPS_CSPACE_GMCS :
+ case CUPS_CSPACE_WHITE :
+ case CUPS_CSPACE_GOLD :
+ case CUPS_CSPACE_SILVER :
+ memset(row, 0, count);
+ break;
+
+ default :
+ memset(row, 255, count);
+ break;
+ }
+}
+
+
+/*
+ * 'format_CMY()' - Convert image data to CMY.
+ */
+
+static void
+format_CMY(cups_page_header2_t *header, /* I - Page header */
+ unsigned char *row, /* IO - Bitmap data for device */
+ int y, /* I - Current row */
+ int z, /* I - Current plane */
+ int xsize, /* I - Width of image data */
+ int ysize, /* I - Height of image data */
+ int yerr0, /* I - Top Y error */
+ int yerr1, /* I - Bottom Y error */
+ cups_ib_t *r0, /* I - Primary image data */
+ cups_ib_t *r1) /* I - Image data for interpolation */
+{
+ cups_ib_t *ptr, /* Pointer into row */
+ *cptr, /* Pointer into cyan */
+ *mptr, /* Pointer into magenta */
+ *yptr, /* Pointer into yellow */
+ bitmask; /* Current mask for pixel */
+ int bitoffset; /* Current offset in line */
+ int bandwidth; /* Width of a color band */
+ int x, /* Current X coordinate on page */
+ *dither; /* Pointer into dither array */
+
+
+ switch (XPosition)
+ {
+ case -1 :
+ bitoffset = 0;
+ break;
+ default :
+ bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
+ break;
+ case 1 :
+ bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
+ break;
+ }
+
+ ptr = row + bitoffset / 8;
+ bandwidth = header->cupsBytesPerLine / 3;
+
+ switch (header->cupsColorOrder)
+ {
+ case CUPS_ORDER_CHUNKED :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 64 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize ; x > 0; x --)
+ {
+ if (*r0++ > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (*r0++ > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (*r0++ > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 64;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize ; x > 0; x --, r0 += 3)
+ {
+ if ((r0[0] & 63) > dither[x & 7])
+ *ptr ^= (0x30 & OnPixels[r0[0]]);
+ else
+ *ptr ^= (0x30 & OffPixels[r0[0]]);
+
+ if ((r0[1] & 63) > dither[x & 7])
+ *ptr ^= (0x0c & OnPixels[r0[1]]);
+ else
+ *ptr ^= (0x0c & OffPixels[r0[1]]);
+
+ if ((r0[2] & 63) > dither[x & 7])
+ *ptr++ ^= (0x03 & OnPixels[r0[2]]);
+ else
+ *ptr++ ^= (0x03 & OffPixels[r0[2]]);
+ }
+ break;
+
+ case 4 :
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize ; x > 0; x --, r0 += 3)
+ {
+ if ((r0[0] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[0]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[0]]);
+
+ if ((r0[1] & 15) > dither[x & 3])
+ *ptr ^= (0xf0 & OnPixels[r0[1]]);
+ else
+ *ptr ^= (0xf0 & OffPixels[r0[1]]);
+
+ if ((r0[2] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[2]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[2]]);
+ }
+ break;
+
+ case 8 :
+ for (x = xsize * 3; x > 0; x --, r0 ++, r1 ++)
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_BANDED :
+ cptr = ptr;
+ mptr = ptr + bandwidth;
+ yptr = ptr + 2 * bandwidth;
+
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if (*r0++ > dither[x & 15])
+ *cptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *mptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *yptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
+ {
+ if (r0[0] == r1[0])
+ *cptr++ = r0[0];
+ else
+ *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *mptr++ = r0[1];
+ else
+ *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[2] == r1[2])
+ *yptr++ = r0[2];
+ else
+ *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_PLANAR :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ switch (z)
+ {
+ case 0 :
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if (r0[0] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 1 :
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if (r0[1] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if (r0[2] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+ r0 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+ r0 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ r0 += z;
+ r1 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
+ {
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'format_CMYK()' - Convert image data to CMYK.
+ */
+
+static void
+format_CMYK(cups_page_header2_t *header,/* I - Page header */
+ unsigned char *row, /* IO - Bitmap data for device */
+ int y, /* I - Current row */
+ int z, /* I - Current plane */
+ int xsize, /* I - Width of image data */
+ int ysize, /* I - Height of image data */
+ int yerr0, /* I - Top Y error */
+ int yerr1, /* I - Bottom Y error */
+ cups_ib_t *r0, /* I - Primary image data */
+ cups_ib_t *r1) /* I - Image data for interpolation */
+{
+ cups_ib_t *ptr, /* Pointer into row */
+ *cptr, /* Pointer into cyan */
+ *mptr, /* Pointer into magenta */
+ *yptr, /* Pointer into yellow */
+ *kptr, /* Pointer into black */
+ bitmask; /* Current mask for pixel */
+ int bitoffset; /* Current offset in line */
+ int bandwidth; /* Width of a color band */
+ int x, /* Current X coordinate on page */
+ *dither; /* Pointer into dither array */
+ int pc, pm, py; /* CMY pixels */
+
+
+ switch (XPosition)
+ {
+ case -1 :
+ bitoffset = 0;
+ break;
+ default :
+ bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
+ break;
+ case 1 :
+ bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
+ break;
+ }
+
+ ptr = row + bitoffset / 8;
+ bandwidth = header->cupsBytesPerLine / 4;
+
+ switch (header->cupsColorOrder)
+ {
+ case CUPS_ORDER_CHUNKED :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 128 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize ; x > 0; x --)
+ {
+ pc = *r0++ > dither[x & 15];
+ pm = *r0++ > dither[x & 15];
+ py = *r0++ > dither[x & 15];
+
+ if (pc && pm && py)
+ {
+ bitmask >>= 3;
+ *ptr ^= bitmask;
+ }
+ else
+ {
+ if (pc)
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (pm)
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (py)
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+ }
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 128;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize ; x > 0; x --, r0 += 4)
+ {
+ if ((r0[0] & 63) > dither[x & 7])
+ *ptr ^= (0xc0 & OnPixels[r0[0]]);
+ else
+ *ptr ^= (0xc0 & OffPixels[r0[0]]);
+
+ if ((r0[1] & 63) > dither[x & 7])
+ *ptr ^= (0x30 & OnPixels[r0[1]]);
+ else
+ *ptr ^= (0x30 & OffPixels[r0[1]]);
+
+ if ((r0[2] & 63) > dither[x & 7])
+ *ptr ^= (0x0c & OnPixels[r0[2]]);
+ else
+ *ptr ^= (0x0c & OffPixels[r0[2]]);
+
+ if ((r0[3] & 63) > dither[x & 7])
+ *ptr++ ^= (0x03 & OnPixels[r0[3]]);
+ else
+ *ptr++ ^= (0x03 & OffPixels[r0[3]]);
+ }
+ break;
+
+ case 4 :
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize ; x > 0; x --, r0 += 4)
+ {
+ if ((r0[0] & 15) > dither[x & 3])
+ *ptr ^= (0xf0 & OnPixels[r0[0]]);
+ else
+ *ptr ^= (0xf0 & OffPixels[r0[0]]);
+
+ if ((r0[1] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[1]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[1]]);
+
+ if ((r0[2] & 15) > dither[x & 3])
+ *ptr ^= (0xf0 & OnPixels[r0[2]]);
+ else
+ *ptr ^= (0xf0 & OffPixels[r0[2]]);
+
+ if ((r0[3] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[3]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[3]]);
+ }
+ break;
+
+ case 8 :
+ for (x = xsize * 4; x > 0; x --, r0 ++, r1 ++)
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_BANDED :
+ cptr = ptr;
+ mptr = ptr + bandwidth;
+ yptr = ptr + 2 * bandwidth;
+ kptr = ptr + 3 * bandwidth;
+
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ pc = *r0++ > dither[x & 15];
+ pm = *r0++ > dither[x & 15];
+ py = *r0++ > dither[x & 15];
+
+ if (pc && pm && py)
+ *kptr ^= bitmask;
+ else
+ {
+ if (pc)
+ *cptr ^= bitmask;
+ if (pm)
+ *mptr ^= bitmask;
+ if (py)
+ *yptr ^= bitmask;
+ }
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *kptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *kptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *kptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *kptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
+ {
+ if (r0[0] == r1[0])
+ *cptr++ = r0[0];
+ else
+ *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *mptr++ = r0[1];
+ else
+ *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[2] == r1[2])
+ *yptr++ = r0[2];
+ else
+ *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+
+ if (r0[3] == r1[3])
+ *kptr++ = r0[3];
+ else
+ *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_PLANAR :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ pc = *r0++ > dither[x & 15];
+ pm = *r0++ > dither[x & 15];
+ py = *r0++ > dither[x & 15];
+
+ if ((pc && pm && py && z == 3) ||
+ (pc && z == 0) || (pm && z == 1) || (py && z == 2))
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+ r0 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+ r0 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ r0 += z;
+ r1 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
+ {
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'format_K()' - Convert image data to black.
+ */
+
+static void
+format_K(cups_page_header2_t *header, /* I - Page header */
+ unsigned char *row, /* IO - Bitmap data for device */
+ int y, /* I - Current row */
+ int z, /* I - Current plane */
+ int xsize, /* I - Width of image data */
+ int ysize, /* I - Height of image data */
+ int yerr0, /* I - Top Y error */
+ int yerr1, /* I - Bottom Y error */
+ cups_ib_t *r0, /* I - Primary image data */
+ cups_ib_t *r1) /* I - Image data for interpolation */
+{
+ cups_ib_t *ptr, /* Pointer into row */
+ bitmask; /* Current mask for pixel */
+ int bitoffset; /* Current offset in line */
+ int x, /* Current X coordinate on page */
+ *dither; /* Pointer into dither array */
+
+
+ (void)z;
+
+ switch (XPosition)
+ {
+ case -1 :
+ bitoffset = 0;
+ break;
+ default :
+ bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
+ break;
+ case 1 :
+ bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
+ break;
+ }
+
+ ptr = row + bitoffset / 8;
+
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if (*r0++ > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *ptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *ptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 ++, r1 ++)
+ {
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'format_KCMY()' - Convert image data to KCMY.
+ */
+
+static void
+format_KCMY(cups_page_header2_t *header,/* I - Page header */
+ unsigned char *row, /* IO - Bitmap data for device */
+ int y, /* I - Current row */
+ int z, /* I - Current plane */
+ int xsize, /* I - Width of image data */
+ int ysize, /* I - Height of image data */
+ int yerr0, /* I - Top Y error */
+ int yerr1, /* I - Bottom Y error */
+ cups_ib_t *r0, /* I - Primary image data */
+ cups_ib_t *r1) /* I - Image data for interpolation */
+{
+ cups_ib_t *ptr, /* Pointer into row */
+ *cptr, /* Pointer into cyan */
+ *mptr, /* Pointer into magenta */
+ *yptr, /* Pointer into yellow */
+ *kptr, /* Pointer into black */
+ bitmask; /* Current mask for pixel */
+ int bitoffset; /* Current offset in line */
+ int bandwidth; /* Width of a color band */
+ int x, /* Current X coordinate on page */
+ *dither; /* Pointer into dither array */
+ int pc, pm, py; /* CMY pixels */
+
+
+ switch (XPosition)
+ {
+ case -1 :
+ bitoffset = 0;
+ break;
+ default :
+ bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
+ break;
+ case 1 :
+ bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
+ break;
+ }
+
+ ptr = row + bitoffset / 8;
+ bandwidth = header->cupsBytesPerLine / 4;
+
+ switch (header->cupsColorOrder)
+ {
+ case CUPS_ORDER_CHUNKED :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 128 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize ; x > 0; x --)
+ {
+ pc = *r0++ > dither[x & 15];
+ pm = *r0++ > dither[x & 15];
+ py = *r0++ > dither[x & 15];
+
+ if (pc && pm && py)
+ {
+ *ptr ^= bitmask;
+ bitmask >>= 3;
+ }
+ else
+ {
+ bitmask >>= 1;
+ if (pc)
+ *ptr ^= bitmask;
+
+ bitmask >>= 1;
+ if (pm)
+ *ptr ^= bitmask;
+
+ bitmask >>= 1;
+ if (py)
+ *ptr ^= bitmask;
+ }
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 128;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize ; x > 0; x --, r0 += 4)
+ {
+ if ((r0[3] & 63) > dither[x & 7])
+ *ptr ^= (0xc0 & OnPixels[r0[3]]);
+ else
+ *ptr ^= (0xc0 & OffPixels[r0[3]]);
+
+ if ((r0[0] & 63) > dither[x & 7])
+ *ptr ^= (0x30 & OnPixels[r0[0]]);
+ else
+ *ptr ^= (0x30 & OffPixels[r0[0]]);
+
+ if ((r0[1] & 63) > dither[x & 7])
+ *ptr ^= (0x0c & OnPixels[r0[1]]);
+ else
+ *ptr ^= (0x0c & OffPixels[r0[1]]);
+
+ if ((r0[2] & 63) > dither[x & 7])
+ *ptr++ ^= (0x03 & OnPixels[r0[2]]);
+ else
+ *ptr++ ^= (0x03 & OffPixels[r0[2]]);
+ }
+ break;
+
+ case 4 :
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize ; x > 0; x --, r0 += 4)
+ {
+ if ((r0[3] & 15) > dither[x & 3])
+ *ptr ^= (0xf0 & OnPixels[r0[3]]);
+ else
+ *ptr ^= (0xf0 & OffPixels[r0[3]]);
+
+ if ((r0[0] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[0]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[0]]);
+
+ if ((r0[1] & 15) > dither[x & 3])
+ *ptr ^= (0xf0 & OnPixels[r0[1]]);
+ else
+ *ptr ^= (0xf0 & OffPixels[r0[1]]);
+
+ if ((r0[2] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[2]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[2]]);
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
+ {
+ if (r0[3] == r1[3])
+ *ptr++ = r0[3];
+ else
+ *ptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
+
+ if (r0[0] == r1[0])
+ *ptr++ = r0[0];
+ else
+ *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *ptr++ = r0[1];
+ else
+ *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[2] == r1[2])
+ *ptr++ = r0[2];
+ else
+ *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_BANDED :
+ kptr = ptr;
+ cptr = ptr + bandwidth;
+ mptr = ptr + 2 * bandwidth;
+ yptr = ptr + 3 * bandwidth;
+
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ pc = *r0++ > dither[x & 15];
+ pm = *r0++ > dither[x & 15];
+ py = *r0++ > dither[x & 15];
+
+ if (pc && pm && py)
+ *kptr ^= bitmask;
+ else
+ {
+ if (pc)
+ *cptr ^= bitmask;
+ if (pm)
+ *mptr ^= bitmask;
+ if (py)
+ *yptr ^= bitmask;
+ }
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *kptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *kptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *kptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *kptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
+ {
+ if (r0[0] == r1[0])
+ *cptr++ = r0[0];
+ else
+ *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *mptr++ = r0[1];
+ else
+ *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[2] == r1[2])
+ *yptr++ = r0[2];
+ else
+ *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+
+ if (r0[3] == r1[3])
+ *kptr++ = r0[3];
+ else
+ *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_PLANAR :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ pc = *r0++ > dither[x & 15];
+ pm = *r0++ > dither[x & 15];
+ py = *r0++ > dither[x & 15];
+
+ if ((pc && pm && py && z == 0) ||
+ (pc && z == 1) || (pm && z == 2) || (py && z == 3))
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+ if (z == 0)
+ r0 += 3;
+ else
+ r0 += z - 1;
+
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+ if (z == 0)
+ r0 += 3;
+ else
+ r0 += z - 1;
+
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ if (z == 0)
+ {
+ r0 += 3;
+ r1 += 3;
+ }
+ else
+ {
+ r0 += z - 1;
+ r1 += z - 1;
+ }
+
+ for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
+ {
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'format_KCMYcm()' - Convert image data to KCMYcm.
+ */
+
+static void
+format_KCMYcm(
+ cups_page_header2_t *header, /* I - Page header */
+ unsigned char *row, /* IO - Bitmap data for device */
+ int y, /* I - Current row */
+ int z, /* I - Current plane */
+ int xsize, /* I - Width of image data */
+ int ysize, /* I - Height of image data */
+ int yerr0, /* I - Top Y error */
+ int yerr1, /* I - Bottom Y error */
+ cups_ib_t *r0, /* I - Primary image data */
+ cups_ib_t *r1) /* I - Image data for interpolation */
+{
+ int pc, pm, py, pk; /* Cyan, magenta, yellow, and black values */
+ cups_ib_t *ptr, /* Pointer into row */
+ *cptr, /* Pointer into cyan */
+ *mptr, /* Pointer into magenta */
+ *yptr, /* Pointer into yellow */
+ *kptr, /* Pointer into black */
+ *lcptr, /* Pointer into light cyan */
+ *lmptr, /* Pointer into light magenta */
+ bitmask; /* Current mask for pixel */
+ int bitoffset; /* Current offset in line */
+ int bandwidth; /* Width of a color band */
+ int x, /* Current X coordinate on page */
+ *dither; /* Pointer into dither array */
+
+
+ switch (XPosition)
+ {
+ case -1 :
+ bitoffset = 0;
+ break;
+ default :
+ bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
+ break;
+ case 1 :
+ bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
+ break;
+ }
+
+ ptr = row + bitoffset / 8;
+ bandwidth = header->cupsBytesPerLine / 6;
+
+ switch (header->cupsColorOrder)
+ {
+ case CUPS_ORDER_CHUNKED :
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize ; x > 0; x --)
+ {
+ pc = *r0++ > dither[x & 15];
+ pm = *r0++ > dither[x & 15];
+ py = *r0++ > dither[x & 15];
+ pk = pc && pm && py;
+
+ if (pk)
+ *ptr++ ^= 32; /* Black */
+ else if (pc && pm)
+ *ptr++ ^= 17; /* Blue (cyan + light magenta) */
+ else if (pc && py)
+ *ptr++ ^= 6; /* Green (light cyan + yellow) */
+ else if (pm && py)
+ *ptr++ ^= 12; /* Red (magenta + yellow) */
+ else if (pc)
+ *ptr++ ^= 16;
+ else if (pm)
+ *ptr++ ^= 8;
+ else if (py)
+ *ptr++ ^= 4;
+ else
+ ptr ++;
+ }
+ break;
+
+ case CUPS_ORDER_BANDED :
+ kptr = ptr;
+ cptr = ptr + bandwidth;
+ mptr = ptr + 2 * bandwidth;
+ yptr = ptr + 3 * bandwidth;
+ lcptr = ptr + 4 * bandwidth;
+ lmptr = ptr + 5 * bandwidth;
+
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ pc = *r0++ > dither[x & 15];
+ pm = *r0++ > dither[x & 15];
+ py = *r0++ > dither[x & 15];
+ pk = pc && pm && py;
+
+ if (pk)
+ *kptr ^= bitmask; /* Black */
+ else if (pc && pm)
+ {
+ *cptr ^= bitmask; /* Blue (cyan + light magenta) */
+ *lmptr ^= bitmask;
+ }
+ else if (pc && py)
+ {
+ *lcptr ^= bitmask; /* Green (light cyan + yellow) */
+ *yptr ^= bitmask;
+ }
+ else if (pm && py)
+ {
+ *mptr ^= bitmask; /* Red (magenta + yellow) */
+ *yptr ^= bitmask;
+ }
+ else if (pc)
+ *cptr ^= bitmask;
+ else if (pm)
+ *mptr ^= bitmask;
+ else if (py)
+ *yptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ lcptr ++;
+ lmptr ++;
+ }
+ }
+ break;
+
+ case CUPS_ORDER_PLANAR :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ pc = *r0++ > dither[x & 15];
+ pm = *r0++ > dither[x & 15];
+ py = *r0++ > dither[x & 15];
+ pk = pc && pm && py;
+
+ if (pk && z == 0)
+ *ptr ^= bitmask;
+ else if (pc && pm && (z == 1 || z == 5))
+ *ptr ^= bitmask; /* Blue (cyan + light magenta) */
+ else if (pc && py && (z == 3 || z == 4))
+ *ptr ^= bitmask; /* Green (light cyan + yellow) */
+ else if (pm && py && (z == 2 || z == 3))
+ *ptr ^= bitmask; /* Red (magenta + yellow) */
+ else if (pc && z == 1)
+ *ptr ^= bitmask;
+ else if (pm && z == 2)
+ *ptr ^= bitmask;
+ else if (py && z == 3)
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'format_RGBA()' - Convert image data to RGBA/RGBW.
+ */
+
+static void
+format_RGBA(cups_page_header2_t *header,/* I - Page header */
+ unsigned char *row, /* IO - Bitmap data for device */
+ int y, /* I - Current row */
+ int z, /* I - Current plane */
+ int xsize, /* I - Width of image data */
+ int ysize, /* I - Height of image data */
+ int yerr0, /* I - Top Y error */
+ int yerr1, /* I - Bottom Y error */
+ cups_ib_t *r0, /* I - Primary image data */
+ cups_ib_t *r1) /* I - Image data for interpolation */
+{
+ cups_ib_t *ptr, /* Pointer into row */
+ *cptr, /* Pointer into cyan */
+ *mptr, /* Pointer into magenta */
+ *yptr, /* Pointer into yellow */
+ bitmask; /* Current mask for pixel */
+ int bitoffset; /* Current offset in line */
+ int bandwidth; /* Width of a color band */
+ int x, /* Current X coordinate on page */
+ *dither; /* Pointer into dither array */
+
+
+ switch (XPosition)
+ {
+ case -1 :
+ bitoffset = 0;
+ break;
+ default :
+ bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
+ break;
+ case 1 :
+ bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
+ break;
+ }
+
+ ptr = row + bitoffset / 8;
+ bandwidth = header->cupsBytesPerLine / 4;
+
+ switch (header->cupsColorOrder)
+ {
+ case CUPS_ORDER_CHUNKED :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 128 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize ; x > 0; x --)
+ {
+ if (*r0++ > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (*r0++ > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (*r0++ > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 2)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 128;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize ; x > 0; x --, r0 += 3)
+ {
+ if ((r0[0] & 63) > dither[x & 7])
+ *ptr ^= (0xc0 & OnPixels[r0[0]]);
+ else
+ *ptr ^= (0xc0 & OffPixels[r0[0]]);
+
+ if ((r0[1] & 63) > dither[x & 7])
+ *ptr ^= (0x30 & OnPixels[r0[1]]);
+ else
+ *ptr ^= (0x30 & OffPixels[r0[1]]);
+
+ if ((r0[2] & 63) > dither[x & 7])
+ *ptr ^= (0x0c & OnPixels[r0[2]]);
+ else
+ *ptr ^= (0x0c & OffPixels[r0[2]]);
+
+ ptr ++;
+ }
+ break;
+
+ case 4 :
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize ; x > 0; x --, r0 += 3)
+ {
+ if ((r0[0] & 15) > dither[x & 3])
+ *ptr ^= (0xf0 & OnPixels[r0[0]]);
+ else
+ *ptr ^= (0xf0 & OffPixels[r0[0]]);
+
+ if ((r0[1] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[1]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[1]]);
+
+ if ((r0[2] & 15) > dither[x & 3])
+ *ptr ^= (0xf0 & OnPixels[r0[2]]);
+ else
+ *ptr ^= (0xf0 & OffPixels[r0[2]]);
+
+ ptr ++;
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
+ {
+ if (r0[0] == r1[0])
+ *ptr++ = r0[0];
+ else
+ *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *ptr++ = r0[1];
+ else
+ *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[2] == r1[2])
+ *ptr++ = r0[2];
+ else
+ *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+
+ ptr ++;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_BANDED :
+ cptr = ptr;
+ mptr = ptr + bandwidth;
+ yptr = ptr + 2 * bandwidth;
+
+ memset(ptr + 3 * bandwidth, 255, bandwidth);
+
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if (*r0++ > dither[x & 15])
+ *cptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *mptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *yptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
+ {
+ if (r0[0] == r1[0])
+ *cptr++ = r0[0];
+ else
+ *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *mptr++ = r0[1];
+ else
+ *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[2] == r1[2])
+ *yptr++ = r0[2];
+ else
+ *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_PLANAR :
+ if (z == 3)
+ {
+ memset(row, 255, header->cupsBytesPerLine);
+ break;
+ }
+
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ switch (z)
+ {
+ case 0 :
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if (r0[0] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 1 :
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if (r0[1] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if (r0[2] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+ r0 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+ r0 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ r0 += z;
+ r1 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
+ {
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'format_W()' - Convert image data to luminance.
+ */
+
+static void
+format_W(cups_page_header2_t *header, /* I - Page header */
+ unsigned char *row, /* IO - Bitmap data for device */
+ int y, /* I - Current row */
+ int z, /* I - Current plane */
+ int xsize, /* I - Width of image data */
+ int ysize, /* I - Height of image data */
+ int yerr0, /* I - Top Y error */
+ int yerr1, /* I - Bottom Y error */
+ cups_ib_t *r0, /* I - Primary image data */
+ cups_ib_t *r1) /* I - Image data for interpolation */
+{
+ cups_ib_t *ptr, /* Pointer into row */
+ bitmask; /* Current mask for pixel */
+ int bitoffset; /* Current offset in line */
+ int x, /* Current X coordinate on page */
+ *dither; /* Pointer into dither array */
+
+
+ (void)z;
+
+ switch (XPosition)
+ {
+ case -1 :
+ bitoffset = 0;
+ break;
+ default :
+ bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
+ break;
+ case 1 :
+ bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
+ break;
+ }
+
+ ptr = row + bitoffset / 8;
+
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if (*r0++ > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *ptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *ptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 ++, r1 ++)
+ {
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'format_YMC()' - Convert image data to YMC.
+ */
+
+static void
+format_YMC(cups_page_header2_t *header, /* I - Page header */
+ unsigned char *row, /* IO - Bitmap data for device */
+ int y, /* I - Current row */
+ int z, /* I - Current plane */
+ int xsize, /* I - Width of image data */
+ int ysize, /* I - Height of image data */
+ int yerr0, /* I - Top Y error */
+ int yerr1, /* I - Bottom Y error */
+ cups_ib_t *r0, /* I - Primary image data */
+ cups_ib_t *r1) /* I - Image data for interpolation */
+{
+ cups_ib_t *ptr, /* Pointer into row */
+ *cptr, /* Pointer into cyan */
+ *mptr, /* Pointer into magenta */
+ *yptr, /* Pointer into yellow */
+ bitmask; /* Current mask for pixel */
+ int bitoffset; /* Current offset in line */
+ int bandwidth; /* Width of a color band */
+ int x, /* Current X coordinate on page */
+ *dither; /* Pointer into dither array */
+
+
+ switch (XPosition)
+ {
+ case -1 :
+ bitoffset = 0;
+ break;
+ default :
+ bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
+ break;
+ case 1 :
+ bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
+ break;
+ }
+
+ ptr = row + bitoffset / 8;
+ bandwidth = header->cupsBytesPerLine / 3;
+
+ switch (header->cupsColorOrder)
+ {
+ case CUPS_ORDER_CHUNKED :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 64 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize ; x > 0; x --, r0 += 3)
+ {
+ if (r0[2] > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (r0[1] > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (r0[0] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 64;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize ; x > 0; x --, r0 += 3)
+ {
+ if ((r0[2] & 63) > dither[x & 7])
+ *ptr ^= (0x30 & OnPixels[r0[2]]);
+ else
+ *ptr ^= (0x30 & OffPixels[r0[2]]);
+
+ if ((r0[1] & 63) > dither[x & 7])
+ *ptr ^= (0x0c & OnPixels[r0[1]]);
+ else
+ *ptr ^= (0x0c & OffPixels[r0[1]]);
+
+ if ((r0[0] & 63) > dither[x & 7])
+ *ptr++ ^= (0x03 & OnPixels[r0[0]]);
+ else
+ *ptr++ ^= (0x03 & OffPixels[r0[0]]);
+ }
+ break;
+
+ case 4 :
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize ; x > 0; x --, r0 += 3)
+ {
+ if ((r0[2] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[2]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[2]]);
+
+ if ((r0[1] & 15) > dither[x & 3])
+ *ptr ^= (0xf0 & OnPixels[r0[1]]);
+ else
+ *ptr ^= (0xf0 & OffPixels[r0[1]]);
+
+ if ((r0[0] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[0]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[0]]);
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
+ {
+ if (r0[2] == r1[2])
+ *ptr++ = r0[2];
+ else
+ *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *ptr++ = r0[1];
+ else
+ *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[0] == r1[0])
+ *ptr++ = r0[0];
+ else
+ *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_BANDED :
+ yptr = ptr;
+ mptr = ptr + bandwidth;
+ cptr = ptr + 2 * bandwidth;
+
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if (*r0++ > dither[x & 15])
+ *cptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *mptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *yptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
+ {
+ if (r0[0] == r1[0])
+ *cptr++ = r0[0];
+ else
+ *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *mptr++ = r0[1];
+ else
+ *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[2] == r1[2])
+ *yptr++ = r0[2];
+ else
+ *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_PLANAR :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ switch (z)
+ {
+ case 2 :
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if (r0[0] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 1 :
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if (r0[1] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 0 :
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if (r0[2] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+ z = 2 - z;
+ r0 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+ z = 2 - z;
+ r0 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ z = 2 - z;
+ r0 += z;
+ r1 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
+ {
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'format_YMCK()' - Convert image data to YMCK.
+ */
+
+static void
+format_YMCK(cups_page_header2_t *header,/* I - Page header */
+ unsigned char *row, /* IO - Bitmap data for device */
+ int y, /* I - Current row */
+ int z, /* I - Current plane */
+ int xsize, /* I - Width of image data */
+ int ysize, /* I - Height of image data */
+ int yerr0, /* I - Top Y error */
+ int yerr1, /* I - Bottom Y error */
+ cups_ib_t *r0, /* I - Primary image data */
+ cups_ib_t *r1) /* I - Image data for interpolation */
+{
+ cups_ib_t *ptr, /* Pointer into row */
+ *cptr, /* Pointer into cyan */
+ *mptr, /* Pointer into magenta */
+ *yptr, /* Pointer into yellow */
+ *kptr, /* Pointer into black */
+ bitmask; /* Current mask for pixel */
+ int bitoffset; /* Current offset in line */
+ int bandwidth; /* Width of a color band */
+ int x, /* Current X coordinate on page */
+ *dither; /* Pointer into dither array */
+ int pc, pm, py; /* CMY pixels */
+
+
+ switch (XPosition)
+ {
+ case -1 :
+ bitoffset = 0;
+ break;
+ default :
+ bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
+ break;
+ case 1 :
+ bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
+ break;
+ }
+
+ ptr = row + bitoffset / 8;
+ bandwidth = header->cupsBytesPerLine / 4;
+
+ switch (header->cupsColorOrder)
+ {
+ case CUPS_ORDER_CHUNKED :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 128 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize ; x > 0; x --)
+ {
+ pc = *r0++ > dither[x & 15];
+ pm = *r0++ > dither[x & 15];
+ py = *r0++ > dither[x & 15];
+
+ if (pc && pm && py)
+ {
+ bitmask >>= 3;
+ *ptr ^= bitmask;
+ }
+ else
+ {
+ if (py)
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (pm)
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (pc)
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+ }
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 128;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize ; x > 0; x --, r0 += 4)
+ {
+ if ((r0[2] & 63) > dither[x & 7])
+ *ptr ^= (0xc0 & OnPixels[r0[2]]);
+ else
+ *ptr ^= (0xc0 & OffPixels[r0[2]]);
+
+ if ((r0[1] & 63) > dither[x & 7])
+ *ptr ^= (0x30 & OnPixels[r0[1]]);
+ else
+ *ptr ^= (0x30 & OffPixels[r0[1]]);
+
+ if ((r0[0] & 63) > dither[x & 7])
+ *ptr ^= (0x0c & OnPixels[r0[0]]);
+ else
+ *ptr ^= (0x0c & OffPixels[r0[0]]);
+
+ if ((r0[3] & 63) > dither[x & 7])
+ *ptr++ ^= (0x03 & OnPixels[r0[3]]);
+ else
+ *ptr++ ^= (0x03 & OffPixels[r0[3]]);
+ }
+ break;
+
+ case 4 :
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize ; x > 0; x --, r0 += 4)
+ {
+ if ((r0[2] & 15) > dither[x & 3])
+ *ptr ^= (0xf0 & OnPixels[r0[2]]);
+ else
+ *ptr ^= (0xf0 & OffPixels[r0[2]]);
+
+ if ((r0[1] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[1]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[1]]);
+
+ if ((r0[0] & 15) > dither[x & 3])
+ *ptr ^= (0xf0 & OnPixels[r0[0]]);
+ else
+ *ptr ^= (0xf0 & OffPixels[r0[0]]);
+
+ if ((r0[3] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[3]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[3]]);
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
+ {
+ if (r0[2] == r1[2])
+ *ptr++ = r0[2];
+ else
+ *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *ptr++ = r0[1];
+ else
+ *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[0] == r1[0])
+ *ptr++ = r0[0];
+ else
+ *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+
+ if (r0[3] == r1[3])
+ *ptr++ = r0[3];
+ else
+ *ptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_BANDED :
+ yptr = ptr;
+ mptr = ptr + bandwidth;
+ cptr = ptr + 2 * bandwidth;
+ kptr = ptr + 3 * bandwidth;
+
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ pc = *r0++ > dither[x & 15];
+ pm = *r0++ > dither[x & 15];
+ py = *r0++ > dither[x & 15];
+
+ if (pc && pm && py)
+ *kptr ^= bitmask;
+ else
+ {
+ if (pc)
+ *cptr ^= bitmask;
+ if (pm)
+ *mptr ^= bitmask;
+ if (py)
+ *yptr ^= bitmask;
+ }
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *kptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *kptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *kptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *kptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
+ {
+ if (r0[0] == r1[0])
+ *cptr++ = r0[0];
+ else
+ *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *mptr++ = r0[1];
+ else
+ *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[2] == r1[2])
+ *yptr++ = r0[2];
+ else
+ *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+
+ if (r0[3] == r1[3])
+ *kptr++ = r0[3];
+ else
+ *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_PLANAR :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ pc = *r0++ > dither[x & 15];
+ pm = *r0++ > dither[x & 15];
+ py = *r0++ > dither[x & 15];
+
+ if ((pc && pm && py && z == 3) ||
+ (pc && z == 2) || (pm && z == 1) || (py && z == 0))
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+ if (z == 3)
+ r0 += 3;
+ else
+ r0 += 2 - z;
+
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+ if (z == 3)
+ r0 += 3;
+ else
+ r0 += 2 - z;
+
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ if (z == 3)
+ {
+ r0 += 3;
+ r1 += 3;
+ }
+ else
+ {
+ r0 += 2 - z;
+ r1 += 2 - z;
+ }
+
+ for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
+ {
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'make_lut()' - Make a lookup table given gamma and brightness values.
+ */
+
+static void
+make_lut(cups_ib_t *lut, /* I - Lookup table */
+ int colorspace, /* I - Colorspace */
+ float g, /* I - Image gamma */
+ float b) /* I - Image brightness */
+{
+ int i; /* Looping var */
+ int v; /* Current value */
+
+
+ g = 1.0 / g;
+ b = 1.0 / b;
+
+ for (i = 0; i < 256; i ++)
+ {
+ if (colorspace < 0)
+ v = 255.0 * b * (1.0 - pow(1.0 - (float)i / 255.0, g)) + 0.5;
+ else
+ v = 255.0 * (1.0 - b * (1.0 - pow((float)i / 255.0, g))) + 0.5;
+
+ if (v < 0)
+ *lut++ = 0;
+ else if (v > 255)
+ *lut++ = 255;
+ else
+ *lut++ = v;
+ }
+}
+
+
+/*
+ * 'raster_cb()' - Validate the page header.
+ */
+
+static int /* O - 0 if OK, -1 if not */
+raster_cb(
+ cups_page_header2_t *header, /* IO - Raster header */
+ int preferred_bits) /* I - Preferred bits per color */
+{
+ /*
+ * Ensure that colorimetric colorspaces use at least 8 bits per
+ * component...
+ */
+
+ if ((header->cupsColorSpace == CUPS_CSPACE_CIEXYZ ||
+ header->cupsColorSpace == CUPS_CSPACE_CIELab ||
+ header->cupsColorSpace >= CUPS_CSPACE_ICC1) &&
+ header->cupsBitsPerColor < 8)
+ header->cupsBitsPerColor = 8;
+
+ return (0);
+}
+
diff --git a/filter/mupdftoraster.c b/filter/mupdftoraster.c
new file mode 100644
index 000000000..3af235cb3
--- /dev/null
+++ b/filter/mupdftoraster.c
@@ -0,0 +1,459 @@
+/*
+
+Copyright (c) 2016, Pranjal Bhor
+Copyright (c) 2008-2016, Till Kamppeter
+Copyright (c) 2011, Tim Waugh
+Copyright (c) 2011-2013, Richard Hughes
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+MIT Open Source License - http://www.opensource.org/
+
+*/
+
+
+/* PS/PDF to CUPS Raster filter based on Mutool */
+
+#include <config.h>
+#include <cups/cups.h>
+#if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 6)
+#define HAVE_CUPS_1_7 1
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <cups/raster.h>
+#include <cupsfilters/colormanager.h>
+#include <cupsfilters/raster.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+
+#define PDF_MAX_CHECK_COMMENT_LINES 20
+
+#define CUPS_IPTEMPFILE "/tmp/ip-XXXXXX"
+#define CUPS_OPTEMPFILE "/tmp/op-XXXXXX"
+
+#ifdef CUPS_RASTER_SYNCv1
+typedef cups_page_header2_t mupdf_page_header;
+#else
+typedef cups_page_header_t mupdf_page_header;
+#endif /* CUPS_RASTER_SYNCv1 */
+
+
+void
+parse_doc_type(FILE *fp)
+{
+ char buf[5];
+ char *rc;
+
+ /* get the first few bytes of the file */
+ rewind(fp);
+ rc = fgets(buf,sizeof(buf),fp);
+ if (rc == NULL)
+ goto out;
+
+ /* is PDF */
+ if (strncmp(buf,"%PDF",4) == 0)
+ return;
+ out:
+ fprintf(stderr,"DEBUG: input file cannot be identified\n");
+ exit(EXIT_FAILURE);
+}
+
+static void
+parse_pdf_header_options(FILE *fp, mupdf_page_header *h)
+{
+ char buf[4096];
+ int i;
+
+ rewind(fp);
+ /* skip until PDF start header */
+ while (fgets(buf,sizeof(buf),fp) != 0) {
+ if (strncmp(buf,"%PDF",4) == 0) {
+ break;
+ }
+ }
+ for (i = 0;i < PDF_MAX_CHECK_COMMENT_LINES;i++) {
+ if (fgets(buf,sizeof(buf),fp) == 0) break;
+ if (strncmp(buf,"%%PDFTOPDFNumCopies",19) == 0) {
+ char *p;
+
+ p = strchr(buf+19,':');
+ h->NumCopies = atoi(p+1);
+ } else if (strncmp(buf,"%%PDFTOPDFCollate",17) == 0) {
+ char *p;
+
+ p = strchr(buf+17,':');
+ while (*p == ' ' || *p == '\t') p++;
+ if (strncasecmp(p,"true",4) == 0) {
+ h->Collate = CUPS_TRUE;
+ } else {
+ h->Collate = CUPS_FALSE;
+ }
+ }
+ }
+}
+
+static void
+add_pdf_header_options(mupdf_page_header *h,
+ cups_array_t *mupdf_args)
+{
+ char tmpstr[1024];
+
+ if ((h->HWResolution[0] != 100) || (h->HWResolution[1] != 100)) {
+ snprintf(tmpstr, sizeof(tmpstr), "-r%dx%d", h->HWResolution[0],
+ h->HWResolution[1]);
+ cupsArrayAdd(mupdf_args, strdup(tmpstr));
+ } else {
+ snprintf(tmpstr, sizeof(tmpstr), "-r100x100");
+ cupsArrayAdd(mupdf_args, strdup(tmpstr));
+ }
+
+ snprintf(tmpstr, sizeof(tmpstr), "-w%d", h->cupsWidth);
+ cupsArrayAdd(mupdf_args, strdup(tmpstr));
+
+ snprintf(tmpstr, sizeof(tmpstr), "-h%d", h->cupsHeight);
+ cupsArrayAdd(mupdf_args, strdup(tmpstr));
+
+ switch (h->cupsColorSpace) {
+ case CUPS_CSPACE_RGB:
+ case CUPS_CSPACE_CMY:
+ case CUPS_CSPACE_SRGB:
+ case CUPS_CSPACE_ADOBERGB:
+ snprintf(tmpstr, sizeof(tmpstr), "-crgb");
+ break;
+
+ case CUPS_CSPACE_CMYK:
+ snprintf(tmpstr, sizeof(tmpstr), "-ccmyk");
+ break;
+
+ case CUPS_CSPACE_SW:
+ snprintf(tmpstr, sizeof(tmpstr), "-cgray");
+ break;
+
+ default:
+ case CUPS_CSPACE_K:
+ case CUPS_CSPACE_W:
+ snprintf(tmpstr, sizeof(tmpstr), "-cmono");
+ break;
+ }
+ cupsArrayAdd(mupdf_args, strdup(tmpstr));
+}
+
+static int
+mutool_spawn (const char *filename,
+ cups_array_t *mupdf_args,
+ char **envp,
+ FILE *fp,
+ int ipfiledes,
+ int opfiledes)
+{
+ char *argument;
+ char buf[BUFSIZ];
+ char **mutoolargv;
+ const char* apos;
+ int i;
+ int n;
+ int numargs;
+ int pid;
+ int status = 65536;
+ int wstatus;
+ FILE *tempfp;
+
+ /* Put mutool command line argument into an array for the "exec()"
+ call */
+ numargs = cupsArrayCount(mupdf_args);
+ mutoolargv = calloc(numargs + 1, sizeof(char *));
+ for (argument = (char *)cupsArrayFirst(mupdf_args), i = 0; argument;
+ argument = (char *)cupsArrayNext(mupdf_args), i++) {
+ mutoolargv[i] = argument;
+ }
+ mutoolargv[i] = NULL;
+
+ /* Debug output: Full Mutool command line and environment variables */
+ fprintf(stderr, "DEBUG: Mutool command line:");
+ for (i = 0; mutoolargv[i]; i ++) {
+ if ((strchr(mutoolargv[i],' ')) || (strchr(mutoolargv[i],'\t')))
+ apos = "'";
+ else
+ apos = "";
+ fprintf(stderr, " %s%s%s", apos, mutoolargv[i], apos);
+ }
+ fprintf(stderr, "\n");
+
+ for (i = 0; envp[i]; i ++)
+ fprintf(stderr, "DEBUG: envp[%d]=\"%s\"\n", i, envp[i]);
+
+ /* save the contents for the file to a temporary location */
+ tempfp = fdopen(ipfiledes, "wb");
+ while ((n = fread(buf, 1, BUFSIZ, fp)) > 0)
+ fwrite(buf, 1, n, tempfp);
+
+ fclose(tempfp);
+
+ if ((pid = fork()) == 0) {
+ /* Execute Mutool command line ... */
+ execvpe(filename, mutoolargv, envp);
+ perror(filename);
+ goto out;
+ }
+
+ retry_wait:
+ if (waitpid (pid, &wstatus, 0) == -1) {
+ if (errno == EINTR)
+ goto retry_wait;
+ perror ("gs");
+ goto out;
+ }
+
+ /* How did Mutool process terminate */
+ if (WIFEXITED(wstatus))
+ /* Via exit() anywhere or return() in the main() function */
+ status = WEXITSTATUS(wstatus);
+ else if (WIFSIGNALED(wstatus))
+ /* Via signal */
+ status = 256 * WTERMSIG(wstatus);
+
+ /* write the output to stdout */
+ tempfp = fdopen(opfiledes, "rb");
+ while ((n = fread(buf, 1, BUFSIZ, tempfp)) > 0)
+ fwrite(buf, 1, BUFSIZ, stdout);
+
+ fclose(tempfp);
+
+ out:
+ free(mutoolargv);
+ return status;
+}
+
+int
+main (int argc, char **argv, char *envp[])
+{
+ char buf[BUFSIZ];
+ char *icc_profile = NULL;
+ char tmpstr[1024];
+ char ipfilebuf[20],
+ opfilebuf[20];
+ const char *t = NULL;
+ cups_array_t *mupdf_args = NULL;
+ cups_option_t *options = NULL;
+ FILE *fp = NULL;
+ mupdf_page_header h;
+ int fd,
+ ipfiledes,
+ opfiledes;
+ int cm_disabled;
+ int n;
+ int num_options;
+ int status = 1;
+ ppd_file_t *ppd = NULL;
+ struct sigaction sa;
+ cm_calibration_t cm_calibrate;
+#ifdef HAVE_CUPS_1_7
+ ppd_attr_t *attr;
+#endif /* HAVE_CUPS_1_7 */
+
+ if (argc < 6 || argc > 7) {
+ fprintf(stderr, "ERROR: %s job-id user title copies options [file]\n",
+ argv[0]);
+ goto out;
+ }
+
+ memset(&sa, 0, sizeof(sa));
+ /* Ignore SIGPIPE and have write return an error instead */
+ sa.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &sa, NULL);
+
+ num_options = cupsParseOptions(argv[5], 0, &options);
+
+ t = getenv("PPD");
+ if (t && t[0] != '\0')
+ if ((ppd = ppdOpenFile(t)) == NULL) {
+ fprintf(stderr, "ERROR: Failed to open PPD: %s\n", t);
+ }
+
+ if (ppd) {
+ ppdMarkDefaults (ppd);
+ cupsMarkOptions (ppd, num_options, options);
+ }
+
+ if (argc == 6) {
+ /* stdin */
+
+ fd = cupsTempFd(buf,BUFSIZ);
+ if (fd < 0) {
+ fprintf(stderr, "ERROR: Can't create temporary file\n");
+ goto out;
+ }
+ /* remove name */
+ unlink(buf);
+
+ /* copy stdin to the tmp file */
+ while ((n = read(0,buf,BUFSIZ)) > 0) {
+ if (write(fd,buf,n) != n) {
+ fprintf(stderr, "ERROR: Can't copy stdin to temporary file\n");
+ close(fd);
+ goto out;
+ }
+ }
+ if (lseek(fd,0,SEEK_SET) < 0) {
+ fprintf(stderr, "ERROR: Can't rewind temporary file\n");
+ close(fd);
+ goto out;
+ }
+
+ if ((fp = fdopen(fd,"rb")) == 0) {
+ fprintf(stderr, "ERROR: Can't fdopen temporary file\n");
+ close(fd);
+ goto out;
+ }
+ } else {
+ /* argc == 7 filename is specified */
+
+ if ((fp = fopen(argv[6],"rb")) == 0) {
+ fprintf(stderr, "ERROR: Can't open input file %s\n",argv[6]);
+ goto out;
+ }
+ }
+
+ /* If doc type is not PDF exit */
+ parse_doc_type(fp);
+
+ /* Check status of color management in CUPS */
+ cm_calibrate = cmGetCupsColorCalibrateMode(options, num_options);
+
+ if (cm_calibrate == CM_CALIBRATION_ENABLED)
+ cm_disabled = 1;
+ else
+ cm_disabled = cmIsPrinterCmDisabled(getenv("PRINTER"));
+
+ if (!cm_disabled)
+ cmGetPrinterIccProfile(getenv("PRINTER"), &icc_profile, ppd);
+
+ /* Create temporary input and output files */
+ memset(ipfilebuf,0,sizeof(ipfilebuf));
+ memset(opfilebuf,0,sizeof(opfilebuf));
+ strncpy(ipfilebuf,CUPS_IPTEMPFILE,14);
+ strncpy(opfilebuf,CUPS_OPTEMPFILE,14);
+ ipfiledes = mkstemp(ipfilebuf);
+ opfiledes = mkstemp(opfilebuf);
+
+ /* Mutool parameters */
+ mupdf_args = cupsArrayNew(NULL, NULL);
+ if (!mupdf_args) {
+ fprintf(stderr, "ERROR: Unable to allocate memory for Mutool arguments array\n");
+ goto out;
+ }
+
+ fprintf(stderr,"command: %s\n",CUPS_MUTOOL);
+ snprintf(tmpstr, sizeof(tmpstr), "%s", CUPS_MUTOOL);
+ cupsArrayAdd(mupdf_args, strdup(tmpstr));
+ cupsArrayAdd(mupdf_args, strdup("draw"));
+ cupsArrayAdd(mupdf_args, strdup("-L"));
+ snprintf(tmpstr, sizeof(tmpstr), "-o%s", opfilebuf);
+ cupsArrayAdd(mupdf_args, strdup(tmpstr));
+ cupsArrayAdd(mupdf_args, strdup("-smtf"));
+
+ /* Mutool output parameters */
+ cupsArrayAdd(mupdf_args, strdup("-Fpwg"));
+
+ /* Note that MuPDF only creates PWG Raster and never CUPS Raster,
+ so we always set the PWG Raster flag in the cupsRasterParseIPPOptions()
+ calls.
+ Make also sure that the width and height of the page in pixels is
+ the size of the full page (as PWG Raster and MuPDF require it) and not
+ only the printable area (as cupsRasterInterpretPPD() sets, to fulfill
+ CUPS Raster standard) */
+ if (ppd) {
+ cupsRasterInterpretPPD(&h, ppd, num_options, options, 0);
+ h.cupsWidth = h.HWResolution[0] * h.PageSize[0] / 72;
+ h.cupsHeight = h.HWResolution[1] * h.PageSize[1] / 72;
+#ifdef HAVE_CUPS_1_7
+ cupsRasterParseIPPOptions(&h, num_options, options, 1, 0);
+#endif /* HAVE_CUPS_1_7 */
+ } else {
+#ifdef HAVE_CUPS_1_7
+ cupsRasterParseIPPOptions(&h, num_options, options, 1, 1);
+#else
+ fprintf(stderr, "ERROR: No PPD file specified.\n");
+ goto out;
+#endif /* HAVE_CUPS_1_7 */
+ }
+
+ if ((h.HWResolution[0] == 100) && (h.HWResolution[1] == 100)) {
+ /* No "Resolution" option */
+ if (ppd && (attr = ppdFindAttr(ppd, "DefaultResolution", 0)) != NULL) {
+ /* "*DefaultResolution" keyword in the PPD */
+ const char *p = attr->value;
+ h.HWResolution[0] = atoi(p);
+ if ((p = strchr(p, 'x')) != NULL)
+ h.HWResolution[1] = atoi(p);
+ else
+ h.HWResolution[1] = h.HWResolution[0];
+ if (h.HWResolution[0] <= 0)
+ h.HWResolution[0] = 300;
+ if (h.HWResolution[1] <= 0)
+ h.HWResolution[1] = h.HWResolution[0];
+ } else {
+ h.HWResolution[0] = 300;
+ h.HWResolution[1] = 300;
+ }
+ h.cupsWidth = h.HWResolution[0] * h.PageSize[0] / 72;
+ h.cupsHeight = h.HWResolution[1] * h.PageSize[1] / 72;
+ }
+
+ /* set PDF-specific options */
+ parse_pdf_header_options(fp, &h);
+
+ /* fixed other values that pdftopdf handles */
+ h.MirrorPrint = CUPS_FALSE;
+ h.Orientation = CUPS_ORIENT_0;
+
+ /* get all the data from the header and pass it to Mutool */
+ add_pdf_header_options (&h, mupdf_args);
+
+ snprintf(tmpstr, sizeof(tmpstr), "%s", ipfilebuf);
+ cupsArrayAdd(mupdf_args, strdup(tmpstr));
+
+ /* Execute Mutool command line ... */
+ snprintf(tmpstr, sizeof(tmpstr), "%s", CUPS_MUTOOL);
+
+ /* call mutool */
+ rewind(fp);
+ status = mutool_spawn (tmpstr, mupdf_args, envp, fp, ipfiledes, opfiledes);
+ if (status != 0) status = 1;
+out:
+ if (fp)
+ fclose(fp);
+ if (mupdf_args)
+ cupsArrayDelete(mupdf_args);
+
+ free(icc_profile);
+ if (ppd)
+ ppdClose(ppd);
+ unlink(ipfilebuf);
+ unlink(opfilebuf);
+ return status;
+}
diff --git a/filter/pcl-common.c b/filter/pcl-common.c
new file mode 100644
index 000000000..2488d2514
--- /dev/null
+++ b/filter/pcl-common.c
@@ -0,0 +1,320 @@
+/*
+ * Common PCL functions for CUPS.
+ *
+ * Copyright 2007 by Apple Inc.
+ * Copyright 1993-2005 by Easy Software Products
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * pcl_set_media_size() - Set media size using the page size command.
+ * pjl_write() - Write a PJL command string, performing
+ * substitutions as needed.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <cupsfilters/driver.h>
+#include "pcl-common.h"
+#include <math.h>
+
+
+/*
+ * 'pcl_set_media_size()' - Set media size using the page size command.
+ */
+
+void
+pcl_set_media_size(ppd_file_t *ppd, /* I - PPD file */
+ float width, /* I - Width of page */
+ float length) /* I - Length of page */
+{
+ float l;
+ int l_int;
+
+ if (width < length)
+ l = length;
+ else
+ l = width;
+ l_int = (int)(l + 0.5f);
+ fprintf (stderr, "DEBUG: Width: %f Length: %f Long Edge: %f\n",
+ width, length, l);
+
+ printf("\033&l0O"); /* Set portrait orientation */
+
+ if (!ppd || ppd->model_number & PCL_PAPER_SIZE)
+ {
+ if (l_int >= 418 && l_int <= 420) /* Postcard */
+ printf("\033&l71A"); /* Set page size */
+ else if (l_int >= 539 && l_int <= 541) /* Monarch Envelope */
+ printf("\033&l80A"); /* Set page size */
+ else if (l_int >= 566 && l_int <= 568) /* Double Postcard */
+ printf("\033&l72A"); /* Set page size */
+ else if (l_int >= 594 && l_int <= 596) /* A5 */
+ printf("\033&l25A"); /* Set page size */
+ else if (l_int >= 611 && l_int <= 613) /* Statement */
+ printf("\033&l5A"); /* Set page size */
+ else if (l_int >= 623 && l_int <= 625) /* DL Envelope */
+ printf("\033&l90A"); /* Set page size */
+ else if (l_int >= 648 && l_int <= 650) /* C5 Envelope */
+ printf("\033&l91A"); /* Set page size */
+ else if (l_int >= 683 && l_int <= 685) /* COM-10 Envelope */
+ printf("\033&l81A"); /* Set page size */
+ else if (l_int >= 708 && l_int <= 710) /* B5 Envelope */
+ printf("\033&l100A"); /* Set page size */
+ else if (l_int >= 728 && l_int <= 730) /* B5 */
+ printf("\033&l45A"); /* Set page size */
+ else if (l_int >= 755 && l_int <= 757) /* Executive */
+ printf("\033&l1A"); /* Set page size */
+ else if (l_int >= 791 && l_int <= 793) /* Letter */
+ printf("\033&l2A"); /* Set page size */
+ else if (l_int >= 841 && l_int <= 843) /* A4 */
+ printf("\033&l26A"); /* Set page size */
+ else if (l_int >= 935 && l_int <= 937) /* Foolscap */
+ printf("\033&l23A"); /* Set page size */
+ else if (l_int >= 1007 && l_int <= 1009) /* Legal */
+ printf("\033&l3A"); /* Set page size */
+ else if (l_int >= 1031 && l_int <= 1033) /* B4 */
+ printf("\033&l46A"); /* Set page size */
+ else if (l_int >= 1190 && l_int <= 1192) /* A3 */
+ printf("\033&l27A"); /* Set page size */
+ else if (l_int >= 1223 && l_int <= 1225) /* Tabloid */
+ printf("\033&l6A"); /* Set page size */
+ else
+ {
+ printf("\033&l101A"); /* Set page size */
+ printf("\033&l6D\033&k12H"); /* Set 6 LPI, 10 CPI */
+ printf("\033&l%.2fP", l / 12.0); /* Set page length */
+ printf("\033&l%.0fF", l / 12.0); /* Set text length to page */
+ }
+#if 0
+ switch ((int)(l + 0.5f))
+ {
+ case 419 : /* Postcard */
+ printf("\033&l71A"); /* Set page size */
+ break;
+
+ case 540 : /* Monarch Envelope */
+ printf("\033&l80A"); /* Set page size */
+ break;
+
+ case 567 : /* Double Postcard */
+ printf("\033&l72A"); /* Set page size */
+ break;
+
+ case 595 : /* A5 */
+ printf("\033&l25A"); /* Set page size */
+ break;
+
+ case 612 : /* Statement */
+ printf("\033&l5A"); /* Set page size */
+ break;
+
+ case 624 : /* DL Envelope */
+ printf("\033&l90A"); /* Set page size */
+ break;
+
+ case 649 : /* C5 Envelope */
+ printf("\033&l91A"); /* Set page size */
+ break;
+
+ case 684 : /* COM-10 Envelope */
+ printf("\033&l81A"); /* Set page size */
+ break;
+
+ case 709 : /* B5 Envelope */
+ printf("\033&l100A"); /* Set page size */
+ break;
+
+ case 729 : /* B5 */
+ printf("\033&l45A"); /* Set page size */
+ break;
+
+ case 756 : /* Executive */
+ printf("\033&l1A"); /* Set page size */
+ break;
+
+ case 792 : /* Letter */
+ printf("\033&l2A"); /* Set page size */
+ break;
+
+ case 842 : /* A4 */
+ printf("\033&l26A"); /* Set page size */
+ break;
+
+ case 936 : /* Foolscap */
+ printf("\033&l23A"); /* Set page size */
+ break;
+
+ case 1008 : /* Legal */
+ printf("\033&l3A"); /* Set page size */
+ break;
+
+ case 1032 : /* B4 */
+ printf("\033&l46A"); /* Set page size */
+ break;
+
+ case 1191 : /* A3 */
+ printf("\033&l27A"); /* Set page size */
+ break;
+
+ case 1224 : /* Tabloid */
+ printf("\033&l6A"); /* Set page size */
+ break;
+
+ default :
+ printf("\033&l101A"); /* Set page size */
+ printf("\033&l6D\033&k12H"); /* Set 6 LPI, 10 CPI */
+ printf("\033&l%.2fP", l / 12.0);
+ /* Set page length */
+ printf("\033&l%.0fF", l / 12.0);
+ /* Set text length to page */
+ break;
+ }
+#endif
+ }
+ else
+ {
+ printf("\033&l6D\033&k12H"); /* Set 6 LPI, 10 CPI */
+ printf("\033&l%.2fP", l / 12.0);
+ /* Set page length */
+ printf("\033&l%.0fF", l / 12.0);
+ /* Set text length to page */
+ }
+
+ printf("\033&l0L"); /* Turn off perforation skip */
+ printf("\033&l0E"); /* Reset top margin to 0 */
+}
+
+
+/*
+ * 'pjl_write()' - Write a PJL command string, performing substitutions as needed.
+ */
+
+void
+pjl_write(const char *format, /* I - Format string */
+ const char *value, /* I - Value for %s */
+ int job_id, /* I - Job ID */
+ const char *user, /* I - Username */
+ const char *title, /* I - Title */
+ int num_options, /* I - Number of options */
+ cups_option_t *options) /* I - Options */
+{
+ const char *optval; /* Option value */
+ char match[255], /* Match string */
+ *mptr; /* Pointer into match string */
+
+
+ if (!format)
+ return;
+
+ while (*format)
+ {
+ if (*format == '%')
+ {
+ /*
+ * Perform substitution...
+ */
+
+ format ++;
+ switch (*format)
+ {
+ case 'b' : /* job-billing */
+ if ((optval = cupsGetOption("job-billing", num_options,
+ options)) != NULL)
+ fputs(optval, stdout);
+ break;
+
+ case 'h' : /* job-originating-host-name */
+ if ((optval = cupsGetOption("job-originating-host-name",
+ num_options, options)) != NULL)
+ fputs(optval, stdout);
+ break;
+
+ case 'j' : /* job-id */
+ printf("%d", job_id);
+ break;
+
+ case 'n' : /* CR + LF */
+ putchar('\r');
+ putchar('\n');
+ break;
+
+ case 'q' : /* double quote (") */
+ putchar('\"');
+ break;
+
+ case 's' : /* "value" */
+ if (value)
+ fputs(value, stdout);
+ break;
+
+ case 't' : /* job-name */
+ fputs(title, stdout);
+ break;
+
+ case 'u' : /* job-originating-user-name */
+ fputs(user, stdout);
+ break;
+
+ case '?' : /* ?value:string; */
+ /*
+ * Get the match value...
+ */
+
+ for (format ++, mptr = match; *format && *format != ':'; format ++)
+ if (mptr < (match + sizeof(match) - 1))
+ *mptr++ = *format;
+
+ if (!*format)
+ return;
+
+ /*
+ * See if we have a match...
+ */
+
+ format ++;
+ *mptr = '\0';
+
+ if (!value || strcmp(match, value))
+ {
+ /*
+ * Value doesn't match; skip the string that follows...
+ */
+
+ while (*format && *format != ';')
+ format ++;
+ }
+ else
+ {
+ /*
+ * Value matches; copy the string that follows...
+ */
+
+ while (*format && *format != ';')
+ putchar(*format++);
+ }
+
+ if (!*format)
+ return;
+ break;
+
+ default : /* Anything else */
+ putchar('%');
+ case '%' : /* %% = single % */
+ putchar(*format);
+ break;
+ }
+ }
+ else
+ putchar(*format);
+
+ format ++;
+ }
+}
+
diff --git a/filter/pcl-common.h b/filter/pcl-common.h
new file mode 100644
index 000000000..9249aaf1b
--- /dev/null
+++ b/filter/pcl-common.h
@@ -0,0 +1,66 @@
+/*
+ * Common HP-PCL definitions for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2005 by Easy Software Products, All Rights Reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <string.h>
+#include <ctype.h>
+#include "pcl.h"
+
+
+/*
+ * Functions/macros...
+ */
+
+#define pcl_reset()\
+ printf("\033E")
+#define pcl_set_copies(copies)\
+ printf("\033&l%dX", (copies))
+#define pcl_set_pcl_mode(m)\
+ printf("\033%%%dA", (m))
+#define pcl_set_hpgl_mode(m)\
+ printf("\033%%%dB", (m))
+#define pcl_set_negative_motion()\
+ printf("\033&a1N")
+#define pcl_set_media_source(source)\
+ printf("\033&l%dH", source)
+#define pcl_set_media_type(type)\
+ printf("\033&l%dM", type)
+#define pcl_set_duplex(duplex,landscape)\
+ if (duplex) printf("\033&l%dS", (duplex) + (landscape))
+#define pcl_set_simple_black()\
+ printf("\033*r-1U")
+#define pcl_set_simple_color()\
+ printf("\033*r3U")
+#define pcl_set_simple_cmy()\
+ printf("\033*r-3U")
+#define pcl_set_simple_kcmy()\
+ printf("\033*r-4U")
+#define pcl_set_simple_resolution(r)\
+ printf("\033*t%dR", (r))
+
+#define pjl_escape()\
+ printf("\033%%-12345X@PJL\r\n")
+#define pjl_set_job(job_id,user,title)\
+ printf("@PJL JOB NAME = \"%s\" DISPLAY = \"%d %s %s\"\r\n", \
+ (title), (job_id), (user), (title))
+#define pjl_enter_language(lang)\
+ printf("@PJL ENTER LANGUAGE=%s\r\n", (lang))
+
+extern void pcl_set_media_size(ppd_file_t *ppd, float width, float length);
+extern void pjl_write(const char *format,
+ const char *value, int job_id,
+ const char *user, const char *title,
+ int num_options, cups_option_t *options);
+
diff --git a/filter/pcl.h b/filter/pcl.h
new file mode 100644
index 000000000..802eb9a0d
--- /dev/null
+++ b/filter/pcl.h
@@ -0,0 +1,31 @@
+/*
+ * This file contains model number definitions for the CUPS unified
+ * PCL driver.
+ *
+ * Copyright 2007 by Apple Inc.
+ * Copyright 1997-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ */
+
+/* General PCL Support */
+#define PCL_PAPER_SIZE 0x1 /* Use ESC&l#A */
+#define PCL_INKJET 0x2 /* Use inkjet commands */
+
+/* Raster Support */
+#define PCL_RASTER_END_COLOR 0x100 /* Use ESC*rC */
+#define PCL_RASTER_CID 0x200 /* Use ESC*v#W */
+#define PCL_RASTER_CRD 0x400 /* Use ESC*g#W */
+#define PCL_RASTER_SIMPLE 0x800 /* Use ESC*r#U */
+#define PCL_RASTER_RGB24 0x1000 /* Use 24-bit RGB mode */
+
+/* PJL Support */
+#define PCL_PJL 0x10000 /* Use PJL Commands */
+#define PCL_PJL_PAPERWIDTH 0x20000 /* Use PJL PAPERWIDTH/LENGTH */
+#define PCL_PJL_HPGL2 0x40000 /* Enter HPGL2 */
+#define PCL_PJL_PCL3GUI 0x80000 /* Enter PCL3GUI */
+#define PCL_PJL_RESOLUTION 0x100000 /* Use PJL SET RESOLUTION */
+
diff --git a/filter/pdf.cxx b/filter/pdf.cxx
new file mode 100644
index 000000000..206ccf883
--- /dev/null
+++ b/filter/pdf.cxx
@@ -0,0 +1,1807 @@
+/*
+ * Copyright 2012 Canonical Ltd.
+ * Copyright 2013 ALT Linux, Andrew V. Stepanov <stanv@altlinux.com>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include "pdf.h"
+
+#include <PDFDoc.h>
+#include <GlobalParams.h>
+#include <Form.h>
+#include <Gfx.h>
+#include <GfxFont.h>
+#include <Page.h>
+#include <PDFDocEncoding.h>
+#ifdef HAVE_CPP_POPPLER_VERSION_H
+#include "cpp/poppler-version.h"
+#endif
+
+extern "C" {
+#include <embed.h>
+#include <sfnt.h>
+}
+
+#include <fontconfig/fontconfig.h>
+
+/*
+ * Useful reference:
+ *
+ * http://www.gnupdf.org/Indirect_Object
+ * http://www.gnupdf.org/Introduction_to_PDF
+ * http://blog.idrsolutions.com/2011/05/understanding-the-pdf-file-format-%E2%80%93-pdf-xref-tables-explained
+ * http://labs.appligent.com/pdfblog/pdf-hello-world/
+*/
+
+static EMB_PARAMS *get_font(const char *font);
+
+static const char *emb_pdf_escape_name(const char *name, int len);
+
+static int utf8_to_utf16(const char *utf8, unsigned short **out_ptr);
+
+static const char* get_next_wide(const char *utf8, int *unicode_out);
+
+extern "C" {
+ static int pdf_embed_font(
+ pdf_t *doc,
+ Page *page,
+ const char *typeface);
+}
+
+static void fill_font_stream(
+ const char *buf,
+ int len,
+ void *context);
+
+static Object *make_fontdescriptor_dic(pdf_t *doc,
+ EMB_PARAMS *emb,
+ EMB_PDF_FONTDESCR *fdes,
+ Ref fontfile_obj_ref);
+
+static Object *make_font_dic(pdf_t *doc,
+ EMB_PARAMS *emb,
+ EMB_PDF_FONTDESCR *fdes,
+ EMB_PDF_FONTWIDTHS *fwid,
+ Ref fontdescriptor_obj_ref);
+
+static Object *make_cidfont_dic(pdf_t *doc,
+ EMB_PARAMS *emb,
+ const char *fontname,
+ Ref fontdescriptor_obj_ref);
+
+/* Font to use to fill form */
+static EMB_PARAMS *Font;
+
+extern "C" pdf_t * pdf_load_template(const char *filename)
+{
+ /* Init poppler */
+ globalParams = new GlobalParams();
+
+ PDFDoc *doc = new PDFDoc(new GooString(filename));
+
+ if (!doc->isOk()) {
+ fprintf(stderr,
+ "Error: unable to open template document '%s'\n",
+ filename);
+ delete doc;
+ return NULL;
+ }
+
+ if (doc->getNumPages() != 1) {
+ fprintf(stderr,
+ "Error: PDF template must contain exactly 1 page: %s\n",
+ filename);
+ delete doc;
+ return NULL;
+ }
+
+ return doc;
+}
+
+
+extern "C" void pdf_free(pdf_t *pdf)
+{
+ delete pdf;
+}
+
+
+extern "C" void pdf_prepend_stream(pdf_t *doc,
+ int page,
+ char *buf,
+ size_t len)
+{
+ XRef *xref = doc->getXRef();
+ Ref *pageref = doc->getCatalog()->getPageRef(page);
+ Object dict, lenobj, stream, streamrefobj;
+ Object pageobj, contents;
+ Object array;
+ Ref r;
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ pageobj = xref->fetch(pageref->num, pageref->gen);
+#else
+ xref->fetch(pageref->num, pageref->gen, &pageobj);
+#endif
+ if (!pageobj.isDict() ||
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ (contents = pageobj.dictLookupNF("Contents")).isNull()
+#else
+ !pageobj.dictLookupNF("Contents", &contents)
+#endif
+ ) {
+ fprintf(stderr, "Error: malformed pdf\n");
+ return;
+ }
+
+ if (contents.isRef()) {
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ contents = xref->fetch(contents.getRefNum(), contents.getRefGen());
+#else
+ xref->fetch(contents.getRefNum(), contents.getRefGen(), &contents);
+#endif
+ }
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ (void) lenobj;
+ dict = Object(new Dict(xref));
+ dict.dictSet("Length", Object(static_cast<int>(len)));
+ stream = Object(static_cast<Stream *>(new MemStream(buf, 0, len, std::move(dict))));
+#else
+ lenobj.initInt(len);
+ dict.initDict(xref);
+ dict.dictSet("Length", &lenobj);
+ stream.initStream(new MemStream(buf, 0, len, &dict));
+#endif
+
+ r = xref->addIndirectObject(&stream);
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ streamrefobj = Object(r.num, r.gen);
+#else
+ streamrefobj.initRef(r.num, r.gen);
+#endif
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ array = Object(new Array(xref));
+ array.arrayAdd(std::move(streamrefobj));
+#else
+ array.initArray(xref);
+ array.arrayAdd(&streamrefobj);
+#endif
+
+ if (contents.isStream()) {
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ contents = pageobj.dictLookupNF("Contents"); // streams must be indirect, i.e. not fetch()-ed
+ array.arrayAdd(std::move(contents));
+#else
+ pageobj.dictLookupNF("Contents", &contents); // streams must be indirect, i.e. not fetch()-ed
+ array.arrayAdd(&contents);
+#endif
+ }
+ else if (contents.isArray()) {
+ int i, len = contents.arrayGetLength();
+ Object obj;
+ for (i = 0; i < len; i++) {
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ obj = contents.arrayGetNF(i);
+ array.arrayAdd(std::move(obj));
+#else
+ contents.arrayGetNF(i, &obj);
+ array.arrayAdd(&obj);
+#endif
+ }
+ }
+ else
+ fprintf(stderr, "Error: malformed pdf\n");
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ pageobj.dictSet("Contents", std::move(array));
+#else
+ pageobj.dictSet("Contents", &array);
+#endif
+
+ xref->setModifiedObject(&pageobj, *pageref);
+#if POPPLER_VERSION_MAJOR <= 0 && POPPLER_VERSION_MINOR < 58
+ pageobj.free();
+#endif
+}
+
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+static Object name_object(const char *s)
+{
+ return Object(new GooString(s));
+}
+#else
+static Object * name_object(const char *s)
+{
+ Object *o = new Object();
+ o->initName((char *)s);
+ return o;
+}
+#endif
+
+/*
+ * Create new PDF integer type object.
+ */
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+static Object int_object(int i)
+{
+ return Object(i);
+}
+#else
+static Object * int_object(int i)
+{
+ Object *o = new Object();
+ o->initInt(i);
+ return o;
+}
+#endif
+
+static Object * get_resource_dict(XRef *xref,
+ Dict *pagedict,
+ Object *resdict,
+ Ref *resref)
+{
+ Object res;
+
+ /* TODO resource dict can also be inherited */
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ res = pagedict->lookupNF("Resources");
+ if (res.isNull())
+#else
+ if (!pagedict->lookupNF("Resources", &res))
+#endif
+ return NULL;
+
+ if (res.isRef()) {
+ *resref = res.getRef();
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ *resdict = xref->fetch(resref->num, resref->gen);
+#else
+ xref->fetch(resref->num, resref->gen, resdict);
+#endif
+ }
+ else if (res.isDict()) {
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ *resdict = res.copy();
+#else
+ res.copy(resdict);
+#endif
+ resref->num = 0;
+ }
+ else
+ resdict = NULL;
+
+#if POPPLER_VERSION_MAJOR <= 0 && POPPLER_VERSION_MINOR < 58
+ res.free();
+#endif
+ return resdict;
+}
+
+
+extern "C" void pdf_add_type1_font(pdf_t *doc,
+ int page,
+ const char *name)
+{
+ XRef *xref = doc->getXRef();
+ Ref *pageref = doc->getCatalog()->getPageRef(page);
+ Object pageobj, font, fonts;
+
+ Object resdict;
+ Ref resref;
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ pageobj = xref->fetch(pageref->num, pageref->gen);
+#else
+ xref->fetch(pageref->num, pageref->gen, &pageobj);
+#endif
+ if (!pageobj.isDict()) {
+ fprintf(stderr, "Error: malformed pdf\n");
+ return;
+ }
+
+ if (!get_resource_dict(xref, pageobj.getDict(), &resdict, &resref)) {
+ fprintf(stderr, "Error: malformed pdf\n");
+#if POPPLER_VERSION_MAJOR <= 0 && POPPLER_VERSION_MINOR < 58
+ pageobj.free();
+#endif
+ return;
+ }
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ font = Object(new Dict(xref));
+#else
+ font.initDict(xref);
+#endif
+ font.dictSet("Type", name_object("Font"));
+ font.dictSet("Subtype", name_object("Type1"));
+ font.dictSet("BaseFont", name_object(name));
+ xref->addIndirectObject(&font);
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ fonts = resdict.dictLookupNF("Font");
+#else
+ resdict.dictLookupNF("Font", &fonts);
+#endif
+ if (fonts.isNull()) {
+ /* Create new font dic obj in page's resources */
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ resdict.dictSet("Font", Object(new Dict(xref)));
+#else
+ fonts.initDict(xref);
+ resdict.dictSet("Font", &fonts);
+#endif
+ }
+
+ Object *fonts_dic;
+ Object dereferenced_obj;
+
+ if ( fonts.isDict() ) {
+ /* "Font" resource is dictionary object */
+ fonts_dic = &fonts;
+ } else if ( fonts.isRef() ) {
+ /* "Font" resource is indirect reference object */
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ dereferenced_obj = xref->fetch(fonts.getRefNum(), fonts.getRefGen());
+#else
+ xref->fetch(fonts.getRefNum(), fonts.getRefGen(), &dereferenced_obj);
+#endif
+ fonts_dic = &dereferenced_obj;
+ }
+
+ if ( ! fonts_dic->isDict() ) {
+ fprintf(stderr, "Can't recognize Font resource in PDF template.\n");
+ return;
+ }
+
+ /* Add new entry to "Font" resource */
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ fonts_dic->dictSet("bannertopdf-font", std::move(font));
+#else
+ fonts_dic->dictSet("bannertopdf-font", &font);
+#endif
+
+ /* Notify poppler about changes */
+ if ( fonts.isRef() ) {
+ xref->setModifiedObject(fonts_dic, fonts.getRef());
+ }
+
+ if (resref.num == 0)
+ xref->setModifiedObject(&pageobj, *pageref);
+ else
+ xref->setModifiedObject(&resdict, resref);
+
+#if POPPLER_VERSION_MAJOR <= 0 && POPPLER_VERSION_MINOR < 58
+ pageobj.free();
+#endif
+}
+
+
+static bool dict_lookup_rect(Object *dict,
+ const char *key,
+ float rect[4])
+{
+ Object o;
+ Array *array;
+ int i;
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ o = dict->dictLookup(key);
+ if (o.isNull())
+#else
+ if (!dict->dictLookup(key, &o))
+#endif
+ return false;
+
+ if (!o.isArray()) {
+#if POPPLER_VERSION_MAJOR <= 0 && POPPLER_VERSION_MINOR < 58
+ o.free();
+#endif
+ return false;
+ }
+
+ array = o.getArray();
+ for (i = 0; i < 4; i++) {
+ Object el;
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ el = array->get(i);
+ if (el.isNum())
+ rect[i] = el.getNum();
+#else
+ if (array->get(i, &el) && el.isNum())
+ rect[i] = el.getNum();
+ el.free();
+#endif
+ }
+
+#if POPPLER_VERSION_MAJOR <= 0 && POPPLER_VERSION_MINOR < 58
+ o.free();
+#endif
+ return i == 4;
+}
+
+
+static void dict_set_rect(XRef *xref,
+ Object *dict,
+ const char *key,
+ float rect[4])
+{
+ Object array;
+ int i;
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ array = Object(new Array(xref));
+
+ for (i = 0; i < 4; i++) {
+ array.arrayAdd(Object(static_cast<double>(rect[i])));
+ }
+
+ dict->dictSet(key, std::move(array));
+#else
+ array.initArray(xref);
+
+ for (i = 0; i < 4; i++) {
+ Object el;
+ el.initReal(rect[i]);
+ array.arrayAdd(&el);
+ }
+
+ dict->dictSet(key, &array);
+#endif
+}
+
+
+static void fit_rect(float oldrect[4],
+ float newrect[4],
+ float *scale)
+{
+ float oldwidth = oldrect[2] - oldrect[0];
+ float oldheight = oldrect[3] - oldrect[1];
+ float newwidth = newrect[2] - newrect[0];
+ float newheight = newrect[3] - newrect[1];
+
+ *scale = newwidth / oldwidth;
+ if (oldheight * *scale > newheight)
+ *scale = newheight / oldheight;
+}
+
+
+extern "C" void pdf_resize_page (pdf_t *doc,
+ int page,
+ float width,
+ float length,
+ float *scale)
+{
+ XRef *xref = doc->getXRef();
+ Ref *pageref = doc->getCatalog()->getPageRef(page);
+ Object pageobj;
+ float mediabox[4] = { 0.0, 0.0, width, length };
+ float old_mediabox[4];
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ pageobj = xref->fetch(pageref->num, pageref->gen);
+#else
+ xref->fetch(pageref->num, pageref->gen, &pageobj);
+#endif
+ if (!pageobj.isDict()) {
+ fprintf(stderr, "Error: malformed pdf\n");
+ return;
+ }
+
+ if (!dict_lookup_rect (&pageobj, "MediaBox", old_mediabox)) {
+ fprintf(stderr, "Error: pdf doesn't contain a valid mediabox\n");
+ return;
+ }
+
+ fit_rect(old_mediabox, mediabox, scale);
+
+ dict_set_rect (xref, &pageobj, "MediaBox", mediabox);
+ dict_set_rect (xref, &pageobj, "CropBox", mediabox);
+ dict_set_rect (xref, &pageobj, "TrimBox", mediabox);
+ dict_set_rect (xref, &pageobj, "ArtBox", mediabox);
+ dict_set_rect (xref, &pageobj, "BleedBox", mediabox);
+
+ xref->setModifiedObject(&pageobj, *pageref);
+#if POPPLER_VERSION_MAJOR <= 0 && POPPLER_VERSION_MINOR < 58
+ pageobj.free();
+#endif
+}
+
+
+extern "C" void pdf_duplicate_page (pdf_t *doc,
+ int pagenr,
+ int count)
+{
+ XRef *xref = doc->getXRef();
+ Ref *pageref = doc->getCatalog()->getPageRef(pagenr);
+ Object page, parentref, parent, kids, ref, countobj;
+ int i;
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ page = xref->fetch(pageref->num, pageref->gen);
+#else
+ xref->fetch(pageref->num, pageref->gen, &page);
+#endif
+ if (!page.isDict("Page")) {
+ fprintf(stderr, "Error: malformed pdf (invalid Page object)\n");
+ return;
+ }
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ parentref = page.dictLookupNF("Parent");
+ parent = parentref.fetch(xref);
+#else
+ page.dictLookupNF("Parent", &parentref);
+ parentref.fetch(xref, &parent);
+#endif
+ if (!parent.isDict("Pages")) {
+ fprintf(stderr, "Error: malformed pdf (Page.Parent must point to a "
+ "Pages object)\n");
+ return;
+ }
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ kids = parent.dictLookup("Kids");
+#else
+ parent.dictLookup("Kids", &kids);
+#endif
+ if (!kids.isArray()) {
+ fprintf(stderr, "Error: malformed pdf (Pages.Kids must be an array)\n");
+ return;
+ }
+
+ // Since we're dealing with single page pdfs, simply append the same page
+ // object to the end of the array
+ // Note: We must make a (shallow) copy of the page object to avoid loops in
+ // the pages tree (not supported by major pdf implementations).
+ for (i = 1; i < count; i++) {
+ Ref r = xref->addIndirectObject(&page);
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ kids.arrayAdd(Object(r.num, r.gen));
+#else
+ ref.initRef(r.num, r.gen);
+ kids.arrayAdd(&ref);
+ ref.free();
+#endif
+ }
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ parent.dictSet("Count", Object(count));
+#else
+ countobj.initInt(count);
+ parent.dictSet("Count", &countobj);
+ countobj.free();
+#endif
+
+ xref->setModifiedObject(&parent, parentref.getRef());
+}
+
+
+class NonSeekableFileOutStream: public OutStream
+{
+public:
+ NonSeekableFileOutStream(FILE *f):
+ file(f), pos(0)
+ {
+ }
+
+ void close()
+ {
+ }
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 23
+ Goffset getPos()
+#else
+ int getPos()
+#endif
+ {
+ return this->pos;
+ }
+
+ void put(char c)
+ {
+ fputc(c, this->file);
+ this->pos++;
+ }
+
+ void printf(const char *fmt, ...)
+ {
+ va_list args;
+ va_start(args, fmt);
+ this->pos += vfprintf(this->file, fmt, args);
+ va_end(args);
+ }
+
+private:
+ FILE *file;
+ int pos;
+};
+
+
+extern "C" void pdf_write(pdf_t *doc,
+ FILE *file)
+{
+ NonSeekableFileOutStream outs(file);
+ doc->saveAs(&outs, writeForceRewrite);
+}
+
+/*
+ * Get value according to key.
+ */
+const char *lookup_opt(opt_t *opt, const char *key) {
+ if ( ! opt || ! key ) {
+ return NULL;
+ }
+
+ while (opt) {
+ if (opt->key && opt->val) {
+ if ( strcmp(opt->key, key) == 0 ) {
+ return opt->val;
+ }
+ }
+ opt = opt->next;
+ }
+
+ return NULL;
+}
+
+/*
+ * 1. Lookup in PDF template file for form.
+ * 2. Lookup for form fields' names.
+ * 3. Fill recognized fields with information.
+ */
+extern "C" int pdf_fill_form(pdf_t *doc, opt_t *opt)
+{
+ XRef *xref = doc->getXRef();
+ Catalog *catalog = doc->getCatalog();
+ Catalog::FormType form_type = catalog->getFormType();
+ if ( form_type == Catalog::NoForm ) {
+ fprintf(stderr, "PDF template file doesn't have form. It's okay.\n");
+ return 0;
+ }
+
+ Page *page = catalog->getPage(1);
+ if ( !page ) {
+ fprintf(stderr, "Can't get page from PDF tamplate file.\n");
+ return 0;
+ }
+ Object pageobj;
+ Ref pageref = page->getRef();
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ pageobj = xref->fetch(pageref.num, pageref.gen);
+#else
+ xref->fetch(pageref.num, pageref.gen, &pageobj);
+#endif
+
+ const char *font_size = lookup_opt(opt, "banner-font-size");
+ if ( ! font_size ) {
+ /* Font size isn't specified use next one. */
+ font_size = "14";
+ }
+
+ /* Embed font into PDF */
+ const char *font = lookup_opt(opt, "banner-font");
+ if ( ! font ) {
+ /* Font isn't specified use next one. */
+ font = "FreeMono";
+ }
+ int res = pdf_embed_font(doc, page, font);
+ if ( ! res ) {
+ fprintf(stderr, "Can't integrate %s font into PDF file.\n", font);
+ return 0;
+ }
+
+ /* Page's resources dictionary */
+ Object resdict;
+ Ref resref;
+
+ get_resource_dict(xref, pageobj.getDict(), &resdict, &resref);
+
+ FormPageWidgets *widgets = page->getFormWidgets();
+ if ( !widgets ) {
+ fprintf(stderr, "Can't get page's widgets.\n");
+ return 0;
+ }
+ int num_widgets = widgets->getNumWidgets();
+
+ /* Go through widgets and fill them as necessary */
+ for (int i=0; i < num_widgets; ++i)
+ {
+ FormWidget *fm = widgets->getWidget(i);
+
+ /* Take into consideration only Text widgets */
+ if ( fm->getType() != formText ) {
+ continue;
+ }
+
+ FormWidgetText *fm_text = static_cast<FormWidgetText*>(fm);
+
+ /* Ignore R/O widget */
+ if ( fm_text->isReadOnly() ) {
+ continue;
+ }
+
+ FormField *ff = fm_text->getField();
+ GooString *field_name;
+ field_name = ff->getFullyQualifiedName();
+ if ( ! field_name )
+ field_name = ff->getPartialName();
+ if ( ! field_name ) {
+ fprintf(stderr, "Ignore widget #%d (unknown name)\n", i);
+ continue;
+ }
+
+ const char *name = field_name->getCString();
+ const char *fill_with = lookup_opt(opt, name);
+ if ( ! fill_with ) {
+ fprintf(stderr, "Lack information for widget: %s.\n", name);
+ fill_with = "N/A";
+ }
+
+ fprintf(stderr, "Fill widget name %s with value %s.\n", name, fill_with);
+
+ unsigned short *fill_with_w;
+ int len = utf8_to_utf16(fill_with, &fill_with_w);
+ if ( !len ) {
+ fprintf(stderr, "Bad data for widget: %s.\n", name);
+ continue;
+ }
+
+ GooString *content = new GooString((char*)fill_with_w, len);
+ fm_text->setContent(content);
+
+ /* Object for form field */
+ Object *field_obj = ff->getObj();
+ Ref field_ref = ff->getRef();
+
+ /* Construct appearance object in form of: "/stanv_font 12 Tf" */
+ GooString *appearance = new GooString();
+ appearance->append("/stanv_font ");
+ appearance->append(font_size);
+ appearance->append(" Tf");
+
+ /* Modify field's appearance */
+ Object appearance_obj;
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ field_obj->getDict()->set("DA", Object(appearance));
+#else
+ appearance_obj.initString(appearance);
+ field_obj->getDict()->set("DA", &appearance_obj);
+#endif
+
+ /*
+ * Create /AP - entry stuff.
+ * This is right way to display characters other then Latin1
+ */
+
+ /* UTF8 '/0' ending string */
+ const char *ptr_text = fill_with;
+
+ GooString *ap_text = new GooString("<");
+ while ( *ptr_text ) {
+ int unicode;
+ /* Get next character in Unicode */
+ ptr_text = get_next_wide(ptr_text, &unicode);
+ const unsigned short gid = emb_get(Font, unicode);
+ char text[5];
+ memset(text, 0, sizeof(text));
+ sprintf(text,"%04x", gid);
+ ap_text->append(text, 4);
+ }
+ ap_text->append("> Tj\n");
+
+ /* Create empty string for stream */
+ GooString *appearance_stream = new GooString();
+
+ /* Orde has matter */
+ appearance_stream->append("/Tx BMC \n");
+ appearance_stream->append("BT\n"); // Begin text object
+ appearance_stream->append("/stanv_font ");
+ appearance_stream->append(font_size);
+ appearance_stream->append(" Tf\n");
+ appearance_stream->append("2 12.763 Td\n");
+ appearance_stream->append(ap_text);
+ appearance_stream->append("ET\n");
+ appearance_stream->append("EMC\n");
+
+ Object appearance_stream_dic;
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ appearance_stream_dic = Object(new Dict(xref));
+#else
+ appearance_stream_dic.initDict(xref);
+#endif
+
+ /*
+ * Appearance stream dic.
+ * See: 4.9 Form XObjects
+ * TABLE 4.41 Additional entries specific to a type 1 form dictionary
+ */
+ appearance_stream_dic.dictSet("Type", name_object("XObject"));
+ appearance_stream_dic.dictSet("Subtype", name_object("Form"));
+ appearance_stream_dic.dictSet("FormType", int_object(1));
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ appearance_stream_dic.dictSet("Resources", Object(resref.num, resref.gen));
+#else
+ Object obj_ref_x;
+ obj_ref_x.initRef(resref.num, resref.gen);
+ appearance_stream_dic.dictSet("Resources", &obj_ref_x);
+#endif
+
+ /* BBox array: TODO. currently out of the head. */
+ Object array;
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ array = Object(new Array(xref));
+ array.arrayAdd(Object(0.0));
+ array.arrayAdd(Object(0.0));
+ array.arrayAdd(Object(237.0));
+ array.arrayAdd(Object(25.0));
+
+ appearance_stream_dic.dictSet("BBox", std::move(array));
+ appearance_stream_dic.dictSet("Length", Object(appearance_stream->getLength()));
+
+ MemStream *mem_stream = new MemStream(appearance_stream->getCString(),
+ 0, appearance_stream->getLength(), std::move(appearance_stream_dic));
+
+ /* Make obj stream */
+ Object stream = Object(static_cast<Stream *>(mem_stream));
+
+ Ref r = xref->addIndirectObject(&stream);
+
+ /* Update Xref table */
+ Object obj_ref = Object(r.num, r.gen);
+
+ /*
+ * Fill Annotation's appearance streams dic /AP
+ * See: 8.4.4 Appearance Streams
+ */
+ Object appearance_streams_dic = Object(new Dict(xref));
+ appearance_streams_dic.dictSet("N", std::move(obj_ref));
+
+ field_obj->getDict()->set("AP", std::move(appearance_streams_dic));
+#else
+ array.initArray(xref);
+ Object el;
+ el.initReal(0);
+ array.arrayAdd(&el);
+ el.initReal(0);
+ array.arrayAdd(&el);
+ el.initReal(237);
+ array.arrayAdd(&el);
+ el.initReal(25);
+ array.arrayAdd(&el);
+ appearance_stream_dic.dictSet("BBox", &array);
+ appearance_stream_dic.dictSet("Length", int_object(appearance_stream->getLength()));
+
+ MemStream *mem_stream = new MemStream(appearance_stream->getCString(),
+ 0, appearance_stream->getLength(), &appearance_stream_dic);
+
+ /* Make obj stream */
+ Object stream;
+ stream.initStream(mem_stream);
+
+ Ref r;
+ r = xref->addIndirectObject(&stream);
+
+ /* Update Xref table */
+ Object obj_ref;
+ obj_ref.initRef(r.num, r.gen);
+
+ /*
+ * Fill Annotation's appearance streams dic /AP
+ * See: 8.4.4 Appearance Streams
+ */
+ Object appearance_streams_dic;
+ appearance_streams_dic.initDict(xref);
+ appearance_streams_dic.dictSet("N", &obj_ref);
+
+ field_obj->getDict()->set("AP", &appearance_streams_dic);
+#endif
+
+ /* Notify poppler about changes */
+ xref->setModifiedObject(field_obj, field_ref);
+ }
+
+ /*
+ * Adjust form's NeedAppearances flag.
+ * We need to fill form's fields with specified font.
+ * The right way to this is via /AP.
+ *
+ * false - is default value for PDF. See:
+ * PDFReference.pdf - table 8.47 Entries in the interactive form dictionary
+ *
+ * OpenOffice - by default sets it to 'true'.
+ */
+ Object *obj_form = catalog->getAcroForm();
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ obj_form->dictSet("NeedAppearances", Object(gFalse));
+#else
+ Object obj1;
+ obj1.initBool(gFalse);
+ obj_form->dictSet("NeedAppearances", &obj1);
+#endif
+
+ /* Add AccroForm as indirect obj */
+ Ref ref_form = xref->addIndirectObject(obj_form);
+
+ /*
+ * So update Catalog object.
+ */
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ Object catObj = xref->getCatalog();
+#else
+ Object* catObj = new Object();
+ catObj = xref->getCatalog(catObj);
+#endif
+ Ref catRef;
+ catRef.gen = xref->getRootGen();
+ catRef.num = xref->getRootNum();
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ catObj.dictSet("AcroForm", Object(ref_form.num, ref_form.gen));
+ xref->setModifiedObject(&catObj, catRef);
+#else
+ Object obj2;
+ obj2.initRef(ref_form.num, ref_form.gen);
+ catObj->dictSet("AcroForm", &obj2);
+ xref->setModifiedObject(catObj, catRef);
+#endif
+
+ /* Success */
+ return 1;
+}
+
+/* Embeded font into PDF */
+static int pdf_embed_font(pdf_t *doc,
+ Page *page,
+ const char *typeface) {
+
+ /* Load font using libfontconfig */
+ Font = get_font(typeface);
+ if ( ! Font ) {
+ fprintf(stderr, "Can't load font: %s\n", typeface);
+ return 0;
+ }
+
+ /* Font's description */
+ EMB_PDF_FONTDESCR *Fdes = emb_pdf_fontdescr(Font);
+ if ( ! Fdes ) {
+ return 0;
+ }
+
+ /* Font's widths description */
+ EMB_PDF_FONTWIDTHS *Fwid=emb_pdf_fontwidths(Font);
+ if ( ! Fwid ) {
+ return 0;
+ }
+
+ /* Create empty string for stream */
+ GooString *font_stream = new GooString();
+
+ /* Fill stream */
+ const int outlen = emb_embed(Font, fill_font_stream, font_stream);
+ assert( font_stream->getLength() == outlen );
+
+ /* Get XREF table */
+ XRef *xref = doc->getXRef();
+
+ /* Font dictionary object for embeded font */
+ Object f_dic;
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ f_dic = Object(new Dict(xref));
+#else
+ f_dic.initDict(xref);
+#endif
+ f_dic.dictSet("Type", name_object("Font"));
+
+ /* Stream lenght */
+ f_dic.dictSet("Length", int_object(outlen));
+
+ /* Lenght for EMB_FMT_TTF font type */
+ if ( Font->outtype == EMB_FMT_TTF ) {
+ f_dic.dictSet("Length1", int_object(outlen));
+ }
+
+ /* Add font subtype */
+ const char *subtype = emb_pdf_get_fontfile_subtype(Font);
+ if ( subtype ) {
+ f_dic.dictSet("Subtype", name_object(copyString(subtype)));
+ }
+
+ /* Create memory stream font. Add it to font dic. */
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ MemStream *mem_stream = new MemStream(font_stream->getCString(),
+ 0, outlen, std::move(f_dic));
+ Object stream = Object(static_cast<Stream *>(mem_stream));
+#else
+ MemStream *mem_stream = new MemStream(font_stream->getCString(),
+ 0, outlen, &f_dic);
+
+ /* Make obj stream */
+ Object stream;
+ stream.initStream(mem_stream);
+#endif
+
+ Ref r;
+
+ /* Update Xref table */
+ r = xref->addIndirectObject(&stream);
+
+ /* Get page object */
+ Object pageobj;
+ Ref pageref = page->getRef();
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ pageobj = xref->fetch(pageref.num, pageref.gen);
+#else
+ xref->fetch(pageref.num, pageref.gen, &pageobj);
+#endif
+ if (!pageobj.isDict()) {
+ fprintf(stderr, "Error: malformed pdf.\n");
+ return 0;
+ }
+
+ /* Page's resources dictionary */
+ Object resdict;
+ Ref resref;
+ Object *ret = get_resource_dict(xref, pageobj.getDict(), &resdict, &resref);
+ if ( !ret ) {
+ fprintf(stderr, "Error: malformed pdf\n");
+#if POPPLER_VERSION_MAJOR <= 0 && POPPLER_VERSION_MINOR < 58
+ pageobj.free();
+#endif
+ return 0;
+ }
+
+ /* Dictionary for all fonts in page's resources */
+ Object fonts;
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ fonts = resdict.dictLookupNF("Font");
+#else
+ resdict.dictLookupNF("Font", &fonts);
+#endif
+ if (fonts.isNull()) {
+ /* Create new one, if doesn't exists */
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ resdict.dictSet("Font", Object(new Dict(xref)));
+ fonts = resdict.dictLookupNF("Font");
+#else
+ fonts.initDict(xref);
+ resdict.dictSet("Font", &fonts);
+#endif
+ fprintf(stderr, "Create new font dict in page's resources.\n");
+ }
+
+ /*
+ * For embeded font there are 4 inderect objects and 4 reference obj.
+ * Each next point to previsious one.
+ * Last one object goes to Font dic.
+ *
+ * 1. Font stream obj + reference obj
+ * 2. FontDescriptor obj + reference obj
+ * 3. Width resource obj + reference obj
+ * 4. Multibyte resourcse obj + reference obj
+ *
+ */
+
+ /* r - indirect object refrence to dict with stream */
+ Object *font_desc_resource_dic = make_fontdescriptor_dic(doc, Font, Fdes, r);
+ r = xref->addIndirectObject(font_desc_resource_dic);
+
+ /* r - indirect object reference to dict font descriptor resource */
+ Object *font_resource_dic = make_font_dic(doc, Font, Fdes, Fwid, r);
+ r = xref->addIndirectObject(font_resource_dic);
+
+ /* r - widths resource dic */
+ Object *cidfont_resource_dic = make_cidfont_dic(doc, Font, Fdes->fontname, r);
+ r = xref->addIndirectObject(cidfont_resource_dic);
+
+ /* r - cid resource dic */
+ Object font_res_obj_ref;
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ font_res_obj_ref = Object(r.num, r.gen);
+#else
+ font_res_obj_ref.initRef(r.num, r.gen);
+#endif
+
+ Object *fonts_dic;
+ Object dereferenced_obj;
+
+ if ( fonts.isDict() ) {
+ /* "Font" resource is dictionary object */
+ fonts_dic = &fonts;
+ } else if ( fonts.isRef() ) {
+ /* "Font" resource is indirect reference object */
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ dereferenced_obj = xref->fetch(fonts.getRefNum(), fonts.getRefGen());
+#else
+ xref->fetch(fonts.getRefNum(), fonts.getRefGen(), &dereferenced_obj);
+#endif
+ fonts_dic = &dereferenced_obj;
+ }
+
+ if ( ! fonts_dic->isDict() ) {
+ fprintf(stderr, "Can't recognize Font resource in PDF template.\n");
+ return 0;
+ }
+
+ /* Add to fonts dic new font */
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ fonts_dic->dictSet("stanv_font", std::move(font_res_obj_ref));
+#else
+ fonts_dic->dictSet("stanv_font", &font_res_obj_ref);
+#endif
+
+ /* Notify poppler about changes in fonts dic */
+ if ( fonts.isRef() ) {
+ xref->setModifiedObject(fonts_dic, fonts.getRef());
+ }
+
+ /* Notify poppler about changes in resources dic */
+ xref->setModifiedObject(&resdict, resref);
+ fprintf(stderr, "Resource dict was changed.\n");
+
+#if POPPLER_VERSION_MAJOR <= 0 && POPPLER_VERSION_MINOR < 58
+ pageobj.free();
+#endif
+
+ /* Success */
+ return 1;
+}
+
+/*
+ * Call-back function to fill font stream object.
+ */
+static void fill_font_stream(const char *buf, int len, void *context)
+{
+ GooString *s = (GooString *)context;
+ s->append(buf, len);
+}
+
+/*
+ * Use libfontconfig to pick up suitable font.
+ * Memory should be freed.
+ * XXX: doesn't work correctly. Need to do some revise.
+ */
+static char *get_font_libfontconfig(const char *font) {
+ FcPattern *pattern = NULL;
+ FcFontSet *candidates = NULL;
+ FcChar8* found_font = NULL;
+ FcResult result;
+
+ FcInit ();
+ pattern = FcNameParse ((const FcChar8 *)font);
+
+ /* guide fc, in case substitution becomes necessary */
+ FcPatternAddInteger (pattern, FC_SPACING, FC_MONO);
+ FcConfigSubstitute (0, pattern, FcMatchPattern);
+ FcDefaultSubstitute (pattern);
+
+ /* Receive a sorted list of fonts matching our pattern */
+ candidates = FcFontSort (0, pattern, FcFalse, 0, &result);
+ FcPatternDestroy (pattern);
+
+ /* In the list of fonts returned by FcFontSort()
+ find the first one that is both in TrueType format and monospaced */
+ for (int i = 0; i < candidates->nfont; i++) {
+
+ /* TODO? or just try? */
+ FcChar8 *fontformat=NULL;
+
+ /* sane default, as FC_MONO == 100 */
+ int spacing=0;
+ FcPatternGetString(
+ candidates->fonts[i],
+ FC_FONTFORMAT,
+ 0,
+ &fontformat);
+
+ FcPatternGetInteger(
+ candidates->fonts[i],
+ FC_SPACING,
+ 0,
+ &spacing);
+
+ if ( (fontformat) && (spacing == FC_MONO) ) {
+ if (strcmp((const char *)fontformat, "TrueType") == 0) {
+ found_font = FcPatternFormat (
+ candidates->fonts[i],
+ (const FcChar8 *)"%{file|cescape}/%{index}");
+
+ /* Don't take into consideration remain candidates */
+ break;
+ } else if (strcmp((const char *)fontformat, "CFF") == 0) {
+
+ /* TTC only possible with non-cff glyphs! */
+ found_font = FcPatternFormat (
+ candidates->fonts[i],
+ (const FcChar8 *)"%{file|cescape}");
+
+ /* Don't take into consideration remain candidates */
+ break;
+ }
+ }
+ }
+
+ FcFontSetDestroy (candidates);
+
+ if ( ! found_font ) {
+ fprintf(stderr,"No viable font found\n");
+ return NULL;
+ }
+
+ return (char *)found_font;
+}
+
+/*
+ * Load font file using fontembed file.
+ * Test for requirements.
+ */
+static EMB_PARAMS *load_font(const char *font) {
+ assert(font);
+
+ OTF_FILE *otf;
+ otf = otf_load(font);
+ if ( ! otf ) {
+ return NULL;
+ }
+
+ FONTFILE *ff=fontfile_open_sfnt(otf);
+ if ( ! ff ) {
+ return NULL;
+ }
+
+ EMB_PARAMS *emb=emb_new(ff,
+ EMB_DEST_PDF16,
+ static_cast<EMB_CONSTRAINTS>( /* bad fontembed */
+ EMB_C_FORCE_MULTIBYTE|
+ EMB_C_TAKE_FONTFILE|
+ EMB_C_NEVER_SUBSET));
+ if ( ! emb ) {
+ return NULL;
+ }
+
+ if ( ! (emb->plan & EMB_A_MULTIBYTE) ) {
+ return NULL;
+ }
+
+ EMB_PDF_FONTDESCR *fdes=emb_pdf_fontdescr(emb);
+ if ( ! fdes ) {
+ return NULL;
+ }
+
+ /* Success */
+ return emb;
+}
+
+/*
+ * Return fontembed library object that corresponds requirements.
+ */
+static EMB_PARAMS *get_font(const char *font)
+{
+ assert(font);
+
+ char *fontname = NULL;
+ EMB_PARAMS *emb = NULL;
+
+ /* Font file specified. */
+ if ( (font[0]=='/') || (font[0]=='.') ) {
+ fontname = strdup(font);
+ emb = load_font(fontname);
+ }
+
+ /* Use libfontconfig. */
+ if ( ! emb ) {
+ fontname = get_font_libfontconfig(font);
+ emb = load_font(fontname);
+ }
+
+ free(fontname);
+
+ return emb;
+}
+
+/*
+ * Was taken from ./fontembed/embed_pdf.c
+ */
+static const char *emb_pdf_escape_name(const char *name, int len)
+{
+ assert(name);
+ if (len==-1) {
+ len=strlen(name);
+ }
+
+ /* PDF implementation limit */
+ assert(len<=127);
+
+ static char buf[128*3];
+ int iA,iB;
+ const char hex[]="0123456789abcdef";
+
+ for (iA=0,iB=0;iA<len;iA++,iB++) {
+ if ( ((unsigned char)name[iA]<33)||((unsigned char)name[iA]>126)||
+ (strchr("#()<>[]{}/%",name[iA])) ) {
+ buf[iB]='#';
+ buf[++iB]=hex[(name[iA]>>4)&0x0f];
+ buf[++iB]=hex[name[iA]&0xf];
+ } else {
+ buf[iB]=name[iA];
+ }
+ }
+ buf[iB]=0;
+ return buf;
+}
+
+/*
+ * Construct font description dictionary.
+ * Translated to Poppler function emb_pdf_simple_fontdescr() from
+ * cups-filters/fontembed/embed_pdf.c
+ */
+static Object *make_fontdescriptor_dic(
+ pdf_t *doc,
+ EMB_PARAMS *emb,
+ EMB_PDF_FONTDESCR *fdes,
+ Ref fontfile_obj_ref)
+{
+ assert(emb);
+ assert(fdes);
+
+ /* Get XREF table */
+ XRef *xref = doc->getXRef();
+
+ /* Font dictionary for embeded font */
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ Object *dic = new Object(new Dict(xref));
+#else
+ Object *dic = new Object();
+ dic->initDict(xref);
+#endif
+
+ dic->dictSet("Type", name_object("FontDescriptor"));
+ dic->dictSet(
+ "FontName",
+ name_object(copyString(emb_pdf_escape_name(fdes->fontname,-1))));
+ dic->dictSet("Flags", int_object(fdes->flags));
+ dic->dictSet("ItalicAngle", int_object(fdes->italicAngle));
+ dic->dictSet("Ascent", int_object(fdes->ascent));
+ dic->dictSet("Descent", int_object(fdes->descent));
+ dic->dictSet("CapHeight", int_object(fdes->capHeight));
+ dic->dictSet("StemV", int_object(fdes->stemV));
+
+ /* FontBox array */
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ Object array = Object(new Array(xref));
+ array.arrayAdd(Object(static_cast<double>(fdes->bbxmin)));
+ array.arrayAdd(Object(static_cast<double>(fdes->bbymin)));
+ array.arrayAdd(Object(static_cast<double>(fdes->bbxmax)));
+ array.arrayAdd(Object(static_cast<double>(fdes->bbymax)));
+
+ dic->dictSet("FontBBox", std::move(array));
+#else
+ Object array;
+ array.initArray(xref);
+
+ Object el;
+
+ el.initReal(fdes->bbxmin);
+ array.arrayAdd(&el);
+
+ el.initReal(fdes->bbymin);
+ array.arrayAdd(&el);
+
+ el.initReal(fdes->bbxmax);
+ array.arrayAdd(&el);
+
+ el.initReal(fdes->bbymax);
+ array.arrayAdd(&el);
+
+ dic->dictSet("FontBBox", &array);
+#endif
+
+ if (fdes->xHeight) {
+ dic->dictSet("XHeight", int_object(fdes->xHeight));
+ }
+
+ if (fdes->avgWidth) {
+ dic->dictSet("AvgWidth", int_object(fdes->avgWidth));
+ }
+
+ if (fdes->panose) {
+ /* Font dictionary for embeded font */
+ Object style_dic;
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ style_dic = Object(new Dict(xref));
+#else
+ style_dic.initDict(xref);
+#endif
+
+ GooString *panose_str = new GooString(fdes->panose, 12);
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ style_dic.dictSet("Panose", Object(panose_str));
+
+ dic->dictSet("Style", std::move(style_dic));
+#else
+ Object panose;
+
+ panose.initString(panose_str);
+ style_dic.dictSet("Panose", &panose);
+
+ dic->dictSet("Style", &style_dic);
+#endif
+ }
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ dic->dictSet(emb_pdf_get_fontfile_key(emb), Object(fontfile_obj_ref.num, fontfile_obj_ref.gen));
+#else
+ Object ref_obj;
+ ref_obj.initRef(fontfile_obj_ref.num, fontfile_obj_ref.gen);
+ dic->dictSet(emb_pdf_get_fontfile_key(emb), &ref_obj);
+#endif
+
+ return dic;
+}
+
+static Object *make_font_dic(
+ pdf_t *doc,
+ EMB_PARAMS *emb,
+ EMB_PDF_FONTDESCR *fdes,
+ EMB_PDF_FONTWIDTHS *fwid,
+ Ref fontdescriptor_obj_ref)
+{
+ assert(emb);
+ assert(fdes);
+ assert(fwid);
+
+ /* Get XREF table */
+ XRef *xref = doc->getXRef();
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ Object *dic = new Object(new Dict(xref));
+#else
+ Object *dic = new Object();
+ dic->initDict(xref);
+#endif
+
+ dic->dictSet("Type", name_object("Font"));
+ dic->dictSet(
+ "Subtype",
+ name_object(copyString(emb_pdf_get_font_subtype(emb))));
+ dic->dictSet(
+ "BaseFont",
+ name_object(copyString(emb_pdf_escape_name(fdes->fontname,-1))));
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ dic->dictSet("FontDescriptor", Object(fontdescriptor_obj_ref.num, fontdescriptor_obj_ref.gen));
+#else
+ Object ref_obj;
+ ref_obj.initRef(fontdescriptor_obj_ref.num, fontdescriptor_obj_ref.gen);
+ dic->dictSet("FontDescriptor", &ref_obj);
+#endif
+
+ if ( emb->plan & EMB_A_MULTIBYTE ) {
+ assert(fwid->warray);
+
+ Object CIDSystemInfo_dic;
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ CIDSystemInfo_dic = Object(new Dict(xref));
+#else
+ CIDSystemInfo_dic.initDict(xref);
+#endif
+
+ Object registry;
+ Object ordering;
+
+ GooString *str;
+
+ str = new GooString(copyString(fdes->registry));
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ CIDSystemInfo_dic.dictSet("Registry", Object(str));
+#else
+ registry.initString(str);
+ CIDSystemInfo_dic.dictSet("Registry", &registry);
+#endif
+
+ str = new GooString(copyString(fdes->ordering));
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ CIDSystemInfo_dic.dictSet("Ordering", Object(str));
+#else
+ ordering.initString(str);
+ CIDSystemInfo_dic.dictSet("Ordering", &ordering);
+#endif
+
+ CIDSystemInfo_dic.dictSet("Supplement", int_object(fdes->supplement));
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ dic->dictSet("CIDSystemInfo", std::move(CIDSystemInfo_dic));
+#else
+ dic->dictSet("CIDSystemInfo", &CIDSystemInfo_dic);
+#endif
+
+ dic->dictSet("DW", int_object(fwid->default_width));
+ }
+
+ return dic;
+}
+
+
+static Object *make_cidfont_dic(
+ pdf_t *doc,
+ EMB_PARAMS *emb,
+ const char *fontname,
+ Ref fontdescriptor_obj_ref)
+{
+ assert(emb);
+ assert(fontname);
+
+ /*
+ * For CFF: one of:
+ * UniGB-UCS2-H, UniCNS-UCS2-H, UniJIS-UCS2-H, UniKS-UCS2-H
+ */
+ const char *encoding="Identity-H";
+ const char *addenc="-";
+
+ if ( emb->outtype == EMB_FMT_TTF ) { // !=CidType0
+ addenc="";
+ }
+
+ /* Get XREF table */
+ XRef *xref = doc->getXRef();
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ Object *dic = new Object(new Dict(xref));
+#else
+ Object *dic = new Object();
+ dic->initDict(xref);
+#endif
+
+ dic->dictSet("Type", name_object("Font"));
+ dic->dictSet("Subtype", name_object("Type0"));
+
+
+ GooString * basefont = new GooString();
+ basefont->append(emb_pdf_escape_name(fontname,-1));
+ basefont->append(addenc);
+ basefont->append((addenc[0])?encoding:"");
+
+ dic->dictSet("BaseFont",
+ name_object(copyString(basefont->getCString())));
+
+ dic->dictSet("Encoding", name_object(copyString(encoding)));
+
+ Object obj;
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ obj = Object(fontdescriptor_obj_ref.num, fontdescriptor_obj_ref.gen);
+#else
+ obj.initRef(fontdescriptor_obj_ref.num, fontdescriptor_obj_ref.gen);
+#endif
+
+ Object array;
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 58
+ array = Object(new Array(xref));
+ array.arrayAdd(std::move(obj));
+
+ dic->dictSet("DescendantFonts", std::move(array));
+#else
+ array.initArray(xref);
+ array.arrayAdd(&obj);
+
+ dic->dictSet("DescendantFonts", &array);
+#endif
+
+ return dic;
+}
+
+
+/*
+ * Convert UTF8 to UTF16.
+ * Version for poppler - UTF16BE.
+ *
+ * Reference:
+ * http://stackoverflow.com/questions/7153935/how-to-convert-utf-8-stdstring-to-utf-16-stdwstring
+ */
+static int utf8_to_utf16(const char *utf8, unsigned short **out_ptr)
+{
+ unsigned long *unicode, *head;
+
+ int strl = strlen(utf8);
+
+ unicode = head = (unsigned long*) malloc(strl * sizeof(unsigned long));
+
+ if ( ! head ) {
+ fprintf(stderr,"stanv: 1\n");
+ return 0;
+ }
+
+ while (*utf8){
+ unsigned long uni;
+ size_t todo;
+ unsigned char ch = *utf8;
+
+ if (ch <= 0x7F)
+ {
+ uni = ch;
+ todo = 0;
+ }
+ else if (ch <= 0xBF)
+ {
+ /* not a UTF-8 string */
+ return 0;
+ }
+ else if (ch <= 0xDF)
+ {
+ uni = ch&0x1F;
+ todo = 1;
+ }
+ else if (ch <= 0xEF)
+ {
+ uni = ch&0x0F;
+ todo = 2;
+ }
+ else if (ch <= 0xF7)
+ {
+ uni = ch&0x07;
+ todo = 3;
+ }
+ else
+ {
+ /* not a UTF-8 string */
+ return 0;
+ }
+
+ for (size_t j = 0; j < todo; ++j)
+ {
+ utf8++;
+ if ( ! *utf8 ) {
+ /* not a UTF-8 string */
+ return 0;
+ }
+
+ unsigned char ch = *utf8;
+
+ if (ch < 0x80 || ch > 0xBF) {
+ /* not a UTF-8 string */
+ return 0;
+ }
+
+ uni <<= 6;
+ uni += ch & 0x3F;
+ }
+
+ if (uni >= 0xD800 && uni <= 0xDFFF) {
+ /* not a UTF-8 string */
+ return 0;
+ }
+
+ if (uni > 0x10FFFF) {
+ /* not a UTF-8 string */
+ return 0;
+ }
+
+ *unicode = uni;
+ unicode++;
+ utf8++;
+ }
+
+ ssize_t len = sizeof(unsigned short) * (unicode - head + 1) * 2;
+ unsigned short * out = (unsigned short *)malloc(len);
+
+ if ( ! out ) {
+ return 0;
+ }
+
+ *out_ptr = out;
+
+ while ( head != unicode ) {
+ unsigned long uni = *head;
+
+ if (uni <= 0xFFFF)
+ {
+ *out = (unsigned short)uni;
+ *out = ((0xff & uni) << 8) | ((uni & 0xff00) >> 8);
+ }
+ else
+ {
+ uni -= 0x10000;
+
+ *out += (unsigned short)((uni >> 10) + 0xD800);
+ *out = ((0xff & uni) << 8) | ((uni & 0xff00) >> 8);
+ out++;
+ *out += (unsigned short)((uni >> 10) + 0xD800);
+ *out = ((0xff & uni) << 8) | ((uni & 0xff00) >> 8);
+ }
+
+ head++;
+ out++;
+ }
+
+ return (out - *out_ptr) * sizeof (unsigned short);
+}
+
+const char *get_next_wide(const char *utf8, int *unicode_out) {
+
+ unsigned long uni;
+ size_t todo;
+
+ if ( !utf8 || !*utf8 ) {
+ return utf8;
+ }
+
+ unsigned char ch = *utf8;
+
+ *unicode_out = 0;
+
+ if (ch <= 0x7F)
+ {
+ uni = ch;
+ todo = 0;
+ }
+ else if (ch <= 0xBF)
+ {
+ /* not a UTF-8 string */
+ return utf8;
+ }
+ else if (ch <= 0xDF)
+ {
+ uni = ch&0x1F;
+ todo = 1;
+ }
+ else if (ch <= 0xEF)
+ {
+ uni = ch&0x0F;
+ todo = 2;
+ }
+ else if (ch <= 0xF7)
+ {
+ uni = ch&0x07;
+ todo = 3;
+ }
+ else
+ {
+ /* not a UTF-8 string */
+ return utf8;
+ }
+
+ for (size_t j = 0; j < todo; ++j)
+ {
+ utf8++;
+ if ( ! *utf8 ) {
+ /* not a UTF-8 string */
+ return utf8;
+ }
+
+ unsigned char ch = *utf8;
+
+ if (ch < 0x80 || ch > 0xBF) {
+ /* not a UTF-8 string */
+ return utf8;
+ }
+
+ uni <<= 6;
+ uni += ch & 0x3F;
+ }
+
+ if (uni >= 0xD800 && uni <= 0xDFFF) {
+ /* not a UTF-8 string */
+ return utf8;
+ }
+
+ if (uni > 0x10FFFF) {
+ /* not a UTF-8 string */
+ return utf8;
+ }
+
+ *unicode_out = (int)uni;
+ utf8++;
+
+ return utf8;
+}
diff --git a/filter/pdf.h b/filter/pdf.h
new file mode 100644
index 000000000..513f44f52
--- /dev/null
+++ b/filter/pdf.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2012 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef pdf_h
+#define pdf_h
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct PDFDoc pdf_t;
+
+typedef struct _opt opt_t;
+
+/*
+ * Type to bunch PDF form field name and its value.
+ */
+struct _opt {
+ const char* key;
+ const char* val;
+ opt_t *next;
+};
+
+pdf_t * pdf_load_template(const char *filename);
+void pdf_free(pdf_t *pdf);
+void pdf_write(pdf_t *doc, FILE *file);
+void pdf_prepend_stream(pdf_t *doc, int page, char *buf, size_t len);
+void pdf_add_type1_font(pdf_t *doc, int page, const char *name);
+void pdf_resize_page (pdf_t *doc, int page, float width, float length, float *scale);
+void pdf_duplicate_page (pdf_t *doc, int page, int count);
+int pdf_fill_form(pdf_t *doc, opt_t *opt);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/filter/pdftoijs.cxx b/filter/pdftoijs.cxx
new file mode 100644
index 000000000..22bc33f43
--- /dev/null
+++ b/filter/pdftoijs.cxx
@@ -0,0 +1,538 @@
+/*
+Copyright (c) 2008, BBR Inc. All rights reserved.
+ (c) 2008 Tobias Hoffmann
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+/*
+ pdftoijs.cc
+ pdf to ijs filter
+*/
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_CPP_POPPLER_VERSION_H
+#include "cpp/poppler-version.h"
+#endif
+#include <goo/GooString.h>
+#include <goo/gmem.h>
+#include <Object.h>
+#include <Stream.h>
+#include <PDFDoc.h>
+#include <SplashOutputDev.h>
+#include <cups/cups.h>
+#include <cups/ppd.h>
+#include <stdarg.h>
+#include "PDFError.h"
+#include <GlobalParams.h>
+#include <splash/SplashTypes.h>
+#include <splash/SplashBitmap.h>
+extern "C" {
+#include <ijs/ijs.h>
+#include <ijs/ijs_client.h>
+}
+#include <vector>
+#include <string>
+
+#define MAX_CHECK_COMMENT_LINES 20
+
+namespace {
+ int exitCode = 0;
+ char *outputfile = NULL;
+// int deviceCopies = 1;
+// bool deviceCollate = false;
+ const char *ijsserver = NULL;
+ int resolution[2] = {0,0};
+ enum ColEnum { NONE=-1, COL_RGB, COL_CMYK, COL_BLACK1, COL_WHITE1, COL_BLACK8, COL_WHITE8 } colspace=NONE;
+ const char *devManu=NULL, *devModel=NULL;
+ std::vector<std::pair<std::string,std::string> > params;
+
+ ppd_file_t *ppd = 0; // holds the memory for the strings
+}
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 23
+void CDECL myErrorFun(void *data, ErrorCategory category,
+ Goffset pos, char *msg)
+#else
+void CDECL myErrorFun(void *data, ErrorCategory category,
+ int pos, char *msg)
+#endif
+{
+ if (pos >= 0) {
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 23
+ fprintf(stderr, "ERROR (%lld): ", pos);
+#else
+ fprintf(stderr, "ERROR (%d): ", pos);
+#endif
+ } else {
+ fprintf(stderr, "ERROR: ");
+ }
+ fprintf(stderr, "%s\n",msg);
+ fflush(stderr);
+}
+#else
+void CDECL myErrorFun(int pos, char *msg, va_list args)
+{
+ if (pos >= 0) {
+ fprintf(stderr, "ERROR (%d): ", pos);
+ } else {
+ fprintf(stderr, "ERROR: ");
+ }
+ vfprintf(stderr, msg, args);
+ fprintf(stderr, "\n");
+ fflush(stderr);
+}
+#endif
+
+/* parse "300 400" */
+void parse_resolution(const char *str)
+{
+ const char *tmp=strchr(str,' ');
+ if (tmp) {
+ resolution[0]=atoi(str);
+ resolution[1]=atoi(tmp+1);
+ } else {
+ resolution[0]=resolution[1]=atoi(str);
+ }
+}
+
+/* parse "cmyk" "grey" "rgb" */
+void parse_colorspace(const char *str)
+{
+ if (strcasecmp(str,"rgb")==0) {
+ colspace=COL_RGB;
+ } else if (strcasecmp(str,"black1")==0) {
+ colspace=COL_BLACK1;
+ } else if (strcasecmp(str,"white1")==0) {
+ colspace=COL_WHITE1;
+ } else if (strcasecmp(str,"black8")==0) {
+ colspace=COL_BLACK8;
+ } else if (strcasecmp(str,"white8")==0) {
+ colspace=COL_WHITE8;
+#ifdef SPLASH_CMYK
+ } else if (strcasecmp(str,"cmyk")==0) {
+ colspace=COL_CMYK;
+ } else {
+ pdfError(-1,"Unknown colorspace; supported are 'rgb', 'cmyk', 'white1', 'black1', 'white8', 'black8'");
+#else
+ } else {
+ pdfError(-1,"Unknown colorspace; supported are 'rgb', 'white1', 'black1', 'white8', 'black8'");
+#endif
+ exit(1);
+ }
+}
+
+std::string str_trim(const char *str,int len)
+{
+ int start=strspn(str," \r\n\t");
+ for (len--;len>=0;len--) {
+ if (!strchr(" \r\n\t",str[len])) {
+ break;
+ }
+ }
+ len++;
+ if (start>=len) {
+ return std::string();
+ }
+ return std::string(str+start,len-start);
+}
+
+/* parse key=value */
+void parse_param(const char *str)
+{
+ const char *eq=strchr(str,'=');
+ if (!eq) {
+ fprintf(stderr, "WARNING: ignored ijsParam without '='");
+ return;
+ }
+ params.push_back(make_pair(str_trim(str,eq-str),str_trim(eq+1,strlen(eq+1))));
+}
+
+/* parse key1=value1,key2=value2,... */
+void parse_paramlist(const char *str)
+{
+ std::string tmp;
+ const char *cur=str;
+ while (*cur) {
+ tmp.clear();
+ for (;*cur;++cur) {
+ if ( (*cur=='\\')&&(cur[1]) ) {
+ ++cur;
+ tmp.push_back(*cur);
+ } else if(*cur==',') {
+ ++cur;
+ break;
+ } else {
+ tmp.push_back(*cur);
+ }
+ }
+ parse_param(tmp.c_str());
+ }
+}
+
+void parseOpts(int argc, char **argv)
+{
+ int num_options = 0;
+ cups_option_t *options = 0;
+
+ if (argc < 6 || argc > 7) {
+ pdfError(-1,"%s job-id user title copies options [file]",
+ argv[0]);
+ exit(1);
+ }
+
+ assert(!ppd);
+ ppd = ppdOpenFile(getenv("PPD"));
+ ppdMarkDefaults(ppd);
+
+ // handle *ijsServer, *ijsManufacturer, *ijsModel, *ijsColorspace
+ ppd_attr_t *attr;
+ if ((attr = ppdFindAttr(ppd,"ijsServer",0)) != 0) {
+ ijsserver=attr->value;
+ }
+ if ((attr = ppdFindAttr(ppd,"ijsManufacturer",0)) != 0) {
+ devManu=attr->value;
+ }
+ if ((attr = ppdFindAttr(ppd,"ijsModel",0)) != 0) {
+ devModel=attr->value;
+ }
+ if ((attr = ppdFindAttr(ppd,"ijsColorspace",0)) != 0) {
+ parse_colorspace(attr->value);
+ }
+ if ( (!ijsserver)||(!devManu)||(!devModel)||(colspace==NONE) ) {
+ pdfError(-1,"ijsServer, ijsManufacturer, ijsModel and ijsColorspace must be specified in the PPD");
+ exit(1);
+ }
+
+ options = NULL;
+
+ num_options = cupsParseOptions(argv[5],0,&options);
+// cupsMarkOptions(ppd,num_options,options); // TODO? returns 1 on conflict
+ // handle *ijsResolution, *ijsParam here
+ char spec[PPD_MAX_NAME];
+ for (int iA=0;iA<num_options;iA++) {
+ snprintf(spec,PPD_MAX_NAME,"%s=%s",options[iA].name,options[iA].value);
+ if ((attr = ppdFindAttr(ppd,"ijsResolution",spec)) != 0) {
+ parse_resolution(attr->value);
+ }
+ if ((attr = ppdFindAttr(ppd,"ijsParams",spec)) != 0) {
+ parse_paramlist(attr->value);
+ }
+ if (strcmp(options[iA].name,"ijsOutputFile")==0) {
+ outputfile=strdup(options[iA].value);
+ }
+ }
+ if (!resolution[0]) {
+ pdfError(-1,"ijsResolution must be specified");
+ exit(1);
+ }
+ cupsFreeOptions(num_options,options);
+}
+
+#if 0
+void parsePDFTOPDFComment(FILE *fp)
+{
+ char buf[4096];
+ int i;
+
+ /* skip until PDF start header */
+ while (fgets(buf,sizeof(buf),fp) != 0) {
+ if (strncmp(buf,"%PDF",4) == 0) {
+ break;
+ }
+ }
+ for (i = 0;i < MAX_CHECK_COMMENT_LINES;i++) {
+ if (fgets(buf,sizeof(buf),fp) == 0) break;
+ if (strncmp(buf,"%%PDFTOPDFNumCopies",19) == 0) {
+ char *p;
+
+ p = strchr(buf+19,':');
+ deviceCopies = atoi(p+1);
+ } else if (strncmp(buf,"%%PDFTOPDFCollate",17) == 0) {
+ char *p;
+
+ p = strchr(buf+17,':');
+ while (*p == ' ' || *p == '\t') p++;
+ if (strncasecmp(p,"true",4) == 0) {
+ deviceCollate = true;
+ } else {
+ deviceCollate = false;
+ }
+ }
+ }
+}
+#endif
+
+int main(int argc, char *argv[]) {
+ PDFDoc *doc;
+ SplashOutputDev *out;
+ SplashColor paperColor;
+ int i;
+ int npages;
+ IjsClientCtx *ctx=NULL;
+ int job_id;
+ enum SplashColorMode cmode;
+ int rowpad;
+ GBool reverseVideo;
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+ setErrorCallback(::myErrorFun,NULL);
+#else
+ setErrorFunction(::myErrorFun);
+#endif
+ globalParams = new GlobalParams();
+ parseOpts(argc, argv);
+
+ if (argc == 6) {
+ /* stdin */
+ int fd;
+ char name[BUFSIZ];
+ char buf[BUFSIZ];
+ int n;
+
+ fd = cupsTempFd(name,sizeof(name));
+ if (fd < 0) {
+ pdfError(-1,"Can't create temporary file");
+ exit(1);
+ }
+
+ /* copy stdin to the tmp file */
+ while ((n = read(0,buf,BUFSIZ)) > 0) {
+ if (write(fd,buf,n) != n) {
+ pdfError(-1,"Can't copy stdin to temporary file");
+ close(fd);
+ exit(1);
+ }
+ }
+ close(fd);
+ doc = new PDFDoc(new GooString(name));
+ /* remove name */
+ unlink(name);
+ } else {
+ GooString *fileName = new GooString(argv[6]);
+ /* argc == 7 filenmae is specified */
+ FILE *fp;
+
+ if ((fp = fopen(argv[6],"rb")) == 0) {
+ pdfError(-1,"Can't open input file %s",argv[6]);
+ exit(1);
+ }
+// parsePDFTOPDFComment(fp); // TODO?
+ fclose(fp);
+ doc = new PDFDoc(fileName,NULL,NULL);
+ }
+
+ if (!doc->isOk()) {
+ exitCode = 1;
+ goto err1;
+ }
+
+ char tmp[100];
+ tmp[99]=0;
+ // ... OutputFD=stdout .. needs to be done before forking
+ int outfd;
+ outfd=dup(fileno(stdout));
+
+#if 0
+ /* fix NumCopies, Collate ccording to PDFTOPDFComments */
+ header.NumCopies = deviceCopies;
+ header.Collate = deviceCollate ? CUPS_TRUE : CUPS_FALSE;
+ /* fixed other values that pdftopdf handles */
+ header.MirrorPrint = CUPS_FALSE;
+ header.Orientation = CUPS_ORIENT_0;
+#endif
+
+ job_id=atoi(argv[1]);
+ ctx = ijs_invoke_server (ijsserver);
+ ijs_client_open (ctx);
+ ijs_client_begin_job (ctx,job_id);
+ if (outputfile) {
+ ijs_client_set_param(ctx,job_id,"OutputFile",outputfile,strlen(outputfile));
+ } else {
+ snprintf(tmp,99,"%d",outfd);
+ ijs_client_set_param(ctx,job_id,"OutputFD",tmp,strlen(tmp));
+ close(outfd);
+ }
+ ijs_client_set_param(ctx,job_id,"DeviceManufacturer",devManu,strlen(devManu));
+ ijs_client_set_param(ctx,job_id,"DeviceModel",devModel,strlen(devModel));
+ // TODO: get supported output-formats from ijs-server, overriding PPD
+
+ /* set image's values */
+ int numChan,bitsPerSample;
+ const char *devName;
+ reverseVideo = gFalse;
+ switch (colspace) {
+ case COL_RGB:
+ numChan=3;
+ bitsPerSample=8;
+ cmode = splashModeRGB8;
+ devName = "DeviceRGB";
+ rowpad = 3;
+ /* set paper color white */
+ paperColor[0] = 255;
+ paperColor[1] = 255;
+ paperColor[2] = 255;
+ break;
+ case COL_BLACK1:
+ reverseVideo = gTrue;
+ case COL_WHITE1:
+ numChan=1;
+ bitsPerSample=1;
+ cmode = splashModeMono1;
+ devName = "DeviceGray";
+ /* set paper color white */
+ paperColor[0] = 255;
+ rowpad = 1;
+ break;
+ case COL_BLACK8:
+ reverseVideo = gTrue;
+ case COL_WHITE8:
+ numChan=1;
+ bitsPerSample=8;
+ cmode = splashModeMono8;
+ devName = "DeviceGray";
+ /* set paper color white */
+ paperColor[0] = 255;
+ rowpad = 1;
+ break;
+#ifdef SPLASH_CMYK
+ case COL_CMYK:
+ numChan=4;
+ bitsPerSample=8;
+ cmode = splashModeCMYK8;
+ devName = "DeviceCMYK";
+ /* set paper color white */
+ paperColor[0] = 0;
+ paperColor[1] = 0;
+ paperColor[2] = 0;
+ paperColor[3] = 0;
+ rowpad = 4;
+ break;
+#endif
+ default:
+ pdfError(-1,"Specified ColorSpace is not supported");
+ exit(1);
+ break;
+ }
+
+ out = new SplashOutputDev(cmode,rowpad/* row padding */,
+ reverseVideo,paperColor,gTrue
+#if POPPLER_VERSION_MAJOR == 0 && POPPLER_VERSION_MINOR <= 30
+ ,gFalse
+#endif
+ );
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+ out->startDoc(doc);
+#else
+ out->startDoc(doc->getXRef());
+#endif
+
+ snprintf(tmp,99,"%d",numChan);
+ ijs_client_set_param(ctx,job_id,"NumChan",tmp,strlen(tmp));
+ snprintf(tmp,99,"%d",bitsPerSample);
+ ijs_client_set_param(ctx,job_id,"BitsPerSample",tmp,strlen(tmp));
+ ijs_client_set_param(ctx,job_id,"ColorSpace",devName,strlen(devName));
+ snprintf(tmp,99,"%dx%d",resolution[0],resolution[1]);
+ ijs_client_set_param(ctx,job_id,"Dpi",tmp,strlen(tmp));
+
+ { // set the custom ijs parameters
+ const int plen=params.size();
+ for (i=0;i<plen;i++) {
+ ijs_client_set_param(ctx,job_id,params[i].first.c_str(),params[i].second.c_str(),params[i].second.size());
+ }
+ }
+
+ npages = doc->getNumPages();
+ for (i = 1;i <= npages;i++) {
+ SplashBitmap *bitmap;
+ unsigned int size;
+
+ doc->displayPage(out,i,resolution[0],resolution[1],0,gFalse,gFalse,gFalse);
+ bitmap = out->getBitmap();
+
+ /* set page parameters */
+ snprintf(tmp,99,"%d",bitmap->getWidth());
+ ijs_client_set_param(ctx,job_id,"Width",tmp,strlen(tmp));
+ snprintf(tmp,99,"%d",bitmap->getHeight());
+ ijs_client_set_param(ctx,job_id,"Height",tmp,strlen(tmp));
+ ijs_client_begin_page(ctx,job_id);
+
+ /* write page image */
+ size = bitmap->getRowSize()*bitmap->getHeight();
+ int status=ijs_client_send_data_wait(ctx,job_id,(const char *)bitmap->getDataPtr(),size);
+ if (status) {
+ pdfError(-1,"Can't write page %d image: %d",i,status);
+ exit(1);
+ }
+
+ status=ijs_client_end_page(ctx,job_id);
+ if (status) {
+ pdfError(-1,"Can't finish page %d: %d",i,status);
+ exit(1);
+ }
+ }
+ ijs_client_end_job (ctx, job_id);
+ ijs_client_close (ctx);
+
+ ijs_client_begin_cmd (ctx, IJS_CMD_EXIT);
+ ijs_client_send_cmd_wait (ctx);
+
+ delete out;
+err1:
+ delete doc;
+ ppdClose(ppd);
+ free(outputfile);
+
+ // Check for memory leaks
+ Object::memCheck(stderr);
+ gMemReport(stderr);
+
+ return exitCode;
+}
+
+/* replace memory allocation methods for memory check */
+/* For compatibility with g++ >= 4.7 compilers _GLIBCXX_THROW
+ * should be used as a guard, otherwise use traditional definition */
+#ifndef _GLIBCXX_THROW
+#define _GLIBCXX_THROW throw
+#endif
+
+void * operator new(size_t size) _GLIBCXX_THROW (std::bad_alloc)
+{
+ return gmalloc(size);
+}
+
+void operator delete(void *p) throw ()
+{
+ gfree(p);
+}
+
+void * operator new[](size_t size) _GLIBCXX_THROW (std::bad_alloc)
+{
+ return gmalloc(size);
+}
+
+void operator delete[](void *p) throw ()
+{
+ gfree(p);
+}
diff --git a/filter/pdftoopvp/99pdftoopvp.conf b/filter/pdftoopvp/99pdftoopvp.conf
new file mode 100644
index 000000000..2737e1784
--- /dev/null
+++ b/filter/pdftoopvp/99pdftoopvp.conf
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- conf.d/pdftoopvp.fconf -->
+<fontconfig>
+<!-- Symbol and ZapfDingbats -->
+ <alias>
+ <family>ZapfDingbats</family>
+ <prefer>
+ <family>Dingbats</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>Symbol</family>
+ <prefer>
+ <family>Standard Symbols L</family>
+ </prefer>
+ </alias>
+</fontconfig>
diff --git a/filter/pdftoopvp/OPVPError.h b/filter/pdftoopvp/OPVPError.h
new file mode 100644
index 000000000..5f1b9a317
--- /dev/null
+++ b/filter/pdftoopvp/OPVPError.h
@@ -0,0 +1,44 @@
+/*
+
+Copyright (c) 2012, BBR Inc. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+/*
+ OPVPError.h
+*/
+#ifndef _OPVPERROR_H_
+#define _OPVPERROR_H_
+
+#include <config.h>
+#include <stdarg.h>
+#include <Error.h>
+#ifdef HAVE_CPP_POPPLER_VERSION_H
+#include "cpp/poppler-version.h"
+#endif
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+#define opvpError(pos,...) error(errInternal,pos,__VA_ARGS__)
+#else
+#define opvpError(pos,...) error(pos,__VA_ARGS__)
+#endif
+
+#endif
diff --git a/filter/pdftoopvp/OPVPOutputDev.cxx b/filter/pdftoopvp/OPVPOutputDev.cxx
new file mode 100644
index 000000000..63806e8a4
--- /dev/null
+++ b/filter/pdftoopvp/OPVPOutputDev.cxx
@@ -0,0 +1,2003 @@
+//
+// OPVPOutputDev.cc
+// Based SplashOutputDev.cc : Copyright 2003 Glyph & Cog, LLC
+//
+// Copyright 2005 AXE,Inc.
+//
+// 2007,2008 Modified by BBR Inc.
+//========================================================================
+
+#include <config.h>
+#ifdef HAVE_CPP_POPPLER_VERSION_H
+#include "cpp/poppler-version.h"
+#endif
+
+#ifdef USE_GCC_PRAGMAS
+#pragma implementation
+#endif
+
+#include <string.h>
+#include <math.h>
+#include "goo/gfile.h"
+#include "GlobalParams.h"
+#include "OPVPError.h"
+#include "Object.h"
+#include "GfxState.h"
+#include "GfxFont.h"
+#include "Link.h"
+#include "CharCodeToUnicode.h"
+#include "FontEncodingTables.h"
+#include "fofi/FoFiTrueType.h"
+#include "splash/SplashMath.h"
+#include "CMap.h"
+#include "splash/SplashBitmap.h"
+#include "splash/SplashGlyphBitmap.h"
+#include "splash/SplashPattern.h"
+#include "splash/SplashScreen.h"
+#include "splash/SplashErrorCodes.h"
+#include "splash/SplashFontEngine.h"
+#include "splash/SplashFont.h"
+#include "splash/SplashFontFile.h"
+#include "splash/SplashFontFileID.h"
+#include "OPVPSplashPath.h"
+#include "OPVPSplashState.h"
+#include "OPRS.h"
+#include "OPVPOutputDev.h"
+
+#define SLICE_FOR_PATTERN 1000
+
+//------------------------------------------------------------------------
+// Font substitutions
+//------------------------------------------------------------------------
+
+struct SplashOutFontSubst {
+ char *name;
+ double mWidth;
+};
+
+//------------------------------------------------------------------------
+
+#define soutRound(x) ((int)(x + 0.5))
+
+//------------------------------------------------------------------------
+// SplashOutFontFileID
+//------------------------------------------------------------------------
+
+class SplashOutFontFileID: public SplashFontFileID {
+public:
+
+ SplashOutFontFileID(Ref *rA) { r = *rA; substIdx = -1; }
+
+ ~SplashOutFontFileID() {}
+
+ GBool matches(SplashFontFileID *id) {
+ return ((SplashOutFontFileID *)id)->r.num == r.num &&
+ ((SplashOutFontFileID *)id)->r.gen == r.gen;
+ }
+
+ void setSubstIdx(int substIdxA) { substIdx = substIdxA; }
+ int getSubstIdx() { return substIdx; }
+
+private:
+
+ Ref r;
+ int substIdx;
+};
+
+//------------------------------------------------------------------------
+// T3FontCache
+//------------------------------------------------------------------------
+
+struct T3FontCacheTag {
+ Gushort code;
+ Gushort mru; // valid bit (0x8000) and MRU index
+};
+
+class T3FontCache {
+public:
+
+ T3FontCache(Ref *fontID, double m11A, double m12A,
+ double m21A, double m22A,
+ int glyphXA, int glyphYA, int glyphWA, int glyphHA,
+ GBool aa);
+ ~T3FontCache();
+ GBool matches(Ref *idA, double m11A, double m12A,
+ double m21A, double m22A)
+ { return fontID.num == idA->num && fontID.gen == idA->gen &&
+ m11 == m11A && m12 == m12A && m21 == m21A && m22 == m22A; }
+
+ Ref fontID; // PDF font ID
+ double m11, m12, m21, m22; // transform matrix
+ int glyphX, glyphY; // pixel offset of glyph bitmaps
+ int glyphW, glyphH; // size of glyph bitmaps, in pixels
+ int glyphSize; // size of glyph bitmaps, in bytes
+ int cacheSets; // number of sets in cache
+ int cacheAssoc; // cache associativity (glyphs per set)
+ Guchar *cacheData; // glyph pixmap cache
+ T3FontCacheTag *cacheTags; // cache tags, i.e., char codes
+};
+
+T3FontCache::T3FontCache(Ref *fontIDA, double m11A, double m12A,
+ double m21A, double m22A,
+ int glyphXA, int glyphYA, int glyphWA, int glyphHA,
+ GBool aa) {
+ int i;
+
+ fontID = *fontIDA;
+ m11 = m11A;
+ m12 = m12A;
+ m21 = m21A;
+ m22 = m22A;
+ glyphX = glyphXA;
+ glyphY = glyphYA;
+ glyphW = glyphWA;
+ glyphH = glyphHA;
+ if (aa) {
+ glyphSize = glyphW * glyphH;
+ } else {
+ glyphSize = ((glyphW + 7) >> 3) * glyphH;
+ }
+ cacheAssoc = 8;
+ if (glyphSize <= 256) {
+ cacheSets = 8;
+ } else if (glyphSize <= 512) {
+ cacheSets = 4;
+ } else if (glyphSize <= 1024) {
+ cacheSets = 2;
+ } else {
+ cacheSets = 1;
+ }
+ cacheData = (Guchar *)gmallocn3(cacheSets , cacheAssoc , glyphSize);
+ cacheTags = (T3FontCacheTag *)gmallocn3(cacheSets , cacheAssoc ,
+ sizeof(T3FontCacheTag));
+ for (i = 0; i < cacheSets * cacheAssoc; ++i) {
+ cacheTags[i].mru = i & (cacheAssoc - 1);
+ }
+}
+
+T3FontCache::~T3FontCache() {
+ gfree(cacheData);
+ gfree(cacheTags);
+}
+
+struct T3GlyphStack {
+ Gushort code; // character code
+ double x, y; // position to draw the glyph
+
+ //----- cache info
+ T3FontCache *cache; // font cache for the current font
+ T3FontCacheTag *cacheTag; // pointer to cache tag for the glyph
+ Guchar *cacheData; // pointer to cache data for the glyph
+
+ //----- saved state
+ SplashBitmap *origBitmap;
+ OPRS *origOPRS;
+ double origCTM4, origCTM5;
+
+ T3GlyphStack *next; // next object on stack
+};
+
+//------------------------------------------------------------------------
+// OPVPOutputDev
+//------------------------------------------------------------------------
+
+OPVPOutputDev::OPVPOutputDev()
+{
+ xref = 0;
+ bitmap = 0;
+ fontEngine = 0;
+ nT3Fonts = 0;
+ t3GlyphStack = 0;
+ font = NULL;
+ needFontUpdate = gFalse;
+ textClipPath = 0;
+ underlayCbk = 0;
+ underlayCbkData = 0;
+ scaleWidth = scaleHeight = -1;
+ leftMargin = 0;
+ bottomMargin = 0;
+ rotate = 0;
+ sliceHeight = 0;
+ yoffset = 0;
+ oprs = 0;
+}
+
+void OPVPOutputDev::setScale(double w, double h,
+ double leftMarginA, double bottomMarginA, int rotateA,
+ int yoffsetA, int sliceHeightA)
+{
+ scaleWidth = w;
+ scaleHeight = h;
+ leftMargin = leftMarginA;
+ bottomMargin = bottomMarginA;
+ rotate = rotateA;
+ yoffset = yoffsetA;
+ sliceHeight = sliceHeightA;
+}
+
+int OPVPOutputDev::init(SplashColorMode colorModeA,
+ GBool colorProfile,
+ GBool reverseVideoA,
+ SplashColor paperColorA,
+ const char *driverName,
+ int outputFD,
+ const char *printerModel,
+ int nOptions,
+ const char *optionKeys[],
+ const char *optionVals[]) {
+ int result;
+
+ oprs = new OPRS();
+
+ if ((result = oprs->init(driverName, outputFD, printerModel,
+ nOptions,optionKeys,optionVals)) < 0) {
+ opvpError(-1,"OPRS initialization fail");
+ return result;
+ }
+ colorMode = colorModeA;
+ if ((result = oprs->setColorMode(colorMode,colorProfile)) < 0) {
+ opvpError(-1,"Can't setColorMode");
+ return result;
+ }
+ reverseVideo = reverseVideoA;
+ splashColorCopy(paperColor,paperColorA);
+
+ return 0;
+}
+
+OPVPOutputDev::~OPVPOutputDev() {
+ int i;
+
+ for (i = 0; i < nT3Fonts; ++i) {
+ delete t3FontCache[i];
+ }
+ if (fontEngine) {
+ delete fontEngine;
+ }
+ if (oprs) {
+ delete oprs;
+ }
+ if (bitmap) {
+ delete bitmap;
+ }
+}
+
+void OPVPOutputDev::startDoc(XRef *xrefA) {
+ int i;
+
+ xref = xrefA;
+ if (fontEngine) {
+ delete fontEngine;
+ }
+ fontEngine = new SplashFontEngine(
+#if HAVE_T1LIB_H
+ globalParams->getEnableT1lib(),
+#endif
+#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+ globalParams->getEnableFreeType(),
+ gFalse,
+ gFalse,
+#endif
+#if POPPLER_VERSION_MAJOR == 0 && POPPLER_VERSION_MINOR <= 30
+ globalParams->getAntialias());
+#else
+ gFalse);
+#endif
+ for (i = 0; i < nT3Fonts; ++i) {
+ delete t3FontCache[i];
+ }
+ nT3Fonts = 0;
+}
+
+void OPVPOutputDev::startPage(int pageNum, GfxState *state) {
+ int w, h;
+
+ if (state) {
+ if (scaleWidth > 0 && scaleHeight > 0) {
+ double *ctm = state->getCTM();
+
+ switch (rotate) {
+ case 90:
+ state->setCTM(0,ctm[1],ctm[2],0,leftMargin,bottomMargin-yoffset);
+ break;
+ case 180:
+ state->setCTM(ctm[0],0,0,ctm[3],paperWidth-leftMargin,
+ bottomMargin-yoffset);
+ break;
+ case 270:
+ state->setCTM(0,ctm[1],ctm[2],0,paperWidth-leftMargin,
+ -bottomMargin+paperHeight-yoffset);
+ break;
+ default:
+ state->setCTM(ctm[0],0,0,ctm[3],leftMargin,
+ -bottomMargin+paperHeight-yoffset);
+ break;
+ }
+ state->concatCTM(scaleWidth,0.0,0.0,scaleHeight,0,0);
+ }
+ w = (int)(state->getPageWidth()+0.5);
+ h = (int)(state->getPageHeight()+0.5);
+ } else {
+ w = h = 1;
+ }
+ oprs->initGS(colorMode,w,h,paperColor);
+
+ if (underlayCbk) {
+ (*underlayCbk)(underlayCbkData);
+ }
+}
+
+void OPVPOutputDev::endPage() {
+ oprs->endPage();
+}
+
+void OPVPOutputDev::saveState(GfxState *state) {
+ oprs->saveState();
+}
+
+void OPVPOutputDev::restoreState(GfxState *state) {
+ oprs->restoreState();
+ needFontUpdate = gTrue;
+}
+
+void OPVPOutputDev::updateAll(GfxState *state) {
+ updateLineDash(state);
+ updateLineJoin(state);
+ updateLineCap(state);
+ updateLineWidth(state);
+ updateFlatness(state);
+ updateMiterLimit(state);
+ updateFillColor(state);
+ updateStrokeColor(state);
+ needFontUpdate = gTrue;
+}
+
+void OPVPOutputDev::updateCTM(GfxState *state, double m11, double m12,
+ double m21, double m22,
+ double m31, double m32) {
+ updateLineDash(state);
+ updateLineJoin(state);
+ updateLineCap(state);
+ updateLineWidth(state);
+}
+
+void OPVPOutputDev::transLineDash(GfxState *state, SplashCoord **adash,
+ int *adashLength, SplashCoord *aphase) {
+ double *dashPattern;
+ double dashStart;
+ static SplashCoord dash[20];
+ int i;
+
+ state->getLineDash(&dashPattern, adashLength, &dashStart);
+ if (*adashLength > 20) {
+ *adashLength = 20;
+ }
+ for (i = 0; i < *adashLength; ++i) {
+ dash[i] = (SplashCoord)state->transformWidth(dashPattern[i]);
+ if (dash[i] < 1) {
+ dash[i] = 1;
+ }
+ }
+ *adash = dash;
+ *aphase = (SplashCoord)state->transformWidth(dashStart);
+}
+
+void OPVPOutputDev::updateSplashLineDash(GfxState *state, Splash *splash) {
+ int dashLength;
+ SplashCoord *dash;
+ SplashCoord phase;
+
+ transLineDash(state, &dash, &dashLength, &phase);
+ splash->setLineDash(dash, dashLength, phase);
+}
+
+void OPVPOutputDev::updateLineDash(GfxState *state) {
+ int dashLength;
+ SplashCoord *dash;
+ SplashCoord phase;
+
+ transLineDash(state, &dash, &dashLength, &phase);
+ oprs->setLineDash(dash, dashLength, phase);
+}
+
+void OPVPOutputDev::updateFlatness(GfxState *state) {
+ oprs->setFlatness(state->getFlatness());
+}
+
+void OPVPOutputDev::updateLineJoin(GfxState *state) {
+ oprs->setLineJoin(state->getLineJoin());
+}
+
+void OPVPOutputDev::updateLineCap(GfxState *state) {
+ oprs->setLineCap(state->getLineCap());
+}
+
+void OPVPOutputDev::updateMiterLimit(GfxState *state) {
+ oprs->setMiterLimit(state->getMiterLimit());
+}
+
+void OPVPOutputDev::updateLineWidth(GfxState *state) {
+ oprs->setLineWidth(state->getTransformedLineWidth());
+}
+
+void OPVPOutputDev::updateFillColor(GfxState *state) {
+ GfxGray gray;
+ GfxRGB rgb;
+
+ state->getFillGray(&gray);
+ state->getFillRGB(&rgb);
+ oprs->setFillPattern(getColor(gray, &rgb));
+}
+
+void OPVPOutputDev::updateStrokeColor(GfxState *state) {
+ GfxGray gray;
+ GfxRGB rgb;
+
+ state->getStrokeGray(&gray);
+ state->getStrokeRGB(&rgb);
+ oprs->setStrokePattern(getColor(gray, &rgb));
+}
+
+#ifdef SPLASH_CMYK
+SplashPattern *OPVPOutputDev::getColor(double gray, GfxRGB *rgb,
+ GfxCMYK *cmyk) {
+#else
+SplashPattern *OPVPOutputDev::getColor(GfxGray gray, GfxRGB *rgb) {
+#endif
+ SplashPattern *pattern;
+ SplashColor color1;
+ GfxColorComp r, g, b;
+
+ if (reverseVideo) {
+ gray = gfxColorComp1 - gray;
+ r = gfxColorComp1 - rgb->r;
+ g = gfxColorComp1 - rgb->g;
+ b = gfxColorComp1 - rgb->b;
+ } else {
+ r = rgb->r;
+ g = rgb->g;
+ b = rgb->b;
+ }
+
+ pattern = NULL; // make gcc happy
+ switch (colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ color1[0] = colToByte(gray);
+ pattern = new SplashSolidColor(color1);
+ break;
+ case splashModeRGB8:
+ color1[0] = colToByte(r);
+ color1[1] = colToByte(g);
+ color1[2] = colToByte(b);
+ pattern = new SplashSolidColor(color1);
+ break;
+#if SPLASH_CMYK
+ case splashModeCMYK8:
+ color[0] = colToByte(cmyk->c);
+ color[1] = colToByte(cmyk->m);
+ color[2] = colToByte(cmyk->y);
+ color[3] = colToByte(cmyk->k);
+ pattern = new SplashSolidColor(color);
+ break;
+#endif
+ default:
+ opvpError(-1, "no supported color mode");
+ break;
+ }
+
+ return pattern;
+}
+
+void OPVPOutputDev::updateFont(GfxState *state) {
+ needFontUpdate = gTrue;
+}
+
+void OPVPOutputDev::doUpdateFont(GfxState *state) {
+ GfxFont *gfxFont;
+ GfxFontType fontType;
+ SplashOutFontFileID *id;
+ SplashFontFile *fontFile;
+ SplashFontSrc *fontsrc = NULL;
+ FoFiTrueType *ff;
+ Ref embRef;
+ Object refObj, strObj;
+ GooString *fileName;
+ char *tmpBuf;
+ int tmpBufLen;
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+ int *codeToGID;
+#else
+ Gushort *codeToGID;
+#endif
+ double m11, m12, m21, m22;
+ int n;
+ int faceIndex = 0;
+ GBool recreateFont = gFalse;
+
+ needFontUpdate = gFalse;
+ font = NULL;
+ fileName = NULL;
+ tmpBuf = NULL;
+
+ if (!(gfxFont = state->getFont())) {
+ goto err1;
+ }
+ fontType = gfxFont->getType();
+ if (fontType == fontType3) {
+ goto err1;
+ }
+
+ // check the font file cache
+ id = new SplashOutFontFileID(gfxFont->getID());
+ if ((fontFile = fontEngine->getFontFile(id))) {
+ delete id;
+
+ } else {
+
+ // if there is an embedded font, write it to disk
+ if (gfxFont->getEmbeddedFontID(&embRef)) {
+ tmpBuf = gfxFont->readEmbFontFile(xref, &tmpBufLen);
+ if (! tmpBuf)
+ goto err2;
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+ } else {
+ SysFontType sftype;
+ fileName = globalParams->findSystemFontFile(gfxFont,&sftype,
+ &faceIndex, NULL);
+ if (fileName == 0) {
+ opvpError(-1, "Couldn't find a font for '%s'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ switch (sftype) {
+ case sysFontPFA:
+ case sysFontPFB:
+ fontType = gfxFont->isCIDFont() ? fontCIDType0 : fontType1;
+ break;
+ case sysFontTTF:
+ case sysFontTTC:
+ fontType = gfxFont->isCIDFont() ? fontCIDType2 : fontTrueType;
+ break;
+ }
+ }
+#else
+ // if there is an external font file, use it
+ } else if (!(fileName = gfxFont->getExtFontFile())) {
+ DisplayFontParam *dfp;
+ // look for a display font mapping or a substitute font
+ dfp = NULL;
+ if (gfxFont->getName()) {
+ dfp = globalParams->getDisplayFont(gfxFont);
+ }
+ if (!dfp) {
+ opvpError(-1, "Couldn't find a font for '%s'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ switch (dfp->kind) {
+ case displayFontT1:
+ fileName = dfp->t1.fileName;
+ fontType = gfxFont->isCIDFont() ? fontCIDType0 : fontType1;
+ break;
+ case displayFontTT:
+ fileName = dfp->tt.fileName;
+ fontType = gfxFont->isCIDFont() ? fontCIDType2 : fontTrueType;
+ faceIndex = dfp->tt.faceIndex;
+ break;
+ }
+ }
+#endif
+
+ fontsrc = new SplashFontSrc;
+ if (fileName)
+ fontsrc->setFile(fileName, gFalse);
+ else
+ fontsrc->setBuf(tmpBuf, tmpBufLen, gTrue);
+
+ // load the font file
+ switch (fontType) {
+ case fontType1:
+ if (!(fontFile = fontEngine->loadType1Font(
+ id,
+ fontsrc,
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+ (const char **)
+#endif
+ ((Gfx8BitFont *)gfxFont)->getEncoding()))) {
+ opvpError(-1, "Couldn't create a font for '%s'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ case fontType1C:
+ if (!(fontFile = fontEngine->loadType1CFont(
+ id,
+ fontsrc,
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+ (const char **)
+#endif
+ ((Gfx8BitFont *)gfxFont)->getEncoding()))) {
+ opvpError(-1, "Couldn't create a font for '%s'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ case fontType1COT:
+ if (!(fontFile = fontEngine->loadOpenTypeT1CFont(
+ id,
+ fontsrc,
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+ (const char **)
+#endif
+ ((Gfx8BitFont *)gfxFont)->getEncoding()))) {
+ opvpError(-1, "Couldn't create a font for '%s'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ case fontTrueTypeOT:
+ case fontTrueType:
+ if (fileName)
+ ff = FoFiTrueType::load(fileName->getCString());
+ else
+ ff = FoFiTrueType::make(tmpBuf, tmpBufLen);
+ if (ff) {
+ codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ff);
+ n = 256;
+ delete ff;
+ } else {
+ codeToGID = NULL;
+ n = 0;
+ }
+ if (!(fontFile = fontEngine->loadTrueTypeFont(
+ id,
+ fontsrc,
+ codeToGID, n))) {
+ opvpError(-1, "Couldn't create a font for '%s'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ case fontCIDType0:
+ case fontCIDType0C:
+ if (!(fontFile = fontEngine->loadCIDFont(
+ id,
+ fontsrc))) {
+ opvpError(-1, "Couldn't create a font for '%s'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ case fontCIDType0COT:
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+ n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
+ if (n) {
+ codeToGID = (int *)gmallocn(n, sizeof(int));
+ memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(),
+ n * sizeof(int));
+ } else {
+ codeToGID = NULL;
+ }
+ if (!(fontFile = fontEngine->loadOpenTypeCFFFont(
+ id,
+ fontsrc,codeToGID,n))) {
+#else
+ if (!(fontFile = fontEngine->loadOpenTypeCFFFont(
+ id,
+ fontsrc))) {
+#endif
+ opvpError(-1, "Couldn't create a font for '%s'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ case fontCIDType2OT:
+ case fontCIDType2:
+ codeToGID = NULL;
+ n = 0;
+ if (((GfxCIDFont *)gfxFont)->getCIDToGID()) {
+ n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
+ if (n) {
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+ codeToGID = (int *)gmallocn(n, sizeof(int));
+ memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(),
+ n * sizeof(int));
+#else
+ codeToGID = (Gushort *)gmallocn(n, sizeof(Gushort));
+ memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(),
+ n * sizeof(Gushort));
+#endif
+ }
+ } else {
+ if (fileName)
+ ff = FoFiTrueType::load(fileName->getCString());
+ else
+ ff = FoFiTrueType::make(tmpBuf, tmpBufLen);
+ if (! ff)
+ goto err2;
+ codeToGID = ((GfxCIDFont *)gfxFont)->getCodeToGIDMap(ff, &n);
+ delete ff;
+ }
+ if (!(fontFile = fontEngine->loadTrueTypeFont(
+ id,
+ fontsrc,
+ codeToGID, n, faceIndex))) {
+ opvpError(-1, "Couldn't create a font for '%s'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ default:
+ // this shouldn't happen
+ goto err2;
+ }
+ fontFile->doAdjustMatrix = gTrue;
+ }
+
+ // get the font matrix
+ state->getFontTransMat(&m11, &m12, &m21, &m22);
+ m11 *= state->getHorizScaling();
+ m12 *= state->getHorizScaling();
+
+ // create the scaled font
+ fontMat[0] = m11; fontMat[1] = m12;
+ fontMat[2] = m21; fontMat[3] = m22;
+ font = fontEngine->getFont(fontFile, fontMat, oprs->getMatrix());
+
+ // for substituted fonts: adjust the font matrix -- compare the
+ // width of 'm' in the original font and the substituted font
+ if (fontFile->doAdjustMatrix && !gfxFont->isCIDFont()) {
+ double w1, w2;
+ CharCode code;
+ char *name;
+ for (code = 0; code < 256; ++code) {
+ if ((name = ((Gfx8BitFont *)gfxFont)->getCharName(code)) &&
+ name[0] == 'm' && name[1] == '\0') {
+ break;
+ }
+ }
+ if (code < 256) {
+ w1 = ((Gfx8BitFont *)gfxFont)->getWidth(code);
+ w2 = font->getGlyphAdvance(code);
+ if (!gfxFont->isSymbolic() && w2 > 0) {
+ // if real font is substantially narrower than substituted
+ // font, reduce the font size accordingly
+ if (w1 > 0.01 && w1 < 0.9 * w2) {
+ w1 /= w2;
+ m11 *= w1;
+ m21 *= w1;
+ recreateFont = gTrue;
+ }
+ }
+ }
+ }
+
+ if (recreateFont)
+ {
+ fontMat[0] = m11; fontMat[1] = m12;
+ fontMat[2] = m21; fontMat[3] = m22;
+ font = fontEngine->getFont(fontFile, fontMat, oprs->getMatrix());
+ }
+
+ if (fontsrc && !fontsrc->isFile)
+ fontsrc->unref();
+ return;
+
+ err2:
+ delete id;
+ err1:
+ if (fontsrc && !fontsrc->isFile)
+ fontsrc->unref();
+ return;
+}
+
+void OPVPOutputDev::stroke(GfxState *state) {
+ OPVPSplashPath *path;
+ GfxColorSpace *cs;
+
+ /* check None separate color */
+ if ((cs = state->getStrokeColorSpace()) == NULL) return;
+ if (cs->getMode() == csSeparation) {
+ GooString *name;
+
+ name = (dynamic_cast<GfxSeparationColorSpace *>(cs))->getName();
+ if (name == NULL) return;
+ if (name->cmp("None") == 0) return;
+ }
+
+ path = convertPath(state, state->getPath());
+ oprs->stroke(path);
+ delete path;
+}
+
+void OPVPOutputDev::fill(GfxState *state) {
+ OPVPSplashPath *path;
+ GfxColorSpace *cs;
+
+ /* check None separate color */
+ if ((cs = state->getFillColorSpace()) == NULL) return;
+ if (cs->getMode() == csSeparation) {
+ GooString *name;
+
+ name = (dynamic_cast<GfxSeparationColorSpace *>(cs))->getName();
+ if (name == NULL) return;
+ if (name->cmp("None") == 0) return;
+ }
+
+ path = convertPath(state, state->getPath());
+ oprs->fill(path, gFalse);
+ delete path;
+}
+
+void OPVPOutputDev::eoFill(GfxState *state) {
+ OPVPSplashPath *path;
+ GfxColorSpace *cs;
+
+ /* check None separate color */
+ if ((cs = state->getFillColorSpace()) == NULL) return;
+ if (cs->getMode() == csSeparation) {
+ GooString *name;
+
+ name = (dynamic_cast<GfxSeparationColorSpace *>(cs))->getName();
+ if (name == NULL) return;
+ if (name->cmp("None") == 0) return;
+ }
+
+ path = convertPath(state, state->getPath());
+ oprs->fill(path, gTrue);
+ delete path;
+}
+
+void OPVPOutputDev::clip(GfxState *state) {
+ OPVPSplashPath *path;
+
+ path = convertPath(state, state->getPath());
+ oprs->clipToPath(path, gFalse);
+ delete path;
+}
+
+void OPVPOutputDev::eoClip(GfxState *state) {
+ OPVPSplashPath *path;
+
+ path = convertPath(state, state->getPath());
+ oprs->clipToPath(path, gTrue);
+ delete path;
+}
+
+OPVPSplashPath *OPVPOutputDev::bitmapToPath(SplashBitmap *bitmapA,
+ int width, int height)
+{
+ int x,y;
+ OPVPSplashPath *path;
+ int x1, x2;
+ SplashColor pix;
+
+ path = new OPVPSplashPath();
+
+ for (y = 0;y < height;y++) {
+ for (x = 0;x < width;x++) {
+ bitmapA->getPixel(x,y,pix);
+ if (pix[0] == 0) {
+ /* start */
+ x1 = x;
+ for (x++;x < width;x++) {
+ bitmapA->getPixel(x,y,pix);
+ if (pix[0] != 0) {
+ /* end */
+ break;
+ }
+ }
+ x2 = x-1;
+ path->moveTo(x1,y);
+ path->lineTo(x2,y);
+ path->lineTo(x2,(y+1));
+ path->lineTo(x1,(y+1));
+ path->close();
+ }
+ }
+ }
+ return path;
+}
+
+void OPVPOutputDev::clipToStrokePath(GfxState *state) {
+ SplashBitmap *tbitmap;
+ Splash *tsplash;
+ SplashPath *spath;
+ OPVPSplashPath *path, *path2;
+
+ // use splash for makeStrokePath
+ // create dummy bitmap for creating splash
+ tbitmap = new SplashBitmap(1, 1, 1, splashModeMono1, gFalse);
+ tsplash = new Splash(tbitmap, gFalse);
+ // set line parameters
+ // except colors
+ updateSplashLineDash(state, tsplash);
+ tsplash->setLineJoin(state->getLineJoin());
+ tsplash->setLineCap(state->getLineCap());
+ tsplash->setMiterLimit(state->getMiterLimit());
+ tsplash->setLineWidth(state->getTransformedLineWidth());
+
+ path = convertPath(state, state->getPath());
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+ spath = tsplash->makeStrokePath(path,0);
+#else
+ spath = tsplash->makeStrokePath(path);
+#endif
+ path2 = new OPVPSplashPath(spath);
+ delete spath;
+ delete path;
+ delete tsplash;
+ delete tbitmap;
+ oprs->clipToPath(path2, gFalse);
+ delete path2;
+}
+
+OPVPSplashPath *OPVPOutputDev::convertPath(GfxState *state, GfxPath *path) {
+ OPVPSplashPath *sPath;
+ GfxSubpath *subpath;
+ double x1, y1, x2, y2, x3, y3;
+ int i, j;
+
+ sPath = new OPVPSplashPath();
+ for (i = 0; i < path->getNumSubpaths(); ++i) {
+ subpath = path->getSubpath(i);
+ if (subpath->getNumPoints() > 0) {
+ state->transform(subpath->getX(0), subpath->getY(0), &x1, &y1);
+ sPath->moveTo((SplashCoord)x1, (SplashCoord)y1);
+ j = 1;
+ while (j < subpath->getNumPoints()) {
+ if (subpath->getCurve(j)) {
+ state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1);
+ state->transform(subpath->getX(j+1), subpath->getY(j+1), &x2, &y2);
+ state->transform(subpath->getX(j+2), subpath->getY(j+2), &x3, &y3);
+ sPath->curveTo((SplashCoord)x1, (SplashCoord)y1,
+ (SplashCoord)x2, (SplashCoord)y2,
+ (SplashCoord)x3, (SplashCoord)y3);
+ j += 3;
+ } else {
+ state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1);
+ sPath->lineTo((SplashCoord)x1, (SplashCoord)y1);
+ ++j;
+ }
+ }
+ if (subpath->isClosed()) {
+ sPath->close();
+ }
+ }
+ }
+ return sPath;
+}
+
+void OPVPOutputDev::drawChar(GfxState *state, double x, double y,
+ double dx, double dy,
+ double originX, double originY,
+ CharCode code, int nBytes,
+ Unicode *u, int uLen) {
+ double x1, y1;
+ SplashPath *spath;
+ OPVPSplashPath *path;
+ int render;
+
+ // check for invisible text -- this is used by Acrobat Capture
+ render = state->getRender();
+ if (render == 3) {
+ return;
+ }
+
+ if (needFontUpdate) {
+ doUpdateFont(state);
+ }
+ if (!font) {
+ return;
+ }
+
+ x -= originX;
+ y -= originY;
+ state->transform(x,y,&x1,&y1);
+
+ // fill
+ if (!(render & 1)) {
+ oprs->fillChar((SplashCoord)x1, (SplashCoord)y1, code, font, u, fontMat);
+ }
+
+ // stroke
+ if ((render & 3) == 1 || (render & 3) == 2) {
+ if ((spath = font->getGlyphPath(code))) {
+ path = new OPVPSplashPath(spath);
+ delete spath;
+ path->closeAllSubPath();
+ path->offset((SplashCoord)x1, (SplashCoord)y1);
+ oprs->stroke(path);
+ delete path;
+ } else {
+ opvpError(-1,"No glyph outline infomation");
+ }
+ }
+
+ // clip
+ if (render & 4) {
+ if ((spath = font->getGlyphPath(code)) != NULL) {
+ path = new OPVPSplashPath(spath);
+ delete spath;
+ path->offset((SplashCoord)x1, (SplashCoord)y1);
+ if (textClipPath) {
+ textClipPath->append(path);
+ delete path;
+ } else {
+ textClipPath = path;
+ }
+ } else {
+ opvpError(-1,"No glyph outline infomation");
+ }
+ }
+}
+
+GBool OPVPOutputDev::beginType3Char(GfxState *state, double x, double y,
+ double dx, double dy,
+ CharCode code, Unicode *u, int uLen) {
+ /* In a vector mode, cache is not needed */
+ return gFalse;
+}
+
+void OPVPOutputDev::endType3Char(GfxState *state) {
+ /* In a vector mode, cache is not needed */
+ /* do nothing */
+}
+
+void OPVPOutputDev::type3D0(GfxState *state, double wx, double wy) {
+ /* In a vector mode, cache is not needed */
+ /* do nothing */
+}
+
+void OPVPOutputDev::type3D1(GfxState *state, double wx, double wy,
+ double llx, double lly, double urx, double ury) {
+}
+
+void OPVPOutputDev::drawType3Glyph(T3FontCache *t3Font,
+ T3FontCacheTag *tag, Guchar *data,
+ double x, double y) {
+ SplashGlyphBitmap glyph;
+
+ glyph.x = -t3Font->glyphX;
+ glyph.y = -t3Font->glyphY;
+ glyph.w = t3Font->glyphW;
+ glyph.h = t3Font->glyphH;
+ glyph.aa = colorMode != splashModeMono1;
+ glyph.data = data;
+ glyph.freeData = gFalse;
+ oprs->fillGlyph((SplashCoord)x, (SplashCoord)y, &glyph);
+}
+
+void OPVPOutputDev::endTextObject(GfxState *state) {
+ if (textClipPath) {
+ oprs->clipToPath(textClipPath, gFalse);
+ delete textClipPath;
+ textClipPath = NULL;
+ }
+}
+
+struct SplashOutImageMaskData {
+ ImageStream *imgStr;
+ GBool invert;
+ int width, height, y;
+};
+
+GBool OPVPOutputDev::imageMaskSrc(void *data, SplashColorPtr line) {
+ SplashOutImageMaskData *imgMaskData = (SplashOutImageMaskData *)data;
+ Guchar *p;
+ SplashColorPtr q;
+ int x;
+
+ if (imgMaskData->y == imgMaskData->height) {
+ return gFalse;
+ }
+ for (x = 0, p = imgMaskData->imgStr->getLine(), q = line;
+ x < imgMaskData->width;
+ ++x) {
+ *q++ = *p++ ^ imgMaskData->invert;
+ }
+ ++imgMaskData->y;
+ return gTrue;
+}
+
+void OPVPOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
+ int width, int height, GBool invert,
+ GBool interpolate,
+ GBool inlineImg) {
+ double *ctm;
+ SplashCoord mat[6];
+ SplashOutImageMaskData imgMaskData;
+
+ ctm = state->getCTM();
+ mat[0] = ctm[0];
+ mat[1] = ctm[1];
+ mat[2] = -ctm[2];
+ mat[3] = -ctm[3];
+ mat[4] = ctm[2] + ctm[4];
+ mat[5] = ctm[3] + ctm[5];
+
+ imgMaskData.imgStr = new ImageStream(str, width, 1, 1);
+ imgMaskData.imgStr->reset();
+ imgMaskData.invert = invert ? 0 : 1;
+ imgMaskData.width = width;
+ imgMaskData.height = height;
+ imgMaskData.y = 0;
+
+ oprs->fillImageMask(&imageMaskSrc, &imgMaskData, width, height, mat,
+ t3GlyphStack != NULL);
+ if (inlineImg) {
+ while (imgMaskData.y < height) {
+ imgMaskData.imgStr->getLine();
+ ++imgMaskData.y;
+ }
+ }
+
+ delete imgMaskData.imgStr;
+}
+
+struct SplashOutImageData {
+ ImageStream *imgStr;
+ GfxImageColorMap *colorMap;
+ SplashColorPtr lookup;
+ int *maskColors;
+ SplashColorMode colorMode;
+ int width, height, y;
+};
+
+GBool OPVPOutputDev::imageSrc(void *data, SplashColorPtr line,
+ Guchar *alphaLine)
+{
+ SplashOutImageData *imgData = (SplashOutImageData *)data;
+ Guchar *p;
+ SplashColorPtr q, col;
+ GfxRGB rgb;
+ GfxGray gray;
+#if SPLASH_CMYK
+ GfxCMYK cmyk;
+#endif
+ int nComps, x;
+
+ if (imgData->y == imgData->height) {
+ return gFalse;
+ }
+
+ nComps = imgData->colorMap->getNumPixelComps();
+
+ if (imgData->lookup) {
+ switch (imgData->colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ for (x = 0, p = imgData->imgStr->getLine(), q = line;
+ x < imgData->width;
+ ++x, ++p) {
+ *q++ = imgData->lookup[*p];
+ }
+ break;
+ case splashModeRGB8:
+ case splashModeBGR8:
+ for (x = 0, p = imgData->imgStr->getLine(), q = line;
+ x < imgData->width;
+ ++x, ++p) {
+ col = &imgData->lookup[3 * *p];
+ *q++ = col[0];
+ *q++ = col[1];
+ *q++ = col[2];
+ }
+ break;
+#if SPLASH_CMYK
+ case splashModeCMYK8:
+ for (x = 0, p = imgData->imgStr->getLine(), q = line;
+ x < imgData->width;
+ ++x, ++p) {
+ col = &imgData->lookup[4 * *p];
+ *q++ = col[0];
+ *q++ = col[1];
+ *q++ = col[2];
+ *q++ = col[3];
+ }
+ break;
+#endif
+ default:
+ //~ unimplemented
+ break;
+ }
+ } else {
+ switch (imgData->colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ for (x = 0, p = imgData->imgStr->getLine(), q = line;
+ x < imgData->width;
+ ++x, p += nComps) {
+ imgData->colorMap->getGray(p, &gray);
+ *q++ = colToByte(gray);
+ }
+ break;
+ case splashModeRGB8:
+ for (x = 0, p = imgData->imgStr->getLine(), q = line;
+ x < imgData->width;
+ ++x, p += nComps) {
+ imgData->colorMap->getRGB(p, &rgb);
+ *q++ = colToByte(rgb.r);
+ *q++ = colToByte(rgb.g);
+ *q++ = colToByte(rgb.b);
+ }
+ break;
+ case splashModeBGR8:
+ for (x = 0, p = imgData->imgStr->getLine(), q = line;
+ x < imgData->width;
+ ++x, p += nComps) {
+ imgData->colorMap->getRGB(p, &rgb);
+ *q++ = colToByte(rgb.b);
+ *q++ = colToByte(rgb.g);
+ *q++ = colToByte(rgb.r);
+ }
+ break;
+#if SPLASH_CMYK
+ case splashModeCMYK8:
+ for (x = 0, p = imgData->imgStr->getLine(), q = line;
+ x < imgData->width;
+ ++x, p += nComps) {
+ imgData->colorMap->getCMYK(p, &cmyk);
+ *q++ = colToByte(cmyk.c);
+ *q++ = colToByte(cmyk.m);
+ *q++ = colToByte(cmyk.y);
+ *q++ = colToByte(cmyk.k);
+ }
+ break;
+#endif
+ default:
+ //~ unimplemented
+ break;
+ }
+ }
+
+ ++imgData->y;
+ return gTrue;
+}
+
+GBool OPVPOutputDev::alphaImageSrc(void *data, SplashColorPtr line,
+ Guchar *alphaLine) {
+ SplashOutImageData *imgData = (SplashOutImageData *)data;
+ Guchar *p;
+ SplashColorPtr q, col;
+ GfxRGB rgb;
+ GfxGray gray;
+#if SPLASH_CMYK
+ GfxCMYK cmyk;
+#endif
+ Guchar alpha;
+ int nComps, x, i;
+
+ if (imgData->y == imgData->height) {
+ return gFalse;
+ }
+
+ nComps = imgData->colorMap->getNumPixelComps();
+
+ for (x = 0, p = imgData->imgStr->getLine(), q = line;
+ x < imgData->width;
+ ++x, p += nComps) {
+ alpha = 0;
+ for (i = 0; i < nComps; ++i) {
+ if (p[i] < imgData->maskColors[2*i] ||
+ p[i] > imgData->maskColors[2*i+1]) {
+ alpha = 0xff;
+ break;
+ }
+ }
+ if (imgData->lookup) {
+ switch (imgData->colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ *q++ = alpha;
+ *q++ = imgData->lookup[*p];
+ break;
+ case splashModeRGB8:
+ *q++ = alpha;
+ col = &imgData->lookup[3 * *p];
+ *q++ = col[0];
+ *q++ = col[1];
+ *q++ = col[2];
+ break;
+ case splashModeBGR8:
+ col = &imgData->lookup[3 * *p];
+ *q++ = col[0];
+ *q++ = col[1];
+ *q++ = col[2];
+ *q++ = alpha;
+ break;
+#if SPLASH_CMYK
+ case splashModeCMYK8:
+ *q++ = alpha;
+ col = &imgData->lookup[4 * *p];
+ *q++ = col[0];
+ *q++ = col[1];
+ *q++ = col[2];
+ *q++ = col[3];
+ break;
+#endif
+ default:
+ //~ unimplemented
+ break;
+ }
+ } else {
+ switch (imgData->colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ imgData->colorMap->getGray(p, &gray);
+ *q++ = alpha;
+ *q++ = colToByte(gray);
+ break;
+ case splashModeRGB8:
+ imgData->colorMap->getRGB(p, &rgb);
+ *q++ = alpha;
+ *q++ = colToByte(rgb.r);
+ *q++ = colToByte(rgb.g);
+ *q++ = colToByte(rgb.b);
+ break;
+ case splashModeBGR8:
+ imgData->colorMap->getRGB(p, &rgb);
+ *q++ = colToByte(rgb.b);
+ *q++ = colToByte(rgb.g);
+ *q++ = colToByte(rgb.r);
+ *q++ = alpha;
+ break;
+#if SPLASH_CMYK
+ case splashModeCMYK8:
+ imgData->colorMap->getCMYK(p, &cmyk);
+ *q++ = alpha;
+ *q++ = colToByte(cmyk.c);
+ *q++ = colToByte(cmyk.m);
+ *q++ = colToByte(cmyk.y);
+ *q++ = colToByte(cmyk.k);
+ break;
+#endif
+ default:
+ //~ unimplemented
+ break;
+ }
+ }
+ }
+
+ ++imgData->y;
+ return gTrue;
+}
+
+void OPVPOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
+ int width, int height,
+ GfxImageColorMap *colorMap,
+ GBool interpolate,
+ int *maskColors, GBool inlineImg) {
+ double *ctm;
+ SplashCoord mat[6];
+ SplashOutImageData imgData;
+ SplashColorMode srcMode;
+ SplashImageSource src;
+ GfxGray gray;
+ GfxRGB rgb;
+#if SPLASH_CMYK
+ GfxCMYK cmyk;
+#endif
+ Guchar pix;
+ int n, i;
+
+ ctm = state->getCTM();
+ mat[0] = ctm[0];
+ mat[1] = ctm[1];
+ mat[2] = -ctm[2];
+ mat[3] = -ctm[3];
+ mat[4] = ctm[2] + ctm[4];
+ mat[5] = ctm[3] + ctm[5];
+
+ imgData.imgStr = new ImageStream(str, width,
+ colorMap->getNumPixelComps(),
+ colorMap->getBits());
+ imgData.imgStr->reset();
+ imgData.colorMap = colorMap;
+ imgData.maskColors = maskColors;
+ imgData.colorMode = colorMode;
+ imgData.width = width;
+ imgData.height = height;
+ imgData.y = 0;
+
+ // special case for one-channel (monochrome/gray/separation) images:
+ // build a lookup table here
+ imgData.lookup = NULL;
+ if (colorMap->getNumPixelComps() == 1) {
+ n = 1 << colorMap->getBits();
+ switch (colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ imgData.lookup = (SplashColorPtr)gmallocn(n,1);
+ for (i = 0; i < n; ++i) {
+ pix = (Guchar)i;
+ colorMap->getGray(&pix, &gray);
+ imgData.lookup[i] = colToByte(gray);
+ }
+ break;
+ case splashModeRGB8:
+ imgData.lookup = (SplashColorPtr)gmallocn(n,3);
+ for (i = 0; i < n; ++i) {
+ pix = (Guchar)i;
+ colorMap->getRGB(&pix, &rgb);
+ imgData.lookup[3*i] = colToByte(rgb.r);
+ imgData.lookup[3*i+1] = colToByte(rgb.g);
+ imgData.lookup[3*i+2] = colToByte(rgb.b);
+ }
+ break;
+ case splashModeBGR8:
+ imgData.lookup = (SplashColorPtr)gmallocn(n,3);
+ for (i = 0; i < n; ++i) {
+ pix = (Guchar)i;
+ colorMap->getRGB(&pix, &rgb);
+ imgData.lookup[3*i] = colToByte(rgb.b);
+ imgData.lookup[3*i+1] = colToByte(rgb.g);
+ imgData.lookup[3*i+2] = colToByte(rgb.r);
+ }
+ break;
+#if SPLASH_CMYK
+ case splashModeCMYK8:
+ imgData.lookup = (SplashColorPtr)gmallocn(n,4);
+ for (i = 0; i < n; ++i) {
+ pix = (Guchar)i;
+ colorMap->getCMYK(&pix, &cmyk);
+ imgData.lookup[4*i] = colToByte(cmyk.c);
+ imgData.lookup[4*i+1] = colToByte(cmyk.m);
+ imgData.lookup[4*i+2] = colToByte(cmyk.y);
+ imgData.lookup[4*i+3] = colToByte(cmyk.k);
+ }
+ break;
+#endif
+ default:
+ //~ unimplemented
+ break;
+ }
+ }
+
+ if (colorMode == splashModeMono1) {
+ srcMode = splashModeMono8;
+ } else {
+ srcMode = colorMode;
+ }
+ src = maskColors ? &alphaImageSrc : &imageSrc;
+ oprs->drawImage(src, &imgData, srcMode, maskColors ? gTrue : gFalse,
+ width, height, mat);
+ if (inlineImg) {
+ while (imgData.y < height) {
+ imgData.imgStr->getLine();
+ ++imgData.y;
+ }
+ }
+
+ gfree(imgData.lookup);
+ delete imgData.imgStr;
+ str->close();
+}
+
+struct SplashOutMaskedImageData {
+ ImageStream *imgStr;
+ GfxImageColorMap *colorMap;
+ SplashBitmap *mask;
+ SplashColorPtr lookup;
+ SplashColorMode colorMode;
+ int width, height, y;
+};
+
+GBool OPVPOutputDev::maskedImageSrc(void *data, SplashColorPtr line,
+ Guchar *alphaLine) {
+ SplashOutMaskedImageData *imgData = (SplashOutMaskedImageData *)data;
+ Guchar *p;
+ SplashColor maskColor;
+ SplashColorPtr q, col;
+ GfxRGB rgb;
+ GfxGray gray;
+#if SPLASH_CMYK
+ GfxCMYK cmyk;
+#endif
+ Guchar alpha;
+ int nComps, x;
+
+ if (imgData->y == imgData->height) {
+ return gFalse;
+ }
+
+ nComps = imgData->colorMap->getNumPixelComps();
+
+ for (x = 0, p = imgData->imgStr->getLine(), q = line;
+ x < imgData->width;
+ ++x, p += nComps) {
+ imgData->mask->getPixel(x, imgData->y, maskColor);
+ alpha = maskColor[0] ? 0xff : 0x00;
+ if (imgData->lookup) {
+ switch (imgData->colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ *q++ = alpha;
+ *q++ = imgData->lookup[*p];
+ break;
+ case splashModeRGB8:
+ *q++ = alpha;
+ col = &imgData->lookup[3 * *p];
+ *q++ = col[0];
+ *q++ = col[1];
+ *q++ = col[2];
+ break;
+ case splashModeBGR8:
+ col = &imgData->lookup[3 * *p];
+ *q++ = col[0];
+ *q++ = col[1];
+ *q++ = col[2];
+ *q++ = alpha;
+ break;
+#if SPLASH_CMYK
+ case splashModeCMYK8:
+ *q++ = alpha;
+ col = &imgData->lookup[4 * *p];
+ *q++ = col[0];
+ *q++ = col[1];
+ *q++ = col[2];
+ *q++ = col[3];
+ break;
+#endif
+ default:
+ //~ unimplemented
+ break;
+ }
+ } else {
+ switch (imgData->colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ imgData->colorMap->getGray(p, &gray);
+ *q++ = alpha;
+ *q++ = colToByte(gray);
+ break;
+ case splashModeRGB8:
+ imgData->colorMap->getRGB(p, &rgb);
+ *q++ = alpha;
+ *q++ = colToByte(rgb.r);
+ *q++ = colToByte(rgb.g);
+ *q++ = colToByte(rgb.b);
+ break;
+ case splashModeBGR8:
+ imgData->colorMap->getRGB(p, &rgb);
+ *q++ = colToByte(rgb.b);
+ *q++ = colToByte(rgb.g);
+ *q++ = colToByte(rgb.r);
+ *q++ = alpha;
+ break;
+#if SPLASH_CMYK
+ case splashModeCMYK8:
+ imgData->colorMap->getCMYK(p, &cmyk);
+ *q++ = alpha;
+ *q++ = colToByte(cmyk.c);
+ *q++ = colToByte(cmyk.m);
+ *q++ = colToByte(cmyk.y);
+ *q++ = colToByte(cmyk.k);
+ break;
+#endif
+ default:
+ //~ unimplemented
+ break;
+ }
+ }
+ }
+
+ ++imgData->y;
+ return gTrue;
+}
+
+void OPVPOutputDev::drawMaskedImage(GfxState *state, Object *ref,
+ Stream *str, int width, int height,
+ GfxImageColorMap *colorMap,
+ GBool interpolate,
+ Stream *maskStr, int maskWidth,
+ int maskHeight, GBool maskInvert,
+ GBool maskInterpolate) {
+ double *ctm;
+ SplashCoord mat[6];
+ SplashOutMaskedImageData imgData;
+ SplashOutImageMaskData imgMaskData;
+ SplashColorMode srcMode;
+ SplashBitmap *maskBitmap;
+ Splash *maskSplash;
+ SplashColor maskColor;
+ GfxGray gray;
+ GfxRGB rgb;
+#if SPLASH_CMYK
+ GfxCMYK cmyk;
+#endif
+ Guchar pix;
+ int n, i;
+
+ //----- scale the mask image to the same size as the source image
+
+ mat[0] = (SplashCoord)width;
+ mat[1] = 0;
+ mat[2] = 0;
+ mat[3] = (SplashCoord)height;
+ mat[4] = 0;
+ mat[5] = 0;
+ imgMaskData.imgStr = new ImageStream(maskStr, maskWidth, 1, 1);
+ imgMaskData.imgStr->reset();
+ imgMaskData.invert = maskInvert ? 0 : 1;
+ imgMaskData.width = maskWidth;
+ imgMaskData.height = maskHeight;
+ imgMaskData.y = 0;
+ maskBitmap = new SplashBitmap(width, height, 1, splashModeMono1, gFalse);
+ maskSplash = new Splash(maskBitmap, gFalse);
+ maskColor[0] = 0;
+ maskSplash->clear(maskColor);
+ maskColor[0] = 1;
+ maskSplash->setFillPattern(new SplashSolidColor(maskColor));
+ maskSplash->fillImageMask(&imageMaskSrc, &imgMaskData,
+ maskWidth, maskHeight, mat, gFalse);
+ delete imgMaskData.imgStr;
+ maskStr->close();
+ delete maskSplash;
+
+ //----- draw the source image
+
+ ctm = state->getCTM();
+ mat[0] = ctm[0];
+ mat[1] = ctm[1];
+ mat[2] = -ctm[2];
+ mat[3] = -ctm[3];
+ mat[4] = ctm[2] + ctm[4];
+ mat[5] = ctm[3] + ctm[5];
+
+ imgData.imgStr = new ImageStream(str, width,
+ colorMap->getNumPixelComps(),
+ colorMap->getBits());
+ imgData.imgStr->reset();
+ imgData.colorMap = colorMap;
+ imgData.mask = maskBitmap;
+ imgData.colorMode = colorMode;
+ imgData.width = width;
+ imgData.height = height;
+ imgData.y = 0;
+
+ // special case for one-channel (monochrome/gray/separation) images:
+ // build a lookup table here
+ imgData.lookup = NULL;
+ if (colorMap->getNumPixelComps() == 1) {
+ n = 1 << colorMap->getBits();
+ switch (colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ imgData.lookup = (SplashColorPtr)gmallocn(n,1);
+ for (i = 0; i < n; ++i) {
+ pix = (Guchar)i;
+ colorMap->getGray(&pix, &gray);
+ imgData.lookup[i] = colToByte(gray);
+ }
+ break;
+ case splashModeRGB8:
+ imgData.lookup = (SplashColorPtr)gmallocn(n,3);
+ for (i = 0; i < n; ++i) {
+ pix = (Guchar)i;
+ colorMap->getRGB(&pix, &rgb);
+ imgData.lookup[3*i] = colToByte(rgb.r);
+ imgData.lookup[3*i+1] = colToByte(rgb.g);
+ imgData.lookup[3*i+2] = colToByte(rgb.b);
+ }
+ break;
+ case splashModeBGR8:
+ imgData.lookup = (SplashColorPtr)gmallocn(n,3);
+ for (i = 0; i < n; ++i) {
+ pix = (Guchar)i;
+ colorMap->getRGB(&pix, &rgb);
+ imgData.lookup[3*i] = colToByte(rgb.b);
+ imgData.lookup[3*i+1] = colToByte(rgb.g);
+ imgData.lookup[3*i+2] = colToByte(rgb.r);
+ }
+ break;
+#if SPLASH_CMYK
+ case splashModeCMYK8:
+ imgData.lookup = (SplashColorPtr)gmallocn(n,4);
+ for (i = 0; i < n; ++i) {
+ pix = (Guchar)i;
+ colorMap->getCMYK(&pix, &cmyk);
+ imgData.lookup[4*i] = colToByte(cmyk.c);
+ imgData.lookup[4*i+1] = colToByte(cmyk.m);
+ imgData.lookup[4*i+2] = colToByte(cmyk.y);
+ imgData.lookup[4*i+3] = colToByte(cmyk.k);
+ }
+ break;
+#endif
+ default:
+ //~ unimplemented
+ break;
+ }
+ }
+
+ switch (colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ srcMode = splashModeMono8;
+ break;
+ case splashModeRGB8:
+ srcMode = splashModeRGB8;
+ break;
+ case splashModeBGR8:
+ srcMode = splashModeBGR8;
+ break;
+#if SPLASH_CMYK
+ case splashModeCMYK8:
+ srcMode = splashModeCMYK8;
+ break;
+#endif
+ default:
+ //~ unimplemented
+ srcMode = splashModeRGB8;
+ break;
+ }
+ oprs->drawImage(&maskedImageSrc, &imgData, srcMode, gTrue,
+ width, height, mat);
+
+ delete maskBitmap;
+ gfree(imgData.lookup);
+ delete imgData.imgStr;
+ str->close();
+}
+
+void OPVPOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
+ Stream *str, int width, int height,
+ GfxImageColorMap *colorMap,
+ GBool interpolate,
+ Stream *maskStr,
+ int maskWidth, int maskHeight,
+ GfxImageColorMap *maskColorMap,
+ GBool maskInterpolate) {
+ double *ctm;
+ SplashCoord mat[6];
+ SplashOutImageData imgData;
+ SplashOutImageData imgMaskData;
+ SplashColorMode srcMode;
+ SplashBitmap *maskBitmap;
+ Splash *maskSplash;
+ SplashColor maskColor;
+ GfxGray gray;
+ GfxRGB rgb;
+#if SPLASH_CMYK
+ GfxCMYK cmyk;
+#endif
+ Guchar pix;
+ int n, i;
+
+ ctm = state->getCTM();
+ mat[0] = ctm[0];
+ mat[1] = ctm[1];
+ mat[2] = -ctm[2];
+ mat[3] = -ctm[3];
+ mat[4] = ctm[2] + ctm[4];
+ mat[5] = ctm[3] + ctm[5];
+
+ //----- set up the soft mask
+
+ imgMaskData.imgStr = new ImageStream(maskStr, maskWidth,
+ maskColorMap->getNumPixelComps(),
+ maskColorMap->getBits());
+ imgMaskData.imgStr->reset();
+ imgMaskData.colorMap = maskColorMap;
+ imgMaskData.maskColors = NULL;
+ imgMaskData.colorMode = splashModeMono8;
+ imgMaskData.width = maskWidth;
+ imgMaskData.height = maskHeight;
+ imgMaskData.y = 0;
+ n = 1 << maskColorMap->getBits();
+ imgMaskData.lookup = (SplashColorPtr)gmallocn(n,1);
+ for (i = 0; i < n; ++i) {
+ pix = (Guchar)i;
+ maskColorMap->getGray(&pix, &gray);
+ imgMaskData.lookup[i] = colToByte(gray);
+ }
+ maskBitmap = new SplashBitmap(maskWidth,maskHeight,
+ 1, splashModeMono8, gFalse);
+ maskSplash = new Splash(maskBitmap, gFalse);
+ maskColor[0] = 0;
+ maskSplash->clear(maskColor);
+#if POPPLER_VERSION_MAJOR <= 0 && (POPPLER_VERSION_MINOR <= 20 || (POPPLER_VERSION_MINOR == 21 && POPPLER_VERSION_MICRO <= 2))
+ maskSplash->drawImage(&imageSrc, &imgMaskData,
+ splashModeMono8, gFalse, maskWidth, maskHeight, mat);
+#elif POPPLER_VERSION_MAJOR <= 0 && POPPLER_VERSION_MINOR <= 33
+ maskSplash->drawImage(&imageSrc, &imgMaskData,
+ splashModeMono8, gFalse, maskWidth, maskHeight,
+ mat,gFalse);
+#else
+ maskSplash->drawImage(&imageSrc, 0, &imgMaskData,
+ splashModeMono8, gFalse, maskWidth, maskHeight,
+ mat,gFalse);
+#endif
+ delete imgMaskData.imgStr;
+ maskStr->close();
+ gfree(imgMaskData.lookup);
+ delete maskSplash;
+ oprs->setSoftMask(maskBitmap);
+
+ //----- draw the source image
+
+ imgData.imgStr = new ImageStream(str, width,
+ colorMap->getNumPixelComps(),
+ colorMap->getBits());
+ imgData.imgStr->reset();
+ imgData.colorMap = colorMap;
+ imgData.maskColors = NULL;
+ imgData.colorMode = colorMode;
+ imgData.width = width;
+ imgData.height = height;
+ imgData.y = 0;
+
+ // special case for one-channel (monochrome/gray/separation) images:
+ // build a lookup table here
+ imgData.lookup = NULL;
+ if (colorMap->getNumPixelComps() == 1) {
+ n = 1 << colorMap->getBits();
+ switch (colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ imgData.lookup = (SplashColorPtr)gmallocn(n,1);
+ for (i = 0; i < n; ++i) {
+ pix = (Guchar)i;
+ colorMap->getGray(&pix, &gray);
+ imgData.lookup[i] = colToByte(gray);
+ }
+ break;
+ case splashModeRGB8:
+ imgData.lookup = (SplashColorPtr)gmallocn(n,3);
+ for (i = 0; i < n; ++i) {
+ pix = (Guchar)i;
+ colorMap->getRGB(&pix, &rgb);
+ imgData.lookup[3*i] = colToByte(rgb.r);
+ imgData.lookup[3*i+1] = colToByte(rgb.g);
+ imgData.lookup[3*i+2] = colToByte(rgb.b);
+ }
+ break;
+ case splashModeBGR8:
+ imgData.lookup = (SplashColorPtr)gmallocn(n,3);
+ for (i = 0; i < n; ++i) {
+ pix = (Guchar)i;
+ colorMap->getRGB(&pix, &rgb);
+ imgData.lookup[3*i] = colToByte(rgb.b);
+ imgData.lookup[3*i+1] = colToByte(rgb.g);
+ imgData.lookup[3*i+2] = colToByte(rgb.r);
+ }
+ break;
+#if SPLASH_CMYK
+ case splashModeCMYK8:
+ imgData.lookup = (SplashColorPtr)gmallocn(n,4);
+ for (i = 0; i < n; ++i) {
+ pix = (Guchar)i;
+ colorMap->getCMYK(&pix, &cmyk);
+ imgData.lookup[4*i] = colToByte(cmyk.c);
+ imgData.lookup[4*i+1] = colToByte(cmyk.m);
+ imgData.lookup[4*i+2] = colToByte(cmyk.y);
+ imgData.lookup[4*i+3] = colToByte(cmyk.k);
+ }
+ break;
+#endif
+ default:
+ //~ unimplemented
+ break;
+ }
+ }
+
+ switch (colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ srcMode = splashModeMono8;
+ break;
+ case splashModeRGB8:
+ srcMode = splashModeRGB8;
+ break;
+ case splashModeBGR8:
+ srcMode = splashModeBGR8;
+ break;
+#if SPLASH_CMYK
+ case splashModeCMYK8:
+ srcMode = splashModeCMYK8;
+ break;
+#endif
+ default:
+ //~ unimplemented
+ srcMode = splashModeRGB8;
+ break;
+ }
+ oprs->drawImage(&imageSrc, &imgData, srcMode, gFalse, width, height, mat);
+
+ oprs->setSoftMask(NULL);
+ gfree(imgData.lookup);
+ delete imgData.imgStr;
+ str->close();
+}
+
+int OPVPOutputDev::getBitmapWidth() {
+ return bitmap->getWidth();
+}
+
+int OPVPOutputDev::getBitmapHeight() {
+ return bitmap->getHeight();
+}
+
+void OPVPOutputDev::xorRectangle(int x0, int y0, int x1, int y1,
+ SplashPattern *pattern) {
+ /* no need in printing */
+}
+
+void OPVPOutputDev::setFillColor(int r, int g, int b) {
+ GfxRGB rgb;
+ GfxGray gray;
+#if SPLASH_CMYK
+ GfxCMYK cmyk;
+#endif
+
+ rgb.r = byteToCol(r);
+ rgb.g = byteToCol(g);
+ rgb.b = byteToCol(b);
+ gray = (GfxColorComp)(0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.g + 0.5);
+ if (gray > gfxColorComp1) {
+ gray = gfxColorComp1;
+ }
+#if SPLASH_CMYK
+ cmyk.c = gfxColorComp1 - rgb.r;
+ cmyk.m = gfxColorComp1 - rgb.g;
+ cmyk.y = gfxColorComp1 - rgb.b;
+ cmyk.k = 0;
+ oprs->setFillPattern(getColor(gray, &rgb, &cmyk));
+#else
+ oprs->setFillPattern(getColor(gray, &rgb));
+#endif
+}
+
+int OPVPOutputDev::OPVPStartJob(char *jobInfo)
+{
+ return oprs->OPVPStartJob(jobInfo);
+}
+
+int OPVPOutputDev::OPVPEndJob()
+{
+ return oprs->OPVPEndJob();
+}
+
+int OPVPOutputDev::OPVPStartDoc(char *docInfo)
+{
+ return oprs->OPVPStartDoc(docInfo);
+}
+
+int OPVPOutputDev::OPVPEndDoc()
+{
+ return oprs->OPVPEndDoc();
+}
+
+int OPVPOutputDev::OPVPStartPage(char *pageInfo,
+ int rasterWidth, int rasterHeight)
+{
+ paperWidth = rasterWidth;
+ paperHeight = rasterHeight;
+ return oprs->OPVPStartPage(pageInfo,rasterWidth);
+}
+
+int OPVPOutputDev::OPVPEndPage()
+{
+ return oprs->OPVPEndPage();
+}
+
+int OPVPOutputDev::outSlice()
+{
+ return oprs->outSlice();
+}
+
+void OPVPOutputDev::psXObject(Stream *psStream, Stream *level1Stream)
+{
+ opvpError(-1,"psXObject is found, but it is not supported");
+}
diff --git a/filter/pdftoopvp/OPVPOutputDev.h b/filter/pdftoopvp/OPVPOutputDev.h
new file mode 100644
index 000000000..c2af86e3a
--- /dev/null
+++ b/filter/pdftoopvp/OPVPOutputDev.h
@@ -0,0 +1,250 @@
+//========================================================================
+//
+// OPVPOutputDev.h
+//
+// Copyright 2005 AXE,Inc.
+//
+//========================================================================
+
+#ifndef OPVPOUTPUTDEV_H
+#define OPVPOUTPUTDEV_H
+
+#include <config.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma interface
+#endif
+
+#include "goo/gtypes.h"
+#include "splash/SplashTypes.h"
+#include "config.h"
+#include "OutputDev.h"
+#include "GfxState.h"
+#include "GfxFont.h"
+
+class GfxState;
+class GfxPath;
+class Gfx8BitFont;
+class SplashBitmap;
+class OPRS;
+class OPVPSplashPath;
+class SplashPattern;
+class SplashFontEngine;
+class SplashFont;
+class T3FontCache;
+struct T3FontCacheTag;
+struct T3GlyphStack;
+struct GfxRGB;
+
+//------------------------------------------------------------------------
+
+// number of Type 3 fonts to cache
+#define splashOutT3FontCacheSize 8
+
+//------------------------------------------------------------------------
+// OPVPOutputDev
+//------------------------------------------------------------------------
+
+class OPVPOutputDev: public OutputDev {
+public:
+
+ // Constructor.
+ OPVPOutputDev();
+
+ // Second Constructor
+ int init(SplashColorMode colorModeA, GBool colorProfile, GBool reverseVideoA,
+ SplashColor paperColorA,
+ const char *driverName, int outputFD,
+ const char *printerModel,
+ int nOptions,
+ const char *optionKeys[], const char *optionVals[]);
+
+ // Destructor.
+ virtual ~OPVPOutputDev();
+
+ //----- get info about output device
+
+ // Does this device use upside-down coordinates?
+ // (Upside-down means (0,0) is the top left corner of the page.)
+ virtual GBool upsideDown() { return gTrue; }
+
+ // Does this device use drawChar() or drawString()?
+ virtual GBool useDrawChar() { return gTrue; }
+
+ // Does this device use beginType3Char/endType3Char? Otherwise,
+ // text in Type 3 fonts will be drawn with drawChar/drawString.
+ virtual GBool interpretType3Chars() { return gTrue; }
+
+ //----- initialization and control
+
+ // Start a page.
+ virtual void startPage(int pageNum, GfxState *state);
+
+ // End a page.
+ virtual void endPage();
+
+ //----- save/restore graphics state
+ virtual void saveState(GfxState *state);
+ virtual void restoreState(GfxState *state);
+
+ //----- update graphics state
+ virtual void updateAll(GfxState *state);
+ virtual void updateCTM(GfxState *state, double m11, double m12,
+ double m21, double m22, double m31, double m32);
+ virtual void updateLineDash(GfxState *state);
+ virtual void updateFlatness(GfxState *state);
+ virtual void updateLineJoin(GfxState *state);
+ virtual void updateLineCap(GfxState *state);
+ virtual void updateMiterLimit(GfxState *state);
+ virtual void updateLineWidth(GfxState *state);
+ virtual void updateFillColor(GfxState *state);
+ virtual void updateStrokeColor(GfxState *state);
+
+ //----- update text state
+ virtual void updateFont(GfxState *state);
+
+ //----- path painting
+ virtual void stroke(GfxState *state);
+ virtual void fill(GfxState *state);
+ virtual void eoFill(GfxState *state);
+
+ //----- path clipping
+ virtual void clip(GfxState *state);
+ virtual void eoClip(GfxState *state);
+ virtual void clipToStrokePath(GfxState *state);
+
+ //----- text drawing
+ virtual void drawChar(GfxState *state, double x, double y,
+ double dx, double dy,
+ double originX, double originY,
+ CharCode code, int nBytes, Unicode *u, int uLen);
+ virtual GBool beginType3Char(GfxState *state, double x, double y,
+ double dx, double dy,
+ CharCode code, Unicode *u, int uLen);
+ virtual void endType3Char(GfxState *state);
+ virtual void endTextObject(GfxState *state);
+
+ //----- image drawing
+ virtual void drawImageMask(GfxState *state, Object *ref, Stream *str,
+ int width, int height, GBool invert,
+ GBool interpolate,
+ GBool inlineImg);
+ virtual void drawImage(GfxState *state, Object *ref, Stream *str,
+ int width, int height, GfxImageColorMap *colorMap,
+ GBool interpolate,
+ int *maskColors, GBool inlineImg);
+ virtual void drawMaskedImage(GfxState *state, Object *ref, Stream *str,
+ int width, int height,
+ GfxImageColorMap *colorMap,
+ GBool interpolate,
+ Stream *maskStr, int maskWidth, int maskHeight,
+ GBool maskInvert, GBool maskeInterpolate);
+ virtual void drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
+ int width, int height,
+ GfxImageColorMap *colorMap,
+ GBool interpolate,
+ Stream *maskStr,
+ int maskWidth, int maskHeight,
+ GfxImageColorMap *maskColorMap,
+ GBool maskInterpolate);
+
+ //----- Type 3 font operators
+ virtual void type3D0(GfxState *state, double wx, double wy);
+ virtual void type3D1(GfxState *state, double wx, double wy,
+ double llx, double lly, double urx, double ury);
+
+ //----- special access
+
+ // Called to indicate that a new PDF document has been loaded.
+ void startDoc(XRef *xrefA);
+
+ GBool isReverseVideo() { return reverseVideo; }
+
+ // Get the bitmap and its size.
+ SplashBitmap *getBitmap() { return bitmap; }
+ int getBitmapWidth();
+ int getBitmapHeight();
+
+ // Get the Splash object.
+ OPRS *getOPRS() { return oprs; }
+
+ // XOR a rectangular region in the bitmap with <pattern>. <pattern>
+ // is passed to Splash::setFillPattern, so it should not be used
+ // after calling this function.
+ void xorRectangle(int x0, int y0, int x1, int y1, SplashPattern *pattern);
+
+ // Set the Splash fill color.
+ void setFillColor(int r, int g, int b);
+
+ void setUnderlayCbk(void (*cbk)(void *data), void *data)
+ { underlayCbk = cbk; underlayCbkData = data; }
+
+ int OPVPStartJob(char *jobInfo);
+ int OPVPEndJob();
+ int OPVPStartDoc(char *docInfo);
+ int OPVPEndDoc();
+ int OPVPStartPage(char *pageInfo, int rasterWidth, int rasterHeight);
+ int OPVPEndPage();
+ int outSlice();
+ virtual void psXObject(Stream *psStream, Stream *level1Stream);
+ void setScale(double w, double h, double leftMarginA, double bottomMarginA,
+ int rotateA, int yoffsetA, int sliceHeightA);
+
+private:
+
+ SplashPattern *getColor(GfxGray gray, GfxRGB *rgb);
+ OPVPSplashPath *convertPath(GfxState *state, GfxPath *path);
+ void drawType3Glyph(T3FontCache *t3Font,
+ T3FontCacheTag *tag, Guchar *data,
+ double x, double y);
+ void patternFillChar(GfxState *state,
+ double x, double y, CharCode code);
+
+ static GBool imageMaskSrc(void *data, SplashColorPtr line);
+ static GBool imageSrc(void *data, SplashColorPtr line,
+ Guchar *alphaLine);
+ static GBool alphaImageSrc(void *data, SplashColorPtr line,
+ Guchar *alphaLine);
+ static GBool maskedImageSrc(void *data, SplashColorPtr line,
+ Guchar *alphaLine);
+
+ OPVPSplashPath *bitmapToPath(SplashBitmap *bitmapA, int width, int height);
+ void closeAllSubPath(OPVPSplashPath *path);
+ void patternFillImageMask(GfxState *state,
+ SplashImageMaskSource src, void *srcData, int w, int h, SplashCoord *mat);
+ void doUpdateFont(GfxState *state);
+ void transLineDash(GfxState *state, SplashCoord **adash,
+ int *adashLength, SplashCoord *aphase);
+ void updateSplashLineDash(GfxState *state, Splash *splash);
+
+ SplashColorMode colorMode;
+ GBool reverseVideo; // reverse video mode
+ SplashColor paperColor; // paper color
+
+ XRef *xref; // xref table for current document
+
+ SplashBitmap *bitmap;
+ OPRS *oprs;
+ SplashFontEngine *fontEngine;
+
+ T3FontCache * // Type 3 font cache
+ t3FontCache[splashOutT3FontCacheSize];
+ int nT3Fonts; // number of valid entries in t3FontCache
+ T3GlyphStack *t3GlyphStack; // Type 3 glyph context stack
+
+ SplashFont *font; // current font
+ GBool needFontUpdate; // set when the font needs to be updated
+ OPVPSplashPath *textClipPath; // clipping path built with text object
+
+ void (*underlayCbk)(void *data);
+ void *underlayCbkData;
+ double fontMat[4];
+ double scaleWidth, scaleHeight;
+ int paperWidth, paperHeight;
+ double leftMargin, bottomMargin;
+ int rotate;
+ int yoffset;
+ int sliceHeight;
+};
+
+#endif
diff --git a/filter/pdftoopvp/oprs/OPRS.cxx b/filter/pdftoopvp/oprs/OPRS.cxx
new file mode 100644
index 000000000..e9c7e86d1
--- /dev/null
+++ b/filter/pdftoopvp/oprs/OPRS.cxx
@@ -0,0 +1,604 @@
+//========================================================================
+//
+// OPRS.cc
+//
+//========================================================================
+
+#include <config.h>
+#ifdef HAVE_CPP_POPPLER_VERSION_H
+#include "cpp/poppler-version.h"
+#endif
+
+#ifdef USE_GCC_PRAGMAS
+#pragma implementation
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <stdarg.h>
+#include <math.h>
+#if defined __OpenBSD__
+#include <sys/endian.h>
+#if BYTE_ORDER == BIG_ENDIAN
+#define __BYTE_ORDER __BIG_ENDIAN
+#else
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
+#endif
+
+#include "goo/gmem.h"
+#include "splash/SplashErrorCodes.h"
+#include "splash/SplashMath.h"
+#include "splash/SplashBitmap.h"
+#include "splash/SplashState.h"
+#include "splash/SplashXPathScanner.h"
+#include "splash/SplashPattern.h"
+#include "splash/SplashScreen.h"
+#include "splash/SplashFont.h"
+#include "splash/SplashGlyphBitmap.h"
+#include "splash/Splash.h"
+#include "OPVPSplash.h"
+#include "OPVPSplashClip.h"
+#include "OPVPSplashPath.h"
+#include "OPVPSplashXPath.h"
+#include "OPRS.h"
+
+//------------------------------------------------------------------------
+// Splash
+//------------------------------------------------------------------------
+
+#define SPLASH(x) (rasterMode ? (splash->x) : (opvpSplash->x))
+
+OPRS::OPRS()
+{
+ opvp = 0;
+ splash = 0;
+ opvpSplash = 0;
+ rasterMode = gFalse;
+}
+
+int OPRS::setBitmap(SplashBitmap *bitmapA) {
+ if (splash != 0) {
+ delete splash;
+ }
+ splash = new Splash(bitmapA, gFalse);
+ rasterMode = gTrue;
+ return 0;
+}
+
+OPRS::~OPRS() {
+ if (splash != 0) {
+ delete splash;
+ splash = 0;
+ }
+ if (opvpSplash != 0) {
+ opvpSplash->restoreAllDriverState();
+ delete opvpSplash;
+ opvpSplash = 0;
+ }
+}
+
+//------------------------------------------------------------------------
+// state read
+//------------------------------------------------------------------------
+
+
+SplashPattern *OPRS::getStrokePattern() {
+ return SPLASH(getStrokePattern());
+}
+
+SplashPattern *OPRS::getFillPattern() {
+ return SPLASH(getFillPattern());
+}
+
+SplashScreen *OPRS::getScreen() {
+ return SPLASH(getScreen());
+}
+
+SplashCoord OPRS::getLineWidth() {
+ return SPLASH(getLineWidth());
+}
+
+int OPRS::getLineCap() {
+ return SPLASH(getLineCap());
+}
+
+int OPRS::getLineJoin() {
+ return SPLASH(getLineJoin());
+}
+
+SplashCoord OPRS::getMiterLimit() {
+ return SPLASH(getMiterLimit());
+}
+
+SplashCoord OPRS::getFlatness() {
+ return 1;
+}
+
+SplashCoord *OPRS::getLineDash() {
+ return SPLASH(getLineDash());
+}
+
+int OPRS::getLineDashLength() {
+ return SPLASH(getLineDashLength());
+}
+
+SplashCoord OPRS::getLineDashPhase() {
+ return SPLASH(getLineDashPhase());
+}
+
+OPVPSplashClip *OPRS::getClip() {
+ if (rasterMode) {
+ SplashClip *sclip = splash->getClip();
+ OPVPSplashClip *r = new OPVPSplashClip(sclip);
+ delete sclip;
+ return r;
+ } else {
+ return opvpSplash->getClip();
+ }
+}
+
+//------------------------------------------------------------------------
+// state write
+//------------------------------------------------------------------------
+
+void OPRS::setStrokePattern(SplashPattern *strokePattern) {
+ SPLASH(setStrokePattern(strokePattern));
+}
+
+void OPRS::setFillPattern(SplashPattern *fillPattern) {
+ SPLASH(setFillPattern(fillPattern));
+}
+
+void OPRS::setScreen(SplashScreen *screen) {
+ SPLASH(setScreen(screen));
+}
+
+void OPRS::setLineWidth(SplashCoord lineWidth) {
+ SPLASH(setLineWidth(lineWidth));
+}
+
+void OPRS::setMiterLimit(SplashCoord miterLimit) {
+ SPLASH(setMiterLimit(miterLimit));
+}
+
+void OPRS::setLineCap(int lineCap) {
+ SPLASH(setLineCap(lineCap));
+}
+
+void OPRS::setLineJoin(int lineJoin) {
+ SPLASH(setLineJoin(lineJoin));
+}
+
+void OPRS::setFlatness(SplashCoord flatness) {
+/* ignore flatness */
+}
+
+void OPRS::setLineDash(SplashCoord *lineDash, int lineDashLength,
+ SplashCoord lineDashPhase) {
+ SPLASH(setLineDash(lineDash,lineDashLength,lineDashPhase));
+}
+
+SplashError OPRS::clipToPath(OPVPSplashPath *path, GBool eo) {
+ return SPLASH(clipToPath(path,eo));
+}
+
+//------------------------------------------------------------------------
+// state save/restore
+//------------------------------------------------------------------------
+
+void OPRS::saveState() {
+ SPLASH(saveState());
+}
+
+SplashError OPRS::restoreState() {
+ SPLASH(restoreState());
+ return splashOk;
+}
+
+//------------------------------------------------------------------------
+// drawing operations
+//------------------------------------------------------------------------
+
+void OPRS::clear(SplashColor color) {
+ SPLASH(clear(color));
+}
+
+SplashError OPRS::stroke(OPVPSplashPath *path) {
+ return SPLASH(stroke(path));
+}
+
+SplashError OPRS::fill(OPVPSplashPath *path, GBool eo) {
+ return SPLASH(fill(path,eo));
+}
+
+SplashError OPRS::fillChar(SplashCoord x, SplashCoord y,
+ int c, SplashFont *font, Unicode *u,
+ double *fontMat) {
+ if (rasterMode) {
+ return splash->fillChar(x,y,c,font);
+ } else {
+ return opvpSplash->fillChar(x,y,c,font,u,fontMat);
+ }
+}
+
+SplashError OPRS::fillGlyph(SplashCoord x, SplashCoord y,
+ SplashGlyphBitmap *glyph) {
+ SPLASH(fillGlyph(x,y,glyph));
+ return splashOk;
+}
+
+SplashError OPRS::fillImageMask(SplashImageMaskSource src, void *srcData,
+ int w, int h, SplashCoord *mat, GBool glyphMode) {
+ return SPLASH(fillImageMask(src,srcData,w,h,mat,glyphMode));
+}
+
+SplashError OPRS::drawImage(SplashImageSource src, void *srcData,
+ SplashColorMode srcMode, GBool srcAlpha,
+ int w, int h, SplashCoord *mat) {
+ if (rasterMode) {
+#if POPPLER_VERSION_MAJOR <= 0 && (POPPLER_VERSION_MINOR <= 20 || (POPPLER_VERSION_MINOR == 21 && POPPLER_VERSION_MICRO <= 2))
+ return splash->drawImage(src,srcData,srcMode,srcAlpha,w,h,mat);
+#elif POPPLER_VERSION_MAJOR <= 0 && POPPLER_VERSION_MINOR <= 33
+ return splash->drawImage(src,srcData,srcMode,srcAlpha,w,h,mat,gFalse);
+#else
+ return splash->drawImage(src,0,srcData,srcMode,srcAlpha,w,h,mat,gFalse);
+#endif
+ } else {
+ return opvpSplash->drawImage(src,srcData,srcMode,srcAlpha,w,h,mat);
+ }
+}
+
+/*
+ * initialize and load vector-driver
+ */
+int OPRS::init(const char *driverName, int outputFD,
+ const char *printerModel, int nOptions,
+ const char *optionKeys[], const char *optionVals[])
+{
+ opvp = OPVPWrapper::loadDriver(driverName,outputFD,printerModel);
+ if (opvp == 0) return -1;
+ rasterMode = gFalse;
+ if (!rasterMode) {
+ opvpSplash = new OPVPSplash(opvp,nOptions,
+ optionKeys, optionVals);
+ }
+ return 0;
+}
+
+int OPRS::OPVPStartJob(char *jobInfo)
+{
+ if (!opvp->supportStartJob) {
+ return 0;
+ }
+ return opvp->StartJob((const opvp_char_t *)jobInfo);
+}
+
+int OPRS::OPVPEndJob()
+{
+ if (!opvp->supportEndJob) {
+ return 0;
+ }
+ return opvp->EndJob();
+}
+
+int OPRS::OPVPStartDoc(char *docInfo)
+{
+ if (!opvp->supportStartDoc) {
+ return 0;
+ }
+ return opvp->StartDoc((const opvp_char_t *)docInfo);
+}
+
+int OPRS::OPVPEndDoc()
+{
+ if (!opvp->supportEndDoc) {
+ return 0;
+ }
+ return opvp->EndDoc();
+}
+
+int OPRS::OPVPStartPage(char *pageInfo, int rasterWidth)
+{
+ int r;
+
+ if (opvp->supportStartPage) {
+ if ((r = opvp->StartPage((const opvp_char_t *)pageInfo)) < 0) {
+ return r;
+ }
+ }
+ if (rasterMode) {
+ if (!opvp->supportStartRaster) {
+ error("No StartRaster error in raster mode\n");
+ return -1;
+ }
+ if (opvp->supportSetCurrentPoint) {
+ opvp_fix_t x,y;
+
+ OPVP_F2FIX(0.0,x);
+ OPVP_F2FIX(0.0,y);
+ opvp->SetCurrentPoint(x,y);
+ }
+ opvp->StartRaster(rasterWidth);
+ }
+ return 0;
+}
+
+int OPRS::OPVPEndPage()
+{
+ int r;
+
+ if (rasterMode) {
+ if (!opvp->supportEndRaster) {
+ error("No EndRaster error in raster mode\n");
+ return -1;
+ }
+ opvp->EndRaster();
+ }
+ if (opvp->supportEndPage) {
+ if ((r = opvp->EndPage()) < 0) {
+ return r;
+ }
+ }
+ return splashOk;
+}
+
+unsigned char *OPRS::getScanLineDataMono1(unsigned char *dst,
+ unsigned char *bitmap, int rasterWidth)
+{
+ int n = (rasterWidth+7)/8;
+
+ memcpy(dst,bitmap,n);
+ return bitmap+n;
+}
+
+unsigned char *OPRS::getScanLineDataMono8(unsigned char *dst,
+ unsigned char *bitmap, int rasterWidth)
+{
+ memcpy(dst,bitmap,rasterWidth);
+ return bitmap+rasterWidth;
+}
+
+unsigned char *OPRS::getScanLineDataRGB8(unsigned char *dst,
+ unsigned char *bitmap, int rasterWidth)
+{
+ int i;
+
+ for (i = 0;i < rasterWidth;i++) {
+#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN
+ bitmap++;
+ *dst++ = *bitmap++;
+ *dst++ = *bitmap++;
+ *dst++ = *bitmap++;
+#else
+ dst[2] = *bitmap++;
+ dst[1] = *bitmap++;
+ dst[0] = *bitmap++;
+ bitmap++;
+ dst += 3;
+#endif
+ }
+ return bitmap;
+}
+
+unsigned char *OPRS::getScanLineDataBGR8Packed(unsigned char *dst,
+ unsigned char *bitmap, int rasterWidth)
+{
+ memcpy(dst,bitmap,rasterWidth*3);
+ return bitmap+rasterWidth*3;
+}
+
+OPRS::GetScanLineDataFunT OPRS::getGetScanLineDataFun(SplashBitmap *bitmap)
+{
+ switch (bitmap->getMode()) {
+ case splashModeMono1:
+ return getScanLineDataMono1;
+ case splashModeMono8:
+ return getScanLineDataMono8;
+ case splashModeRGB8:
+ return getScanLineDataRGB8;
+ default:
+ OPRS::error("Unknown bitmap mode\n");
+ break;
+ }
+ return getScanLineDataMono8;
+}
+
+int OPRS::getRasterSize(SplashBitmap *bitmap)
+{
+ int rw = bitmap->getWidth();
+
+ switch (bitmap->getMode()) {
+ case splashModeMono1:
+ return (rw+7)/8;
+ case splashModeMono8:
+ return rw;
+ case splashModeRGB8:
+ return rw*3;
+ default:
+ OPRS::error("Unknown bitmap mode\n");
+ break;
+ }
+ return 0;
+}
+
+GBool OPRS::checkAll1(unsigned char *bp, int n, int width, int mode)
+{
+ int lastbytemask = 0xff;
+ int i;
+
+ if (mode == splashModeMono1) {
+ lastbytemask <<= (width & 0x7);
+ lastbytemask &= 0xff;
+ }
+ for (i = 0;i < n-1;i++) {
+ if (*bp++ != 0xff) return gFalse;
+ }
+ return (*bp & lastbytemask) == lastbytemask;
+}
+
+int OPRS::outSlice()
+{
+ if (rasterMode) {
+ /* out bitmap */
+ int rasterWidth;
+ int nScanLines;
+ int rasterSize;
+ unsigned char *p;
+ int i;
+ SplashBitmap *bitmap;
+ SplashColorPtr cp;
+ unsigned char *bp;
+ GetScanLineDataFunT fun;
+ int mode;
+
+ if (!opvp->supportStartRaster || !opvp->supportTransferRasterData
+ || !opvp->supportEndRaster) {
+ OPRS::error("No raster supporting printer driver\n");
+ return -1;
+ }
+
+ bitmap = splash->getBitmap();
+ rasterWidth = bitmap->getWidth();
+ nScanLines = bitmap->getHeight();
+ rasterSize = getRasterSize(bitmap);
+ if ((bp = new unsigned char[rasterSize]) == 0) {
+ OPRS::error("Not enough memory\n");
+ return -1;
+ }
+ cp = (bitmap->getDataPtr());
+ p = reinterpret_cast<unsigned char *>(cp);
+ fun = getGetScanLineDataFun(bitmap);
+ mode = bitmap->getMode();
+ for (i = 0;i < nScanLines;i++) {
+ p = (*fun)(bp,p,rasterWidth);
+ if (opvp->supportSkipRaster
+ && checkAll1(bp,rasterSize,rasterWidth,mode)) {
+ /* all white, skip raster */
+ opvp->SkipRaster(1);
+ } else {
+ opvp->TransferRasterData(rasterSize,bp);
+ }
+ }
+ delete[] bp;
+ }
+ return 0;
+}
+
+int OPRS::setColorMode(int colorModeA, GBool colorProfile)
+{
+ opvp_cspace_t cspace = OPVP_CSPACE_STANDARDRGB;
+
+ if (opvp->supportGetColorSpace) opvp->GetColorSpace(&cspace);
+ switch (cspace){
+ case OPVP_CSPACE_BW:
+ if (colorModeA != splashModeMono1) {
+ OPRS::error("not mono mode is specified on a monochrome printer\n");
+ return -1;
+ }
+ break;
+ case OPVP_CSPACE_DEVICEGRAY:
+ if (colorModeA != splashModeMono1 && colorModeA != splashModeMono8) {
+ OPRS::error("colorMode is specified on not a color printer\n");
+ return -1;
+ }
+ break;
+ case OPVP_CSPACE_DEVICERGB:
+ if (colorProfile) break;
+ default:
+ /* rgb color */
+ if (colorProfile) {
+ /* try set colorspace to DEVICERGB */
+ if (opvp->supportSetColorSpace) opvp->SetColorSpace(
+ OPVP_CSPACE_DEVICERGB);
+ if (opvp->supportGetColorSpace) opvp->GetColorSpace(&cspace);
+ if (cspace == OPVP_CSPACE_DEVICERGB) break;
+ /* fail to set, fall through */
+ }
+ if (opvp->supportSetColorSpace) opvp->SetColorSpace(
+ OPVP_CSPACE_STANDARDRGB);
+ break;
+ }
+ if (!rasterMode) {
+ opvpSplash->setColorMode(colorModeA);
+ }
+ return 0;
+}
+
+SplashBitmap *OPRS::getBitmap()
+{
+ return SPLASH(getBitmap());
+}
+
+void OPRS::setDebugMode(GBool debugModeA)
+{
+ SPLASH(setDebugMode(debugModeA));
+}
+
+void OPRS::initGS(int colorMode, int w, int h, SplashColor paperColor)
+{
+ SplashColor color;
+
+ if (!rasterMode && opvp->supportInitGS) {
+ opvp->InitGS();
+ }
+ if (opvp->supportSetPaintMode) {
+ opvp->SetPaintMode(OPVP_PAINTMODE_TRANSPARENT);
+ }
+ switch (colorMode) {
+ case splashModeMono1: color[0] = 0; break;
+ case splashModeMono8: color[0] = 0; break;
+ case splashModeRGB8: color[0] = color[1] = color[2] = 0; break;
+ }
+ if (!rasterMode) {
+ opvpSplash->setStateBypass(gTrue);
+ }
+ SPLASH(setStrokePattern(new SplashSolidColor(color)));
+ SPLASH(setFillPattern(new SplashSolidColor(color)));
+ SPLASH(setLineCap(splashLineCapButt));
+ SPLASH(setLineJoin(splashLineJoinMiter));
+ SPLASH(setLineDash(0, 0, 0));
+ SPLASH(setLineWidth(0));
+ SPLASH(setMiterLimit(10));
+ SPLASH(setFlatness(1));
+ SPLASH(clipResetToRect(0,0,w-1,h-1));
+ SPLASH(clear(paperColor));
+ if (!rasterMode) {
+ opvpSplash->setStateBypass(gFalse);
+ }
+}
+
+void OPRS::error(const char *msg, ...)
+{
+ va_list args;
+
+ fprintf(stderr,"ERROR:OPRS:");
+ va_start(args, msg);
+ vfprintf(stderr, msg, args);
+ va_end(args);
+ fflush(stderr);
+}
+
+void OPRS::endPage()
+{
+ /* restore state */
+ while (SPLASH(restoreState()) == splashOk);
+ if (!rasterMode) {
+ opvpSplash->endPage();
+ }
+}
+
+void OPRS::setSoftMask(SplashBitmap *softMaskA)
+{
+ /* Soft Mask is not supported in vector mode. */
+ if (rasterMode) {
+ splash->setSoftMask(softMaskA);
+ }
+}
+
+SplashCoord *OPRS::getMatrix()
+{
+ return SPLASH(getMatrix());
+}
diff --git a/filter/pdftoopvp/oprs/OPRS.h b/filter/pdftoopvp/oprs/OPRS.h
new file mode 100644
index 000000000..d72dd1575
--- /dev/null
+++ b/filter/pdftoopvp/oprs/OPRS.h
@@ -0,0 +1,188 @@
+//========================================================================
+//
+// OPRS.h
+//
+//========================================================================
+
+#ifndef OPRS_H
+#define OPRS_H
+
+#include <config.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma interface
+#endif
+
+#include "splash/SplashTypes.h"
+#include "opvp_common.h"
+#include "splash/Splash.h"
+#include "OPVPSplash.h"
+#include "OPVPWrapper.h"
+
+#define OPVP_BUFF_SIZE 256
+
+class SplashBitmap;
+class SplashGlyphBitmap;
+class SplashState;
+class SplashPattern;
+class SplashScreen;
+class OPVPSplashPath;
+class SplashXPath;
+class OPVPSplashClip;
+class SplashFont;
+
+//------------------------------------------------------------------------
+// OPRS
+//------------------------------------------------------------------------
+
+class OPRS {
+public:
+
+ static void error(const char *msg, ...);
+ OPRS();
+ ~OPRS();
+
+ int setBitmap(SplashBitmap *bitmapA);
+
+ //----- state read
+
+ SplashPattern *getStrokePattern();
+ SplashPattern *getFillPattern();
+ SplashScreen *getScreen();
+ SplashCoord getLineWidth();
+ int getLineCap();
+ int getLineJoin();
+ SplashCoord getMiterLimit();
+ SplashCoord getFlatness();
+ SplashCoord *getLineDash();
+ int getLineDashLength();
+ SplashCoord getLineDashPhase();
+ OPVPSplashClip *getClip();
+
+ //----- state write
+
+ void setStrokePattern(SplashPattern *strokeColor);
+ void setFillPattern(SplashPattern *fillColor);
+ void setScreen(SplashScreen *screen);
+ void setLineWidth(SplashCoord lineWidth);
+ void setMiterLimit(SplashCoord miterLimit);
+ void setLineCap(int lineCap);
+ void setLineJoin(int lineJoin);
+ void setFlatness(SplashCoord flatness);
+ // the <lineDash> array will be copied
+ void setLineDash(SplashCoord *lineDash, int lineDashLength,
+ SplashCoord lineDashPhase);
+ SplashError clipToPath(OPVPSplashPath *path, GBool eo);
+
+ //----- state save/restore
+
+ void saveState();
+ SplashError restoreState();
+
+ void setSoftMask(SplashBitmap *softMaskA);
+
+ //----- drawing operations
+
+ // Fill the bitmap with <color>. This is not subject to clipping.
+ void clear(SplashColor color);
+
+ // Stroke a path using the current stroke pattern.
+ SplashError stroke(OPVPSplashPath *path);
+
+ // Fill a path using the current fill pattern.
+ SplashError fill(OPVPSplashPath *path, GBool eo);
+
+ // Draw a character, using the current fill pattern.
+ SplashError fillChar(SplashCoord x, SplashCoord y, int c, SplashFont *font,
+ Unicode *u, double *fontMat);
+
+ // Draw a glyph, using the current fill pattern. This function does
+ // not free any data, i.e., it ignores glyph->freeData.
+ SplashError fillGlyph(SplashCoord x, SplashCoord y,
+ SplashGlyphBitmap *glyph);
+
+ // Draws an image mask using the fill color. This will read <w>*<h>
+ // pixels from <src>, in raster order, starting with the top line.
+ // "1" pixels will be drawn with the current fill color; "0" pixels
+ // are transparent. The matrix:
+ // [ mat[0] mat[1] 0 ]
+ // [ mat[2] mat[3] 0 ]
+ // [ mat[4] mat[5] 1 ]
+ // maps a unit square to the desired destination for the image, in
+ // PostScript style:
+ // [x' y' 1] = [x y 1] * mat
+ // Note that the Splash y axis points downward, and the image source
+ // is assumed to produce pixels in raster order, starting from the
+ // top line.
+ SplashError fillImageMask(SplashImageMaskSource src, void *srcData,
+ int w, int h, SplashCoord *mat, GBool glyphMode);
+
+ // Draw an image. This will read <w>*<h> pixels from <src>, in
+ // raster order, starting with the top line. These pixels are
+ // assumed to be in the source mode, <srcMode>. The following
+ // combinations of source and target modes are supported:
+ // source target
+ // ------ ------
+ // Mono1 Mono1
+ // Mono8 Mono1 -- with dithering
+ // Mono8 Mono8
+ // RGB8 RGB8
+ // BGR8packed BGR8Packed
+ // The matrix behaves as for fillImageMask.
+ SplashError drawImage(SplashImageSource src, void *srcData,
+ SplashColorMode srcMode, GBool srcAlpha,
+ int w, int h, SplashCoord *mat);
+
+ //~ drawMaskedImage
+
+ //----- misc
+
+ // Return the associated bitmap.
+ SplashBitmap *getBitmap();
+
+ // Toggle debug mode on or off.
+ void setDebugMode(GBool debugModeA);
+
+ int init(const char *driverName, int outputFD,
+ const char *printerModel, int nOptions,
+ const char *optionKeys[], const char *optionVals[]);
+ void initGS(int colorMode, int w, int h, SplashColor paperColor);
+ int setColorMode(int colorModeA, GBool colorProfile);
+ int unloadVectorDriver();
+
+ int OPVPStartJob(char *jobInfo);
+ int OPVPEndJob();
+ int OPVPStartDoc(char *docInfo);
+ int OPVPEndDoc();
+ int OPVPStartPage(char *pageInfo, int rasterWidth);
+ int OPVPEndPage();
+ int outSlice();
+ Splash *getSplash() { return splash; }
+ int getRasterMode() { return rasterMode; }
+ void endPage();
+ SplashCoord *getMatrix();
+
+private:
+ int rasterMode;
+ OPVPSplash *opvpSplash;
+ Splash *splash;
+ OPVPWrapper *opvp;
+ int getRasterSize(SplashBitmap *bitmap);
+
+ typedef unsigned char *(*GetScanLineDataFunT)(unsigned char *dst,
+ unsigned char *bitmap, int rasterWidth);
+
+ static unsigned char *getScanLineDataMono1(unsigned char *dst,
+ unsigned char *bitmap, int rasterWidth);
+ static unsigned char *getScanLineDataMono8(unsigned char *dst,
+ unsigned char *bitmap, int rasterWidth);
+ static unsigned char *getScanLineDataRGB8(unsigned char *dst,
+ unsigned char *bitmap, int rasterWidth);
+ static unsigned char *getScanLineDataBGR8Packed(unsigned char *dst,
+ unsigned char *bitmap, int rasterWidth);
+
+ GetScanLineDataFunT getGetScanLineDataFun(SplashBitmap *bitmap);
+ GBool checkAll1(unsigned char *bp, int n, int width, int mode);
+};
+
+#endif
diff --git a/filter/pdftoopvp/oprs/OPVPSplash.cxx b/filter/pdftoopvp/oprs/OPVPSplash.cxx
new file mode 100644
index 000000000..d0b3f2044
--- /dev/null
+++ b/filter/pdftoopvp/oprs/OPVPSplash.cxx
@@ -0,0 +1,2327 @@
+//========================================================================
+//
+// OPVPSplash.cc
+//
+//========================================================================
+
+#include <config.h>
+#ifdef HAVE_CPP_POPPLER_VERSION_H
+#include "cpp/poppler-version.h"
+#endif
+
+#ifdef USE_GCC_PRAGMAS
+#pragma implementation
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <limits.h>
+#include "goo/gmem.h"
+#include "splash/SplashErrorCodes.h"
+#include "splash/SplashMath.h"
+#include "splash/SplashBitmap.h"
+#include "splash/SplashXPathScanner.h"
+#include "splash/SplashPattern.h"
+#include "splash/SplashScreen.h"
+#include "splash/SplashFont.h"
+#include "splash/SplashGlyphBitmap.h"
+#include "splash/Splash.h"
+#include "OPRS.h"
+#include "OPVPSplashState.h"
+#include "OPVPSplash.h"
+#include "OPVPSplashPath.h"
+#include "OPVPSplashXPath.h"
+#include "OPVPSplashClip.h"
+
+//------------------------------------------------------------------------
+// OPVPSplash
+//------------------------------------------------------------------------
+
+inline void OPVPSplash::transform(SplashCoord *matrix,
+ SplashCoord xi, SplashCoord yi,
+ SplashCoord *xo, SplashCoord *yo) {
+ // [ m[0] m[1] 0 ]
+ // [xo yo 1] = [xi yi 1] * [ m[2] m[3] 0 ]
+ // [ m[4] m[5] 1 ]
+ *xo = xi * matrix[0] + yi * matrix[2] + matrix[4];
+ *yo = xi * matrix[1] + yi * matrix[3] + matrix[5];
+}
+
+OPVPSplash::OPVPSplash(OPVPWrapper *opvpA,
+ int nOptions, const char *optionKeys[], const char *optionVals[])
+{
+ const char *opv;
+
+ opvp = opvpA;
+ // with default screen params
+ state = new OPVPSplashState(0,0,gFalse,(SplashScreenParams *)NULL);
+ debugMode = gFalse;
+ stateBypass = gFalse;
+ clipPath = 0;
+ if (getOption("OPVP_OLDLIPSDRIVER",nOptions,
+ optionKeys,optionVals) != NULL) {
+ oldLipsDriver = gTrue;
+ } else {
+ oldLipsDriver = gFalse;
+ }
+ if (getOption("OPVP_CLIPPATHNOTSAVED",nOptions,
+ optionKeys,optionVals) != NULL) {
+ clipPathNotSaved = gTrue;
+ } else {
+ clipPathNotSaved = gFalse;
+ }
+ if (getOption("OPVP_NOSHEARIMAGE",nOptions,
+ optionKeys,optionVals) != NULL) {
+ noShearImage = gTrue;
+ } else {
+ noShearImage = gFalse;
+ }
+ if (getOption("OPVP_NOLINESTYLE",nOptions,
+ optionKeys,optionVals) != NULL) {
+ noLineStyle = gTrue;
+ } else {
+ noLineStyle = gFalse;
+ }
+ if (!opvpA->supportSetLineStyle || !opvpA->supportSetLineDash
+ || !opvpA->supportSetLineDashOffset) {
+ noLineStyle = gTrue;
+ }
+ if (getOption("OPVP_NOCLIPPATH",nOptions,
+ optionKeys,optionVals) != NULL) {
+ noClipPath = gTrue;
+ } else {
+ noClipPath = gFalse;
+ }
+ if (getOption("OPVP_IGNOREMITERLIMIT",nOptions,
+ optionKeys,optionVals) != NULL) {
+ ignoreMiterLimit = gTrue;
+ } else {
+ ignoreMiterLimit = gFalse;
+ }
+ if (getOption("OPVP_NOMITERLIMIT",nOptions,
+ optionKeys,optionVals) != NULL) {
+ noMiterLimit = gTrue;
+ } else {
+ noMiterLimit = gFalse;
+ }
+ if (!opvpA->supportSetMiterLimit) {
+ noMiterLimit = gTrue;
+ }
+ if ((opv = getOption("OPVP_BITMAPCHARTHRESHOLD",nOptions,
+ optionKeys,optionVals)) != NULL) {
+ bitmapCharThreshold = atoi(opv);
+ } else {
+ bitmapCharThreshold = OPVP_BITMAPCHAR_THRESHOLD;
+ }
+ if ((opv = getOption("OPVP_MAXCLIPPATHLENGTH",nOptions,
+ optionKeys,optionVals)) != NULL) {
+ maxClipPathLength = atoi(opv);
+ } else {
+ maxClipPathLength = OPVP_MAX_CLIPPATH_LENGTH;
+ }
+ if ((opv = getOption("OPVP_MAXFILLPATHLENGTH",nOptions,
+ optionKeys,optionVals)) != NULL) {
+ maxFillPathLength = atoi(opv);
+ } else {
+ maxFillPathLength = OPVP_MAX_FILLPATH_LENGTH;
+ }
+ if (getOption("OPVP_NOIMAGEMASK",nOptions,
+ optionKeys,optionVals) != NULL) {
+ noImageMask = gTrue;
+ } else {
+ noImageMask = gFalse;
+ }
+ if (getOption("OPVP_NOBITMAPCHAR",nOptions,
+ optionKeys,optionVals) != NULL) {
+ bitmapCharThreshold = 0;
+ }
+ if (!opvpA->supportSetClipPath) {
+ noClipPath = gTrue;
+ }
+ savedNoClipPath = noClipPath;
+ saveDriverStateCount = 0;
+ if (noImageMask) {
+ /* We draw bitmapChar with imageMask feature.
+ So, when noImageMask, noBitmapChar */
+ bitmapCharThreshold = 0;
+ }
+#ifdef OPTION_DEBUG
+fprintf(stderr,"noClipPath=%d\n",noClipPath);
+fprintf(stderr,"oldLipsDriver=%d\n",oldLipsDriver);
+fprintf(stderr,"noLineStyle=%d\n",noLineStyle);
+fprintf(stderr,"noMiterLimit=%d\n",noMiterLimit);
+fprintf(stderr,"ignoreMiterLimit=%d\n",ignoreMiterLimit);
+fprintf(stderr,"noShearImage=%d\n",noShearImage);
+fprintf(stderr,"clipPathNotSaved=%d\n",clipPathNotSaved);
+fprintf(stderr,"bitmapCharThreshold=%d\n",bitmapCharThreshold);
+fprintf(stderr,"maxClipPathLength=%d\n",maxClipPathLength);
+#endif
+}
+
+OPVPSplash::~OPVPSplash()
+{
+ while (state->next) {
+ restoreState();
+ }
+ delete state;
+ if (opvp->supportClosePrinter) {
+ opvp->ClosePrinter();
+ }
+ delete opvp;
+}
+
+//------------------------------------------------------------------------
+// state read
+//------------------------------------------------------------------------
+
+
+SplashPattern *OPVPSplash::getStrokePattern() {
+ return state->strokePattern;
+}
+
+SplashPattern *OPVPSplash::getFillPattern() {
+ return state->fillPattern;
+}
+
+SplashScreen *OPVPSplash::getScreen() {
+ return state->screen;
+}
+
+SplashCoord OPVPSplash::getLineWidth() {
+ return state->lineWidth;
+}
+
+int OPVPSplash::getLineCap() {
+ return state->lineCap;
+}
+
+int OPVPSplash::getLineJoin() {
+ return state->lineJoin;
+}
+
+SplashCoord OPVPSplash::getMiterLimit() {
+ return state->miterLimit;
+}
+
+SplashCoord OPVPSplash::getFlatness() {
+ return state->flatness;
+}
+
+SplashCoord *OPVPSplash::getLineDash() {
+ return state->lineDash;
+}
+
+int OPVPSplash::getLineDashLength() {
+ return state->lineDashLength;
+}
+
+SplashCoord OPVPSplash::getLineDashPhase() {
+ return state->lineDashPhase;
+}
+
+OPVPSplashClip *OPVPSplash::getClip() {
+ return state->clip;
+}
+
+//------------------------------------------------------------------------
+// state write
+//------------------------------------------------------------------------
+
+opvp_cspace_t OPVPSplash::getOPVPColorSpace()
+{
+ switch (colorMode) {
+ case splashModeMono1:
+ return OPVP_CSPACE_BW;
+ break;
+ case splashModeMono8:
+ return OPVP_CSPACE_DEVICEGRAY;
+ break;
+ case splashModeRGB8:
+ default:
+ break;
+ }
+ return OPVP_CSPACE_STANDARDRGB;
+}
+
+void OPVPSplash::makeBrush(SplashPattern *pattern, opvp_brush_t *brush)
+{
+ brush->colorSpace = getOPVPColorSpace();
+ brush->pbrush = NULL;
+ brush->color[3] = -1;
+ brush->xorg = brush->yorg = 0;
+ if (pattern == NULL) {
+ /* set default black color */
+ brush->color[2] = 0;
+ brush->color[1] = 0;
+ brush->color[0] = 0;
+ } else if (typeid(*pattern) == typeid(SplashSolidColor)) {
+ /* solid color */
+ SplashColor color;
+
+ pattern->getColor(0,0,color);
+ switch (colorMode) {
+ case splashModeMono1:
+ brush->color[2] = color[0];
+ brush->color[1] = 0;
+ brush->color[0] = 0;
+ break;
+ case splashModeMono8:
+ brush->color[2] = color[0];
+ brush->color[1] = 0;
+ brush->color[0] = 0;
+ break;
+ case splashModeRGB8:
+ brush->color[2] = splashRGB8R(color);
+ brush->color[1] = splashRGB8G(color);
+ brush->color[0] = splashRGB8B(color);
+ break;
+ default:
+ OPRS::error("Unknown color mode\n");
+ brush->color[2] = splashRGB8R(color);
+ brush->color[1] = splashRGB8G(color);
+ brush->color[0] = splashRGB8B(color);
+ break;
+ }
+ } else {
+ /* error */
+ return;
+ }
+}
+
+GBool OPVPSplash::equalPattern(SplashPattern *pat1, SplashPattern *pat2)
+{
+ SplashColor c1, c2;
+ if (pat1 == NULL || pat2 == NULL) {
+ return pat1 == pat2;
+ }
+ if (typeid(*pat1) != typeid(*pat2)) return gFalse;
+
+ pat1->getColor(0,0,c1);
+ pat2->getColor(0,0,c2);
+ switch (colorMode) {
+ case splashModeMono1:
+ return c1[0] == c2[0];
+ break;
+ case splashModeMono8:
+ return c1[0] == c2[0];
+ break;
+ case splashModeRGB8:
+ return c1[0] == c2[0] && c1[1] == c2[1] && c1[2] == c2[2];
+ break;
+ default:
+ break;
+ }
+ return gTrue;
+}
+
+void OPVPSplash::setStrokePattern(SplashPattern *strokePattern) {
+ opvp_brush_t brush;
+
+ if (!stateBypass && equalPattern(strokePattern,state->strokePattern)) {
+ delete strokePattern;
+ return;
+ }
+ state->setStrokePattern(strokePattern);
+ makeBrush(strokePattern,&brush);
+ if (opvp->SetStrokeColor(&brush) != 0) {
+ OPRS::error("SetStrokeColor error\n");
+ return;
+ }
+}
+
+void OPVPSplash::setFillPattern(SplashPattern *fillPattern) {
+ opvp_brush_t brush;
+
+ if (!stateBypass && equalPattern(fillPattern,state->fillPattern)) {
+ delete fillPattern;
+ return;
+ }
+ state->setFillPattern(fillPattern);
+ makeBrush(fillPattern,&brush);
+ if (opvp->SetFillColor(&brush) != 0) {
+ OPRS::error("SetFillColor error\n");
+ return;
+ }
+}
+
+void OPVPSplash::setScreen(SplashScreen *screen) {
+ state->setScreen(screen);
+}
+
+void OPVPSplash::setLineWidth(SplashCoord lineWidth) {
+ if (stateBypass || state->lineWidth != lineWidth) {
+ opvp_fix_t width;
+
+ state->lineWidth = lineWidth;
+ OPVP_F2FIX(lineWidth,width);
+ if (opvp->SetLineWidth(width) < 0) {
+ OPRS::error("SetLineWidth error\n");
+ return;
+ }
+ }
+}
+
+void OPVPSplash::setLineCap(int lineCap) {
+ if (stateBypass || state->lineCap != lineCap) {
+ opvp_linecap_t cap;
+
+ state->lineCap = lineCap;
+ switch (lineCap) {
+ case splashLineCapButt:
+ cap = OPVP_LINECAP_BUTT;
+ break;
+ case splashLineCapRound:
+ cap = OPVP_LINECAP_ROUND;
+ break;
+ case splashLineCapProjecting:
+ cap = OPVP_LINECAP_SQUARE;
+ break;
+ default:
+ /* error */
+ cap = OPVP_LINECAP_BUTT;
+ break;
+ }
+ if (opvp->SetLineCap(cap) < 0) {
+ OPRS::error("SetLineCap error\n");
+ return;
+ }
+ }
+}
+
+void OPVPSplash::setLineJoin(int lineJoin) {
+ if (stateBypass || state->lineJoin != lineJoin) {
+ opvp_linejoin_t join;
+
+ state->lineJoin = lineJoin;
+ switch (lineJoin) {
+ case splashLineJoinMiter:
+ join = OPVP_LINEJOIN_MITER;
+ break;
+ case splashLineJoinRound:
+ join = OPVP_LINEJOIN_ROUND;
+ break;
+ case splashLineJoinBevel:
+ join = OPVP_LINEJOIN_BEVEL;
+ break;
+ default:
+ /* error */
+ join = OPVP_LINEJOIN_MITER;
+ break;
+ }
+ if (opvp->SetLineJoin(join) < 0) {
+ OPRS::error("SetLineJoin error\n");
+ return;
+ }
+ }
+}
+
+void OPVPSplash::setMiterLimit(SplashCoord miterLimit) {
+ if (stateBypass || state->miterLimit != miterLimit) {
+ opvp_fix_t limit;
+
+ state->miterLimit = miterLimit;
+ if (noMiterLimit) return;
+ if (oldLipsDriver) {
+ /* for old driver for lips */
+ /* miterLimit is length/2 */
+ miterLimit = miterLimit*state->lineWidth*0.5;
+ }
+ OPVP_F2FIX(miterLimit,limit);
+ if (opvp->SetMiterLimit(limit) < 0) {
+ OPRS::error("SetMiterLimit error\n");
+ return;
+ }
+ }
+}
+
+void OPVPSplash::setFlatness(SplashCoord flatness) {
+ if (flatness < 1) {
+ state->flatness = 1;
+ } else {
+ state->flatness = flatness;
+ }
+}
+
+void OPVPSplash::setLineDash(SplashCoord *lineDash, int lineDashLength,
+ SplashCoord lineDashPhase) {
+ int i;
+ opvp_fix_t *pdash;
+ GBool equal;
+
+ if (stateBypass || lineDash != state->lineDash) {
+ if (lineDash == NULL || lineDashLength == 0) {
+ if (!noLineStyle
+ && opvp->SetLineStyle(OPVP_LINESTYLE_SOLID) < 0) {
+ OPRS::error("SetLineStyle error\n");
+ return;
+ }
+ state->setLineDash(lineDash, lineDashLength, lineDashPhase);
+ return;
+ } else if (stateBypass || state->lineDash == NULL) {
+ if (!noLineStyle
+ && opvp->SetLineStyle(OPVP_LINESTYLE_DASH) < 0) {
+ OPRS::error("SetLineStyle error\n");
+ return;
+ }
+ }
+ }
+ if (lineDash == NULL || lineDashLength == 0) return;
+ if (!noLineStyle) {
+ equal = (state->lineDash != NULL);
+ pdash = new opvp_fix_t[lineDashLength];
+ for (i = 0;i < lineDashLength;i++) {
+ if (equal && lineDash[i] != state->lineDash[i]) equal = gFalse;
+ OPVP_F2FIX(lineDash[i],pdash[i]);
+ }
+ if (!equal && opvp->SetLineDash(lineDashLength,pdash) < 0) {
+ OPRS::error("SetLineDash error\n");
+ goto err;
+ }
+ if (stateBypass || lineDashPhase != state->lineDashPhase) {
+ opvp_fix_t offset;
+
+ OPVP_F2FIX(lineDashPhase,offset);
+ if (opvp->SetLineDashOffset(offset) < 0) {
+ OPRS::error("SetLineDashOffset error\n");
+ goto err;
+ }
+ }
+err:
+ delete[] pdash;
+ }
+ state->setLineDash(lineDash, lineDashLength, lineDashPhase);
+}
+
+SplashError OPVPSplash::doClipPath(OPVPSplashPath *path, GBool eo,
+ OPVPClipPath *prevClip)
+{
+ SplashError result;
+
+ if (path->getLength() > maxClipPathLength) {
+ if (!noClipPath) {
+ if (prevClip != 0 &&
+ prevClip->getPath()->getLength() <= maxClipPathLength) {
+ /* previous clipping is printer clipping */
+ if (opvp->ResetClipPath() != 0) {
+ OPRS::error("ResetClipPath error\n");
+ return splashErrOPVP;
+ }
+ }
+ noClipPath = gTrue;
+ }
+ } else {
+ noClipPath = savedNoClipPath;
+ }
+ if (!noClipPath && path->getLength() > 0) {
+ /* when path->length == 0, no drawable arae, and no output
+ so, it isn't need to set ClipPath */
+ if ((result = path->makePath(opvp)) != splashOk) {
+ return result;
+ }
+ if (opvp->SetClipPath(
+ eo ? OPVP_CLIPRULE_EVENODD : OPVP_CLIPRULE_WINDING) < 0) {
+ OPRS::error("SetClipPath error\n");
+ return splashErrOPVP;
+ }
+ }
+ return splashOk;
+}
+
+SplashError OPVPSplash::makeRectanglePath(SplashCoord x0,
+ SplashCoord y0, SplashCoord x1, SplashCoord y1, OPVPSplashPath **p)
+{
+ SplashError result;
+
+ *p = new OPVPSplashPath();
+ if ((result = (*p)->moveTo(x0,y0)) != splashOk) return result;
+ if ((result = (*p)->lineTo(x1,y0)) != splashOk) return result;
+ if ((result = (*p)->lineTo(x1,y1)) != splashOk) return result;
+ if ((result = (*p)->lineTo(x0,y1)) != splashOk) return result;
+ if ((result = (*p)->close()) != splashOk) return result;
+ return splashOk;
+}
+
+void OPVPSplash::clipResetToRect(SplashCoord x0, SplashCoord y0,
+ SplashCoord x1, SplashCoord y1) {
+ OPVPSplashPath *p;
+ OPVPClipPath *cp;
+
+ while ((cp = OPVPClipPath::pop()) != NULL) delete cp;
+ if (clipPath != 0) {
+ delete clipPath;
+ clipPath = 0;
+ }
+
+ if (makeRectanglePath(x0,y0,x1,y1,&p) != splashOk) return;
+
+ if (doClipPath(p,gTrue,clipPath) != splashOk) return;
+ clipPath = new OPVPClipPath(p,gTrue);
+ state->clip->resetToRect(x0, y0, x1, y1);
+}
+
+SplashError OPVPSplash::clipToPath(OPVPSplashPath *path, GBool eo) {
+ SplashError result;
+ SplashCoord x0, y0, x1, y1;
+ SplashCoord x2, y2, x3, y3;
+ SplashClipResult clipResult;
+ int xMin, yMin, xMax, yMax;
+
+ if (path == 0) return splashErrBogusPath;
+ if (path->getLength() == 0) return splashOk;
+ if (clipPath == 0) {
+ /* no clip region exist */
+ if ((result = state->clip->clipToPath(path, state->matrix,
+ state->flatness, eo)) != splashOk) {
+ return result;
+ }
+ path = path->copy();
+ } else {
+ OPVPSplashPath *oldPath = clipPath->getPath();
+ if (path->isRectanglePath(&x0,&y0,&x1,&y1)) {
+ if ((clipResult = state->clip->testRect(
+ splashRound(x0), splashRound(y0), splashRound(x1), splashRound(y1)))
+ == splashClipAllOutside) {
+ /* no drawable area */
+ if ((result = state->clip->clipToPath(path, state->matrix,
+ state->flatness, eo)) != splashOk) {
+ return result;
+ }
+ path = new OPVPSplashPath();
+ } else if (clipResult == splashClipPartial) {
+ if (oldPath->isRectanglePath(&x2,&y2,&x3,&y3)) {
+ if ((result = state->clip->clipToPath(path, state->matrix,
+ state->flatness, eo)) != splashOk) {
+ return result;
+ }
+ /* both rectangle */
+ if (x0 < x2) x0 = x2;
+ if (y0 < y2) y0 = y2;
+ if (x1 > x3) x1 = x3;
+ if (y1 > y3) y1 = y3;
+ if ((result = makeRectanglePath(x0,y0,x1,y1,&path)) != splashOk) {
+ return result;
+ }
+ } else {
+ state->clip->getBBox(&xMin,&yMin,&xMax,&yMax);
+ if (splashRound(x0) <= xMin && splashRound(y0) <= yMin
+ && splashRound(x1) >= xMax && splashRound(y1)) {
+ /* The old path is all inside the new path */
+ /* We may ignore the new path */
+ return splashOk;
+ }
+ if ((result = state->clip->clipToPath(path, state->matrix,
+ state->flatness, eo)) != splashOk) {
+ return result;
+ }
+ if (state->clip->getNumPaths() > 0) {
+ path = state->clip->makePath();
+ } else {
+ path = new OPVPSplashPath();
+ }
+ }
+ } else {
+ /* splashClipAllInside */
+ /* We may ignore the previous region. */
+ if ((result = state->clip->clipToPath(path, state->matrix,
+ state->flatness, eo)) != splashOk) {
+ return result;
+ }
+ path = path->copy();
+ }
+ } else {
+ /* non rectangle path */
+
+ OPVPSplashXPath *xpath = new OPVPSplashXPath(path, state->matrix,
+ state->flatness, gFalse);
+
+ xpath->sort();
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+ SplashXPathScanner *scanner = new SplashXPathScanner(xpath,eo,
+ INT_MIN,INT_MAX);
+#else
+ SplashXPathScanner *scanner = new SplashXPathScanner(xpath,eo);
+#endif
+ scanner->getBBox(&xMin,&yMin,&xMax,&yMax);
+ delete scanner;
+ delete xpath;
+ if ((clipResult = state->clip->testRect(xMin,yMin,xMax,yMax))
+ == splashClipAllOutside) {
+ /* no efect */
+ /* no drawable area */
+ if ((result = state->clip->clipToPath(path, state->matrix,
+ state->flatness, eo)) != splashOk) {
+ return result;
+ }
+ path = new OPVPSplashPath();
+ } else if (clipResult == splashClipPartial) {
+ OPVPSplashClip *nclip = new OPVPSplashClip(xMin,yMin,xMax,yMax,gFalse);
+ nclip->clipToPath(path,state->matrix,state->flatness,eo);
+ state->clip->getBBox(&xMin,&yMin,&xMax,&yMax);
+ if ((clipResult = nclip->testRect(xMin,yMin,xMax,yMax))
+ == splashClipAllOutside) {
+ /* no drawable area */
+ delete nclip;
+ if ((result = state->clip->clipToPath(path, state->matrix,
+ state->flatness, eo)) != splashOk) {
+ return result;
+ }
+ path = new OPVPSplashPath();
+ } else {
+ delete nclip;
+ if (clipResult == splashClipAllInside) {
+ /* The old path is all inside the new path */
+ /* We may ignore the new path */
+ return splashOk;
+ }
+ if ((result = state->clip->clipToPath(path, state->matrix,
+ state->flatness, eo)) != splashOk) {
+ return result;
+ }
+ if (state->clip->getNumPaths() > 0) {
+ path = state->clip->makePath();
+ } else {
+ path = new OPVPSplashPath();
+ }
+ }
+ } else {
+ /* splashClipAllInside */
+ /* We may ignore the previous region. */
+ if ((result = state->clip->clipToPath(path, state->matrix,
+ state->flatness, eo)) != splashOk) {
+ return result;
+ }
+ path = path->copy();
+ }
+ }
+ }
+ if ((result = doClipPath(path,eo,clipPath)) != splashOk) {
+ delete path;
+ return result;
+ }
+ if (clipPath != 0) delete clipPath;
+ clipPath = new OPVPClipPath(path,eo);
+
+ return splashOk;
+}
+
+//------------------------------------------------------------------------
+// state save/restore
+//------------------------------------------------------------------------
+
+void OPVPSplash::saveState() {
+ OPVPSplashState *newState;
+
+ newState = state->copy();
+ newState->next = state;
+ state = newState;
+ if (clipPath != 0) clipPath->push();
+ if (opvp->SaveGS() != 0) {
+ OPRS::error("SaveGS error\n");
+ return;
+ }
+ saveDriverStateCount++;
+}
+
+SplashError OPVPSplash::restoreState() {
+ OPVPSplashState *oldState;
+ OPVPClipPath *oldClip;
+ OPVPSplashPath *path;
+ GBool saved = gFalse;
+
+ if (!state->next) {
+ return splashErrNoSave;
+ }
+ oldState = state;
+ state = state->next;
+ delete oldState;
+ if (saveDriverStateCount > 0 && opvp->RestoreGS() != 0) {
+ OPRS::error("RestoreGS error\n");
+ return splashErrOPVP;
+ }
+ saveDriverStateCount--;
+ oldClip = clipPath;
+ if (clipPath != 0) {
+ saved = clipPath->getSaved();
+ delete clipPath;
+ clipPath = 0;
+ }
+ clipPath = OPVPClipPath::pop();
+ if (clipPath != 0) {
+ path = clipPath->getPath();
+ if (path->getLength() > maxClipPathLength) {
+ if (clipPathNotSaved && !noClipPath) {
+ if (opvp->ResetClipPath() != 0) {
+ OPRS::error("ResetClipPath error\n");
+ return splashErrOPVP;
+ }
+ noClipPath = gTrue;
+ }
+ } else {
+ noClipPath = savedNoClipPath;
+ }
+ } else {
+ noClipPath = savedNoClipPath;
+ }
+ if (clipPathNotSaved && !noClipPath) {
+ if (clipPath != 0) {
+ if (!saved) {
+ SplashError result;
+
+ if ((result = doClipPath(clipPath->getPath(),clipPath->getEo(),
+ oldClip))
+ != splashOk) return result;
+ }
+ } else if (oldClip != 0) {
+ if (opvp->ResetClipPath() != 0) {
+ OPRS::error("ResetClipPath error\n");
+ return splashErrOPVP;
+ }
+ }
+ }
+ return splashOk;
+}
+
+//------------------------------------------------------------------------
+// drawing operations
+//------------------------------------------------------------------------
+
+void OPVPSplash::clear(SplashColor color)
+{
+ opvp_brush_t brush;
+
+ brush.colorSpace = getOPVPColorSpace();
+ brush.pbrush = NULL;
+ brush.color[3] = -1;
+ brush.xorg = brush.yorg = 0;
+ switch (colorMode) {
+ case splashModeMono1:
+ brush.color[2] = color[0];
+ brush.color[1] = 0;
+ brush.color[0] = 0;
+ break;
+ case splashModeMono8:
+ brush.color[2] = color[0];
+ brush.color[1] = 0;
+ brush.color[0] = 0;
+ break;
+ case splashModeRGB8:
+ brush.color[2] = splashRGB8R(color);
+ brush.color[1] = splashRGB8G(color);
+ brush.color[0] = splashRGB8B(color);
+ break;
+ default:
+ OPRS::error("Unknown color mode\n");
+ brush.color[2] = splashRGB8R(color);
+ brush.color[1] = splashRGB8G(color);
+ brush.color[0] = splashRGB8B(color);
+ break;
+ }
+ opvp->SetBgColor(&brush);
+}
+
+/*
+ Translate arc to Bezier Curve
+
+ input start point (x0,y0) , center (cx, cy) and end point (x3, y3)
+ return Bezier curve control points (rx1,ry1 and rx2, ry2)
+
+ an angle should be less than eqaul 90 degree
+
+*/
+void OPVPSplash::arcToCurve(SplashCoord x0, SplashCoord y0,
+ SplashCoord x3, SplashCoord y3,
+ SplashCoord cx, SplashCoord cy, SplashCoord *rx1, SplashCoord *ry1,
+ SplashCoord *rx2, SplashCoord *ry2)
+{
+#define ROTX(x,y) (x*rotcos-y*rotsin)*r+cx
+#define ROTY(x,y) (x*rotsin+y*rotcos)*r+cy
+
+ SplashCoord x1,y1,x2,y2;
+ SplashCoord r;
+ SplashCoord rotcos, rotsin;
+ SplashCoord ox,oy,hx,hy,d;
+
+ hx = (x0+x3)/2;
+ hy = (y0+y3)/2;
+ r = splashDist(x0,y0,cx,cy);
+ d = splashDist(x0,y0,hx,hy);
+ rotcos = (hx-cx)/d;
+ rotsin = (hy-cy)/d;
+ oy = (splashDist(x0,y0,x3,y3)/2)/r;
+ ox = splashDist(hx,hy,cx,cy)/r;
+ x1 = ((4-ox)/3);
+ y1 = ((1-ox)*(3-ox)/(3*oy));
+ x2 = x1;
+ y2 = -y1;
+ *rx1 = ROTX(x1,y1);
+ *ry1 = ROTY(x1,y1);
+ *rx2 = ROTX(x2,y2);
+ *ry2 = ROTY(x2,y2);
+#undef ROTX
+#undef ROTY
+}
+
+SplashError OPVPSplash::strokeByMyself(OPVPSplashPath *path)
+{
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+ SplashPath *dPath;
+ OPVPSplashPath *oPath;
+ Splash *osplash;
+ SplashPattern *savedPattern;
+
+ /* draw dashed line by myself */
+ if (path->getLength() == 0) {
+ return splashOk;
+ }
+
+ osplash = new Splash(new SplashBitmap(1,1,4,splashModeMono1,gFalse),gFalse);
+ state->setState(osplash);
+ dPath = osplash->makeStrokePath(path,state->lineWidth);
+ oPath = new OPVPSplashPath(dPath);
+ delete dPath;
+
+ if (state->lineWidth <= 1) {
+ OPVPSplashXPath *xPath;
+ xPath = new OPVPSplashXPath(oPath, state->matrix, state->flatness, gFalse);
+ xPath->strokeNarrow(this,state);
+ delete xPath;
+ } else {
+ /* change fill pattern temprarily */
+ savedPattern = state->fillPattern->copy();
+ setFillPattern(state->strokePattern->copy());
+
+ fillByMyself(oPath,gFalse);
+
+ /* restore fill pattern */
+ setFillPattern(savedPattern);
+ }
+ delete osplash;
+ return splashOk;
+#else
+ OPVPSplashXPath *xPath, *xPath2;
+ SplashPattern *savedPattern;
+
+ /* draw dashed line by myself */
+ if (path->getLength() == 0) {
+ return splashOk;
+ }
+ xPath = new OPVPSplashXPath(path, state->matrix, state->flatness, gFalse);
+ if (state->lineDash != NULL && state->lineDashLength > 0) {
+ xPath2 = xPath->makeDashedPath(state);
+ delete xPath;
+ xPath = xPath2;
+ }
+
+ if (state->lineWidth <= 1) {
+ xPath->strokeNarrow(this,state);
+ } else {
+ /* change fill pattern temprarily */
+ savedPattern = state->fillPattern->copy();
+ setFillPattern(state->strokePattern->copy());
+
+ xPath->strokeWide(this,state);
+
+ /* restore fill pattern */
+ setFillPattern(savedPattern);
+ }
+
+ delete xPath;
+ return splashOk;
+#endif
+}
+
+SplashError OPVPSplash::stroke(OPVPSplashPath *path) {
+ SplashError result;
+
+ if (clipPath != 0 && clipPath->getPath()->getLength() == 0) {
+ return splashOk;
+ }
+ if ((state->lineDash != NULL
+ && state->lineDashLength > 0 && noLineStyle)) {
+ return strokeByMyself(path);
+ }
+ if (noMiterLimit && (!ignoreMiterLimit) && state->lineWidth != 0
+ && state->lineJoin == splashLineJoinMiter) {
+ return strokeByMyself(path);
+ }
+ if (noClipPath) {
+ int xMin, yMin, xMax, yMax;
+ SplashClipResult clipResult;
+ int fatOffset = splashCeil(state->lineWidth/2);
+ int miterLimit = splashCeil(state->miterLimit/2);
+
+ if (fatOffset < miterLimit) fatOffset = miterLimit;
+ path->getBBox(&xMin,&yMin,&xMax,&yMax);
+ xMin -= fatOffset;
+ yMin -= fatOffset;
+ xMax += fatOffset;
+ yMax += fatOffset;
+ clipResult = state->clip->testRect(xMin,yMin,xMax,yMax);
+ if (clipResult == splashClipAllOutside) {
+ /* not need to draw */
+ return splashOk;
+ } else if (clipResult == splashClipPartial) {
+ return strokeByMyself(path);
+ }
+ /* splashClipAllInside */
+ /* fall through */
+ }
+ if ((result = path->makePath(opvp)) != 0) return result;
+ if (opvp->StrokePath() < 0) {
+ OPRS::error("StrokePath error\n");
+ return splashErrOPVP;
+ }
+ return splashOk;
+}
+
+SplashError OPVPSplash::fillByMyself(OPVPSplashPath *path, GBool eo)
+{
+ OPVPSplashXPath *xPath;
+ SplashXPathScanner *scanner;
+ int xMinI, yMinI, xMaxI, yMaxI, x0, x1, y;
+ SplashClipResult clipRes, clipRes2;
+
+ if (path->getLength() == 0) {
+ return splashOk;
+ }
+ xPath = new OPVPSplashXPath(path, state->matrix, state->flatness, gTrue);
+ xPath->sort();
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+ scanner = new SplashXPathScanner(xPath, eo, INT_MIN, INT_MAX);
+#else
+ scanner = new SplashXPathScanner(xPath, eo);
+#endif
+
+ // get the min and max x and y values
+ scanner->getBBox(&xMinI, &yMinI, &xMaxI, &yMaxI);
+
+ // check clipping
+ if ((clipRes = state->clip->testRect(xMinI, yMinI, xMaxI, yMaxI))
+ != splashClipAllOutside) {
+ SplashPattern *savedPattern;
+
+ /* change stroke pattern temporarily */
+ savedPattern = state->strokePattern->copy();
+ setStrokePattern(state->fillPattern->copy());
+
+ for (y = yMinI; y < yMaxI; ++y) {
+ while (scanner->getNextSpan(y, &x0, &x1)) {
+ if (x0 == x1) continue;
+ if (clipRes == splashClipAllInside) {
+ drawSpan(x0, x1-1, y, gTrue);
+ } else {
+ clipRes2 = state->clip->testSpan(x0, x1, y);
+ drawSpan(x0, x1-1, y, clipRes2 == splashClipAllInside);
+ }
+ }
+ }
+ /* restore stroke pattern */
+ setStrokePattern(savedPattern);
+ }
+
+ delete scanner;
+ delete xPath;
+ return splashOk;
+}
+
+SplashError OPVPSplash::fill(OPVPSplashPath *path, GBool eo) {
+ SplashError result;
+ opvp_fillmode_t mode;
+
+ if (path->getLength() <= 1) return splashOk;
+ if (clipPath != 0 && clipPath->getPath()->getLength() == 0) {
+ return splashOk;
+ }
+ if (path->getLength() > maxFillPathLength) {
+ return fillByMyself(path,eo);
+ }
+ if (noClipPath) {
+ int xMin, yMin, xMax, yMax;
+ SplashClipResult clipResult;
+
+ path->getBBox(&xMin,&yMin,&xMax,&yMax);
+ clipResult = state->clip->testRect(xMin,yMin,xMax,yMax);
+ if (clipResult == splashClipAllOutside) {
+ /* not need to draw */
+ return splashOk;
+ } else if (clipResult == splashClipPartial) {
+ return fillByMyself(path,eo);
+ }
+ /* splashClipAllInside */
+ /* fall through */
+ }
+ if ((result = path->makePath(opvp)) != 0) return result;
+ mode = eo ? OPVP_FILLMODE_EVENODD : OPVP_FILLMODE_WINDING;
+ if (opvp->SetFillMode(mode) < 0) {
+ OPRS::error("SetFillMode error\n");
+ return splashErrOPVP;
+ }
+ if (opvp->FillPath() < 0) {
+ OPRS::error("FillPath error\n");
+ return splashErrOPVP;
+ }
+ return splashOk;
+}
+
+void OPVPSplash::fillGlyph(SplashCoord x, SplashCoord y,
+ SplashGlyphBitmap *glyph)
+{
+ opvp_fix_t opvpx,opvpy;
+ int opvpbytes;
+ int x0, y0;
+ Guchar *bp;
+ SplashClipResult clipRes;
+ SplashCoord xt, yt;
+
+ transform(state->matrix,x,y,&xt,&yt);
+ x0 = splashFloor(xt)-glyph->x;
+ y0 = splashFloor(yt)-glyph->y;
+ clipRes = state->clip->testRect(x0,y0,
+ x0 + glyph->w - 1,
+ y0 + glyph->h - 1);
+ if (clipRes == splashClipAllOutside) return;
+ OPVP_i2Fix((x0),(opvpx));
+ OPVP_i2Fix((y0),(opvpy));
+ if (opvp->SetCurrentPoint(opvpx,opvpy) < 0) {
+ OPRS::error("SetCurrentPoint error\n");
+ }
+
+ if (oldLipsDriver && (((glyph->w+7)/8) & 3) != 0) {
+ /* not 4bytes aligned, so make aligned */
+ int i;
+ int m = (glyph->w+7)/8;
+
+ opvpbytes = (m+3)/4;
+ opvpbytes *= 4;
+ bp = (Guchar *)gmallocn(glyph->h,opvpbytes);
+ for (i = 0;i < glyph->h;i++) {
+ memcpy(bp+i*opvpbytes,glyph->data+i*m,m);
+ }
+ } else {
+ bp = glyph->data;
+ opvpbytes = (glyph->w+7)/8;
+ }
+ if ((!noClipPath || clipRes != splashClipPartial) && !noImageMask) {
+ if (opvp->DrawImage(glyph->w,glyph->h,opvpbytes,OPVP_IFORMAT_MASK,
+ glyph->w,glyph->h,(void *)bp) < 0) {
+ OPRS::error("DrawImage error\n");
+ }
+ } else {
+ int tx,ty;
+ int sx = 0;
+ SplashPattern *savedPattern;
+ SplashCoord *savedLineDash = 0;
+ int savedLineDashLength;
+ SplashCoord savedLineDashPhase;
+ SplashCoord savedLineWidth;
+
+ /* change stroke pattern temprarily */
+ savedPattern = state->strokePattern->copy();
+ setStrokePattern(state->fillPattern->copy());
+ /* change lins style temporarily */
+ savedLineDashLength = state->lineDashLength;
+ savedLineDashPhase = state->lineDashPhase;
+ if (savedLineDashLength > 0 && state->lineDash != 0) {
+ savedLineDash = new SplashCoord[savedLineDashLength];
+ memcpy(savedLineDash, state->lineDash,
+ savedLineDashLength*sizeof(SplashCoord));
+ }
+ setLineDash(0,0,0);
+ savedLineWidth = state->lineWidth;
+ setLineWidth(0.0);
+
+
+ for (ty = 0;ty < glyph->h;ty++) {
+ GBool dmode = gFalse;
+ for (tx = 0;tx < glyph->w;tx++) {
+ GBool on = (bp[opvpbytes*ty+(tx/8)] & (0x80 >> (tx & 7))) != 0;
+
+ if (on && !dmode) {
+ sx = tx;
+ dmode = gTrue;
+ } else if (!on && dmode) {
+ drawSpan(x0+sx,x0+tx-1,y0+ty,gTrue);
+ dmode = gFalse;
+ }
+ }
+ if (dmode) {
+ drawSpan(x0+sx,x0+tx-1,y0+ty,gTrue);
+ }
+ }
+ /* restore stroke pattern */
+ setStrokePattern(savedPattern);
+ /* restore line style */
+ setLineDash(savedLineDash,savedLineDashLength,
+ savedLineDashPhase);
+ if (savedLineDash != 0) {
+ delete[] savedLineDash;
+ }
+ setLineWidth(savedLineWidth);
+ }
+ if (bp != glyph->data) gfree(bp);
+}
+
+SplashError OPVPSplash::fillChar(SplashCoord x, SplashCoord y,
+ int c, SplashFont *font,
+ Unicode *u, double *fontMat) {
+ SplashError err = splashOk;
+ SplashPath *spath;
+ OPVPSplashPath *path;
+ SplashCoord xt, yt;
+ double mx,my;
+
+ transform(state->matrix, x, y, &xt, &yt);
+ if ((spath = font->getGlyphPath(c)) == 0) return splashOk;
+ path = new OPVPSplashPath(spath);
+ delete spath;
+ if (bitmapCharThreshold > 0) {
+ mx = splashAbs(fontMat[0]);
+ if (mx < splashAbs(fontMat[1])) {
+ mx = splashAbs(fontMat[1]);
+ }
+ my = splashAbs(fontMat[3]);
+ if (my < splashAbs(fontMat[2])) {
+ my = splashAbs(fontMat[2]);
+ }
+ if (path == 0 || (mx*my < bitmapCharThreshold)) {
+ /* if a char is enough small, then out a char as a bitmask */
+ SplashGlyphBitmap glyph;
+ int x0, y0, xFrac, yFrac;
+ SplashClipResult clipRes;
+
+ x0 = splashFloor(xt);
+ xFrac = splashFloor((xt - x0) * splashFontFraction);
+ y0 = splashFloor(yt);
+ yFrac = splashFloor((yt - y0) * splashFontFraction);
+ if (font->getGlyph(c, xFrac, yFrac, &glyph, x0, y0, state->clip,
+ &clipRes)) {
+ if (path != 0) delete path;
+ if (glyph.w == 0 || glyph.h == 0) {
+ /* empty glyph */
+ return splashOk;
+ }
+ if (clipRes != splashClipAllOutside) {
+ fillGlyph(xt, yt, &glyph);
+ }
+ if (glyph.freeData) {
+ gfree(glyph.data);
+ }
+ return err;
+ }
+ }
+ /* fall through and out a char as a path */
+ }
+ if (path == 0) {
+ //OPRS::error("FillPath error\n");
+ err = splashErrOPVP;
+ goto err0;
+ }
+ path->offset(xt,yt);
+ err = fill(path,gFalse);
+err0:
+ if (path != 0) delete path;
+ return err;
+}
+
+SplashError OPVPSplash::fillImageMaskFastWithCTM(SplashImageMaskSource src,
+ void *srcData, int w, int h, int tx, int ty,SplashCoord *mat) {
+ int i, j;
+ opvp_fix_t opvpx,opvpy;
+ int opvpbytes;
+ opvp_ctm_t opvpctm;
+ Guchar *buf = 0, *bp;
+ SplashError result = splashOk;
+ SplashColorPtr lineBuf;
+
+ opvpbytes = (w+7)/8;
+ /* align 4 */
+ opvpbytes = (opvpbytes+3)/4;
+ opvpbytes *= 4;
+ buf = (Guchar *)gmallocn(h,opvpbytes);
+ lineBuf = (SplashColorPtr)gmallocn(8,opvpbytes);
+
+ for (i = 0;i < h;i++) {
+ int k;
+
+ bp = buf+opvpbytes*i;
+ (*src)(srcData, lineBuf);
+ for (j = 0;j < w;j += k) {
+ Guchar d;
+
+ d = 0;
+ for (k = 0;k < 8 && j+k < w;k++) {
+ d <<= 1;
+ if (lineBuf[j+k] != 0) d |= 1;
+ }
+ d <<= 8-k;
+ *bp++ = d;
+ }
+ }
+ free(lineBuf);
+ opvpctm.a = mat[0];
+ opvpctm.b = mat[1];
+ opvpctm.c = mat[2];
+ opvpctm.d = mat[3];
+ opvpctm.e = mat[4];
+ opvpctm.f = mat[5];
+ OPVP_i2Fix((tx),(opvpx));
+ OPVP_i2Fix((ty),(opvpy));
+ if (opvp->SetCurrentPoint(opvpx,opvpy) < 0) {
+ OPRS::error("SetCurrentPoint error\n");
+ }
+
+ if (opvp->SetCTM(&opvpctm) < 0) {
+ OPRS::error("SetCTM error\n");
+ }
+ if (opvp->DrawImage(w,h,opvpbytes,OPVP_IFORMAT_MASK,1,1,(void *)(buf)) < 0) {
+ OPRS::error("DrawImage error\n");
+ result = splashErrOPVP;
+ }
+ /* reset CTM */
+ opvpctm.a = 1.0;
+ opvpctm.b = 0.0;
+ opvpctm.c = 0.0;
+ opvpctm.d = 1.0;
+ opvpctm.e = 0.0;
+ opvpctm.f = 0.0;
+ if (opvp->SetCTM(&opvpctm) < 0) {
+ OPRS::error("SetCTM error\n");
+ }
+
+ if (buf != 0) gfree(buf);
+ return result;
+}
+
+SplashError OPVPSplash::fillImageMask(SplashImageMaskSource src, void *srcData,
+ int w, int h, SplashCoord *mat, GBool glyphMode) {
+ GBool rot;
+ SplashCoord xScale, yScale, xShear, yShear;
+ int tx, ty, scaledWidth, scaledHeight, xSign, ySign;
+ int ulx, uly, llx, lly, urx, ury, lrx, lry;
+ int ulx1, uly1, llx1, lly1, urx1, ury1, lrx1, lry1;
+ int xMin, xMax, yMin, yMax;
+ SplashClipResult clipRes;
+ SplashColorPtr pixBuf;
+ SplashColorPtr p;
+ int x, y;
+ int i;
+ SplashPattern *savedPattern;
+ SplashCoord *savedLineDash = 0;
+ int savedLineDashLength;
+ SplashCoord savedLineDashPhase;
+ SplashCoord savedLineWidth;
+
+ if (debugMode) {
+ printf("fillImageMask: w=%d h=%d mat=[%.2f %.2f %.2f %.2f %.2f %.2f]\n",
+ w, h, mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
+ }
+
+ // check for singular matrix
+ if (splashAbs(mat[0] * mat[3] - mat[1] * mat[2]) < 0.000001) {
+ return splashErrSingularMatrix;
+ }
+
+ // compute scale, shear, rotation, translation parameters
+ rot = splashAbs(mat[1]) > splashAbs(mat[0]);
+ if (rot) {
+ xScale = -mat[1];
+ yScale = mat[2] - (mat[0] * mat[3]) / mat[1];
+ xShear = -mat[3] / yScale;
+ yShear = -mat[0] / mat[1];
+ } else {
+ xScale = mat[0];
+ yScale = mat[3] - (mat[1] * mat[2]) / mat[0];
+ xShear = mat[2] / yScale;
+ yShear = mat[1] / mat[0];
+ }
+ tx = splashRound(mat[4]);
+ ty = splashRound(mat[5]);
+ scaledWidth = abs(splashRound(mat[4] + xScale) - tx) + 1;
+ scaledHeight = abs(splashRound(mat[5] + yScale) - ty) + 1;
+ xSign = (xScale < 0) ? -1 : 1;
+ ySign = (yScale < 0) ? -1 : 1;
+
+ // clipping
+ ulx1 = 0;
+ uly1 = 0;
+ urx1 = xSign * (scaledWidth - 1);
+ ury1 = splashRound(yShear * urx1);
+ llx1 = splashRound(xShear * ySign * (scaledHeight - 1));
+ lly1 = ySign * (scaledHeight - 1) + splashRound(yShear * llx1);
+ lrx1 = xSign * (scaledWidth - 1) +
+ splashRound(xShear * ySign * (scaledHeight - 1));
+ lry1 = ySign * (scaledHeight - 1) + splashRound(yShear * lrx1);
+ if (rot) {
+ ulx = tx + uly1; uly = ty - ulx1;
+ urx = tx + ury1; ury = ty - urx1;
+ llx = tx + lly1; lly = ty - llx1;
+ lrx = tx + lry1; lry = ty - lrx1;
+ } else {
+ ulx = tx + ulx1; uly = ty + uly1;
+ urx = tx + urx1; ury = ty + ury1;
+ llx = tx + llx1; lly = ty + lly1;
+ lrx = tx + lrx1; lry = ty + lry1;
+ }
+ xMin = (ulx < urx) ? (ulx < llx) ? (ulx < lrx) ? ulx : lrx
+ : (llx < lrx) ? llx : lrx
+ : (urx < llx) ? (urx < lrx) ? urx : lrx
+ : (llx < lrx) ? llx : lrx;
+ xMax = (ulx > urx) ? (ulx > llx) ? (ulx > lrx) ? ulx : lrx
+ : (llx > lrx) ? llx : lrx
+ : (urx > llx) ? (urx > lrx) ? urx : lrx
+ : (llx > lrx) ? llx : lrx;
+ yMin = (uly < ury) ? (uly < lly) ? (uly < lry) ? uly : lry
+ : (lly < lry) ? lly : lry
+ : (ury < lly) ? (ury < lry) ? ury : lry
+ : (lly < lry) ? lly : lry;
+ yMax = (uly > ury) ? (uly > lly) ? (uly > lry) ? uly : lry
+ : (lly > lry) ? lly : lry
+ : (ury > lly) ? (ury > lry) ? ury : lry
+ : (lly > lry) ? lly : lry;
+ clipRes = state->clip->testRect(xMin, yMin, xMax, yMax);
+ if (clipRes == splashClipAllOutside) return splashOk;
+
+ if (!noClipPath || clipRes == splashClipAllInside) {
+ if (!noShearImage && !noImageMask) {
+ if (fillImageMaskFastWithCTM(src,srcData,w,h,tx,ty,mat)
+ == splashOk) {
+ return splashOk;
+ }
+ }
+ }
+
+ SplashError result = splashOk;
+ /* change stroke pattern temprarily */
+ savedPattern = state->strokePattern->copy();
+ setStrokePattern(state->fillPattern->copy());
+
+ /* change lins style temporarily */
+ savedLineDashLength = state->lineDashLength;
+ savedLineDashPhase = state->lineDashPhase;
+ if (savedLineDashLength > 0 && state->lineDash != 0) {
+ savedLineDash = new SplashCoord[savedLineDashLength];
+ memcpy(savedLineDash, state->lineDash,
+ savedLineDashLength*sizeof(SplashCoord));
+ }
+ setLineDash(0,0,0);
+ savedLineWidth = state->lineWidth;
+ setLineWidth(0.0);
+
+ /* calculate inverse matrix */
+ SplashCoord imat[4];
+ double det = mat[0] * mat[3] - mat[1] * mat[2];
+ imat[0] = mat[3]/det;
+ imat[1] = -mat[1]/det;
+ imat[2] = -mat[2]/det;
+ imat[3] = mat[0]/det;
+
+ /* read source image */
+ pixBuf = (SplashColorPtr)gmallocn(h , w);
+
+ p = pixBuf;
+ for (i = 0; i < h; ++i) {
+ (*src)(srcData, p);
+ p += w;
+ }
+ int width = xMax-xMin+1;
+ int height = yMax-yMin+1;
+ OPVPSplashClip *clip = state->clip->copy();
+
+ if (w < scaledWidth || h < scaledHeight) {
+ OPVPSplashPath cpath;
+
+ cpath.moveTo(tx,ty);
+ cpath.lineTo(mat[0]+tx,mat[1]+ty);
+ cpath.lineTo(mat[0]+mat[2]+tx,mat[1]+mat[3]+ty);
+ cpath.lineTo(mat[2]+tx,mat[3]+ty);
+ clip->clipToPath(&cpath,state->matrix,1.0,gFalse);
+ }
+ for (y = 0;y < height;y++) {
+ int dy = y+yMin-ty;
+ int sx = 0;
+ GBool dmode = gFalse;
+
+ for (x = 0;x < width;x++) {
+ if (!clip->test(x+xMin,y+yMin)) {
+ if (dmode) {
+ drawSpan(xMin+sx,xMin+x-1,yMin+y,gTrue);
+ dmode = gFalse;
+ }
+ continue;
+ }
+ int ox,oy;
+ /* calculate original coordinate */
+ int dx = x+xMin-tx;
+ ox = (int)trunc((imat[0]*dx+imat[2]*dy)*w);
+ oy = (int)trunc((imat[1]*dx+imat[3]*dy)*h);
+ if (ox >= 0 && ox < w && oy >= 0 && oy < h) {
+ GBool on = pixBuf[oy*w+ox] != 0;
+
+ if (on && !dmode) {
+ dmode = gTrue;
+ sx = x;
+ } else if (!on && dmode) {
+ drawSpan(xMin+sx,xMin+x-1,yMin+y,gTrue);
+ dmode = gFalse;
+ }
+ } else if (dmode) {
+ drawSpan(xMin+sx,xMin+x-1,yMin+y,gTrue);
+ dmode = gFalse;
+ }
+ }
+ if (dmode) {
+ drawSpan(xMin+sx,xMin+x-1,yMin+y,gTrue);
+ }
+ }
+ delete clip;
+ gfree(pixBuf);
+
+ /* restore stroke pattern */
+ setStrokePattern(savedPattern);
+ /* restore line style */
+ setLineDash(savedLineDash,savedLineDashLength,
+ savedLineDashPhase);
+ if (savedLineDash != 0) {
+ delete[] savedLineDash;
+ }
+ setLineWidth(savedLineWidth);
+
+ return result;
+}
+
+SplashError OPVPSplash::drawImageNotShear(SplashImageSource src,
+ void *srcData,
+ int w, int h,
+ int tx, int ty,
+ int scaledWidth, int scaledHeight,
+ int xSign, int ySign, GBool rot) {
+ int i, j;
+ opvp_fix_t opvpx,opvpy;
+ int opvpbytes, linesize;
+ opvp_ctm_t opvpctm;
+ SplashError result = splashOk;
+ Guchar *buf = 0, *bp;
+ SplashColorPtr lineBuf = 0, color;
+ float e,f;
+ int hs,he, hstep;
+ int ow = w;
+ int lineBufSize;
+
+ if (rot) {
+ int t = h;
+
+ h = w;
+ w = t;
+ t = scaledHeight;
+ scaledHeight = scaledWidth;
+ scaledWidth = t;
+ if (xSign != ySign) {
+ xSign = xSign >= 0 ? -1 : 1;
+ } else {
+ ySign = ySign >= 0 ? -1 : 1;
+ }
+ }
+
+ if (xSign > 0) {
+ OPVP_i2Fix((tx),(opvpx));
+ e = tx;
+ } else {
+ OPVP_i2Fix((tx-scaledWidth),(opvpx));
+ e = tx-scaledWidth;
+ }
+ if (ySign > 0) {
+ OPVP_i2Fix((ty),(opvpy));
+ f = ty;
+ } else {
+ OPVP_i2Fix((ty-scaledHeight),(opvpy));
+ f = ty-scaledHeight;
+ }
+ if (opvp->SetCurrentPoint(opvpx,opvpy) < 0) {
+ OPRS::error("SetCurrentPoint error\n");
+ return splashErrOPVP;
+ }
+ switch (colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ linesize = w;
+ opvpbytes = (w+3)/4;
+ opvpbytes *= 4;
+ lineBufSize = (ow+3)/4;
+ lineBufSize *= 4;
+ break;
+ case splashModeRGB8:
+ linesize = w*3;;
+ opvpbytes = (w*3+3)/4;
+ opvpbytes *= 4;
+ lineBufSize = (ow*3+3)/4;
+ lineBufSize *= 4;
+ break;
+ default:
+ OPRS::error("Image: no supported color mode\n");
+ return splashErrOPVP;
+ break;
+ }
+ if (ySign >= 0) {
+ hstep = 1;
+ hs = 0;
+ he = h;
+ } else {
+ hstep = -1;
+ hs = h-1;
+ he = -1;
+ }
+ buf = (Guchar *)gmallocn(h,opvpbytes);
+ lineBuf = (SplashColorPtr)gmallocn(lineBufSize,1);
+ switch (colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ if (rot) {
+ if (xSign >= 0) {
+ for (i = 0;i < w;i++) {
+ (*src)(srcData, lineBuf, NULL);
+ color = lineBuf;
+ for (j = hs;j != he;j += hstep) {
+ bp = buf+i+j*opvpbytes;
+ *bp = *color++;
+ }
+ }
+ } else {
+ for (i = 0;i < w;i++) {
+ (*src)(srcData, lineBuf, NULL);
+ color = lineBuf;
+ for (j = hs;j != he;j += hstep) {
+ bp = buf+linesize-1-i+j*opvpbytes;
+ *bp = *color++;
+ }
+ }
+ }
+ } else {
+ if (xSign >= 0) {
+ for (i = hs;i != he;i += hstep) {
+ bp = buf+opvpbytes*i;
+ (*src)(srcData, lineBuf, NULL);
+ color = lineBuf;
+ for (j = 0;j < w;j++) {
+ *bp++ = *color++;
+ }
+ }
+ } else {
+ for (i = hs;i != he;i += hstep) {
+ bp = buf+opvpbytes*i+linesize-1;
+ (*src)(srcData, lineBuf, NULL);
+ color = lineBuf;
+ for (j = 0;j < w;j++) {
+ *bp-- = *color++;
+ }
+ }
+ }
+ }
+ break;
+ case splashModeRGB8:
+ if (rot) {
+ if (xSign >= 0) {
+ for (i = 0;i < w;i++) {
+ (*src)(srcData, lineBuf, NULL);
+ color = lineBuf;
+ for (j = hs;j != he;j += hstep) {
+ bp = buf+i*3+j*opvpbytes;
+ bp[0] = *color++;
+ bp[1] = *color++;
+ bp[2] = *color++;
+ }
+ }
+ } else {
+ for (i = 0;i < w;i++) {
+ (*src)(srcData, lineBuf, NULL);
+ color = lineBuf;
+ for (j = hs;j != he;j += hstep) {
+ bp = buf+linesize-3-i*3+j*opvpbytes;
+ bp[0] = *color++;
+ bp[1] = *color++;
+ bp[2] = *color++;
+ }
+ }
+ }
+ } else {
+ if (xSign >= 0) {
+ for (i = hs;i != he;i += hstep) {
+ bp = buf+opvpbytes*i;
+ (*src)(srcData, lineBuf, NULL);
+ color = lineBuf;
+ for (j = 0;j < w;j++) {
+ *bp++ = *color++;
+ *bp++ = *color++;
+ *bp++ = *color++;
+ }
+ }
+ } else {
+ for (i = hs;i != he;i += hstep) {
+ bp = buf+opvpbytes*i+linesize-1;
+ (*src)(srcData, lineBuf, NULL);
+ color = lineBuf;
+ for (j = 0;j < w;j++) {
+ *bp-- = color[2];
+ *bp-- = color[1];
+ *bp-- = color[0];
+ color += 3;
+ }
+ }
+ }
+ }
+ break;
+ default:
+ OPRS::error("Image: no supported color mode\n");
+ result = splashErrOPVP;
+ goto err1;
+ break;
+ }
+ if (lineBuf != 0) gfree(lineBuf);
+
+ /* canonlisp driver use CTM only, ignores currentPoint */
+ /* So, set start point to CTM */
+ opvpctm.a = 1.0;
+ opvpctm.b = 0.0;
+ opvpctm.c = 0.0;
+ opvpctm.d = 1.0;
+ opvpctm.e = e;
+ opvpctm.f = f;
+ if (opvp->SetCTM(&opvpctm) < 0) {
+ OPRS::error("SetCTM error\n");
+ }
+
+ if (opvp->DrawImage(w,h,opvpbytes,OPVP_IFORMAT_RAW,
+ scaledWidth,scaledHeight,(void *)(buf)) < 0) {
+ OPRS::error("DrawImage error\n");
+ result = splashErrOPVP;
+ goto err1;
+ }
+err1:
+ /* reset CTM */
+ opvpctm.e = 0.0;
+ opvpctm.f = 0.0;
+ if (opvp->SetCTM(&opvpctm) < 0) {
+ OPRS::error("SetCTM error\n");
+ }
+
+ if (buf != 0) gfree(buf);
+ return result;
+}
+
+SplashError OPVPSplash::drawImageFastWithCTM(SplashImageSource src,
+ void *srcData,
+ int w, int h, int tx, int ty,
+ SplashCoord *mat) {
+ int i;
+ opvp_fix_t opvpx,opvpy;
+ int opvpbytes;
+ opvp_ctm_t opvpctm;
+ Guchar *buf = 0, *bp;
+
+ switch (colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ opvpbytes = (w+3)/4;
+ opvpbytes *= 4;
+ break;
+ case splashModeRGB8:
+ opvpbytes = (w*3+3)/4;
+ opvpbytes *= 4;
+ break;
+ default:
+ OPRS::error("Image: no supported color mode\n");
+ return splashErrOPVP;
+ break;
+ }
+ buf = (Guchar *)gmallocn(h,opvpbytes);
+
+ switch (colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ for (i = 0;i < h;i++) {
+ bp = buf+opvpbytes*i;
+ (*src)(srcData, (SplashColorPtr)bp, NULL);
+ }
+ break;
+ case splashModeRGB8:
+ for (i = 0;i < h;i++) {
+ bp = buf+opvpbytes*i;
+ (*src)(srcData, (SplashColorPtr)bp, NULL);
+ }
+ break;
+ default:
+ OPRS::error("Image: no supported color mode\n");
+ goto err0;
+ break;
+ }
+
+ opvpctm.a = mat[0];
+ opvpctm.b = mat[1];
+ opvpctm.c = mat[2];
+ opvpctm.d = mat[3];
+ opvpctm.e = mat[4];
+ opvpctm.f = mat[5];
+ OPVP_i2Fix((tx),(opvpx));
+ OPVP_i2Fix((ty),(opvpy));
+ if (opvp->SetCurrentPoint(opvpx,opvpy) < 0) {
+ OPRS::error("SetCurrentPoint error\n");
+ }
+
+ if (opvp->SetCTM(&opvpctm) < 0) {
+ OPRS::error("SetCTM error\n");
+ }
+ if (opvp->DrawImage(w,h,opvpbytes,OPVP_IFORMAT_RAW,1,1,(void *)(buf)) < 0) {
+ OPRS::error("DrawImage error\n");
+ }
+err0:
+ /* reset CTM */
+ opvpctm.a = 1.0;
+ opvpctm.b = 0.0;
+ opvpctm.c = 0.0;
+ opvpctm.d = 1.0;
+ opvpctm.e = 0.0;
+ opvpctm.f = 0.0;
+ if (opvp->SetCTM(&opvpctm) < 0) {
+ OPRS::error("SetCTM error\n");
+ }
+
+ if (buf != 0) gfree(buf);
+ return splashOk;
+}
+
+SplashError OPVPSplash::drawImage(SplashImageSource src, void *srcData,
+ SplashColorMode srcMode, GBool srcAlpha,
+ int w, int h, SplashCoord *mat) {
+ GBool ok, rot;
+ SplashCoord xScale, yScale, xShear, yShear;
+ int tx, ty, scaledWidth, scaledHeight, xSign, ySign;
+ int ulx, uly, llx, lly, urx, ury, lrx, lry;
+ int ulx1, uly1, llx1, lly1, urx1, ury1, lrx1, lry1;
+ int xMin, xMax, yMin, yMax;
+ SplashClipResult clipRes;
+ SplashColorPtr pixBuf, p;
+ int x, y;
+ int i;
+
+ if (debugMode) {
+ printf("drawImage: srcMode=%d w=%d h=%d mat=[%.2f %.2f %.2f %.2f %.2f %.2f]\n",
+ srcMode, w, h, mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
+ }
+
+ // check color modes
+ ok = gFalse; // make gcc happy
+ switch (colorMode) {
+ case splashModeMono1:
+ ok = srcMode == splashModeMono1 || srcMode == splashModeMono8;
+ break;
+ case splashModeMono8:
+ ok = srcMode == splashModeMono8;
+ break;
+ case splashModeRGB8:
+ ok = srcMode == splashModeRGB8;
+ break;
+ }
+ if (!ok) {
+ OPRS::error("Image Mode mismatch\n");
+ return splashErrModeMismatch;
+ }
+
+ // check for singular matrix
+ if (splashAbs(mat[0] * mat[3] - mat[1] * mat[2]) < 0.000001) {
+ OPRS::error("Image Not Singular Matrix\n");
+ return splashErrSingularMatrix;
+ }
+
+ // compute scale, shear, rotation, translation parameters
+ rot = splashAbs(mat[1]) > splashAbs(mat[0]);
+ if (rot) {
+ xScale = -mat[1];
+ yScale = mat[2] - (mat[0] * mat[3]) / mat[1];
+ xShear = -mat[3] / yScale;
+ yShear = -mat[0] / mat[1];
+ } else {
+ xScale = mat[0];
+ yScale = mat[3] - (mat[1] * mat[2]) / mat[0];
+ xShear = mat[2] / yScale;
+ yShear = mat[1] / mat[0];
+ }
+ tx = splashRound(mat[4]);
+ ty = splashRound(mat[5]);
+ scaledWidth = abs(splashRound(mat[4] + xScale) - tx) + 1;
+ scaledHeight = abs(splashRound(mat[5] + yScale) - ty) + 1;
+ xSign = (xScale < 0) ? -1 : 1;
+ ySign = (yScale < 0) ? -1 : 1;
+
+ // clipping
+ ulx1 = 0;
+ uly1 = 0;
+ urx1 = xSign * (scaledWidth - 1);
+ ury1 = splashRound(yShear * urx1);
+ llx1 = splashRound(xShear * ySign * (scaledHeight - 1));
+ lly1 = ySign * (scaledHeight - 1) + splashRound(yShear * llx1);
+ lrx1 = xSign * (scaledWidth - 1) +
+ splashRound(xShear * ySign * (scaledHeight - 1));
+ lry1 = ySign * (scaledHeight - 1) + splashRound(yShear * lrx1);
+ if (rot) {
+ ulx = tx + uly1; uly = ty - ulx1;
+ urx = tx + ury1; ury = ty - urx1;
+ llx = tx + lly1; lly = ty - llx1;
+ lrx = tx + lry1; lry = ty - lrx1;
+ } else {
+ ulx = tx + ulx1; uly = ty + uly1;
+ urx = tx + urx1; ury = ty + ury1;
+ llx = tx + llx1; lly = ty + lly1;
+ lrx = tx + lrx1; lry = ty + lry1;
+ }
+ xMin = (ulx < urx) ? (ulx < llx) ? (ulx < lrx) ? ulx : lrx
+ : (llx < lrx) ? llx : lrx
+ : (urx < llx) ? (urx < lrx) ? urx : lrx
+ : (llx < lrx) ? llx : lrx;
+ xMax = (ulx > urx) ? (ulx > llx) ? (ulx > lrx) ? ulx : lrx
+ : (llx > lrx) ? llx : lrx
+ : (urx > llx) ? (urx > lrx) ? urx : lrx
+ : (llx > lrx) ? llx : lrx;
+ yMin = (uly < ury) ? (uly < lly) ? (uly < lry) ? uly : lry
+ : (lly < lry) ? lly : lry
+ : (ury < lly) ? (ury < lry) ? ury : lry
+ : (lly < lry) ? lly : lry;
+ yMax = (uly > ury) ? (uly > lly) ? (uly > lry) ? uly : lry
+ : (lly > lry) ? lly : lry
+ : (ury > lly) ? (ury > lry) ? ury : lry
+ : (lly > lry) ? lly : lry;
+ if ((clipRes = state->clip->testRect(xMin, yMin, xMax, yMax))
+ == splashClipAllOutside) {
+ return splashOk;
+ }
+
+ if (!noClipPath || clipRes == splashClipAllInside) {
+ if (!srcAlpha && !noShearImage) {
+ if (drawImageFastWithCTM(src,srcData,w,h,tx,ty,mat) == splashOk) {
+ return splashOk;
+ }
+ }
+ if (!srcAlpha && splashRound(xShear) == 0 && splashRound(yShear) == 0) {
+ /* no sheared case */
+ if (drawImageNotShear(src,srcData,w,h,tx,ty,
+ scaledWidth, scaledHeight,xSign,ySign,rot) == splashOk) {
+ return splashOk;
+ }
+ }
+ }
+
+ /* shear case */
+ SplashError result = splashOk;
+
+ /* calculate inverse matrix */
+ SplashCoord imat[4];
+ double det = mat[0] * mat[3] - mat[1] * mat[2];
+ imat[0] = mat[3]/det;
+ imat[1] = -mat[1]/det;
+ imat[2] = -mat[2]/det;
+ imat[3] = mat[0]/det;
+
+ opvp_fix_t opvpx,opvpy;
+ int opvpbytes, linesize;
+ int width = xMax-xMin+1;
+ int height = yMax-yMin+1;
+ opvp_ctm_t opvpctm;
+
+ switch (colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ if (srcAlpha) {
+ /* alpha data exists */
+ linesize = w*2;
+ } else {
+ linesize = w;
+ }
+ opvpbytes = (width+3)/4;
+ opvpbytes *= 4;
+ break;
+ case splashModeRGB8:
+ if (srcAlpha) {
+ /* alpha data exists */
+ linesize = w*4;
+ } else {
+ linesize = w*3;
+ }
+ opvpbytes = (width*3+3)/4;
+ opvpbytes *= 4;
+ break;
+ default:
+ OPRS::error("Image: no supported color mode\n");
+ return splashErrOPVP;
+ break;
+ }
+
+ /* read source image */
+ pixBuf = (SplashColorPtr)gmallocn(h , linesize);
+
+ p = pixBuf;
+ for (i = 0; i < h; ++i) {
+ (*src)(srcData, p, NULL);
+ p += linesize;
+ }
+ /* allocate line buffer */
+ Guchar *lineBuf = (Guchar *)gmallocn(opvpbytes,1);
+ Guchar *onBuf = (Guchar *)gmallocn(width,1);
+ OPVPSplashClip *clip;
+ opvpctm.a = 1.0;
+ opvpctm.b = 0.0;
+ opvpctm.c = 0.0;
+ opvpctm.d = 1.0;
+
+ clip = state->clip->copy();
+ if (w < scaledWidth || h < scaledHeight) {
+ OPVPSplashPath cpath;
+
+ cpath.moveTo(tx,ty);
+ cpath.lineTo(mat[0]+tx,mat[1]+ty);
+ cpath.lineTo(mat[0]+mat[2]+tx,mat[1]+mat[3]+ty);
+ cpath.lineTo(mat[2]+tx,mat[3]+ty);
+ clip->clipToPath(&cpath,state->matrix,1.0,gFalse);
+ }
+ for (y = 0;y < height;y++) {
+ int dy = y+yMin-ty;
+ memset(onBuf,0,width);
+ if (srcAlpha) {
+ /* with alpha data */
+ for (x = 0;x < width;x++) {
+ if (!clip->test(x+xMin,y+yMin)) continue;
+ int ox,oy;
+ /* calculate original coordinate */
+ int dx = x+xMin-tx;
+ ox = (int)trunc((imat[0]*dx+imat[2]*dy)*w);
+ oy = (int)trunc((imat[1]*dx+imat[3]*dy)*h);
+ if (ox >= 0 && ox < w && oy >= 0 && oy < h) {
+ /* in the image */
+
+ switch (colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ onBuf[x] = pixBuf[oy*linesize+ox] != 0;
+ lineBuf[x] = pixBuf[oy*linesize+ox+1];
+ break;
+ case splashModeRGB8:
+ p = pixBuf+oy*linesize+ox*4;
+ onBuf[x] = (*p++) != 0;
+ lineBuf[x*3] = *p++;
+ lineBuf[x*3+1] = *p++;
+ lineBuf[x*3+2] = *p;
+ break;
+ default:
+ OPRS::error("Image: no supported color mode\n");
+ result = splashErrOPVP;
+ goto err1;
+ break;
+ }
+ }
+ }
+ } else {
+ for (x = 0;x < width;x++) {
+ if (!clip->test(x+xMin,y+yMin)) continue;
+ int ox,oy;
+ /* calculate original coordinate */
+ int dx = x+xMin-tx;
+ ox = (int)trunc((imat[0]*dx+imat[2]*dy)*w);
+ oy = (int)trunc((imat[1]*dx+imat[3]*dy)*h);
+ if (ox >= 0 && ox < w && oy >= 0 && oy < h) {
+ /* in the image */
+
+ switch (colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ lineBuf[x] = pixBuf[oy*linesize+ox];
+ break;
+ case splashModeRGB8:
+ p = pixBuf+oy*linesize+ox*3;
+ lineBuf[x*3] = *p++;
+ lineBuf[x*3+1] = *p++;
+ lineBuf[x*3+2] = *p;
+ break;
+ default:
+ OPRS::error("Image: no supported color mode\n");
+ result = splashErrOPVP;
+ goto err1;
+ break;
+ }
+ onBuf[x] = 1;
+ }
+ }
+ }
+ /* out pixel */
+ int sx = 0;
+ int ex;
+ while (sx < width) {
+ /* find start pixel */
+ for (;onBuf[sx] == 0 && sx < width;sx++);
+ if (sx >= width) break;
+ /* find end pixel */
+ for (ex = sx+1;onBuf[ex] != 0 && ex < width;ex++);
+ int n = ex-sx;
+ Guchar *bp;
+ int ns;
+
+ switch (colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ bp = lineBuf+sx;
+ ns = n;
+ break;
+ case splashModeRGB8:
+ bp = lineBuf+sx*3;
+ ns = n*3;
+ break;
+ default:
+ OPRS::error("Image: no supported color mode\n");
+ result = splashErrOPVP;
+ goto err1;
+ break;
+ }
+ ns = (ns+3)/4;
+ ns *= 4;
+
+ OPVP_i2Fix(xMin+sx,(opvpx));
+ OPVP_i2Fix(yMin+y,(opvpy));
+ if (opvp->SetCurrentPoint(opvpx,opvpy) < 0) {
+ OPRS::error("SetCurrentPoint error\n");
+ result = splashErrOPVP;
+ goto err1;
+ }
+ /* canonlisp driver use CTM only, ignores currentPoint */
+ /* So, set start point to CTM */
+ opvpctm.e = xMin+sx;
+ opvpctm.f = yMin+y;
+ if (opvp->SetCTM(&opvpctm) < 0) {
+ OPRS::error("SetCTM error\n");
+ }
+
+ if (opvp->DrawImage(n,1,ns,OPVP_IFORMAT_RAW,
+ n,1,(void *)(bp)) < 0) {
+ OPRS::error("DrawImage error\n");
+ result = splashErrOPVP;
+ goto err1;
+ }
+
+ /* reset CTM */
+ opvpctm.e = 0.0;
+ opvpctm.f = 0.0;
+ if (opvp->SetCTM(&opvpctm) < 0) {
+ OPRS::error("SetCTM error\n");
+ }
+
+ sx = ex+1;
+ }
+ }
+
+
+err1:
+ delete clip;
+ gfree(pixBuf);
+ gfree(lineBuf);
+ gfree(onBuf);
+ return result;
+}
+
+void OPVPSplash::setColorMode(int colorModeA)
+{
+ colorMode = colorModeA;
+}
+
+void OPVPSplash::drawSpan(int x0, int x1, int y, GBool noClip)
+{
+ int s,e;
+ opvp_point_t points[1];
+ opvp_fix_t opvpx, opvpy;
+ SplashCoord *savedLineDash = 0;
+ int savedLineDashLength;
+ SplashCoord savedLineDashPhase;
+ SplashCoord savedLineWidth;
+ GBool noSpan;
+
+
+ if (opvp->NewPath() < 0) {
+ OPRS::error("NewPath error\n");
+ return;
+ }
+ if (noClip) {
+ noSpan = gFalse;
+ OPVP_i2Fix(x0,opvpx);
+ OPVP_i2Fix(y,opvpy);
+ if (opvp->SetCurrentPoint(opvpx,opvpy) < 0) {
+ OPRS::error("SetCurrentPoint error\n");
+ return;
+ }
+ OPVP_i2Fix(x1+1,points[0].x);
+ OPVP_i2Fix(y,points[0].y);
+ if (opvp->LinePath(OPVP_PATHOPEN,1,points) < 0) {
+ OPRS::error("LinePath error\n");
+ return;
+ }
+ } else {
+ noSpan = gTrue;
+ s = x0;
+ while (s < x1) {
+ /* find start point */
+ for (;s < x1;s++) {
+ if (state->clip->test(s, y)) break;
+ }
+ if (s < x1) {
+ /* start point was found */
+ /* then find end point */
+ for (e = s+1;e < x1;e++) {
+ if (!state->clip->test(e, y)) break;
+ }
+ /* do make span */
+ noSpan = gFalse;
+ OPVP_i2Fix(s,opvpx);
+ OPVP_i2Fix(y,opvpy);
+ if (opvp->SetCurrentPoint(opvpx,opvpy) < 0) {
+ OPRS::error("SetCurrentPoint error\n");
+ return;
+ }
+ OPVP_i2Fix(e,points[0].x);
+ OPVP_i2Fix(y,points[0].y);
+ if (opvp->LinePath(OPVP_PATHOPEN,1,points) < 0) {
+ OPRS::error("LinePath error\n");
+ return;
+ }
+ s = e;
+ }
+ }
+ }
+ if (opvp->EndPath() < 0) {
+ OPRS::error("EndPath error\n");
+ return;
+ }
+ if (noSpan) return;
+ /* change lins style temporarily */
+ savedLineDashLength = state->lineDashLength;
+ savedLineDashPhase = state->lineDashPhase;
+ if (savedLineDashLength > 0 && state->lineDash != 0) {
+ savedLineDash = new SplashCoord[savedLineDashLength];
+ memcpy(savedLineDash, state->lineDash,
+ savedLineDashLength*sizeof(SplashCoord));
+ }
+ setLineDash(0,0,0);
+ savedLineWidth = state->lineWidth;
+ setLineWidth(0.0);
+
+ if (opvp->StrokePath() < 0) {
+ OPRS::error("StrokePath error\n");
+ return;
+ }
+
+ /* restore line style */
+ setLineDash(savedLineDash,savedLineDashLength,
+ savedLineDashPhase);
+ if (savedLineDash != 0) {
+ delete[] savedLineDash;
+ }
+ setLineWidth(savedLineWidth);
+}
+
+/*
+ draw pixel with StrokePath
+ color is stroke color
+*/
+void OPVPSplash::drawPixel(int x, int y, GBool noClip)
+{
+ opvp_point_t points[1];
+ opvp_fix_t opvpx, opvpy;
+
+ if (noClip || state->clip->test(x, y)) {
+ if (opvp->NewPath() < 0) {
+ OPRS::error("NewPath error\n");
+ return;
+ }
+ OPVP_i2Fix(x,opvpx);
+ OPVP_i2Fix(y,opvpy);
+ if (opvp->SetCurrentPoint(opvpx,opvpy) < 0) {
+ OPRS::error("NewPath error\n");
+ return;
+ }
+ OPVP_i2Fix(x+1,points[0].x);
+ OPVP_i2Fix(y,points[0].y);
+ if (opvp->LinePath(OPVP_PATHOPEN,1,points) < 0) {
+ OPRS::error("LinePath error\n");
+ return;
+ }
+ if (opvp->EndPath() < 0) {
+ OPRS::error("EndPath error\n");
+ return;
+ }
+ if (opvp->StrokePath() < 0) {
+ OPRS::error("StrokePath error\n");
+ return;
+ }
+ }
+}
+
+const char *OPVPSplash::getOption(const char *key, int nOptions,
+ const char *optionKeys[], const char *optionVals[])
+{
+ int i;
+
+ for (i = 0;i < nOptions;i++) {
+ if (strcmp(key,optionKeys[i]) == 0) {
+ return optionVals[i];
+ }
+ }
+ return 0;
+}
+
+void OPVPSplash::endPage()
+{
+ if (clipPath != 0) {
+ delete clipPath;
+ clipPath = 0;
+ }
+}
+
+void OPVPSplash::restoreAllDriverState()
+{
+ for (;saveDriverStateCount > 0;saveDriverStateCount--) {
+ opvp->RestoreGS();
+ }
+}
+
+SplashCoord *OPVPSplash::getMatrix()
+{
+ return state->matrix;
+}
+
+OPVPClipPath *OPVPClipPath::stackTop = 0;
+
+OPVPClipPath::OPVPClipPath(OPVPSplashPath *pathA, GBool eoA)
+{
+ path = pathA;
+ eo = eoA;
+ next = 0;
+ saved = gFalse;
+}
+
+void OPVPClipPath::push()
+{
+ OPVPClipPath *p;
+
+ p = stackTop;
+ stackTop = copy();
+ stackTop->next = p;
+ saved = gTrue;
+}
+
+OPVPClipPath *OPVPClipPath::pop() {
+ OPVPClipPath *p = stackTop;
+ if (stackTop != 0) stackTop = stackTop->next;
+ return p;
+}
+
+OPVPClipPath *OPVPClipPath::copy()
+{
+ OPVPClipPath *p;
+
+ p = new OPVPClipPath(path->copy(),eo);
+ p->saved = saved;
+ return p;
+}
diff --git a/filter/pdftoopvp/oprs/OPVPSplash.h b/filter/pdftoopvp/oprs/OPVPSplash.h
new file mode 100644
index 000000000..525d3c3c3
--- /dev/null
+++ b/filter/pdftoopvp/oprs/OPVPSplash.h
@@ -0,0 +1,244 @@
+//========================================================================
+//
+// OPVPSplash.h
+//
+//========================================================================
+
+#ifndef OPVPSPLASH_H
+#define OPVPSPLASH_H
+
+#include <config.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma interface
+#endif
+
+#include <typeinfo>
+#include "splash/SplashTypes.h"
+#include "splash/SplashPattern.h"
+#include "splash/SplashErrorCodes.h"
+#include "OPVPSplashPath.h"
+#include "OPVPWrapper.h"
+#include "CharTypes.h"
+
+/* extra error code */
+#define splashErrOPVP 100
+
+#define OPVP_MAX_CLIPPATH_LENGTH 2000
+#define OPVP_MAX_FILLPATH_LENGTH 4000
+#define OPVP_BITMAPCHAR_THRESHOLD 2000
+#define OPVP_ROP_SRCCOPY 0xCC
+#define OPVP_ROP_S 0xCC
+#define OPVP_ROP_P 0xF0
+#define OPVP_ROP_PSDPxax 0xB8
+#define OPVP_ROP_DSPDxax 0xE2
+
+class SplashBitmap;
+class SplashGlyphBitmap;
+class OPVPSplashState;
+class SplashPattern;
+class SplashScreen;
+class OPVPSplashPath;
+class OPVPSplashXPath;
+class OPVPSplashClip;
+class SplashFont;
+
+class OPVPClipPath {
+public:
+ OPVPClipPath(OPVPSplashPath *pathA, GBool eoA);
+ void push();
+ static OPVPClipPath *pop();
+ ~OPVPClipPath() { delete path; }
+ OPVPSplashPath *getPath() { return path; }
+ GBool getEo() { return eo; }
+ GBool getSaved() { return saved; }
+private:
+ OPVPClipPath *copy();
+ OPVPClipPath *next;
+ OPVPSplashPath *path;
+ GBool eo;
+ GBool saved;
+ static OPVPClipPath *stackTop;
+};
+
+//------------------------------------------------------------------------
+// Splash
+//------------------------------------------------------------------------
+
+class OPVPSplash {
+public:
+
+ // Create a new rasterizer object.
+ OPVPSplash(OPVPWrapper *opvpA,
+ int nOptions, const char *optionKeys[], const char *optionVals[]);
+
+ virtual ~OPVPSplash();
+
+ //----- state read
+
+ SplashPattern *getStrokePattern();
+ SplashPattern *getFillPattern();
+ SplashScreen *getScreen();
+ SplashCoord getLineWidth();
+ int getLineCap();
+ int getLineJoin();
+ SplashCoord getMiterLimit();
+ SplashCoord getFlatness();
+ SplashCoord *getLineDash();
+ int getLineDashLength();
+ SplashCoord getLineDashPhase();
+ OPVPSplashClip *getClip();
+
+ //----- state write
+
+ void setStrokePattern(SplashPattern *strokeColor);
+ void setFillPattern(SplashPattern *fillColor);
+ void setScreen(SplashScreen *screen);
+ void setLineWidth(SplashCoord lineWidth);
+ void setLineCap(int lineCap);
+ void setLineJoin(int lineJoin);
+ void setMiterLimit(SplashCoord miterLimit);
+ void setFlatness(SplashCoord flatness);
+ // the <lineDash> array will be copied
+ void setLineDash(SplashCoord *lineDash, int lineDashLength,
+ SplashCoord lineDashPhase);
+ void clipResetToRect(SplashCoord x0, SplashCoord y0,
+ SplashCoord x1, SplashCoord y1);
+ SplashError clipToPath(OPVPSplashPath *path, GBool eo);
+
+ //----- state save/restore
+
+ void saveState();
+ SplashError restoreState();
+ void restoreAllDriverState();
+
+ //----- drawing operations
+
+ // Fill the bitmap with <color>. This is not subject to clipping.
+ void clear(SplashColor color);
+
+ // Stroke a path using the current stroke pattern.
+ SplashError stroke(OPVPSplashPath *path);
+
+ // Fill a path using the current fill pattern.
+ SplashError fill(OPVPSplashPath *path, GBool eo);
+
+ // Draw a character, using the current fill pattern.
+ SplashError fillChar(SplashCoord x, SplashCoord y, int c,
+ SplashFont *font, Unicode *u, double *fontMat);
+
+ // Draw a glyph, using the current fill pattern. This function does
+ // not free any data, i.e., it ignores glyph->freeData.
+ // not used in vector mode
+ void fillGlyph(SplashCoord x, SplashCoord y,
+ SplashGlyphBitmap *glyph);
+
+ // Draws an image mask using the fill color. This will read <w>*<h>
+ // pixels from <src>, in raster order, starting with the top line.
+ // "1" pixels will be drawn with the current fill color; "0" pixels
+ // are transparent. The matrix:
+ // [ mat[0] mat[1] 0 ]
+ // [ mat[2] mat[3] 0 ]
+ // [ mat[4] mat[5] 1 ]
+ // maps a unit square to the desired destination for the image, in
+ // PostScript style:
+ // [x' y' 1] = [x y 1] * mat
+ // Note that the Splash y axis points downward, and the image source
+ // is assumed to produce pixels in raster order, starting from the
+ // top line.
+ SplashError fillImageMask(SplashImageMaskSource src, void *srcData,
+ int w, int h, SplashCoord *mat, GBool glyphMode);
+
+ // Draw an image. This will read <w>*<h> pixels from <src>, in
+ // raster order, starting with the top line. These pixels are
+ // assumed to be in the source mode, <srcMode>. The following
+ // combinations of source and target modes are supported:
+ // source target
+ // ------ ------
+ // Mono1 Mono1
+ // Mono8 Mono1 -- with dithering
+ // Mono8 Mono8
+ // RGB8 RGB8
+ // BGR8packed BGR8Packed
+ // The matrix behaves as for fillImageMask.
+ SplashError drawImage(SplashImageSource src, void *srcData,
+ SplashColorMode srcMode, GBool srcAlpha,
+ int w, int h, SplashCoord *mat);
+
+ //~ drawMaskedImage
+
+ //----- misc
+
+ // Return the associated bitmap.
+ SplashBitmap *getBitmap() { return 0; }
+
+ // Toggle debug mode on or off.
+ void setDebugMode(GBool debugModeA) { debugMode = debugModeA; }
+
+ void setColorMode(int colorModeA);
+ void setStateBypass(GBool bypass) {stateBypass = bypass;}
+ void endPage();
+ SplashCoord *getMatrix();
+ void drawSpan(int x0, int x1, int y, GBool noClip);
+#ifdef OLD_DRAW_IMAGE
+ void drawPixel(int x, int y, SplashColor *color, GBool noClip);
+#endif
+ void drawPixel(int x, int y, GBool noClip);
+ void arcToCurve(SplashCoord x0, SplashCoord y0,
+ SplashCoord x3, SplashCoord y3,
+ SplashCoord cx, SplashCoord cy, SplashCoord *rx1, SplashCoord *ry1,
+ SplashCoord *rx2, SplashCoord *ry2);
+
+private:
+ void makeBrush(SplashPattern *pattern, opvp_brush_t *brush);
+ SplashError doClipPath(OPVPSplashPath *path, GBool eo,
+ OPVPClipPath *prevClip);
+ opvp_cspace_t getOPVPColorSpace();
+ GBool equalPattern(SplashPattern *pt1, SplashPattern *pt2);
+ SplashError makeRectanglePath(SplashCoord x0, SplashCoord y0,
+ SplashCoord x1, SplashCoord y1, OPVPSplashPath **p);
+ SplashError drawImageFastWithCTM(SplashImageSource src, void *srcData,
+ int w, int h, int tx, int ty,
+ SplashCoord *mat);
+ SplashError drawImageNotShear(SplashImageSource src,
+ void *srcData,
+ int w, int h,
+ int tx, int ty,
+ int scaledWidth, int scaledHeight,
+ int xSign, int ySign, GBool rot);
+ SplashError fillImageMaskFastWithCTM(SplashImageMaskSource src,
+ void *srcData, int w, int h, int tx, int ty,SplashCoord *mat);
+ SplashError strokeByMyself(OPVPSplashPath *path);
+ SplashError fillByMyself(OPVPSplashPath *path, GBool eo);
+ OPVPSplashXPath *makeDashedPath(OPVPSplashXPath *xPath);
+ void transform(SplashCoord *matrix, SplashCoord xi, SplashCoord yi,
+ SplashCoord *xo, SplashCoord *yo);
+
+ const char *getOption(const char *key, int nOptions, const char *optionKeys[],
+ const char *optionVals[]);
+
+ OPVPWrapper *opvp;
+ int printerContext;
+
+ OPVPSplashState *state;
+ GBool debugMode;
+ int colorMode;
+ GBool stateBypass;
+ OPVPClipPath *clipPath;
+
+ GBool oldLipsDriver;
+ GBool clipPathNotSaved;
+ GBool noShearImage;
+ GBool noLineStyle;
+ GBool noClipPath;
+ GBool noMiterLimit;
+ GBool ignoreMiterLimit;
+ GBool savedNoClipPath;
+ GBool noImageMask;
+ int bitmapCharThreshold;
+ int maxClipPathLength;
+ int maxFillPathLength;
+ int saveDriverStateCount;
+};
+
+#endif
diff --git a/filter/pdftoopvp/oprs/OPVPSplashClip.cxx b/filter/pdftoopvp/oprs/OPVPSplashClip.cxx
new file mode 100644
index 000000000..c9d2e834c
--- /dev/null
+++ b/filter/pdftoopvp/oprs/OPVPSplashClip.cxx
@@ -0,0 +1,91 @@
+#include <config.h>
+#include "splash/SplashXPathScanner.h"
+#include "OPVPSplashClip.h"
+
+void OPVPSplashClip::getBBox(int *xMinA, int *yMinA, int *xMaxA, int *yMaxA)
+{
+ int i;
+ int cxMin = splashRound(xMin), cyMin = splashRound(yMin);
+ int cxMax = splashRound(xMax), cyMax = splashRound(yMax);
+ int txMin, tyMin, txMax, tyMax;
+
+ for (i = 0; i < length; ++i) {
+ scanners[i]->getBBox(&txMin,&tyMin,&txMax,&tyMax);
+ if (txMin > cxMin) cxMin = txMin;
+ if (tyMin > cyMin) cyMin = tyMin;
+ if (txMax < cxMax) cxMax = txMax;
+ if (tyMax < cyMax) cyMax = tyMax;
+ }
+ *xMinA = cxMin;
+ *yMinA = cyMin;
+ *xMaxA = cxMax;
+ *yMaxA = cyMax;
+}
+
+OPVPSplashPath *OPVPSplashClip::makePath()
+{
+ int i,j;
+ int y, x0, x1;
+ int txMin, tyMin, txMax, tyMax;
+ int tsxMin, tsyMin, tsxMax, tsyMax;
+ Guchar *cbuf,*tbuf;
+ int blen;
+ OPVPSplashPath *p = new OPVPSplashPath();
+
+ getBBox(&txMin,&tyMin,&txMax,&tyMax);
+ if (txMin > txMax || tyMin > tyMax) return p;
+ blen = txMax-txMin+1;
+ cbuf = new Guchar[blen];
+ tbuf = new Guchar[blen];
+
+ /* dummy call to clear state */
+ scanners[0]->getBBox(&tsxMin,&tsyMin,&tsxMax,&tsyMax);
+ scanners[0]->getNextSpan(tsyMin-2,&x0,&x1);
+
+ for (y = tyMin;y <= tyMax;y++) {
+ /* clear buffer */
+ for (i = 0;i < blen;i++) {
+ cbuf[i] = 0;
+ }
+ while (scanners[0]->getNextSpan(y,&x0,&x1)) {
+ if (x0 < txMin) x0 = txMin;
+ if (x1 > txMax) x1 = txMax;
+ for (i = x0;i < x1;i++) {
+ cbuf[i-txMin] = 1;
+ }
+ }
+ for (j = 1; j < length; ++j) {
+ /* clear buffer */
+ for (i = 0;i < blen;i++) {
+ tbuf[i] = 0;
+ }
+ while (scanners[j]->getNextSpan(y,&x0,&x1)) {
+ if (x0 < txMin) x0 = txMin;
+ if (x1 > txMax) x1 = txMax;
+ for (i = x0;i < x1;i++) {
+ tbuf[i-txMin] = 1;
+ }
+ }
+ /* and buffer */
+ for (i = 0;i < blen;i++) {
+ cbuf[i] &= tbuf[i];
+ }
+ }
+ /* scan buffer and add path */
+ for (i = 0;i < blen;i = j) {
+ if (cbuf[i] != 0) {
+ p->moveTo(i+txMin,y);
+ for (j = i+1;j < blen && cbuf[j] != 0;j++);
+ p->lineTo(j-1+txMin,y);
+ p->lineTo(j-1+txMin,y+1);
+ p->lineTo(i+txMin,y+1);
+ p->close();
+ } else {
+ j = i+1;
+ }
+ }
+ }
+ delete[] cbuf;
+ delete[] tbuf;
+ return p;
+}
diff --git a/filter/pdftoopvp/oprs/OPVPSplashClip.h b/filter/pdftoopvp/oprs/OPVPSplashClip.h
new file mode 100644
index 000000000..d531fcade
--- /dev/null
+++ b/filter/pdftoopvp/oprs/OPVPSplashClip.h
@@ -0,0 +1,30 @@
+#ifndef OPVPSPLASHCLIP_H
+#define OPVPSPLASHCLIP_H
+
+#include "splash/SplashClip.h"
+#include "OPVPSplashPath.h"
+
+class OPVPSplashClip : public SplashClip {
+public:
+
+ OPVPSplashClip(SplashCoord x0, SplashCoord y0,
+ SplashCoord x1, SplashCoord y1,
+ GBool antialiasA) :
+ SplashClip(x0,y0,x1,y1,antialiasA) {
+ }
+
+ OPVPSplashClip(SplashClip *sclip) : SplashClip(sclip) {
+ }
+
+ OPVPSplashClip *copy() { return new OPVPSplashClip(this); }
+
+ ~OPVPSplashClip() {}
+
+ void getBBox(int *xMinA, int *yMinA, int *xMaxA, int *yMaxA);
+ OPVPSplashPath *makePath();
+private:
+ OPVPSplashClip(OPVPSplashClip *clip) : SplashClip(clip) {
+ }
+};
+
+#endif
diff --git a/filter/pdftoopvp/oprs/OPVPSplashPath.cxx b/filter/pdftoopvp/oprs/OPVPSplashPath.cxx
new file mode 100644
index 000000000..5779dce5a
--- /dev/null
+++ b/filter/pdftoopvp/oprs/OPVPSplashPath.cxx
@@ -0,0 +1,185 @@
+#include <config.h>
+#include <stdio.h>
+#include "splash/SplashMath.h"
+#include "OPVPSplashPath.h"
+#include "OPVPWrapper.h"
+#include "OPRS.h"
+
+void OPVPSplashPath::getBBox(int *xMinA, int *yMinA, int *xMaxA,
+ int *yMaxA)
+{
+ int i;
+ SplashCoord xMin, yMin, xMax, yMax;
+
+ if (length <= 0) {
+ /* return far away point */
+ *xMinA = *yMinA = *xMaxA = *yMaxA = 0xC0000000;
+ return;
+ }
+ xMin = xMax = pts[0].x;
+ yMin = yMax = pts[0].y;
+ for (i = 1;i < length;i++) {
+ if (pts[i].x > xMax) {
+ xMax = pts[i].x;
+ } else if (pts[i].x < xMin) {
+ xMin = pts[i].x;
+ }
+ if (pts[i].y > yMax) {
+ yMax = pts[i].y;
+ } else if (pts[i].y < yMin) {
+ yMin = pts[i].y;
+ }
+ }
+ *xMinA = splashRound(xMin);
+ *xMaxA = splashRound(xMax);
+ *yMinA = splashRound(yMin);
+ *yMaxA = splashRound(yMax);
+}
+
+GBool OPVPSplashPath::isRectanglePath(
+ SplashCoord *xMin, SplashCoord *yMin, SplashCoord *xMax, SplashCoord *yMax)
+{
+ if (length != 5
+ || pts[0].x != pts[4].x
+ || pts[0].y != pts[4].y
+ || flags[0] != (splashPathFirst | splashPathClosed)
+ || flags[1] != 0
+ || flags[2] != 0
+ || flags[3] != 0
+ || flags[4] != (splashPathLast | splashPathClosed)) {
+ return gFalse;
+ }
+ if (splashRound(pts[0].x) == splashRound(pts[1].x)) {
+ if (splashRound(pts[1].y) != splashRound(pts[2].y)
+ || splashRound(pts[2].x) != splashRound(pts[3].x)
+ || splashRound(pts[3].y) != splashRound(pts[4].y)) {
+ return gFalse;
+ }
+ } else if (splashRound(pts[0].y) == splashRound(pts[1].y)) {
+ if (splashRound(pts[1].x) != splashRound(pts[2].x)
+ || splashRound(pts[2].y) != splashRound(pts[3].y)
+ || splashRound(pts[3].x) != splashRound(pts[4].x)) {
+ return gFalse;
+ }
+ } else {
+ return gFalse;
+ }
+ *xMin = pts[0].x;
+ *yMin = pts[0].y;
+ *xMax = pts[2].x;
+ *yMax = pts[2].y;
+ if (*xMin > *xMax) {
+ SplashCoord t = *xMin;
+
+ *xMin = *xMax;
+ *xMax = t;
+ }
+ if (*yMin > *yMax) {
+ SplashCoord t = *yMin;
+
+ *yMin = *yMax;
+ *yMax = t;
+ }
+ return gTrue;
+}
+
+SplashError OPVPSplashPath::makePath(OPVPWrapper *opvp)
+{
+ int i,j;
+ opvp_fix_t x,y;
+
+ if (opvp->NewPath() < 0) {
+ OPRS::error("NewPath error\n");
+ return splashErrOPVP;
+ }
+ for (i = 0;i < length;i = j) {
+ int curve = 0;
+ int n;
+ opvp_point_t *points;
+ int k;
+
+ if ((flags[i] & splashPathFirst) != 0) {
+ /* first point of a subpath */
+ if ((flags[i] & splashPathLast) == 0
+ || (flags[i] & splashPathClosed) != 0) {
+ OPVP_F2FIX((pts[i].x),(x));
+ OPVP_F2FIX((pts[i].y),(y));
+ if (opvp->SetCurrentPoint(x,y) < 0) {
+ OPRS::error("SetCurrentPoint error\n");
+ return splashErrOPVP;
+ }
+ }
+ j = i+1;
+ continue;
+ }
+ if (i+2 < length && flags[i] == splashPathCurve) {
+ /* curve */
+ curve = 1;
+ for (j = i;j+2 < length
+ && flags[j] == splashPathCurve;j += 3);
+ } else {
+ curve = 0;
+ for (j = i;j < length
+ && (flags[j] & splashPathCurve) == 0
+ && (flags[j] & splashPathFirst) == 0;j++);
+ }
+
+ n = j-i;
+ points = new opvp_point_t[n];
+ /* copy points */
+ for (k = i; k < j;k++) {
+ OPVP_F2FIX((pts[k].x),(points[k-i].x));
+ OPVP_F2FIX((pts[k].y),(points[k-i].y));
+ }
+
+ if (curve) {
+ /* curve */
+ if (opvp->BezierPath(n,points) < 0) {
+ OPRS::error("BezierPath error\n");
+ return splashErrOPVP;
+ }
+ } else {
+ /* line */
+ GBool closed = (flags[j-1] & splashPathClosed) != 0;
+
+ if (closed) {
+ if (opvp->LinePath(OPVP_PATHCLOSE,
+ n,points) < 0) {
+ OPRS::error("LinePath error\n");
+ return splashErrOPVP;
+ }
+ } else {
+ if (opvp->LinePath(OPVP_PATHOPEN,
+ n,points) < 0) {
+ OPRS::error("LinePath error\n");
+ return splashErrOPVP;
+ }
+ }
+ }
+ delete[] points;
+ }
+ if (opvp->EndPath() < 0) {
+ OPRS::error("EndPath error\n");
+ return splashErrOPVP;
+ }
+ return splashOk;
+}
+
+void OPVPSplashPath::closeAllSubPath()
+{
+ int i;
+ int f = 0;
+
+ for (i = 0;i < length;i++) {
+ if ((flags[i] & splashPathFirst) != 0) {
+ f = i;
+ }
+ if ((flags[i] & splashPathLast) != 0) {
+ if (pts[f].x == pts[i].x
+ && pts[f].y == pts[i].y) {
+ flags[f] |= splashPathClosed;
+ flags[i] |= splashPathClosed;
+ }
+ }
+ }
+}
diff --git a/filter/pdftoopvp/oprs/OPVPSplashPath.h b/filter/pdftoopvp/oprs/OPVPSplashPath.h
new file mode 100644
index 000000000..d8a3b2335
--- /dev/null
+++ b/filter/pdftoopvp/oprs/OPVPSplashPath.h
@@ -0,0 +1,28 @@
+#ifndef OPVPSPLASHPATH_H
+#define OPVPSPLASHPATH_H
+
+#include "splash/SplashPath.h"
+#include "OPVPWrapper.h"
+
+class OPVPSplashPath : public SplashPath {
+public:
+
+ OPVPSplashPath() {};
+
+ OPVPSplashPath(SplashPath *spath) : SplashPath(spath) {
+ }
+
+ // Copy a path.
+ OPVPSplashPath *copy() { return new OPVPSplashPath(this); }
+
+ void getBBox(int *xMinA, int *yMinA, int *xMaxA, int *yMaxA);
+ GBool isRectanglePath(SplashCoord *xMin, SplashCoord *yMin,
+ SplashCoord *xMax, SplashCoord *yMax);
+ SplashError makePath(OPVPWrapper *opvp);
+ void closeAllSubPath();
+private:
+ OPVPSplashPath(OPVPSplashPath *path) : SplashPath(path) {
+ }
+};
+
+#endif
diff --git a/filter/pdftoopvp/oprs/OPVPSplashState.cxx b/filter/pdftoopvp/oprs/OPVPSplashState.cxx
new file mode 100644
index 000000000..b4a7ec85c
--- /dev/null
+++ b/filter/pdftoopvp/oprs/OPVPSplashState.cxx
@@ -0,0 +1,178 @@
+//========================================================================
+//
+// SplashState.cc
+//
+//========================================================================
+
+#include <config.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma implementation
+#endif
+
+#include <string.h>
+#ifdef HAVE_CPP_POPPLER_VERSION_H
+#include "cpp/poppler-version.h"
+#endif
+#include "goo/gmem.h"
+#include "splash/SplashPattern.h"
+#include "splash/SplashScreen.h"
+#include "splash/SplashBitmap.h"
+#include "splash/SplashState.h"
+#include "OPVPSplashState.h"
+#include "OPVPSplashClip.h"
+
+//------------------------------------------------------------------------
+// SplashState
+//------------------------------------------------------------------------
+
+OPVPSplashState::OPVPSplashState(int width, int height, GBool vectorAntialias,
+ SplashScreenParams *screenParams) {
+ SplashColor color;
+
+ matrix[0] = 1; matrix[1] = 0;
+ matrix[2] = 0; matrix[3] = 1;
+ matrix[4] = 0; matrix[5] = 0;
+ memset(&color, 0, sizeof(SplashColor));
+ strokePattern = new SplashSolidColor(color);
+ fillPattern = new SplashSolidColor(color);
+ screen = new SplashScreen(screenParams);
+ blendFunc = NULL;
+ strokeAlpha = 1;
+ fillAlpha = 1;
+ lineWidth = 0;
+ lineCap = splashLineCapButt;
+ lineJoin = splashLineJoinMiter;
+ miterLimit = 10;
+ flatness = 1;
+ lineDash = NULL;
+ lineDashLength = 0;
+ lineDashPhase = 0;
+ strokeAdjust = gFalse;
+ clip = new OPVPSplashClip(0, 0, width - 0.001,
+ height - 0.001, vectorAntialias);
+ softMask = NULL;
+ deleteSoftMask = gFalse;
+ inNonIsolatedGroup = gFalse;
+ next = NULL;
+}
+
+OPVPSplashState::OPVPSplashState(int width, int height, GBool vectorAntialias,
+ SplashScreen *screenA) {
+ SplashColor color;
+
+ matrix[0] = 1; matrix[1] = 0;
+ matrix[2] = 0; matrix[3] = 1;
+ matrix[4] = 0; matrix[5] = 0;
+ memset(&color, 0, sizeof(SplashColor));
+ strokePattern = new SplashSolidColor(color);
+ fillPattern = new SplashSolidColor(color);
+ screen = screenA->copy();
+ blendFunc = NULL;
+ strokeAlpha = 1;
+ fillAlpha = 1;
+ lineWidth = 0;
+ lineCap = splashLineCapButt;
+ lineJoin = splashLineJoinMiter;
+ miterLimit = 10;
+ flatness = 1;
+ lineDash = NULL;
+ lineDashLength = 0;
+ lineDashPhase = 0;
+ strokeAdjust = gFalse;
+ clip = new OPVPSplashClip(0, 0, width - 0.001,
+ height - 0.001, vectorAntialias);
+ softMask = NULL;
+ deleteSoftMask = gFalse;
+ inNonIsolatedGroup = gFalse;
+ next = NULL;
+}
+
+OPVPSplashState::OPVPSplashState(OPVPSplashState *state) {
+ memcpy(matrix, state->matrix, 6 * sizeof(SplashCoord));
+ strokePattern = state->strokePattern->copy();
+ fillPattern = state->fillPattern->copy();
+ screen = state->screen->copy();
+ blendFunc = state->blendFunc;
+ strokeAlpha = state->strokeAlpha;
+ fillAlpha = state->fillAlpha;
+ lineWidth = state->lineWidth;
+ lineCap = state->lineCap;
+ lineJoin = state->lineJoin;
+ miterLimit = state->miterLimit;
+ flatness = state->flatness;
+ if (state->lineDash) {
+ lineDashLength = state->lineDashLength;
+ lineDash = (SplashCoord *)gmallocn(lineDashLength, sizeof(SplashCoord));
+ memcpy(lineDash, state->lineDash, lineDashLength * sizeof(SplashCoord));
+ } else {
+ lineDash = NULL;
+ lineDashLength = 0;
+ }
+ lineDashPhase = state->lineDashPhase;
+ strokeAdjust = state->strokeAdjust;
+ clip = state->clip->copy();
+ softMask = state->softMask;
+ deleteSoftMask = gFalse;
+ inNonIsolatedGroup = state->inNonIsolatedGroup;
+ next = NULL;
+}
+
+OPVPSplashState::~OPVPSplashState() {
+ delete strokePattern;
+ delete fillPattern;
+ delete screen;
+ gfree(lineDash);
+ delete clip;
+ if (deleteSoftMask && softMask) {
+ delete softMask;
+ }
+}
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+void OPVPSplashState::setState(Splash *osplash) {
+ osplash->setMatrix(matrix);
+ osplash->setFlatness(flatness);
+ osplash->setLineDash(lineDash,lineDashLength,lineDashPhase);
+ osplash->setLineCap(lineCap);
+ osplash->setStrokeAdjust(strokeAdjust);
+ osplash->setMiterLimit(miterLimit);
+ osplash->setLineJoin(lineJoin);
+}
+#endif
+
+void OPVPSplashState::setStrokePattern(SplashPattern *strokePatternA) {
+ delete strokePattern;
+ strokePattern = strokePatternA;
+}
+
+void OPVPSplashState::setFillPattern(SplashPattern *fillPatternA) {
+ delete fillPattern;
+ fillPattern = fillPatternA;
+}
+
+void OPVPSplashState::setScreen(SplashScreen *screenA) {
+ delete screen;
+ screen = screenA;
+}
+
+void OPVPSplashState::setLineDash(SplashCoord *lineDashA, int lineDashLengthA,
+ SplashCoord lineDashPhaseA) {
+ gfree(lineDash);
+ lineDashLength = lineDashLengthA;
+ if (lineDashLength > 0) {
+ lineDash = (SplashCoord *)gmallocn(lineDashLength, sizeof(SplashCoord));
+ memcpy(lineDash, lineDashA, lineDashLength * sizeof(SplashCoord));
+ } else {
+ lineDash = NULL;
+ }
+ lineDashPhase = lineDashPhaseA;
+}
+
+void OPVPSplashState::setSoftMask(SplashBitmap *softMaskA) {
+ if (deleteSoftMask) {
+ delete softMask;
+ }
+ softMask = softMaskA;
+ deleteSoftMask = gTrue;
+}
diff --git a/filter/pdftoopvp/oprs/OPVPSplashState.h b/filter/pdftoopvp/oprs/OPVPSplashState.h
new file mode 100644
index 000000000..9cb16db26
--- /dev/null
+++ b/filter/pdftoopvp/oprs/OPVPSplashState.h
@@ -0,0 +1,95 @@
+//========================================================================
+//
+// OPVPSplashState.h
+//
+//========================================================================
+
+#ifndef OPVPSPLASHSTATE_H
+#define OPVPSPLASHSTATE_H
+
+#ifdef USE_GCC_PRAGMAS
+#pragma interface
+#endif
+
+#ifdef HAVE_CPP_POPPLER_VERSION_H
+#include "cpp/poppler-version.h"
+#endif
+#include "splash/SplashTypes.h"
+#include "splash/SplashState.h"
+#include "splash/Splash.h"
+
+class SplashPattern;
+class SplashScreen;
+class OPVPSplashClip;
+class SplashBitmap;
+
+//------------------------------------------------------------------------
+// SplashState
+//------------------------------------------------------------------------
+
+class OPVPSplashState {
+public:
+
+ // Create a new state object, initialized with default settings.
+ OPVPSplashState(int width, int height, GBool vectorAntialias,
+ SplashScreenParams *screenParams);
+ OPVPSplashState(int width, int height, GBool vectorAntialias,
+ SplashScreen *screenA);
+
+ // Copy a state object.
+ OPVPSplashState *copy() { return new OPVPSplashState(this); }
+
+ ~OPVPSplashState();
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+ void setState(Splash *osplash);
+#endif
+
+ // Set the stroke pattern. This does not copy <strokePatternA>.
+ void setStrokePattern(SplashPattern *strokePatternA);
+
+ // Set the fill pattern. This does not copy <fillPatternA>.
+ void setFillPattern(SplashPattern *fillPatternA);
+
+ // Set the screen. This does not copy <screenA>.
+ void setScreen(SplashScreen *screenA);
+
+ // Set the line dash pattern. This copies the <lineDashA> array.
+ void setLineDash(SplashCoord *lineDashA, int lineDashLengthA,
+ SplashCoord lineDashPhaseA);
+
+ // Set the soft mask bitmap.
+ void setSoftMask(SplashBitmap *softMaskA);
+
+private:
+
+ OPVPSplashState(OPVPSplashState *state);
+
+ SplashCoord matrix[6];
+ SplashPattern *strokePattern;
+ SplashPattern *fillPattern;
+ SplashScreen *screen;
+ SplashBlendFunc blendFunc;
+ SplashCoord strokeAlpha;
+ SplashCoord fillAlpha;
+ SplashCoord lineWidth;
+ int lineCap;
+ int lineJoin;
+ SplashCoord miterLimit;
+ SplashCoord flatness;
+ SplashCoord *lineDash;
+ int lineDashLength;
+ SplashCoord lineDashPhase;
+ GBool strokeAdjust;
+ OPVPSplashClip *clip;
+ SplashBitmap *softMask;
+ GBool deleteSoftMask;
+ GBool inNonIsolatedGroup;
+
+ OPVPSplashState *next; // used by OPVPSplash class
+
+ friend class OPVPSplash;
+ friend class OPVPSplashXPath;
+};
+
+#endif
diff --git a/filter/pdftoopvp/oprs/OPVPSplashXPath.cxx b/filter/pdftoopvp/oprs/OPVPSplashXPath.cxx
new file mode 100644
index 000000000..7a6f429ba
--- /dev/null
+++ b/filter/pdftoopvp/oprs/OPVPSplashXPath.cxx
@@ -0,0 +1,426 @@
+#include <config.h>
+#include <stdio.h>
+#ifdef HAVE_CPP_POPPLER_VERSION_H
+#include "cpp/poppler-version.h"
+#endif
+#include "splash/Splash.h"
+#include "splash/SplashMath.h"
+#include "OPVPSplashClip.h"
+#include "OPVPSplashXPath.h"
+#include "OPVPWrapper.h"
+#include "OPVPSplash.h"
+
+#if POPPLER_VERSION_MAJOR <= 0 && POPPLER_VERSION_MINOR < 19
+OPVPSplashXPath *OPVPSplashXPath::makeDashedPath(OPVPSplashState *state)
+{
+ OPVPSplashXPath *dPath;
+ GBool lineDashStartOn, lineDashOn;
+ GBool atSegStart, atSegEnd, atDashStart, atDashEnd;
+ int lineDashStartIdx, lineDashIdx, subpathStart;
+ SplashCoord lineDashTotal, lineDashStartPhase, lineDashDist;
+ int segIdx;
+ SplashXPathSeg *seg;
+ SplashCoord sx0, sy0, sx1, sy1, ax0, ay0, ax1, ay1, dist;
+ int i;
+
+ dPath = new OPVPSplashXPath();
+
+ lineDashTotal = 0;
+ for (i = 0; i < state->lineDashLength; ++i) {
+ lineDashTotal += state->lineDash[i];
+ }
+ lineDashStartPhase = state->lineDashPhase;
+ i = splashFloor(lineDashStartPhase / lineDashTotal);
+ lineDashStartPhase -= i * lineDashTotal;
+ lineDashStartOn = gTrue;
+ lineDashStartIdx = 0;
+ while (lineDashStartPhase >= state->lineDash[lineDashStartIdx]) {
+ lineDashStartOn = !lineDashStartOn;
+ lineDashStartPhase -= state->lineDash[lineDashStartIdx];
+ ++lineDashStartIdx;
+ }
+
+ segIdx = 0;
+ seg = segs;
+ sx0 = seg->x0;
+ sy0 = seg->y0;
+ sx1 = seg->x1;
+ sy1 = seg->y1;
+ dist = splashDist(sx0, sy0, sx1, sy1);
+ lineDashOn = lineDashStartOn;
+ lineDashIdx = lineDashStartIdx;
+ lineDashDist = state->lineDash[lineDashIdx] - lineDashStartPhase;
+ atSegStart = gTrue;
+ atDashStart = gTrue;
+ subpathStart = dPath->length;
+
+ while (segIdx < length) {
+
+ ax0 = sx0;
+ ay0 = sy0;
+ if (dist <= lineDashDist) {
+ ax1 = sx1;
+ ay1 = sy1;
+ lineDashDist -= dist;
+ dist = 0;
+ atSegEnd = gTrue;
+ atDashEnd = lineDashDist == 0 || (seg->flags & splashXPathLast);
+ } else {
+ ax1 = sx0 + (lineDashDist / dist) * (sx1 - sx0);
+ ay1 = sy0 + (lineDashDist / dist) * (sy1 - sy0);
+ sx0 = ax1;
+ sy0 = ay1;
+ dist -= lineDashDist;
+ lineDashDist = 0;
+ atSegEnd = gFalse;
+ atDashEnd = gTrue;
+ }
+
+ if (lineDashOn) {
+ dPath->addSegment(ax0, ay0, ax1, ay1,
+ atDashStart, atDashEnd,
+ atDashStart, atDashEnd);
+ // end of closed subpath
+ if (atSegEnd &&
+ (seg->flags & splashXPathLast) &&
+ !(seg->flags & splashXPathEnd1)) {
+ dPath->segs[subpathStart].flags &= ~splashXPathEnd0;
+ dPath->segs[dPath->length - 1].flags &= ~splashXPathEnd1;
+ }
+ }
+
+ if (atDashEnd) {
+ lineDashOn = !lineDashOn;
+ if (++lineDashIdx == state->lineDashLength) {
+ lineDashIdx = 0;
+ }
+ lineDashDist = state->lineDash[lineDashIdx];
+ atDashStart = gTrue;
+ } else {
+ atDashStart = gFalse;
+ }
+ if (atSegEnd) {
+ if (++segIdx < length) {
+ ++seg;
+ sx0 = seg->x0;
+ sy0 = seg->y0;
+ sx1 = seg->x1;
+ sy1 = seg->y1;
+ dist = splashDist(sx0, sy0, sx1, sy1);
+ if (seg->flags & splashXPathFirst) {
+ lineDashOn = lineDashStartOn;
+ lineDashIdx = lineDashStartIdx;
+ lineDashDist = state->lineDash[lineDashIdx] - lineDashStartPhase;
+ atDashStart = gTrue;
+ subpathStart = dPath->length;
+ }
+ }
+ atSegStart = gTrue;
+ } else {
+ atSegStart = gFalse;
+ }
+ }
+
+ return dPath;
+}
+
+void OPVPSplashXPath::strokeWide(OPVPSplash *splash, OPVPSplashState *state)
+{
+ SplashXPathSeg *seg, *seg2;
+ OPVPSplashPath *widePath;
+ SplashCoord d, dx, dy, wdx, wdy, dxPrev, dyPrev, wdxPrev, wdyPrev;
+ SplashCoord dotprod, miter;
+ SplashCoord x0,y0,x1,y1,x2,y2,x3,y3;
+ int i, j;
+
+ dx = dy = wdx = wdy = 0; // make gcc happy
+ dxPrev = dyPrev = wdxPrev = wdyPrev = 0; // make gcc happy
+
+ for (i = 0, seg = segs; i < length; ++i, ++seg) {
+
+ // save the deltas for the previous segment; if this is the first
+ // segment on a subpath, compute the deltas for the last segment
+ // on the subpath (which may be used to draw a line join)
+ if (seg->flags & splashXPathFirst) {
+ for (j = i + 1, seg2 = &segs[j];
+ j < length; ++j, ++seg2) {
+ if (seg2->flags & splashXPathLast) {
+ d = splashDist(seg2->x0, seg2->y0, seg2->x1, seg2->y1);
+ if (d == 0) {
+ //~ not clear what the behavior should be for joins with d==0
+ dxPrev = 0;
+ dyPrev = 1;
+ } else {
+ d = 1 / d;
+ dxPrev = d * (seg2->x1 - seg2->x0);
+ dyPrev = d * (seg2->y1 - seg2->y0);
+ }
+ wdxPrev = 0.5 * state->lineWidth * dxPrev;
+ wdyPrev = 0.5 * state->lineWidth * dyPrev;
+ break;
+ }
+ }
+ } else {
+ dxPrev = dx;
+ dyPrev = dy;
+ wdxPrev = wdx;
+ wdyPrev = wdy;
+ }
+
+ // compute deltas for this line segment
+ d = splashDist(seg->x0, seg->y0, seg->x1, seg->y1);
+ if (d == 0) {
+ // we need to draw end caps on zero-length lines
+ //~ not clear what the behavior should be for splashLineCapButt with d==0
+ dx = 0;
+ dy = 1;
+ } else {
+ d = 1 / d;
+ dx = d * (seg->x1 - seg->x0);
+ dy = d * (seg->y1 - seg->y0);
+ }
+ wdx = 0.5 * state->lineWidth * dx;
+ wdy = 0.5 * state->lineWidth * dy;
+
+ // initialize the path (which will be filled)
+ widePath = new OPVPSplashPath();
+ widePath->moveTo(seg->x0 - wdy, seg->y0 + wdx);
+
+ // draw the start cap
+ if (seg->flags & splashXPathEnd0) {
+ switch (state->lineCap) {
+ case splashLineCapButt:
+ widePath->lineTo(seg->x0 + wdy, seg->y0 - wdx);
+ break;
+ case splashLineCapRound:
+ x0 = seg->x0 - wdy;
+ y0 = seg->y0 + wdx;
+ x3 = seg->x0 - wdx;
+ y3 = seg->y0 - wdy;
+ splash->arcToCurve(x0, y0, x3, y3,
+ seg->x0, seg->y0, &x1,&y1,&x2,&y2);
+ widePath->curveTo(x2,y2,x1,y1,x3,y3);
+ x0 = x3;
+ y0 = y3;
+ x3 = seg->x0 + wdy;
+ y3 = seg->y0 - wdx;
+ splash->arcToCurve(x0,y0,x3,y3,
+ seg->x0, seg->y0, &x1,&y1,&x2,&y2);
+ widePath->curveTo(x2,y2,x1,y1,x3,y3);
+ break;
+ case splashLineCapProjecting:
+ widePath->lineTo(seg->x0 - wdx - wdy, seg->y0 + wdx - wdy);
+ widePath->lineTo(seg->x0 - wdx + wdy, seg->y0 - wdx - wdy);
+ widePath->lineTo(seg->x0 + wdy, seg->y0 - wdx);
+ break;
+ }
+ } else {
+ widePath->lineTo(seg->x0 + wdy, seg->y0 - wdx);
+ }
+
+ // draw the left side of the segment
+ widePath->lineTo(seg->x1 + wdy, seg->y1 - wdx);
+
+ // draw the end cap
+ if (seg->flags & splashXPathEnd1) {
+ switch (state->lineCap) {
+ case splashLineCapButt:
+ widePath->lineTo(seg->x1 - wdy, seg->y1 + wdx);
+ break;
+ case splashLineCapRound:
+ x0 = seg->x1 + wdy;
+ y0 = seg->y1 - wdx;
+ x3 = seg->x1 + wdx;
+ y3 = seg->y1 + wdy;
+ splash->arcToCurve(x0, y0, x3, y3,
+ seg->x1, seg->y1, &x1,&y1,&x2,&y2);
+ widePath->curveTo(x2,y2,x1,y1,x3,y3);
+ x0 = x3;
+ y0 = y3;
+ x3 = seg->x1 - wdy;
+ y3 = seg->y1 + wdx;
+ splash->arcToCurve(x0,y0,x3,y3,
+ seg->x1, seg->y1, &x1,&y1,&x2,&y2);
+ widePath->curveTo(x2,y2,x1,y1,x3,y3);
+ break;
+ case splashLineCapProjecting:
+ widePath->lineTo(seg->x1 + wdx + wdy, seg->y1 - wdx + wdy);
+ widePath->lineTo(seg->x1 + wdx - wdy, seg->y1 + wdx + wdy);
+ widePath->lineTo(seg->x1 - wdy, seg->y1 + wdx);
+ break;
+ }
+ } else {
+ widePath->lineTo(seg->x1 - wdy, seg->y1 + wdx);
+ }
+
+ // draw the right side of the segment
+ widePath->lineTo(seg->x0 - wdy, seg->y0 + wdx);
+
+ // fill the segment
+ splash->fill(widePath, gTrue);
+ delete widePath;
+
+ // draw the line join
+ if (!(seg->flags & splashXPathEnd0)) {
+ widePath = NULL;
+ switch (state->lineJoin) {
+ case splashLineJoinMiter:
+ dotprod = -(dx * dxPrev + dy * dyPrev);
+ if (dotprod != 1) {
+ widePath = new OPVPSplashPath();
+ widePath->moveTo(seg->x0, seg->y0);
+ miter = 2 / (1 - dotprod);
+ if (splashSqrt(miter) <= state->miterLimit) {
+ miter = splashSqrt(miter - 1);
+ if (dy * dxPrev > dx * dyPrev) {
+ widePath->lineTo(seg->x0 + wdyPrev, seg->y0 - wdxPrev);
+ widePath->lineTo(seg->x0 + wdy - miter * wdx,
+ seg->y0 - wdx - miter * wdy);
+ widePath->lineTo(seg->x0 + wdy, seg->y0 - wdx);
+ } else {
+ widePath->lineTo(seg->x0 - wdyPrev, seg->y0 + wdxPrev);
+ widePath->lineTo(seg->x0 - wdy - miter * wdx,
+ seg->y0 + wdx - miter * wdy);
+ widePath->lineTo(seg->x0 - wdy, seg->y0 + wdx);
+ }
+ } else {
+ if (dy * dxPrev > dx * dyPrev) {
+ widePath->lineTo(seg->x0 + wdyPrev, seg->y0 - wdxPrev);
+ widePath->lineTo(seg->x0 + wdy, seg->y0 - wdx);
+ } else {
+ widePath->lineTo(seg->x0 - wdyPrev, seg->y0 + wdxPrev);
+ widePath->lineTo(seg->x0 - wdy, seg->y0 + wdx);
+ }
+ }
+ }
+ break;
+ case splashLineJoinRound:
+ widePath = new OPVPSplashPath();
+ /* draw circle */
+ widePath->moveTo(seg->x0 + wdy, seg->y0 - wdx);
+ x0 = seg->x0 + wdy;
+ y0 = seg->y0 - wdx;
+ x3 = seg->x0 - wdx;
+ y3 = seg->y0 - wdy;
+ splash->arcToCurve(x0, y0, x3, y3,
+ seg->x0, seg->y0, &x1,&y1,&x2,&y2);
+ widePath->curveTo(x1,y1,x2,y2,x3,y3);
+ x0 = x3;
+ y0 = y3;
+ x3 = seg->x0 - wdy;
+ y3 = seg->y0 + wdx;
+ splash->arcToCurve(x0, y0, x3, y3,
+ seg->x0, seg->y0, &x1,&y1,&x2,&y2);
+ widePath->curveTo(x1,y1,x2,y2,x3,y3);
+ x0 = x3;
+ y0 = y3;
+ x3 = seg->x0 + wdx;
+ y3 = seg->y0 + wdy;
+ splash->arcToCurve(x0, y0, x3, y3,
+ seg->x0, seg->y0, &x1,&y1,&x2,&y2);
+ widePath->curveTo(x1,y1,x2,y2,x3,y3);
+ x0 = x3;
+ y0 = y3;
+ x3 = seg->x0 + wdy;
+ y3 = seg->y0 - wdx;
+ splash->arcToCurve(x0, y0, x3, y3,
+ seg->x0, seg->y0, &x1,&y1,&x2,&y2);
+ widePath->curveTo(x1,y1,x2,y2,x3,y3);
+ break;
+ case splashLineJoinBevel:
+ widePath = new OPVPSplashPath();
+ widePath->moveTo(seg->x0, seg->y0);
+ if (dy * dxPrev > dx * dyPrev) {
+ widePath->lineTo(seg->x0 + wdyPrev, seg->y0 - wdxPrev);
+ widePath->lineTo(seg->x0 + wdy, seg->y0 - wdx);
+ } else {
+ widePath->lineTo(seg->x0 - wdyPrev, seg->y0 + wdxPrev);
+ widePath->lineTo(seg->x0 - wdy, seg->y0 + wdx);
+ }
+ break;
+ }
+ if (widePath) {
+ splash->fill(widePath, gTrue);
+ delete widePath;
+ }
+ }
+ }
+}
+#endif
+
+void OPVPSplashXPath::strokeNarrow(OPVPSplash *splash, OPVPSplashState *state)
+{
+ SplashXPathSeg *seg;
+ int x0, x1, x2, x3, y0, y1, x, y, t;
+ SplashCoord dx, dy, dxdy;
+ SplashClipResult clipRes;
+ int i;
+
+ for (i = 0, seg = segs; i < length; ++i, ++seg) {
+
+ x0 = splashFloor(seg->x0);
+ x1 = splashFloor(seg->x1);
+ y0 = splashFloor(seg->y0);
+ y1 = splashFloor(seg->y1);
+
+ // horizontal segment
+ if (y0 == y1) {
+ if (x0 > x1) {
+ t = x0; x0 = x1; x1 = t;
+ }
+ if ((clipRes = state->clip->testSpan(x0, x1, y0))
+ != splashClipAllOutside) {
+ splash->drawSpan(x0, x1, y0, clipRes == splashClipAllInside);
+ }
+
+ // segment with |dx| > |dy|
+ } else if (splashAbs(seg->dxdy) > 1) {
+ dx = seg->x1 - seg->x0;
+ dy = seg->y1 - seg->y0;
+ dxdy = seg->dxdy;
+ if (y0 > y1) {
+ t = y0; y0 = y1; y1 = t;
+ t = x0; x0 = x1; x1 = t;
+ dx = -dx;
+ dy = -dy;
+ }
+ if ((clipRes = state->clip->testRect(x0 <= x1 ? x0 : x1, y0,
+ x0 <= x1 ? x1 : x0, y1))
+ != splashClipAllOutside) {
+ if (dx > 0) {
+ x2 = x0;
+ for (y = y0; y < y1; ++y) {
+ x3 = splashFloor(seg->x0 + (y + 1 - seg->y0) * dxdy);
+ splash->drawSpan(x2, x3 - 1, y, clipRes == splashClipAllInside);
+ x2 = x3;
+ }
+ splash->drawSpan(x2, x1, y, clipRes == splashClipAllInside);
+ } else {
+ x2 = x0;
+ for (y = y0; y < y1; ++y) {
+ x3 = splashFloor(seg->x0 + (y + 1 - seg->y0) * dxdy);
+ splash->drawSpan(x3 + 1, x2, y, clipRes == splashClipAllInside);
+ x2 = x3;
+ }
+ splash->drawSpan(x1, x2, y, clipRes == splashClipAllInside);
+ }
+ }
+
+ // segment with |dy| > |dx|
+ } else {
+ dxdy = seg->dxdy;
+ if (y0 > y1) {
+ t = y0; y0 = y1; y1 = t;
+ }
+ if ((clipRes = state->clip->testRect(x0 <= x1 ? x0 : x1, y0,
+ x0 <= x1 ? x1 : x0, y1))
+ != splashClipAllOutside) {
+ for (y = y0; y <= y1; ++y) {
+ x = splashFloor(seg->x0 + (y - seg->y0) * dxdy);
+ splash->drawPixel(x, y, clipRes == splashClipAllInside);
+ }
+ }
+ }
+ }
+}
+
diff --git a/filter/pdftoopvp/oprs/OPVPSplashXPath.h b/filter/pdftoopvp/oprs/OPVPSplashXPath.h
new file mode 100644
index 000000000..f51b86869
--- /dev/null
+++ b/filter/pdftoopvp/oprs/OPVPSplashXPath.h
@@ -0,0 +1,39 @@
+#ifndef OPVPSPLASHXPATH_H
+#define OPVPSPLASHXPATH_H
+
+#include <config.h>
+#ifdef HAVE_CPP_POPPLER_VERSION_H
+#include "cpp/poppler-version.h"
+#endif
+#include "splash/SplashXPath.h"
+#include "OPVPSplashPath.h"
+#include "OPVPSplashState.h"
+
+class OPVPSplash;
+
+class OPVPSplashXPath : public SplashXPath {
+public:
+ OPVPSplashXPath(OPVPSplashPath *path, SplashCoord *matrix,
+ SplashCoord flatness, GBool closeSubpaths) :
+ SplashXPath(path,matrix,flatness,closeSubpaths) {
+ }
+
+ // Copy an expanded path.
+ OPVPSplashXPath *copy() { return new OPVPSplashXPath(this); }
+
+ OPVPSplashXPath *makeDashedPath(OPVPSplashState *state);
+ void strokeNarrow(OPVPSplash *splash, OPVPSplashState *state);
+#if POPPLER_VERSION_MAJOR <= 0 && POPPLER_VERSION_MINOR < 19
+ void strokeWide(OPVPSplash *splash, OPVPSplashState *state);
+#endif
+private:
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+ OPVPSplashXPath() : SplashXPath(new SplashPath(), 0, 0, gFalse) {};
+#else
+ OPVPSplashXPath() {};
+#endif
+ OPVPSplashXPath(OPVPSplashXPath *xPath) : SplashXPath(xPath) {
+ }
+};
+
+#endif
diff --git a/filter/pdftoopvp/oprs/OPVPWrapper.cxx b/filter/pdftoopvp/oprs/OPVPWrapper.cxx
new file mode 100644
index 000000000..3453e0d9b
--- /dev/null
+++ b/filter/pdftoopvp/oprs/OPVPWrapper.cxx
@@ -0,0 +1,910 @@
+/*
+ OPVPWrapper.cc
+*/
+
+
+#include <config.h>
+#include <stdio.h>
+#include "OPRS.h"
+#include "OPVPWrapper.h"
+#include "OPVPWrapper_0_2.h"
+#include <string.h>
+#include <dlfcn.h>
+
+OPVPWrapper::OPVPWrapper(void *opvpHandleA, opvp_int_t *opvpErrorNoA,
+ opvp_api_procs_t *procsA, opvp_dc_t printerContextA)
+{
+ procs = procsA;
+ opvpHandle = opvpHandleA;
+ opvpErrorNo = opvpErrorNoA;
+ printerContext = printerContextA;
+ version[0] = 1;
+ version[1] = 0;
+ supportClosePrinter = (procs->opvpClosePrinter != 0);
+ supportStartJob = (procs->opvpStartJob != 0);
+ supportEndJob = (procs->opvpEndJob != 0);
+ supportAbortJob = (procs->opvpAbortJob != 0);
+ supportStartDoc = (procs->opvpStartDoc != 0);
+ supportEndDoc = (procs->opvpEndDoc != 0);
+ supportStartPage = (procs->opvpStartPage != 0);
+ supportEndPage = (procs->opvpEndPage != 0);
+ supportResetCTM = (procs->opvpResetCTM != 0);
+ supportSetCTM = (procs->opvpSetCTM != 0);
+ supportGetCTM = (procs->opvpGetCTM != 0);
+ supportInitGS = (procs->opvpInitGS != 0);
+ supportSaveGS = (procs->opvpSaveGS != 0);
+ supportRestoreGS = (procs->opvpRestoreGS != 0);
+ supportQueryColorSpace = (procs->opvpQueryColorSpace != 0);
+ supportSetColorSpace = (procs->opvpSetColorSpace != 0);
+ supportGetColorSpace = (procs->opvpGetColorSpace != 0);
+ supportSetFillMode = (procs->opvpSetFillMode != 0);
+ supportGetFillMode = (procs->opvpGetFillMode != 0);
+ supportSetAlphaConstant = (procs->opvpSetAlphaConstant != 0);
+ supportGetAlphaConstant = (procs->opvpGetAlphaConstant != 0);
+ supportSetLineWidth = (procs->opvpSetLineWidth != 0);
+ supportGetLineWidth = (procs->opvpGetLineWidth != 0);
+ supportSetLineDash = (procs->opvpSetLineDash != 0);
+ supportGetLineDash = (procs->opvpGetLineDash != 0);
+ supportSetLineDashOffset = (procs->opvpSetLineDashOffset != 0);
+ supportGetLineDashOffset = (procs->opvpGetLineDashOffset != 0);
+ supportSetLineStyle = (procs->opvpSetLineStyle != 0);
+ supportGetLineStyle = (procs->opvpGetLineStyle != 0);
+ supportSetLineCap = (procs->opvpSetLineCap != 0);
+ supportGetLineCap = (procs->opvpGetLineCap != 0);
+ supportSetLineJoin = (procs->opvpSetLineJoin != 0);
+ supportGetLineJoin = (procs->opvpGetLineJoin != 0);
+ supportSetMiterLimit = (procs->opvpSetMiterLimit != 0);
+ supportGetMiterLimit = (procs->opvpGetMiterLimit != 0);
+ supportSetPaintMode = (procs->opvpSetPaintMode != 0);
+ supportGetPaintMode = (procs->opvpGetPaintMode != 0);
+ supportSetStrokeColor = (procs->opvpSetStrokeColor != 0);
+ supportSetFillColor = (procs->opvpSetFillColor != 0);
+ supportSetBgColor = (procs->opvpSetBgColor != 0);
+ supportNewPath = (procs->opvpNewPath != 0);
+ supportEndPath = (procs->opvpEndPath != 0);
+ supportStrokePath = (procs->opvpStrokePath != 0);
+ supportFillPath = (procs->opvpFillPath != 0);
+ supportStrokeFillPath = (procs->opvpStrokeFillPath != 0);
+ supportSetClipPath = (procs->opvpSetClipPath != 0);
+ supportSetCurrentPoint = (procs->opvpSetCurrentPoint != 0);
+ supportLinePath = (procs->opvpLinePath != 0);
+ supportPolygonPath = (procs->opvpPolygonPath != 0);
+ supportRectanglePath = (procs->opvpRectanglePath != 0);
+ supportRoundRectanglePath = (procs->opvpRoundRectanglePath != 0);
+ supportBezierPath = (procs->opvpBezierPath != 0);
+ supportArcPath = (procs->opvpArcPath != 0);
+ supportDrawImage = (procs->opvpDrawImage != 0);
+ supportStartDrawImage = (procs->opvpStartDrawImage != 0);
+ supportTransferDrawImage = (procs->opvpTransferDrawImage != 0);
+ supportEndDrawImage = (procs->opvpEndDrawImage != 0);
+ supportStartScanline = (procs->opvpStartScanline != 0);
+ supportScanline = (procs->opvpScanline != 0);
+ supportEndScanline = (procs->opvpEndScanline != 0);
+ supportStartRaster = (procs->opvpStartRaster != 0);
+ supportTransferRasterData = (procs->opvpTransferRasterData != 0);
+ supportSkipRaster = (procs->opvpSkipRaster != 0);
+ supportEndRaster = (procs->opvpEndRaster != 0);
+ supportStartStream = (procs->opvpStartStream != 0);
+ supportTransferStreamData = (procs->opvpTransferStreamData != 0);
+ supportEndStream = (procs->opvpEndStream != 0);
+ supportQueryDeviceCapability = (procs->opvpQueryDeviceCapability != 0);
+ supportQueryDeviceInfo = (procs->opvpQueryDeviceInfo != 0);
+ supportResetClipPath = (procs->opvpResetClipPath != 0);
+}
+
+OPVPWrapper::~OPVPWrapper()
+{
+ unloadDriver(opvpHandle);
+ opvpHandle = 0;
+}
+
+opvp_result_t OPVPWrapper::ClosePrinter()
+{
+ if (!supportClosePrinter) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpClosePrinter(printerContext);
+}
+
+opvp_result_t OPVPWrapper::StartJob(const opvp_char_t *jobInfo)
+{
+ if (!supportStartJob) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpStartJob(printerContext,jobInfo);
+}
+
+opvp_result_t OPVPWrapper::EndJob()
+{
+ if (!supportEndJob) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpEndJob(printerContext);
+}
+
+opvp_result_t OPVPWrapper::AbortJob()
+{
+ if (!supportAbortJob) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpAbortJob(printerContext);
+}
+
+opvp_result_t OPVPWrapper::StartDoc(const opvp_char_t *docInfo)
+{
+ if (!supportStartDoc) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpStartDoc(printerContext,docInfo);
+}
+
+opvp_result_t OPVPWrapper::EndDoc()
+{
+ if (!supportEndDoc) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpEndDoc(printerContext);
+}
+
+opvp_result_t OPVPWrapper::StartPage(const opvp_char_t *pageInfo)
+{
+ if (!supportStartPage) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpStartPage(printerContext,pageInfo);
+}
+
+opvp_result_t OPVPWrapper::EndPage()
+{
+ if (!supportEndPage) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpEndPage(printerContext);
+}
+
+opvp_result_t OPVPWrapper::QueryDeviceCapability(opvp_flag_t queryflag,
+ opvp_int_t *buflen, opvp_byte_t *infoBuf)
+{
+ if (!supportQueryDeviceCapability) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpQueryDeviceCapability(printerContext,queryflag,
+ buflen,infoBuf);
+}
+
+opvp_result_t OPVPWrapper::QueryDeviceInfo(opvp_flag_t queryflag,
+ opvp_int_t *buflen, opvp_byte_t *infoBuf)
+{
+ if (!supportQueryDeviceInfo) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpQueryDeviceInfo(printerContext,queryflag,
+ buflen,infoBuf);
+}
+
+opvp_result_t OPVPWrapper::ResetCTM()
+{
+ if (!supportResetCTM) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpResetCTM(printerContext);
+}
+
+opvp_result_t OPVPWrapper::SetCTM(const opvp_ctm_t *pCTM)
+{
+ if (!supportSetCTM) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpSetCTM(printerContext,pCTM);
+}
+
+opvp_result_t OPVPWrapper::GetCTM(opvp_ctm_t *pCTM)
+{
+ if (!supportGetCTM) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpGetCTM(printerContext,pCTM);
+}
+
+opvp_result_t OPVPWrapper::InitGS()
+{
+ if (!supportInitGS) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpInitGS(printerContext);
+}
+
+opvp_result_t OPVPWrapper::SaveGS()
+{
+ if (!supportSaveGS) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpSaveGS(printerContext);
+}
+
+opvp_result_t OPVPWrapper::RestoreGS()
+{
+ if (!supportRestoreGS) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpRestoreGS(printerContext);
+}
+
+opvp_result_t OPVPWrapper::QueryColorSpace(opvp_int_t *pnum,
+ opvp_cspace_t *pcspace)
+{
+ if (!supportQueryColorSpace) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpQueryColorSpace(printerContext,pnum,pcspace);
+}
+
+opvp_result_t OPVPWrapper::SetColorSpace(opvp_cspace_t cspace)
+{
+ if (!supportSetColorSpace) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpSetColorSpace(printerContext,cspace);
+}
+
+opvp_result_t OPVPWrapper::GetColorSpace(opvp_cspace_t *pcspace)
+{
+ if (!supportGetColorSpace) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpGetColorSpace(printerContext,pcspace);
+}
+
+opvp_result_t OPVPWrapper::SetFillMode(opvp_fillmode_t fillmode)
+{
+ if (!supportSetFillMode) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpSetFillMode(printerContext,fillmode);
+}
+
+opvp_result_t OPVPWrapper::GetFillMode(opvp_fillmode_t *pfillmode)
+{
+ if (!supportGetFillMode) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpGetFillMode(printerContext,pfillmode);
+}
+
+opvp_result_t OPVPWrapper::SetAlphaConstant(opvp_float_t alpha)
+{
+ if (!supportSetAlphaConstant) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpSetAlphaConstant(printerContext,alpha);
+}
+
+opvp_result_t OPVPWrapper::GetAlphaConstant(opvp_float_t *palpha)
+{
+ if (!supportGetAlphaConstant) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpGetAlphaConstant(printerContext,palpha);
+}
+
+opvp_result_t OPVPWrapper::SetLineWidth(opvp_fix_t width)
+{
+ if (!supportSetLineWidth) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpSetLineWidth(printerContext,width);
+}
+
+opvp_result_t OPVPWrapper::GetLineWidth(opvp_fix_t *pwidth)
+{
+ if (!supportGetLineWidth) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpGetLineWidth(printerContext,pwidth);
+}
+
+opvp_result_t OPVPWrapper::SetLineDash(opvp_int_t num,
+ const opvp_fix_t *pdash)
+{
+ if (!supportSetLineDash) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpSetLineDash(printerContext,num,pdash);
+}
+
+opvp_result_t OPVPWrapper::GetLineDash(opvp_int_t *pnum, opvp_fix_t *pdash)
+{
+ if (!supportGetLineDash) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpGetLineDash(printerContext,pnum,pdash);
+}
+
+opvp_result_t OPVPWrapper::SetLineDashOffset(opvp_fix_t offset)
+{
+ if (!supportSetLineDashOffset) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpSetLineDashOffset(printerContext,offset);
+}
+
+opvp_result_t OPVPWrapper::GetLineDashOffset(opvp_fix_t *poffset)
+{
+ if (!supportGetLineDashOffset) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpGetLineDashOffset(printerContext,poffset);
+}
+
+opvp_result_t OPVPWrapper::SetLineStyle(opvp_linestyle_t linestyle)
+{
+ if (!supportSetLineStyle) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpSetLineStyle(printerContext,linestyle);
+}
+
+opvp_result_t OPVPWrapper::GetLineStyle(opvp_linestyle_t *plinestyle)
+{
+ if (!supportGetLineStyle) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpGetLineStyle(printerContext,plinestyle);
+}
+
+opvp_result_t OPVPWrapper::SetLineCap(opvp_linecap_t linecap)
+{
+ if (!supportSetLineCap) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpSetLineCap(printerContext,linecap);
+}
+
+opvp_result_t OPVPWrapper::GetLineCap(opvp_linecap_t *plinecap)
+{
+ if (!supportGetLineCap) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpGetLineCap(printerContext,plinecap);
+}
+
+opvp_result_t OPVPWrapper::SetLineJoin(opvp_linejoin_t linejoin)
+{
+ if (!supportSetLineJoin) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpSetLineJoin(printerContext,linejoin);
+}
+
+opvp_result_t OPVPWrapper::GetLineJoin(opvp_linejoin_t *plinejoin)
+{
+ if (!supportGetLineJoin) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpGetLineJoin(printerContext,plinejoin);
+}
+
+opvp_result_t OPVPWrapper::SetMiterLimit(opvp_fix_t miterlimit)
+{
+ if (!supportSetMiterLimit) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpSetMiterLimit(printerContext,miterlimit);
+}
+
+opvp_result_t OPVPWrapper::GetMiterLimit(opvp_fix_t *pmiterlimit)
+{
+ if (!supportGetMiterLimit) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpGetMiterLimit(printerContext,pmiterlimit);
+}
+
+opvp_result_t OPVPWrapper::SetPaintMode(opvp_paintmode_t paintmode)
+{
+ if (!supportSetPaintMode) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpSetPaintMode(printerContext,paintmode);
+}
+
+opvp_result_t OPVPWrapper::GetPaintMode(opvp_paintmode_t *ppaintmode)
+{
+ if (!supportGetPaintMode) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpGetPaintMode(printerContext,ppaintmode);
+}
+
+opvp_result_t OPVPWrapper::SetStrokeColor(const opvp_brush_t *brush)
+{
+ if (!supportSetStrokeColor) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpSetStrokeColor(printerContext,brush);
+}
+
+opvp_result_t OPVPWrapper::SetFillColor(const opvp_brush_t *brush)
+{
+ if (!supportSetFillColor) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpSetFillColor(printerContext,brush);
+}
+
+opvp_result_t OPVPWrapper::SetBgColor(const opvp_brush_t *brush)
+{
+ if (!supportSetBgColor) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpSetBgColor(printerContext,brush);
+}
+
+opvp_result_t OPVPWrapper::NewPath()
+{
+ if (!supportNewPath) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpNewPath(printerContext);
+}
+
+opvp_result_t OPVPWrapper::EndPath()
+{
+ if (!supportEndPath) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpEndPath(printerContext);
+}
+
+opvp_result_t OPVPWrapper::StrokePath()
+{
+ if (!supportStrokePath) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpStrokePath(printerContext);
+}
+
+opvp_result_t OPVPWrapper::FillPath()
+{
+ if (!supportFillPath) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpFillPath(printerContext);
+}
+
+opvp_result_t OPVPWrapper::StrokeFillPath()
+{
+ if (!supportStrokeFillPath) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpStrokeFillPath(printerContext);
+}
+
+opvp_result_t OPVPWrapper::SetClipPath(opvp_cliprule_t clipRule)
+{
+ if (!supportSetClipPath) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpSetClipPath(printerContext,clipRule);
+}
+
+opvp_result_t OPVPWrapper::SetCurrentPoint(opvp_fix_t x, opvp_fix_t y)
+{
+ if (!supportSetCurrentPoint) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpSetCurrentPoint(printerContext,x,y);
+}
+
+opvp_result_t OPVPWrapper::LinePath(opvp_pathmode_t flag,
+ opvp_int_t npoints, const opvp_point_t *points)
+{
+ if (!supportLinePath) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpLinePath(printerContext,flag,npoints,points);
+}
+
+opvp_result_t OPVPWrapper::PolygonPath(opvp_int_t npolygons,
+ const opvp_int_t *nvertexes, const opvp_point_t *points)
+{
+ if (!supportPolygonPath) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpPolygonPath(printerContext,npolygons,nvertexes,points);
+}
+
+opvp_result_t OPVPWrapper::RectanglePath(opvp_int_t nrectangles,
+ const opvp_rectangle_t *rectangles)
+{
+ if (!supportRectanglePath) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpRectanglePath(printerContext,nrectangles,rectangles);
+}
+
+opvp_result_t OPVPWrapper::RoundRectanglePath(opvp_int_t nrectangles,
+ const opvp_roundrectangle_t *rectangles)
+{
+ if (!supportRoundRectanglePath) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpRoundRectanglePath(printerContext,nrectangles,rectangles);
+}
+
+opvp_result_t OPVPWrapper::BezierPath(opvp_int_t npoints,
+ const opvp_point_t *points)
+{
+ if (!supportBezierPath) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpBezierPath(printerContext,npoints,points);
+}
+
+opvp_result_t OPVPWrapper::ArcPath(opvp_arcmode_t kind,
+ opvp_arcdir_t dir, opvp_fix_t bbx0,
+ opvp_fix_t bby0, opvp_fix_t bbx1, opvp_fix_t bby1, opvp_fix_t x0,
+ opvp_fix_t y0, opvp_fix_t x1, opvp_fix_t y1)
+{
+ if (!supportArcPath) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpArcPath(printerContext,kind,dir,bbx0,bby0,
+ bbx1,bby1,x0,y0,x1,y1);
+}
+
+opvp_result_t OPVPWrapper::DrawImage(
+ opvp_int_t sourceWidth, opvp_int_t sourceHeight, opvp_int_t sourcePitch,
+ opvp_imageformat_t imageFormat, opvp_int_t destinationWidth,
+ opvp_int_t destinationHeight, const void *imagedata)
+{
+ if (!supportDrawImage) {
+ int result;
+
+ if ((result = StartDrawImage(sourceWidth,sourceHeight,sourcePitch,
+ imageFormat,destinationWidth,destinationHeight)) < 0) {
+ return result;
+ }
+ if ((result = TransferDrawImage(sourcePitch*sourceHeight,
+ imagedata)) < 0) {
+ return result;
+ }
+ return EndDrawImage();
+ }
+ return procs->opvpDrawImage(printerContext,sourceWidth, sourceHeight,
+ sourcePitch, imageFormat, destinationWidth, destinationHeight,
+ imagedata);
+}
+
+opvp_result_t OPVPWrapper::StartDrawImage(
+ opvp_int_t sourceWidth, opvp_int_t sourceHeight, opvp_int_t sourcePitch,
+ opvp_imageformat_t imageFormat, opvp_int_t destinationWidth,
+ opvp_int_t destinationHeight)
+{
+ if (!supportStartDrawImage) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpStartDrawImage(printerContext,sourceWidth,
+ sourceHeight,sourcePitch,imageFormat,
+ destinationWidth,destinationHeight);
+}
+
+opvp_result_t OPVPWrapper::TransferDrawImage(opvp_int_t count,
+ const void *imagedata)
+{
+ if (!supportTransferDrawImage) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpTransferDrawImage(printerContext,count,imagedata);
+}
+
+opvp_result_t OPVPWrapper::EndDrawImage()
+{
+ if (!supportEndDrawImage) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpEndDrawImage(printerContext);
+}
+
+opvp_result_t OPVPWrapper::StartScanline(opvp_int_t yposition)
+{
+ if (!supportStartScanline) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpStartScanline(printerContext,yposition);
+}
+
+opvp_result_t OPVPWrapper::Scanline(opvp_int_t nscanpairs,
+ const opvp_int_t *scanpairs)
+{
+ if (!supportScanline) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpScanline(printerContext,nscanpairs,scanpairs);
+}
+
+opvp_result_t OPVPWrapper::EndScanline()
+{
+ if (!supportEndScanline) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpEndScanline(printerContext);
+}
+
+opvp_result_t OPVPWrapper::StartRaster(
+ opvp_int_t rasterWidth)
+{
+ if (!supportStartRaster) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpStartRaster(printerContext,rasterWidth);
+}
+
+opvp_result_t OPVPWrapper::TransferRasterData(opvp_int_t count,
+ const opvp_byte_t *data)
+{
+ if (!supportTransferRasterData) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpTransferRasterData(printerContext,count,
+ data);
+}
+
+opvp_result_t OPVPWrapper::SkipRaster(opvp_int_t count)
+{
+ if (!supportSkipRaster) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpSkipRaster(printerContext,count);
+}
+
+opvp_result_t OPVPWrapper::EndRaster()
+{
+ if (!supportEndRaster) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpEndRaster(printerContext);
+}
+
+opvp_result_t OPVPWrapper::StartStream()
+{
+ if (!supportStartStream) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpStartStream(printerContext);
+}
+
+opvp_result_t OPVPWrapper::TransferStreamData(opvp_int_t count,
+ const void *data)
+{
+ if (!supportTransferStreamData) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpTransferStreamData(printerContext,count,data);
+}
+
+opvp_result_t OPVPWrapper::EndStream()
+{
+ if (!supportEndStream) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpEndStream(printerContext);
+}
+
+opvp_result_t OPVPWrapper::ResetClipPath()
+{
+ if (!supportResetClipPath) {
+ *opvpErrorNo = OPVP_NOTSUPPORTED;
+ return -1;
+ }
+ return procs->opvpResetClipPath(printerContext);
+}
+
+char *OPVPWrapper::allocString(char **destin, unsigned int size)
+{
+ if (!destin) return 0;
+
+ if (*destin != 0) delete[] *destin;
+ if (size > 0) {
+ *destin = new char[size];
+ }
+
+ return *destin;
+}
+
+char **OPVPWrapper::genDynamicLibName(const char *name)
+{
+ static char *buff[5] = {0,0,0,0,0};
+
+ allocString(&(buff[0]), strlen(name)+1);
+ strcpy(buff[0], name);
+ allocString(&(buff[1]), strlen(name)+3+1);
+ strcpy(buff[1], name);
+ strcat(buff[1], ".so");
+ allocString(&(buff[2]), strlen(name)+4+1);
+ strcpy(buff[2], name);
+ strcat(buff[2], ".dll");
+ allocString(&(buff[3]), strlen(name)+6+1);
+ strcpy(buff[3], "lib");
+ strcat(buff[3], name);
+ strcat(buff[3], ".so");
+ buff[4] = 0;
+
+ return buff;
+}
+
+OPVPWrapper *OPVPWrapper::loadDriver(const char *driverName,
+ int outputFD, const char *printerModel)
+{
+ char **list = 0;
+ int i;
+ void *h;
+ int nApiEntry;
+ int (*opvpOpenPrinter)(opvp_int_t outputFD,
+ const opvp_char_t * printerModel, const opvp_int_t version[2],
+ opvp_api_procs_t **apiEntry) = 0;
+ int (*opvpOpenPrinter_0_2)(int outputFD, char* printerModel,
+ int *nApiEntry, OPVP_api_procs **apiEntry) = 0;
+ opvp_api_procs_t *opvpProcs;
+ OPVP_api_procs *opvpProcs_0_2;
+ opvp_dc_t opvpContext;
+ int opvpContext_0_2 = 0;
+ opvp_int_t *opvpErrorNo = 0;
+ int *opvpErrorNo_0_2 = 0;
+ void *handle = 0;
+ OPVPWrapper *opvp = 0;
+
+ // remove directory part
+ const char *s = strrchr(driverName,'/');
+ if (s != NULL) {
+ driverName = s+1;
+ }
+
+ list = genDynamicLibName(driverName);
+
+ if (list) {
+ i = 0;
+ while (list[i]) {
+ if ((h = dlopen(list[i],RTLD_NOW))) {
+ opvpOpenPrinter = (int (*)(opvp_int_t,
+ const opvp_char_t *, const opvp_int_t[2],
+ opvp_api_procs_t **))dlsym(h,"opvpOpenPrinter");
+ opvpErrorNo = (opvp_int_t *)dlsym(h,"opvpErrorNo");
+ if (opvpOpenPrinter && opvpErrorNo) {
+ handle = h;
+ break;
+ }
+ opvpOpenPrinter = 0;
+ opvpErrorNo = 0;
+ /* try version 0.2 driver */
+ opvpOpenPrinter_0_2 = (int (*)(int, char*, int *,
+ OPVP_api_procs **))dlsym(h,"OpenPrinter");
+ opvpErrorNo_0_2 = (int *)dlsym(h,"errorno");
+ if (opvpOpenPrinter_0_2 && opvpErrorNo_0_2) {
+ handle = h;
+ break;
+ }
+ opvpOpenPrinter_0_2 = 0;
+ opvpErrorNo_0_2 = 0;
+ }
+ i++;
+ }
+ for (i = 0;list[i] != 0;i++) {
+ delete[] (list[i]);
+ list[i] = 0;
+ }
+ }
+ if (handle == 0) {
+ OPRS::error("Loading vector printer driver (%s) fail\n",driverName);
+ return 0;
+ }
+ if (opvpOpenPrinter != 0) {
+ opvp_int_t apiVersion[2];
+
+ /* require version 1.0 */
+ apiVersion[0] = 1;
+ apiVersion[1] = 0;
+ if ((opvpContext = (*opvpOpenPrinter)(outputFD,
+ (const opvp_char_t *)printerModel,apiVersion,&opvpProcs)) < 0) {
+ OPRS::error("OpenPrinter fail\n",driverName);
+ unloadDriver(handle);
+ return 0;
+ }
+ opvp = new OPVPWrapper(handle, opvpErrorNo, opvpProcs, opvpContext);
+ } else if (opvpOpenPrinter_0_2) {
+ if ((opvpContext_0_2 = (*opvpOpenPrinter_0_2)(outputFD,
+ (char *)printerModel,&nApiEntry,&opvpProcs_0_2)) < 0) {
+ OPRS::error("OpenPrinter fail\n",driverName);
+ unloadDriver(handle);
+ return 0;
+ }
+ opvp = (OPVPWrapper *)new OPVPWrapper_0_2(handle, opvpErrorNo_0_2,
+ opvpProcs_0_2, opvpContext_0_2);
+ }
+ return opvp;
+}
+
+/*
+ * unload vector-driver
+ */
+int OPVPWrapper::unloadDriver(void *opvpHandleA)
+{
+ if (opvpHandleA != 0) {
+ dlclose(opvpHandleA);
+ }
+ return 0;
+}
+
+opvp_int_t OPVPWrapper::getErrorNo()
+{
+ return *opvpErrorNo;
+}
+
diff --git a/filter/pdftoopvp/oprs/OPVPWrapper.h b/filter/pdftoopvp/oprs/OPVPWrapper.h
new file mode 100644
index 000000000..1dfcba3c2
--- /dev/null
+++ b/filter/pdftoopvp/oprs/OPVPWrapper.h
@@ -0,0 +1,205 @@
+/*
+ OPVPWrapper.h
+*/
+
+#ifndef OPVPWRAPPER_H
+#define OPVPWRAPPER_H
+
+#include "opvp_common.h"
+
+class OPVPWrapper {
+public:
+ static OPVPWrapper *loadDriver(const char *driverName, int outputFD,
+ const char *printerModel);
+ static int unloadDriver(void *opvpHandleA);
+private:
+ static char *allocString(char **destin, unsigned int size);
+ static char **genDynamicLibName(const char *name);
+public:
+ OPVPWrapper() {};
+ OPVPWrapper(void *opvpHandleA, opvp_int_t *opvpErrorNoA,
+ opvp_api_procs_t *procsA, opvp_dc_t printerContextA);
+ virtual ~OPVPWrapper();
+
+ virtual opvp_int_t getErrorNo();
+
+ void getVersion(opvp_int_t versionA[2])
+ {
+ versionA[0] = version[0];
+ versionA[1] = version[1];
+ }
+
+ virtual opvp_result_t ClosePrinter();
+ virtual opvp_result_t StartJob(const opvp_char_t *jobInfo);
+ virtual opvp_result_t EndJob();
+ virtual opvp_result_t AbortJob();
+ virtual opvp_result_t StartDoc(const opvp_char_t *docInfo);
+ virtual opvp_result_t EndDoc();
+ virtual opvp_result_t StartPage(const opvp_char_t *pageInfo);
+ virtual opvp_result_t EndPage();
+ virtual opvp_result_t QueryDeviceCapability(opvp_flag_t queryflag,
+ opvp_int_t *buflen, opvp_byte_t *infoBuf);
+ virtual opvp_result_t QueryDeviceInfo(opvp_flag_t queryflag,
+ opvp_int_t *buflen, opvp_byte_t *infoBuf);
+ virtual opvp_result_t ResetCTM();
+ virtual opvp_result_t SetCTM(const opvp_ctm_t *pCTM);
+ virtual opvp_result_t GetCTM(opvp_ctm_t *pCTM);
+ virtual opvp_result_t InitGS();
+ virtual opvp_result_t SaveGS();
+ virtual opvp_result_t RestoreGS();
+ virtual opvp_result_t QueryColorSpace(opvp_int_t *pnum,
+ opvp_cspace_t *pcspace);
+ virtual opvp_result_t SetColorSpace(opvp_cspace_t cspace);
+ virtual opvp_result_t GetColorSpace(opvp_cspace_t *pcspace);
+ virtual opvp_result_t SetFillMode(opvp_fillmode_t fillmode);
+ virtual opvp_result_t GetFillMode(opvp_fillmode_t *pfillmode);
+ virtual opvp_result_t SetAlphaConstant(opvp_float_t alpha);
+ virtual opvp_result_t GetAlphaConstant(opvp_float_t *palpha);
+ virtual opvp_result_t SetLineWidth(opvp_fix_t width);
+ virtual opvp_result_t GetLineWidth(opvp_fix_t *pwidth);
+ virtual opvp_result_t SetLineDash(opvp_int_t num, const opvp_fix_t *pdash);
+ virtual opvp_result_t GetLineDash(opvp_int_t *pnum, opvp_fix_t *pdash);
+ virtual opvp_result_t SetLineDashOffset(opvp_fix_t offset);
+ virtual opvp_result_t GetLineDashOffset(opvp_fix_t *poffset);
+ virtual opvp_result_t SetLineStyle(opvp_linestyle_t linestyle);
+ virtual opvp_result_t GetLineStyle(opvp_linestyle_t *plinestyle);
+ virtual opvp_result_t SetLineCap(opvp_linecap_t linecap);
+ virtual opvp_result_t GetLineCap(opvp_linecap_t *plinecap);
+ virtual opvp_result_t SetLineJoin(opvp_linejoin_t linejoin);
+ virtual opvp_result_t GetLineJoin(opvp_linejoin_t *plinejoin);
+ virtual opvp_result_t SetMiterLimit(opvp_fix_t miterlimit);
+ virtual opvp_result_t GetMiterLimit(opvp_fix_t *pmiterlimit);
+ virtual opvp_result_t SetPaintMode(opvp_paintmode_t paintmode);
+ virtual opvp_result_t GetPaintMode(opvp_paintmode_t *ppaintmode);
+ virtual opvp_result_t SetStrokeColor(const opvp_brush_t *brush);
+ virtual opvp_result_t SetFillColor(const opvp_brush_t *brush);
+ virtual opvp_result_t SetBgColor(const opvp_brush_t *brush);
+ virtual opvp_result_t NewPath();
+ virtual opvp_result_t EndPath();
+ virtual opvp_result_t StrokePath();
+ virtual opvp_result_t FillPath();
+ virtual opvp_result_t StrokeFillPath();
+ virtual opvp_result_t SetClipPath(opvp_cliprule_t clipRule);
+ virtual opvp_result_t SetCurrentPoint(opvp_fix_t x, opvp_fix_t y);
+ virtual opvp_result_t LinePath(opvp_pathmode_t flag,
+ opvp_int_t npoints, const opvp_point_t *points);
+ virtual opvp_result_t PolygonPath(opvp_int_t npolygons,
+ const opvp_int_t *nvertexes, const opvp_point_t *points);
+ virtual opvp_result_t RectanglePath(opvp_int_t nrectangles,
+ const opvp_rectangle_t *reclangles);
+ virtual opvp_result_t RoundRectanglePath(opvp_int_t nrectangles,
+ const opvp_roundrectangle_t *reclangles);
+ virtual opvp_result_t BezierPath(opvp_int_t npoints,
+ const opvp_point_t *points);
+ virtual opvp_result_t ArcPath(opvp_arcmode_t kind,
+ opvp_arcdir_t dir, opvp_fix_t bbx0, opvp_fix_t bby0,
+ opvp_fix_t bbx1, opvp_fix_t bby1, opvp_fix_t x0,
+ opvp_fix_t y0, opvp_fix_t x1, opvp_fix_t y1);
+ virtual opvp_result_t DrawImage(opvp_int_t sourceWidth,
+ opvp_int_t sourceHeight, opvp_int_t sourcePitch,
+ opvp_imageformat_t imageFormat,
+ opvp_int_t destinationWidth, opvp_int_t destinationHeight,
+ const void *imageData);
+ virtual opvp_result_t StartDrawImage(opvp_int_t sourceWidth,
+ opvp_int_t sourceHeight, opvp_int_t sourcePitch,
+ opvp_imageformat_t imageFormat,
+ opvp_int_t destinationWidth, opvp_int_t destinationHeight);
+ virtual opvp_result_t TransferDrawImage(opvp_int_t count,
+ const void *imageData);
+ virtual opvp_result_t EndDrawImage();
+ virtual opvp_result_t StartScanline(opvp_int_t yposition);
+ virtual opvp_result_t Scanline(opvp_int_t nscanpairs,
+ const opvp_int_t *scanpairs);
+ virtual opvp_result_t EndScanline();
+ virtual opvp_result_t StartRaster(opvp_int_t rasterWidth);
+ virtual opvp_result_t TransferRasterData(opvp_int_t count,
+ const opvp_byte_t *data);
+ virtual opvp_result_t SkipRaster(opvp_int_t count);
+ virtual opvp_result_t EndRaster();
+ virtual opvp_result_t StartStream();
+ virtual opvp_result_t TransferStreamData(opvp_int_t count,
+ const void *data);
+ virtual opvp_result_t EndStream();
+ virtual opvp_result_t ResetClipPath();
+
+ bool supportClosePrinter;
+ bool supportStartJob;
+ bool supportEndJob;
+ bool supportAbortJob;
+ bool supportStartDoc;
+ bool supportEndDoc;
+ bool supportStartPage;
+ bool supportEndPage;
+ bool supportResetCTM;
+ bool supportSetCTM;
+ bool supportGetCTM;
+ bool supportInitGS;
+ bool supportSaveGS;
+ bool supportRestoreGS;
+ bool supportQueryColorSpace;
+ bool supportSetColorSpace;
+ bool supportGetColorSpace;
+ bool supportSetFillMode;
+ bool supportGetFillMode;
+ bool supportSetAlphaConstant;
+ bool supportGetAlphaConstant;
+ bool supportSetLineWidth;
+ bool supportGetLineWidth;
+ bool supportSetLineDash;
+ bool supportGetLineDash;
+ bool supportSetLineDashOffset;
+ bool supportGetLineDashOffset;
+ bool supportSetLineStyle;
+ bool supportGetLineStyle;
+ bool supportSetLineCap;
+ bool supportGetLineCap;
+ bool supportSetLineJoin;
+ bool supportGetLineJoin;
+ bool supportSetMiterLimit;
+ bool supportGetMiterLimit;
+ bool supportSetPaintMode;
+ bool supportGetPaintMode;
+ bool supportSetStrokeColor;
+ bool supportSetFillColor;
+ bool supportSetBgColor;
+ bool supportNewPath;
+ bool supportEndPath;
+ bool supportStrokePath;
+ bool supportFillPath;
+ bool supportStrokeFillPath;
+ bool supportSetClipPath;
+ bool supportSetCurrentPoint;
+ bool supportLinePath;
+ bool supportPolygonPath;
+ bool supportRectanglePath;
+ bool supportRoundRectanglePath;
+ bool supportBezierPath;
+ bool supportArcPath;
+ bool supportDrawImage;
+ bool supportStartDrawImage;
+ bool supportTransferDrawImage;
+ bool supportEndDrawImage;
+ bool supportStartScanline;
+ bool supportScanline;
+ bool supportEndScanline;
+ bool supportStartRaster;
+ bool supportTransferRasterData;
+ bool supportSkipRaster;
+ bool supportEndRaster;
+ bool supportStartStream;
+ bool supportTransferStreamData;
+ bool supportEndStream;
+ bool supportQueryDeviceCapability;
+ bool supportQueryDeviceInfo;
+ bool supportResetClipPath;
+
+protected:
+ void *opvpHandle;
+ opvp_int_t version[2];
+private:
+ opvp_api_procs_t *procs;
+ opvp_int_t *opvpErrorNo;
+ opvp_dc_t printerContext;
+};
+
+#endif
diff --git a/filter/pdftoopvp/oprs/OPVPWrapper_0_2.cxx b/filter/pdftoopvp/oprs/OPVPWrapper_0_2.cxx
new file mode 100644
index 000000000..112580e84
--- /dev/null
+++ b/filter/pdftoopvp/oprs/OPVPWrapper_0_2.cxx
@@ -0,0 +1,1172 @@
+/*
+ OPVPWrapper_0_2.cc
+*/
+
+
+#include <config.h>
+#include "OPVPWrapper_0_2.h"
+#include <string.h>
+
+/* color space mapping 0.2 to 1.0 */
+opvp_cspace_t OPVPWrapper_0_2::cspace_0_2_to_1_0[] = {
+ OPVP_CSPACE_BW,
+ OPVP_CSPACE_DEVICEGRAY,
+ OPVP_CSPACE_DEVICECMY,
+ OPVP_CSPACE_DEVICECMYK,
+ OPVP_CSPACE_DEVICERGB,
+ OPVP_CSPACE_STANDARDRGB,
+ OPVP_CSPACE_STANDARDRGB64
+};
+
+/* color space mapping 1.0 to 0.2 */
+OPVP_ColorSpace OPVPWrapper_0_2::cspace_1_0_to_0_2[] = {
+ OPVP_cspaceBW,
+ OPVP_cspaceDeviceGray,
+ OPVP_cspaceDeviceCMY,
+ OPVP_cspaceDeviceCMYK,
+ OPVP_cspaceDeviceRGB,
+ (OPVP_ColorSpace)0, /* 0.2 doesn't have OPVP_CSPACE_DEVICEKRGB */
+ OPVP_cspaceStandardRGB,
+ OPVP_cspaceStandardRGB64,
+};
+
+/* image format mapping 1.0 to 0.2 */
+OPVP_ImageFormat OPVPWrapper_0_2::iformat_1_0_to_0_2[] = {
+ OPVP_iformatRaw,
+ /* OPVP_IFORMAT_MASK use iformat raw in 0.2 */
+ OPVP_iformatRaw,
+ OPVP_iformatRLE,
+ OPVP_iformatJPEG,
+ OPVP_iformatPNG,
+};
+
+/* image colorDepth needed in 0.2 */
+int OPVPWrapper_0_2::colorDepth_0_2[] = {
+ 1, /* OPVP_CSPACE_BW */
+ 8, /* OPVP_CSPACE_DEVICEGRAY */
+ 24, /* OPVP_CSPACE_DEVICECMY */
+ 32, /* OPVP_CSPACE_DEVICECMYK */
+ 24, /* OPVP_CSPACE_DEVICERGB */
+ 32, /* OPVP_CSPACE_DEVICEKRGB */
+ 24, /* OPVP_CSPACE_STANDARDRGB */
+ 64, /* OPVP_CSPACE_STANDARDRGB64 */
+};
+
+OPVPWrapper_0_2::OPVPWrapper_0_2(void *opvpHandleA, int *opvpErrorNoA,
+ OPVP_api_procs *procsA, int printerContextA)
+{
+ procs_0_2 = procsA;
+ opvpHandle = opvpHandleA;
+ opvpErrorNo_0_2 = opvpErrorNoA;
+ printerContext_0_2 = printerContextA;
+ version[0] = 0;
+ version[1] = 2;
+ supportClosePrinter = (procs_0_2->ClosePrinter != 0);
+ supportStartJob = (procs_0_2->StartJob != 0);
+ supportEndJob = (procs_0_2->EndJob != 0);
+ supportAbortJob = false;
+ supportStartDoc = (procs_0_2->StartDoc != 0);
+ supportEndDoc = (procs_0_2->EndDoc != 0);
+ supportStartPage = (procs_0_2->StartPage != 0);
+ supportEndPage = (procs_0_2->EndPage != 0);
+ supportResetCTM = (procs_0_2->ResetCTM != 0);
+ supportSetCTM = (procs_0_2->SetCTM != 0);
+ supportGetCTM = (procs_0_2->GetCTM != 0);
+ supportInitGS = (procs_0_2->InitGS != 0);
+ supportSaveGS = (procs_0_2->SaveGS != 0);
+ supportRestoreGS = (procs_0_2->RestoreGS != 0);
+ supportQueryColorSpace = (procs_0_2->QueryColorSpace != 0);
+ supportSetColorSpace = (procs_0_2->SetColorSpace != 0);
+ supportGetColorSpace = (procs_0_2->GetColorSpace != 0);
+ supportSetFillMode = (procs_0_2->SetFillMode != 0);
+ supportGetFillMode = (procs_0_2->GetFillMode != 0);
+ supportSetAlphaConstant = (procs_0_2->SetAlphaConstant != 0);
+ supportGetAlphaConstant = (procs_0_2->GetAlphaConstant != 0);
+ supportSetLineWidth = (procs_0_2->SetLineWidth != 0);
+ supportGetLineWidth = (procs_0_2->GetLineWidth != 0);
+ supportSetLineDash = (procs_0_2->SetLineDash != 0);
+ supportGetLineDash = (procs_0_2->GetLineDash != 0);
+ supportSetLineDashOffset = (procs_0_2->SetLineDashOffset != 0);
+ supportGetLineDashOffset = (procs_0_2->GetLineDashOffset != 0);
+ supportSetLineStyle = (procs_0_2->SetLineStyle != 0);
+ supportGetLineStyle = (procs_0_2->GetLineStyle != 0);
+ supportSetLineCap = (procs_0_2->SetLineCap != 0);
+ supportGetLineCap = (procs_0_2->GetLineCap != 0);
+ supportSetLineJoin = (procs_0_2->SetLineJoin != 0);
+ supportGetLineJoin = (procs_0_2->GetLineJoin != 0);
+ supportSetMiterLimit = (procs_0_2->SetMiterLimit != 0);
+ supportGetMiterLimit = (procs_0_2->GetMiterLimit != 0);
+ supportSetPaintMode = (procs_0_2->SetPaintMode != 0);
+ supportGetPaintMode = (procs_0_2->GetPaintMode != 0);
+ supportSetStrokeColor = (procs_0_2->SetStrokeColor != 0);
+ supportSetFillColor = (procs_0_2->SetFillColor != 0);
+ supportSetBgColor = (procs_0_2->SetBgColor != 0);
+ supportNewPath = (procs_0_2->NewPath != 0);
+ supportEndPath = (procs_0_2->EndPath != 0);
+ supportStrokePath = (procs_0_2->StrokePath != 0);
+ supportFillPath = (procs_0_2->FillPath != 0);
+ supportStrokeFillPath = (procs_0_2->StrokeFillPath != 0);
+ supportSetClipPath = (procs_0_2->SetClipPath != 0);
+ supportSetCurrentPoint = (procs_0_2->SetCurrentPoint != 0);
+ supportLinePath = (procs_0_2->LinePath != 0);
+ supportPolygonPath = (procs_0_2->PolygonPath != 0);
+ supportRectanglePath = (procs_0_2->RectanglePath != 0);
+ supportRoundRectanglePath = (procs_0_2->RoundRectanglePath != 0);
+ supportBezierPath = (procs_0_2->BezierPath != 0);
+ supportArcPath = (procs_0_2->ArcPath != 0);
+ supportDrawImage = (procs_0_2->DrawImage != 0);
+ supportStartDrawImage = (procs_0_2->StartDrawImage != 0);
+ supportTransferDrawImage = (procs_0_2->TransferDrawImage != 0);
+ supportEndDrawImage = (procs_0_2->EndDrawImage != 0);
+ supportStartScanline = (procs_0_2->StartScanline != 0);
+ supportScanline = (procs_0_2->Scanline != 0);
+ supportEndScanline = (procs_0_2->EndScanline != 0);
+ supportStartRaster = (procs_0_2->StartRaster != 0);
+ supportTransferRasterData = (procs_0_2->TransferRasterData != 0);
+ supportSkipRaster = (procs_0_2->SkipRaster != 0);
+ supportEndRaster = (procs_0_2->EndRaster != 0);
+ supportStartStream = (procs_0_2->StartStream != 0);
+ supportTransferStreamData = (procs_0_2->TransferStreamData != 0);
+ supportEndStream = (procs_0_2->EndStream != 0);
+ supportQueryDeviceCapability = (procs_0_2->QueryDeviceCapability != 0);
+ supportQueryDeviceInfo = (procs_0_2->QueryDeviceInfo != 0);
+ supportResetClipPath = (procs_0_2->ResetClipPath != 0);
+ colorSpace = OPVP_CSPACE_STANDARDRGB;
+ if (supportGetColorSpace) {
+ if (GetColorSpace(&colorSpace) != OPVP_OK) {
+ colorSpace = OPVP_CSPACE_STANDARDRGB;
+ }
+ }
+}
+
+OPVPWrapper_0_2::~OPVPWrapper_0_2()
+{
+}
+
+opvp_result_t OPVPWrapper_0_2::ClosePrinter()
+{
+ if (!supportClosePrinter) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->ClosePrinter(printerContext_0_2);
+}
+
+opvp_result_t OPVPWrapper_0_2::StartJob(
+ const opvp_char_t *jobInfo)
+{
+ if (!supportStartJob) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->StartJob(printerContext_0_2,
+ (char *)jobInfo);
+}
+
+opvp_result_t OPVPWrapper_0_2::EndJob()
+{
+ if (!supportEndJob) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->EndJob(printerContext_0_2);
+}
+
+opvp_result_t OPVPWrapper_0_2::AbortJob()
+{
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+}
+
+opvp_result_t OPVPWrapper_0_2::StartDoc(
+ const opvp_char_t *docInfo)
+{
+ if (!supportStartDoc) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->StartDoc(printerContext_0_2,
+ (char *)docInfo);
+}
+
+opvp_result_t OPVPWrapper_0_2::EndDoc()
+{
+ if (!supportEndDoc) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->EndDoc(printerContext_0_2);
+}
+
+opvp_result_t OPVPWrapper_0_2::StartPage(
+ const opvp_char_t *pageInfo)
+{
+ int r;
+
+ if (!supportStartPage) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ if ((r = procs_0_2->StartPage(printerContext_0_2,
+ /* discard const */(char *)pageInfo)) != OPVP_OK) {
+ /* error */
+ return (opvp_result_t)r;
+ }
+ /* initialize ROP */
+ if (procs_0_2->SetROP != 0) {
+ procs_0_2->SetROP(printerContext_0_2,
+ OPVP_0_2_ROP_P);
+ }
+ return OPVP_OK;
+}
+
+opvp_result_t OPVPWrapper_0_2::EndPage()
+{
+ if (!supportEndPage) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->EndPage(printerContext_0_2);
+}
+
+opvp_result_t OPVPWrapper_0_2::QueryDeviceCapability(
+ opvp_flag_t queryflag, opvp_int_t *buflen, opvp_byte_t *infoBuf)
+{
+ if (!supportQueryDeviceCapability) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->
+ QueryDeviceCapability(printerContext_0_2,queryflag,*buflen,
+ (char *)infoBuf);
+}
+
+opvp_result_t OPVPWrapper_0_2::QueryDeviceInfo(
+ opvp_flag_t queryflag, opvp_int_t *buflen, opvp_byte_t *infoBuf)
+{
+ if (!supportQueryDeviceInfo) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ if (queryflag & OPVP_QF_MEDIACOPY) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ if (queryflag & OPVP_QF_PRINTREGION) {
+ queryflag &= ~OPVP_QF_PRINTREGION;
+ queryflag |= 0x0020000;
+ }
+ return (opvp_result_t)procs_0_2->QueryDeviceInfo(printerContext_0_2,
+ queryflag,*buflen,(char *)infoBuf);
+}
+
+opvp_result_t OPVPWrapper_0_2::ResetCTM()
+{
+ if (!supportResetCTM) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->ResetCTM(printerContext_0_2);
+}
+
+opvp_result_t OPVPWrapper_0_2::SetCTM(const opvp_ctm_t *pCTM)
+{
+ if (!supportSetCTM) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->SetCTM(printerContext_0_2,
+ (OPVP_CTM *)pCTM);
+}
+
+opvp_result_t OPVPWrapper_0_2::GetCTM(opvp_ctm_t *pCTM)
+{
+ if (!supportGetCTM) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->GetCTM(printerContext_0_2,
+ (OPVP_CTM *)pCTM);
+}
+
+opvp_result_t OPVPWrapper_0_2::InitGS()
+{
+ int r;
+
+ if (!supportInitGS) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ if ((r = procs_0_2->InitGS(printerContext_0_2)) != OPVP_OK) {
+ /* error */
+ return (opvp_result_t)r;
+ }
+ /* initialize ROP */
+ if (procs_0_2->SetROP != 0) {
+ procs_0_2->SetROP(printerContext_0_2,
+ OPVP_0_2_ROP_P);
+ }
+ return OPVP_OK;
+}
+
+opvp_result_t OPVPWrapper_0_2::SaveGS()
+{
+ if (!supportSaveGS) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->SaveGS(printerContext_0_2);
+}
+
+opvp_result_t OPVPWrapper_0_2::RestoreGS()
+{
+ if (!supportRestoreGS) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->RestoreGS(printerContext_0_2);
+}
+
+opvp_result_t OPVPWrapper_0_2::QueryColorSpace(
+ opvp_int_t *pnum, opvp_cspace_t *pcspace)
+{
+ int r;
+ int i;
+
+ if (!supportQueryColorSpace) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ if ((r = procs_0_2->QueryColorSpace(printerContext_0_2,
+ (OPVP_ColorSpace *)pcspace,pnum)) != OPVP_OK) {
+ /* error */
+ return (opvp_result_t)r;
+ }
+ /* translate cspaces */
+ for (i = 0;i < *pnum;i++) {
+ if ((unsigned int)pcspace[i]
+ > sizeof(cspace_0_2_to_1_0)/sizeof(opvp_cspace_t)) {
+ /* unknown color space */
+ /* set DEVICERGB instead */
+ pcspace[i] = OPVP_CSPACE_DEVICERGB;
+ } else {
+ pcspace[i] = cspace_0_2_to_1_0[pcspace[i]];
+ }
+ }
+ return OPVP_OK;
+}
+
+opvp_result_t OPVPWrapper_0_2::SetColorSpace(
+ opvp_cspace_t cspace)
+{
+ int r;
+
+ if (!supportSetColorSpace) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ if (cspace == OPVP_CSPACE_DEVICEKRGB) {
+ /* 0.2 doesn't have OPVP_CSPACE_DEVICEKRGB */
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ if ((unsigned int)cspace
+ > sizeof(cspace_1_0_to_0_2)/sizeof(OPVP_ColorSpace)) {
+ /* unknown color space */
+ *opvpErrorNo_0_2 = OPVP_PARAMERROR_0_2;
+ return -1;
+ }
+ r = procs_0_2->SetColorSpace(printerContext_0_2,
+ cspace_1_0_to_0_2[cspace]);
+ if (r == OPVP_OK) {
+ colorSpace = cspace;
+ }
+ return (opvp_result_t)r;
+}
+
+opvp_result_t OPVPWrapper_0_2::GetColorSpace(
+ opvp_cspace_t *pcspace)
+{
+ int r;
+
+ if (!supportGetColorSpace) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ if ((r = procs_0_2->GetColorSpace(printerContext_0_2,
+ (OPVP_ColorSpace *)pcspace)) != OPVP_OK) {
+ /* error */
+ return (opvp_result_t)r;
+ }
+ if ((unsigned int)*pcspace
+ > sizeof(cspace_0_2_to_1_0)/sizeof(opvp_cspace_t)) {
+ /* unknown color space */
+ /* set DEVICERGB instead */
+ *pcspace = OPVP_CSPACE_DEVICERGB;
+ } else {
+ *pcspace = cspace_0_2_to_1_0[*pcspace];
+ }
+ return (opvp_result_t)r;
+}
+
+opvp_result_t OPVPWrapper_0_2::SetFillMode(
+ opvp_fillmode_t fillmode)
+{
+ if (!supportSetFillMode) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ /* OPVP_FillMode is comaptible with opvp_fillmode_t */
+ return (opvp_result_t)procs_0_2->SetFillMode(printerContext_0_2,
+ (OPVP_FillMode)fillmode);
+}
+
+opvp_result_t OPVPWrapper_0_2::GetFillMode(
+ opvp_fillmode_t *pfillmode)
+{
+ if (!supportGetFillMode) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ /* OPVP_FillMode is comaptible with opvp_fillmode_t */
+ return (opvp_result_t)procs_0_2->GetFillMode(printerContext_0_2,
+ (OPVP_FillMode *)pfillmode);
+}
+
+opvp_result_t OPVPWrapper_0_2::SetAlphaConstant(
+ opvp_float_t alpha)
+{
+ if (!supportSetAlphaConstant) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->SetAlphaConstant(printerContext_0_2,alpha);
+}
+
+opvp_result_t OPVPWrapper_0_2::GetAlphaConstant(
+ opvp_float_t *palpha)
+{
+ if (!supportGetAlphaConstant) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->GetAlphaConstant(printerContext_0_2,palpha);
+}
+
+opvp_result_t OPVPWrapper_0_2::SetLineWidth(
+ opvp_fix_t width)
+{
+ if (!supportSetLineWidth) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->SetLineWidth(printerContext_0_2,width);
+}
+
+opvp_result_t OPVPWrapper_0_2::GetLineWidth(
+ opvp_fix_t *pwidth)
+{
+ if (!supportGetLineWidth) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->GetLineWidth(printerContext_0_2,pwidth);
+}
+
+opvp_result_t OPVPWrapper_0_2::SetLineDash(opvp_int_t num,
+ const opvp_fix_t *pdash)
+{
+ if (!supportSetLineDash) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->SetLineDash(printerContext_0_2,
+ /* remove const */ (OPVP_Fix *)pdash,num);
+}
+
+opvp_result_t OPVPWrapper_0_2::GetLineDash(
+ opvp_int_t *pnum, opvp_fix_t *pdash)
+{
+ if (!supportGetLineDash) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->GetLineDash(printerContext_0_2,
+ pdash,pnum);
+}
+
+opvp_result_t OPVPWrapper_0_2::SetLineDashOffset(
+ opvp_fix_t offset)
+{
+ if (!supportSetLineDashOffset) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->SetLineDashOffset(printerContext_0_2,offset);
+}
+
+opvp_result_t OPVPWrapper_0_2::GetLineDashOffset(
+ opvp_fix_t *poffset)
+{
+ if (!supportGetLineDashOffset) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->GetLineDashOffset(printerContext_0_2,poffset);
+}
+
+opvp_result_t OPVPWrapper_0_2::SetLineStyle(
+ opvp_linestyle_t linestyle)
+{
+ if (!supportSetLineStyle) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ /* OPVP_LineStyle is compatible with opvp_linestyle_t */
+ return (opvp_result_t)procs_0_2->SetLineStyle(printerContext_0_2,
+ (OPVP_LineStyle)linestyle);
+}
+
+opvp_result_t OPVPWrapper_0_2::GetLineStyle(
+ opvp_linestyle_t *plinestyle)
+{
+ if (!supportGetLineStyle) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ /* OPVP_LineStyle is compatible with opvp_linestyle_t */
+ return (opvp_result_t)procs_0_2->GetLineStyle(printerContext_0_2,
+ (OPVP_LineStyle *)plinestyle);
+}
+
+opvp_result_t OPVPWrapper_0_2::SetLineCap(
+ opvp_linecap_t linecap)
+{
+ if (!supportSetLineCap) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ /* OPVP_LineCap is compatible with opvp_cap_t */
+ return (opvp_result_t)procs_0_2->SetLineCap(printerContext_0_2,
+ (OPVP_LineCap)linecap);
+}
+
+opvp_result_t OPVPWrapper_0_2::GetLineCap(
+ opvp_linecap_t *plinecap)
+{
+ if (!supportGetLineCap) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ /* OPVP_LineCap is compatible with opvp_cap_t */
+ return (opvp_result_t)procs_0_2->GetLineCap(printerContext_0_2,
+ (OPVP_LineCap *)plinecap);
+}
+
+opvp_result_t OPVPWrapper_0_2::SetLineJoin(
+ opvp_linejoin_t linejoin)
+{
+ if (!supportSetLineJoin) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ /* OPVP_LineJoin is compatible with opvp_linejoin_t */
+ return (opvp_result_t)procs_0_2->SetLineJoin(printerContext_0_2,
+ (OPVP_LineJoin)linejoin);
+}
+
+opvp_result_t OPVPWrapper_0_2::GetLineJoin(
+ opvp_linejoin_t *plinejoin)
+{
+ if (!supportGetLineJoin) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ /* OPVP_LineJoin is compatible with opvp_linejoin_t */
+ return (opvp_result_t)procs_0_2->GetLineJoin(printerContext_0_2,
+ (OPVP_LineJoin *)plinejoin);
+}
+
+opvp_result_t OPVPWrapper_0_2::SetMiterLimit(
+ opvp_fix_t miterlimit)
+{
+ if (!supportSetMiterLimit) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ /* OPVP_Fix is compatible with opvp_fix_t */
+ return (opvp_result_t)procs_0_2->SetMiterLimit(printerContext_0_2,
+ (OPVP_Fix)miterlimit);
+}
+
+opvp_result_t OPVPWrapper_0_2::GetMiterLimit(
+ opvp_fix_t *pmiterlimit)
+{
+ if (!supportGetMiterLimit) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ /* OPVP_Fix is compatible with opvp_fix_t */
+ return (opvp_result_t)procs_0_2->GetMiterLimit(printerContext_0_2,
+ (OPVP_Fix *)pmiterlimit);
+}
+
+opvp_result_t OPVPWrapper_0_2::SetPaintMode(
+ opvp_paintmode_t paintmode)
+{
+ if (!supportSetPaintMode) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ /* OPVP_PaintMode is compatible with opvp_paintmode_t */
+ return (opvp_result_t)procs_0_2->SetPaintMode(printerContext_0_2,
+ (OPVP_PaintMode)paintmode);
+}
+
+opvp_result_t OPVPWrapper_0_2::GetPaintMode(
+ opvp_paintmode_t *ppaintmode)
+{
+ if (!supportGetPaintMode) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ /* OPVP_PaintMode is compatible with opvp_paintmode_t */
+ return (opvp_result_t)procs_0_2->GetPaintMode(printerContext_0_2,
+ (OPVP_PaintMode *)ppaintmode);
+}
+
+opvp_result_t OPVPWrapper_0_2::SetStrokeColor(
+ const opvp_brush_t *brush)
+{
+ OPVP_Brush brush_0_2;
+
+ if (!supportSetStrokeColor) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ if (brush == 0) {
+ *opvpErrorNo_0_2 = OPVP_PARAMERROR_0_2;
+ return -1;
+ }
+ if (brush->colorSpace == OPVP_CSPACE_DEVICEKRGB) {
+ /* 0.2 doesn't have OPVP_CSPACE_DEVICEKRGB */
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ if ((unsigned int)brush->colorSpace
+ > sizeof(cspace_1_0_to_0_2)/sizeof(OPVP_ColorSpace)) {
+ /* unknown color space */
+ *opvpErrorNo_0_2 = OPVP_PARAMERROR_0_2;
+ return -1;
+ }
+ brush_0_2.colorSpace = cspace_1_0_to_0_2[brush->colorSpace];
+ brush_0_2.xorg = brush->xorg;
+ brush_0_2.yorg = brush->yorg;
+ brush_0_2.pbrush = (OPVP_BrushData *)brush->pbrush;
+ memcpy(brush_0_2.color,brush->color,sizeof(brush_0_2.color));
+ return (opvp_result_t)procs_0_2->SetStrokeColor(printerContext_0_2,
+ &brush_0_2);
+}
+
+opvp_result_t OPVPWrapper_0_2::SetFillColor(
+ const opvp_brush_t *brush)
+{
+ OPVP_Brush brush_0_2;
+
+ if (!supportSetFillColor) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ if (brush == 0) {
+ *opvpErrorNo_0_2 = OPVP_PARAMERROR_0_2;
+ return -1;
+ }
+ if (brush->colorSpace == OPVP_CSPACE_DEVICEKRGB) {
+ /* 0.2 doesn't have OPVP_CSPACE_DEVICEKRGB */
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ if ((unsigned int)brush->colorSpace
+ > sizeof(cspace_1_0_to_0_2)/sizeof(OPVP_ColorSpace)) {
+ /* unknown color space */
+ *opvpErrorNo_0_2 = OPVP_PARAMERROR_0_2;
+ return -1;
+ }
+ brush_0_2.colorSpace = cspace_1_0_to_0_2[brush->colorSpace];
+ brush_0_2.xorg = brush->xorg;
+ brush_0_2.yorg = brush->yorg;
+ brush_0_2.pbrush = (OPVP_BrushData *)brush->pbrush;
+ memcpy(brush_0_2.color,brush->color,sizeof(brush_0_2.color));
+ return (opvp_result_t)procs_0_2->SetFillColor(printerContext_0_2,
+ &brush_0_2);
+}
+
+opvp_result_t OPVPWrapper_0_2::SetBgColor(
+ const opvp_brush_t *brush)
+{
+ OPVP_Brush brush_0_2;
+
+ if (!supportSetBgColor) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ if (brush == 0) {
+ *opvpErrorNo_0_2 = OPVP_PARAMERROR_0_2;
+ return -1;
+ }
+ if (brush->colorSpace == OPVP_CSPACE_DEVICEKRGB) {
+ /* 0.2 doesn't have OPVP_CSPACE_DEVICEKRGB */
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ if ((unsigned int)brush->colorSpace
+ > sizeof(cspace_1_0_to_0_2)/sizeof(OPVP_ColorSpace)) {
+ /* unknown color space */
+ *opvpErrorNo_0_2 = OPVP_PARAMERROR_0_2;
+ return -1;
+ }
+ brush_0_2.colorSpace = cspace_1_0_to_0_2[brush->colorSpace];
+ brush_0_2.xorg = brush->xorg;
+ brush_0_2.yorg = brush->yorg;
+ brush_0_2.pbrush = (OPVP_BrushData *)brush->pbrush;
+ memcpy(brush_0_2.color,brush->color,sizeof(brush_0_2.color));
+ return (opvp_result_t)procs_0_2->SetBgColor(printerContext_0_2,
+ &brush_0_2);
+}
+
+opvp_result_t OPVPWrapper_0_2::NewPath()
+{
+ if (!supportNewPath) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->NewPath(printerContext_0_2);
+}
+
+opvp_result_t OPVPWrapper_0_2::EndPath()
+{
+ if (!supportEndPath) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->EndPath(printerContext_0_2);
+}
+
+opvp_result_t OPVPWrapper_0_2::StrokePath()
+{
+ if (!supportStrokePath) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->StrokePath(printerContext_0_2);
+}
+
+opvp_result_t OPVPWrapper_0_2::FillPath()
+{
+ if (!supportFillPath) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->FillPath(printerContext_0_2);
+}
+
+opvp_result_t OPVPWrapper_0_2::StrokeFillPath()
+{
+ if (!supportStrokeFillPath) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->StrokeFillPath(printerContext_0_2);
+}
+
+opvp_result_t OPVPWrapper_0_2::SetClipPath(
+ opvp_cliprule_t clipRule)
+{
+ if (!supportSetClipPath) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ /* OPVP_ClipRule is compatible with opvp_cliprule_t */
+ return (opvp_result_t)procs_0_2->SetClipPath(printerContext_0_2,
+ (OPVP_ClipRule)clipRule);
+}
+
+opvp_result_t OPVPWrapper_0_2::SetCurrentPoint(
+ opvp_fix_t x, opvp_fix_t y)
+{
+ if (!supportSetCurrentPoint) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->SetCurrentPoint(printerContext_0_2,x,y);
+}
+
+opvp_result_t OPVPWrapper_0_2::LinePath(
+ opvp_pathmode_t flag, opvp_int_t npoints, const opvp_point_t *points)
+{
+ if (!supportLinePath) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ /* OPVP_Point is compatible with opvp_point_t */
+ return (opvp_result_t)procs_0_2->LinePath(printerContext_0_2,flag,npoints,
+ (OPVP_Point *)points);
+}
+
+opvp_result_t OPVPWrapper_0_2::PolygonPath(
+ opvp_int_t npolygons, const opvp_int_t *nvertexes,
+ const opvp_point_t *points)
+{
+ if (!supportPolygonPath) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ /* OPVP_Point is compatible with opvp_point_t */
+ return (opvp_result_t)procs_0_2->PolygonPath(printerContext_0_2,
+ (int)npolygons,(int *)nvertexes,(OPVP_Point *)points);
+}
+
+opvp_result_t OPVPWrapper_0_2::RectanglePath(
+ opvp_int_t nrectangles, const opvp_rectangle_t *rectangles)
+{
+ if (!supportRectanglePath) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ /* OPVP_Rectangle is compatible with opvp_rectangle_t */
+ return (opvp_result_t)procs_0_2->RectanglePath(printerContext_0_2,
+ (int)nrectangles,(OPVP_Rectangle *)rectangles);
+}
+
+opvp_result_t OPVPWrapper_0_2::RoundRectanglePath(
+ opvp_int_t nrectangles, const opvp_roundrectangle_t *rectangles)
+{
+ if (!supportRoundRectanglePath) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ /* OPVP_RoundRectangle is compatible with opvp_roundrectangle_t */
+ return (opvp_result_t)procs_0_2->RoundRectanglePath(printerContext_0_2,
+ (int)nrectangles,(OPVP_RoundRectangle *)rectangles);
+}
+
+opvp_result_t OPVPWrapper_0_2::BezierPath(opvp_int_t npoints,
+ const opvp_point_t *points)
+{
+ if (!supportBezierPath) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ /* OPVP_Point is compatible with opvp_point_t */
+ return (opvp_result_t)procs_0_2->BezierPath(printerContext_0_2,(int)npoints,
+ (OPVP_Point *)points);
+}
+
+opvp_result_t OPVPWrapper_0_2::ArcPath(opvp_arcmode_t kind, opvp_arcdir_t dir,
+ opvp_fix_t bbx0, opvp_fix_t bby0, opvp_fix_t bbx1,
+ opvp_fix_t bby1, opvp_fix_t x0, opvp_fix_t y0, opvp_fix_t x1, opvp_fix_t y1)
+{
+ if (!supportArcPath) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ /* opvp_arcmode_t is compatible with int */
+ /* opvp_arcdir_t is compatible with int */
+ return (opvp_result_t)procs_0_2->ArcPath(printerContext_0_2,
+ (int)kind,(int)dir,bbx0,bby0,
+ bbx1,bby1,x0,y0,x1,y1);
+}
+
+opvp_result_t OPVPWrapper_0_2::DrawImage(opvp_int_t sourceWidth,
+ opvp_int_t sourceHeight, opvp_int_t sourcePitch,
+ opvp_imageformat_t imageFormat, opvp_int_t destinationWidth,
+ opvp_int_t destinationHeight, const void *imagedata)
+{
+ int r;
+ OPVP_Rectangle rect;
+ OPVP_ImageFormat iformat_0_2;
+ OPVP_PaintMode paintmode_0_2 = OPVP_paintModeTransparent;
+ int depth;
+
+ if (!supportDrawImage) {
+ int result;
+
+ if ((result = StartDrawImage(sourceWidth,
+ sourceHeight,sourcePitch,imageFormat,destinationWidth,
+ destinationHeight)) < 0) {
+ return result;
+ }
+ if ((result = TransferDrawImage(sourcePitch*sourceHeight,
+ imagedata)) < 0) {
+ return result;
+ }
+ return EndDrawImage();
+ }
+
+ if (imageFormat == OPVP_IFORMAT_MASK) {
+ if (procs_0_2->GetPaintMode != 0) {
+ procs_0_2->GetPaintMode(printerContext_0_2,
+ &paintmode_0_2);
+ }
+ if (paintmode_0_2 != OPVP_paintModeTransparent) {
+ if (procs_0_2->SetROP != 0) {
+ procs_0_2->SetROP(printerContext_0_2,
+ OPVP_0_2_ROP_S);
+ }
+ }
+ else {
+ if (procs_0_2->SetROP != 0) {
+ procs_0_2->SetROP(printerContext_0_2,
+ OPVP_0_2_ROP_OR);
+ }
+ }
+ depth = 1;
+ } else {
+ if (procs_0_2->SetROP != 0) {
+ procs_0_2->SetROP(printerContext_0_2,OPVP_0_2_ROP_S);
+ }
+ depth = colorDepth_0_2[colorSpace];
+ }
+
+ OPVP_I2FIX(0,rect.p0.x);
+ OPVP_I2FIX(0,rect.p0.y);
+ OPVP_I2FIX(destinationWidth,rect.p1.x);
+ OPVP_I2FIX(destinationHeight,rect.p1.y);
+ if ((unsigned int)imageFormat
+ > sizeof(iformat_1_0_to_0_2)/sizeof(OPVP_ImageFormat)) {
+ /* illegal image format */
+ *opvpErrorNo_0_2 = OPVP_PARAMERROR_0_2;
+ return -1;
+ }
+ iformat_0_2 = iformat_1_0_to_0_2[imageFormat];
+ r = procs_0_2->DrawImage(printerContext_0_2,sourceWidth,sourceHeight,
+ depth,iformat_0_2,rect,
+ sourcePitch*sourceHeight,
+ /* remove const */ (void *)imagedata);
+
+ if (procs_0_2->SetROP != 0) {
+ procs_0_2->SetROP(printerContext_0_2,OPVP_0_2_ROP_P);
+ }
+
+ return (opvp_result_t)r;
+}
+
+opvp_result_t OPVPWrapper_0_2::StartDrawImage(opvp_int_t sourceWidth,
+ opvp_int_t sourceHeight, opvp_int_t sourcePitch,
+ opvp_imageformat_t imageFormat, opvp_int_t destinationWidth,
+ opvp_int_t destinationHeight)
+{
+ int r;
+ OPVP_Rectangle rect;
+ OPVP_ImageFormat iformat_0_2;
+ OPVP_PaintMode paintmode_0_2 = OPVP_paintModeTransparent;
+ int depth;
+
+ if (!supportStartDrawImage) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ if (imageFormat == OPVP_IFORMAT_MASK) {
+ if (procs_0_2->GetPaintMode != 0) {
+ procs_0_2->GetPaintMode(printerContext_0_2,
+ &paintmode_0_2);
+ }
+ if (paintmode_0_2 != OPVP_paintModeTransparent) {
+ if (procs_0_2->SetROP != 0) {
+ procs_0_2->SetROP(printerContext_0_2,OPVP_0_2_ROP_S);
+ }
+ }
+ else {
+ if (procs_0_2->SetROP != 0) {
+ procs_0_2->SetROP(printerContext_0_2,OPVP_0_2_ROP_OR);
+ }
+ }
+ depth = 1;
+ } else {
+ if (procs_0_2->SetROP != 0) {
+ procs_0_2->SetROP(printerContext_0_2,OPVP_0_2_ROP_S);
+ }
+ depth = colorDepth_0_2[colorSpace];
+ }
+
+ OPVP_I2FIX(0,rect.p0.x);
+ OPVP_I2FIX(0,rect.p0.y);
+ OPVP_I2FIX(destinationWidth,rect.p1.x);
+ OPVP_I2FIX(destinationHeight,rect.p1.y);
+ if ((unsigned int)imageFormat
+ > sizeof(iformat_1_0_to_0_2)/sizeof(OPVP_ImageFormat)) {
+ /* illegal image format */
+ *opvpErrorNo_0_2 = OPVP_PARAMERROR_0_2;
+ return -1;
+ }
+ iformat_0_2 = iformat_1_0_to_0_2[imageFormat];
+ r = procs_0_2->StartDrawImage(printerContext_0_2,
+ sourceWidth,sourceHeight,
+ depth,iformat_0_2,rect);
+
+ return (opvp_result_t)r;
+}
+
+opvp_result_t OPVPWrapper_0_2::TransferDrawImage(opvp_int_t count,
+ const void *imagedata)
+{
+ if (!supportTransferDrawImage) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->TransferDrawImage(printerContext_0_2,
+ count,(void *)imagedata);
+}
+
+opvp_result_t OPVPWrapper_0_2::EndDrawImage()
+{
+ int r;
+
+ if (!supportEndDrawImage) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ r = procs_0_2->EndDrawImage(printerContext_0_2);
+
+ /* make sure rop is pattern copy */
+ if (procs_0_2->SetROP != 0) {
+ procs_0_2->SetROP(printerContext_0_2,OPVP_0_2_ROP_P);
+ }
+
+ return (opvp_result_t)r;
+}
+
+opvp_result_t OPVPWrapper_0_2::StartScanline(opvp_int_t yposition)
+{
+ if (!supportStartScanline) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->StartScanline(printerContext_0_2,yposition);
+}
+
+opvp_result_t OPVPWrapper_0_2::Scanline(opvp_int_t nscanpairs,
+ const opvp_int_t *scanpairs)
+{
+ if (!supportScanline) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->Scanline(printerContext_0_2,
+ (int)nscanpairs,(int *)scanpairs);
+}
+
+opvp_result_t OPVPWrapper_0_2::EndScanline()
+{
+ if (!supportEndScanline) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->EndScanline(printerContext_0_2);
+}
+
+opvp_result_t OPVPWrapper_0_2::StartRaster(opvp_int_t rasterWidth)
+{
+ if (!supportStartRaster) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->StartRaster(printerContext_0_2,rasterWidth);
+}
+
+opvp_result_t OPVPWrapper_0_2::TransferRasterData(opvp_int_t count,
+ const opvp_byte_t *data)
+{
+ if (!supportTransferRasterData) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->TransferRasterData(printerContext_0_2,
+ (int)count, (unsigned char *)data);
+}
+
+opvp_result_t OPVPWrapper_0_2::SkipRaster(opvp_int_t count)
+{
+ if (!supportSkipRaster) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->SkipRaster(printerContext_0_2,count);
+}
+
+opvp_result_t OPVPWrapper_0_2::EndRaster()
+{
+ if (!supportEndRaster) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->EndRaster(printerContext_0_2);
+}
+
+opvp_result_t OPVPWrapper_0_2::StartStream()
+{
+ if (!supportStartStream) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->StartStream(printerContext_0_2);
+}
+
+opvp_result_t OPVPWrapper_0_2::TransferStreamData(opvp_int_t count,
+ const void *data)
+{
+ if (!supportTransferStreamData) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->TransferStreamData(printerContext_0_2,
+ count,(void *)data);
+}
+
+opvp_result_t OPVPWrapper_0_2::EndStream()
+{
+ if (!supportEndStream) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->EndStream(printerContext_0_2);
+}
+
+opvp_result_t OPVPWrapper_0_2::ResetClipPath()
+{
+ if (!supportResetClipPath) {
+ *opvpErrorNo_0_2 = OPVP_NOTSUPPORTED_0_2;
+ return -1;
+ }
+ return (opvp_result_t)procs_0_2->ResetClipPath(printerContext_0_2);
+}
+
+/* translate error code */
+opvp_int_t OPVPWrapper_0_2::getErrorNo()
+{
+ switch(*opvpErrorNo_0_2) {
+ case OPVP_FATALERROR_0_2:
+ return OPVP_FATALERROR;
+ break;
+ case OPVP_BADREQUEST_0_2:
+ return OPVP_BADREQUEST;
+ break;
+ case OPVP_BADCONTEXT_0_2:
+ return OPVP_BADCONTEXT;
+ break;
+ case OPVP_NOTSUPPORTED_0_2:
+ return OPVP_NOTSUPPORTED;
+ break;
+ case OPVP_JOBCANCELED_0_2:
+ return OPVP_JOBCANCELED;
+ break;
+ case OPVP_PARAMERROR_0_2:
+ return OPVP_PARAMERROR;
+ break;
+ default:
+ break;
+ }
+ /* unknown error no */
+ /* return FATALERROR instead */
+ return OPVP_FATALERROR;
+}
diff --git a/filter/pdftoopvp/oprs/OPVPWrapper_0_2.h b/filter/pdftoopvp/oprs/OPVPWrapper_0_2.h
new file mode 100644
index 000000000..f670a4526
--- /dev/null
+++ b/filter/pdftoopvp/oprs/OPVPWrapper_0_2.h
@@ -0,0 +1,127 @@
+/*
+ OPVPWrapper_0_2.h
+*/
+
+#ifndef OPVPWRAPPER_0_2_H
+#define OPVPWRAPPER_0_2_H
+
+#include "OPVPWrapper.h"
+
+/* ROP */
+#define OPVP_0_2_ROP_S 0xCC
+#define OPVP_0_2_ROP_P 0xF0
+#define OPVP_0_2_ROP_OR 0xB8
+
+class OPVPWrapper_0_2: public OPVPWrapper {
+private:
+ static opvp_cspace_t cspace_0_2_to_1_0[];
+ static OPVP_ColorSpace cspace_1_0_to_0_2[];
+ static OPVP_ImageFormat iformat_1_0_to_0_2[];
+ static int colorDepth_0_2[];
+public:
+ OPVPWrapper_0_2(void *opvpHandleA, int *opvpErrorNoA,
+ OPVP_api_procs *procsA, int printerContextA);
+ virtual ~OPVPWrapper_0_2();
+ virtual opvp_int_t getErrorNo();
+
+ virtual opvp_result_t ClosePrinter();
+ virtual opvp_result_t StartJob(const opvp_char_t *jobInfo);
+ virtual opvp_result_t EndJob();
+ virtual opvp_result_t AbortJob();
+ virtual opvp_result_t StartDoc(const opvp_char_t *docInfo);
+ virtual opvp_result_t EndDoc();
+ virtual opvp_result_t StartPage(const opvp_char_t *pageInfo);
+ virtual opvp_result_t EndPage();
+ virtual opvp_result_t QueryDeviceCapability(opvp_flag_t queryflag,
+ opvp_int_t *buflen, opvp_byte_t *infoBuf);
+ virtual opvp_result_t QueryDeviceInfo(opvp_flag_t queryflag,
+ opvp_int_t *buflen, opvp_byte_t *infoBuf);
+ virtual opvp_result_t ResetCTM();
+ virtual opvp_result_t SetCTM(const opvp_ctm_t *pCTM);
+ virtual opvp_result_t GetCTM(opvp_ctm_t *pCTM);
+ virtual opvp_result_t InitGS();
+ virtual opvp_result_t SaveGS();
+ virtual opvp_result_t RestoreGS();
+ virtual opvp_result_t QueryColorSpace(opvp_int_t *pnum,
+ opvp_cspace_t *pcspace);
+ virtual opvp_result_t SetColorSpace(opvp_cspace_t cspace);
+ virtual opvp_result_t GetColorSpace(opvp_cspace_t *pcspace);
+ virtual opvp_result_t SetFillMode(opvp_fillmode_t fillmode);
+ virtual opvp_result_t GetFillMode(opvp_fillmode_t *pfillmode);
+ virtual opvp_result_t SetAlphaConstant(opvp_float_t alpha);
+ virtual opvp_result_t GetAlphaConstant(opvp_float_t *palpha);
+ virtual opvp_result_t SetLineWidth(opvp_fix_t width);
+ virtual opvp_result_t GetLineWidth(opvp_fix_t *pwidth);
+ virtual opvp_result_t SetLineDash(opvp_int_t num, const opvp_fix_t *pdash);
+ virtual opvp_result_t GetLineDash(opvp_int_t *pnum, opvp_fix_t *pdash);
+ virtual opvp_result_t SetLineDashOffset(opvp_fix_t offset);
+ virtual opvp_result_t GetLineDashOffset(opvp_fix_t *poffset);
+ virtual opvp_result_t SetLineStyle(opvp_linestyle_t linestyle);
+ virtual opvp_result_t GetLineStyle(opvp_linestyle_t *plinestyle);
+ virtual opvp_result_t SetLineCap(opvp_linecap_t linecap);
+ virtual opvp_result_t GetLineCap(opvp_linecap_t *plinecap);
+ virtual opvp_result_t SetLineJoin(opvp_linejoin_t linejoin);
+ virtual opvp_result_t GetLineJoin(opvp_linejoin_t *plinejoin);
+ virtual opvp_result_t SetMiterLimit(opvp_fix_t miterlimit);
+ virtual opvp_result_t GetMiterLimit(opvp_fix_t *pmiterlimit);
+ virtual opvp_result_t SetPaintMode(opvp_paintmode_t paintmode);
+ virtual opvp_result_t GetPaintMode(opvp_paintmode_t *ppaintmode);
+ virtual opvp_result_t SetStrokeColor(const opvp_brush_t *brush);
+ virtual opvp_result_t SetFillColor(const opvp_brush_t *brush);
+ virtual opvp_result_t SetBgColor(const opvp_brush_t *brush);
+ virtual opvp_result_t NewPath();
+ virtual opvp_result_t EndPath();
+ virtual opvp_result_t StrokePath();
+ virtual opvp_result_t FillPath();
+ virtual opvp_result_t StrokeFillPath();
+ virtual opvp_result_t SetClipPath(opvp_cliprule_t clipRule);
+ virtual opvp_result_t SetCurrentPoint(opvp_fix_t x, opvp_fix_t y);
+ virtual opvp_result_t LinePath(opvp_pathmode_t flag,
+ opvp_int_t npoints, const opvp_point_t *points);
+ virtual opvp_result_t PolygonPath(opvp_int_t npolygons,
+ const opvp_int_t *nvertexes, const opvp_point_t *points);
+ virtual opvp_result_t RectanglePath(opvp_int_t nrectangles,
+ const opvp_rectangle_t *reclangles);
+ virtual opvp_result_t RoundRectanglePath(opvp_int_t nrectangles,
+ const opvp_roundrectangle_t *reclangles);
+ virtual opvp_result_t BezierPath(opvp_int_t npoints,
+ const opvp_point_t *points);
+ virtual opvp_result_t ArcPath(opvp_arcmode_t kind,
+ opvp_arcdir_t dir, opvp_fix_t bbx0, opvp_fix_t bby0,
+ opvp_fix_t bbx1, opvp_fix_t bby1, opvp_fix_t x0,
+ opvp_fix_t y0, opvp_fix_t x1, opvp_fix_t y1);
+ virtual opvp_result_t DrawImage(opvp_int_t sourceWidth,
+ opvp_int_t sourceHeight, opvp_int_t sourcePitch,
+ opvp_imageformat_t imageFormat,
+ opvp_int_t destinationWidth, opvp_int_t destinationHeight,
+ const void *imageData);
+ virtual opvp_result_t StartDrawImage(opvp_int_t sourceWidth,
+ opvp_int_t sourceHeight, opvp_int_t sourcePitch,
+ opvp_imageformat_t imageFormat,
+ opvp_int_t destinationWidth, opvp_int_t destinationHeight);
+ virtual opvp_result_t TransferDrawImage(opvp_int_t count,
+ const void *imageData);
+ virtual opvp_result_t EndDrawImage();
+ virtual opvp_result_t StartScanline(opvp_int_t yposition);
+ virtual opvp_result_t Scanline(opvp_int_t nscanpairs,
+ const opvp_int_t *scanpairs);
+ virtual opvp_result_t EndScanline();
+ virtual opvp_result_t StartRaster(opvp_int_t rasterWidth);
+ virtual opvp_result_t TransferRasterData(opvp_int_t count,
+ const opvp_byte_t *data);
+ virtual opvp_result_t SkipRaster(opvp_int_t count);
+ virtual opvp_result_t EndRaster();
+ virtual opvp_result_t StartStream();
+ virtual opvp_result_t TransferStreamData(opvp_int_t count,
+ const void *data);
+ virtual opvp_result_t EndStream();
+ virtual opvp_result_t ResetClipPath();
+
+private:
+ OPVP_api_procs *procs_0_2;
+ int *opvpErrorNo_0_2;
+ int printerContext_0_2;
+ opvp_cspace_t colorSpace;
+};
+
+#endif
diff --git a/filter/pdftoopvp/opvp/opvp.h b/filter/pdftoopvp/opvp/opvp.h
new file mode 100644
index 000000000..41ade3aa7
--- /dev/null
+++ b/filter/pdftoopvp/opvp/opvp.h
@@ -0,0 +1,292 @@
+/*
+ * OpenPrinting Vector Printer Driver API Definitions [opvp.h]
+ *
+ * Copyright (c) 2006 Free Standards Group
+ * Copyright (c) 2006 Fuji Xerox Printing Systems Co., Ltd.
+ * Copyright (c) 2006 Canon Inc.
+ * Copyright (c) 2003-2006 AXE Inc.
+ *
+ * All Rights Reserverd.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation.
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+ /*
+ 2007 Modified for OPVP 1.0 by BBR Inc.
+ */
+
+#ifndef _OPVP_H_
+#define _OPVP_H_
+
+/* Return Values and Error Codes */
+#define OPVP_OK 0 /* -1 for errors */
+#define OPVP_FATALERROR -1 /* error: cannot be recovered */
+#define OPVP_BADREQUEST -2 /* error: called where it should
+ not be called */
+#define OPVP_BADCONTEXT -3 /* error: invalid printer context */
+#define OPVP_NOTSUPPORTED -4 /* error: combination of
+ parameters are set
+ which cannot be handled
+ by driver or printer */
+#define OPVP_JOBCANCELED -5 /* error: job has been canceled
+ by some cause */
+#define OPVP_PARAMERROR -6 /* error: invalid parameter */
+#define OPVP_VERSIONERROR -7 /* error: invalid API version */
+
+/* Basic Types */
+typedef int opvp_dc_t; /* driver/device context */
+typedef int opvp_result_t; /* return value */
+typedef unsigned char opvp_byte_t; /* BYTE */
+typedef unsigned char opvp_char_t; /* character (string) */
+typedef int opvp_int_t; /* integer */
+typedef int opvp_fix_t; /* fixed integer */
+typedef float opvp_float_t; /* float */
+typedef unsigned int opvp_flag_t; /* flags */
+typedef unsigned int opvp_rop_t; /* raster operation */
+
+/* for opvp_fix_t */
+#define OPVP_FIX_FRACT_WIDTH 8
+#define OPVP_FIX_FRACT_DENOM (1<<OPVP_FIX_FRACT_WIDTH)
+#define OPVP_FIX_FLOOR_WIDTH (sizeof(int)*8-OPVP_FIX_FRACT_WIDTH)
+
+/* convert macro */
+#define OPVP_I2FIX(i,fix) (fix=(i)<<OPVP_FIX_FRACT_WIDTH)
+#define OPVP_F2FIX(f,fix) (fix=((int)floor(f)<<OPVP_FIX_FRACT_WIDTH)\
+ |((int)((f-floor(f))*OPVP_FIX_FRACT_DENOM)\
+ &(OPVP_FIX_FRACT_DENOM-1)))
+
+/* graphic elements */
+typedef struct _opvp_point {
+ opvp_fix_t x, y;
+} opvp_point_t;
+
+typedef struct _opvp_rectangle {
+ opvp_point_t p0; /* start point */
+ opvp_point_t p1; /* diagonal point */
+} opvp_rectangle_t;
+
+typedef struct _opvp_roundrectangle {
+ opvp_point_t p0; /* start point */
+ opvp_point_t p1; /* diagonal point */
+ opvp_fix_t xellipse, yellipse;
+} opvp_roundrectangle_t;
+
+/* Image Formats */
+typedef enum _opvp_imageformat {
+ OPVP_IFORMAT_RAW = 0,
+ OPVP_IFORMAT_MASK = 1,
+ OPVP_IFORMAT_RLE = 2,
+ OPVP_IFORMAT_JPEG = 3,
+ OPVP_IFORMAT_PNG = 4
+} opvp_imageformat_t;
+
+/* Color Presentation */
+typedef enum _opvp_colormapping {
+ OPVP_CMAP_DIRECT = 0,
+ OPVP_CMAP_INDEXED = 1
+} opvp_colormapping_t;
+
+typedef enum _opvp_cspace {
+ OPVP_CSPACE_BW = 0,
+ OPVP_CSPACE_DEVICEGRAY = 1,
+ OPVP_CSPACE_DEVICECMY = 2,
+ OPVP_CSPACE_DEVICECMYK = 3,
+ OPVP_CSPACE_DEVICERGB = 4,
+ OPVP_CSPACE_DEVICEKRGB = 5,
+ OPVP_CSPACE_STANDARDRGB = 6,
+ OPVP_CSPACE_STANDARDRGB64 = 7
+} opvp_cspace_t;
+
+/* Fill, Paint, Clip */
+typedef enum _opvp_fillmode {
+ OPVP_FILLMODE_EVENODD = 0,
+ OPVP_FILLMODE_WINDING = 1
+} opvp_fillmode_t;
+
+typedef enum _opvp_paintmode {
+ OPVP_PAINTMODE_OPAQUE = 0,
+ OPVP_PAINTMODE_TRANSPARENT = 1
+} opvp_paintmode_t;
+
+typedef enum _opvp_cliprule {
+ OPVP_CLIPRULE_EVENODD = 0,
+ OPVP_CLIPRULE_WINDING = 1
+} opvp_cliprule_t;
+
+/* Line */
+typedef enum _opvp_linestyle {
+ OPVP_LINESTYLE_SOLID = 0,
+ OPVP_LINESTYLE_DASH = 1
+} opvp_linestyle_t;
+
+typedef enum _opvp_linecap {
+ OPVP_LINECAP_BUTT = 0,
+ OPVP_LINECAP_ROUND = 1,
+ OPVP_LINECAP_SQUARE = 2
+} opvp_linecap_t;
+
+typedef enum _opvp_linejoin {
+ OPVP_LINEJOIN_MITER = 0,
+ OPVP_LINEJOIN_ROUND = 1,
+ OPVP_LINEJOIN_BEVEL = 2
+} opvp_linejoin_t;
+
+/* Brush */
+typedef enum _opvp_bdtype {
+ OPVP_BDTYPE_NORMAL = 0
+} opvp_bdtype_t;
+
+typedef struct _opvp_brushdata {
+ opvp_bdtype_t type;
+ opvp_int_t width, height, pitch;
+ opvp_byte_t data[1];
+
+} opvp_brushdata_t;
+
+typedef struct _opvp_brush {
+ opvp_cspace_t colorSpace;
+ opvp_int_t color[4]; /* aRGB quadruplet */
+ opvp_int_t xorg, yorg; /* brush origin */
+ /* ignored for opvpSetBgColor */
+ opvp_brushdata_t *pbrush; /* pointer to brush data */
+ /* solid brush used, if NULL */
+} opvp_brush_t;
+
+/* Misc. Flags */
+typedef enum _opvp_arcmode {
+ OPVP_ARC = 0,
+ OPVP_CHORD = 1,
+ OPVP_PIE = 2
+} opvp_arcmode_t;
+
+typedef enum _opvp_arcdir {
+ OPVP_CLOCKWISE = 0,
+ OPVP_COUNTERCLOCKWISE = 1
+} opvp_arcdir_t;
+
+typedef enum _opvp_pathmode {
+ OPVP_PATHCLOSE = 0,
+ OPVP_PATHOPEN = 1
+} opvp_pathmode_t;
+
+/* CTM */
+typedef struct _opvp_ctm {
+ opvp_float_t a, b, c, d, e, f;
+} opvp_ctm_t;
+
+/* Device Information and Capabilites */
+typedef enum _opvp_queryinfoflags {
+ OPVP_QF_DEVICERESOLUTION = 0x00000001,
+ OPVP_QF_MEDIASIZE = 0x00000002,
+ OPVP_QF_PAGEROTATION = 0x00000004,
+ OPVP_QF_MEDIANUP = 0x00000008,
+ OPVP_QF_MEDIADUPLEX = 0x00000010,
+ OPVP_QF_MEDIASOURCE = 0x00000020,
+ OPVP_QF_MEDIADESTINATION = 0x00000040,
+ OPVP_QF_MEDIATYPE = 0x00000080,
+ OPVP_QF_MEDIACOPY = 0x00000100, /* Maximum copy number
+ supported */
+ OPVP_QF_PRINTREGION = 0x00010000 /* only for opvpQueryDeviceInfo */
+} opvp_queryinfoflags_t;
+
+
+/* API Procedure Entries */
+typedef struct _opvp_api_procs {
+ opvp_dc_t (*opvpOpenPrinter)(opvp_int_t,const opvp_char_t*,const opvp_int_t[2],struct _opvp_api_procs**);
+ opvp_result_t (*opvpClosePrinter)(opvp_dc_t);
+ opvp_result_t (*opvpStartJob)(opvp_dc_t,const opvp_char_t*);
+ opvp_result_t (*opvpEndJob)(opvp_dc_t);
+ opvp_result_t (*opvpAbortJob)(opvp_dc_t);
+ opvp_result_t (*opvpStartDoc)(opvp_dc_t,const opvp_char_t*);
+ opvp_result_t (*opvpEndDoc)(opvp_dc_t);
+ opvp_result_t (*opvpStartPage)(opvp_dc_t,const opvp_char_t*);
+ opvp_result_t (*opvpEndPage)(opvp_dc_t);
+ opvp_result_t (*opvpQueryDeviceCapability)(opvp_dc_t,opvp_flag_t,opvp_int_t*,opvp_byte_t*);
+ opvp_result_t (*opvpQueryDeviceInfo)(opvp_dc_t,opvp_flag_t,opvp_int_t*,opvp_char_t*);
+ opvp_result_t (*opvpResetCTM)(opvp_dc_t);
+ opvp_result_t (*opvpSetCTM)(opvp_dc_t,const opvp_ctm_t*);
+ opvp_result_t (*opvpGetCTM)(opvp_dc_t,opvp_ctm_t*);
+ opvp_result_t (*opvpInitGS)(opvp_dc_t);
+ opvp_result_t (*opvpSaveGS)(opvp_dc_t);
+ opvp_result_t (*opvpRestoreGS)(opvp_dc_t);
+ opvp_result_t (*opvpQueryColorSpace)(opvp_dc_t,opvp_int_t*,opvp_cspace_t*);
+ opvp_result_t (*opvpSetColorSpace)(opvp_dc_t,opvp_cspace_t);
+ opvp_result_t (*opvpGetColorSpace)(opvp_dc_t,opvp_cspace_t*);
+ opvp_result_t (*opvpSetFillMode)(opvp_dc_t,opvp_fillmode_t);
+ opvp_result_t (*opvpGetFillMode)(opvp_dc_t,opvp_fillmode_t*);
+ opvp_result_t (*opvpSetAlphaConstant)(opvp_dc_t,opvp_float_t);
+ opvp_result_t (*opvpGetAlphaConstant)(opvp_dc_t,opvp_float_t*);
+ opvp_result_t (*opvpSetLineWidth)(opvp_dc_t,opvp_fix_t);
+ opvp_result_t (*opvpGetLineWidth)(opvp_dc_t,opvp_fix_t*);
+ opvp_result_t (*opvpSetLineDash)(opvp_dc_t,opvp_int_t,const opvp_fix_t*);
+ opvp_result_t (*opvpGetLineDash)(opvp_dc_t,opvp_int_t*,opvp_fix_t*);
+ opvp_result_t (*opvpSetLineDashOffset)(opvp_dc_t,opvp_fix_t);
+ opvp_result_t (*opvpGetLineDashOffset)(opvp_dc_t,opvp_fix_t*);
+ opvp_result_t (*opvpSetLineStyle)(opvp_dc_t,opvp_linestyle_t);
+ opvp_result_t (*opvpGetLineStyle)(opvp_dc_t,opvp_linestyle_t*);
+ opvp_result_t (*opvpSetLineCap)(opvp_dc_t,opvp_linecap_t);
+ opvp_result_t (*opvpGetLineCap)(opvp_dc_t,opvp_linecap_t*);
+ opvp_result_t (*opvpSetLineJoin)(opvp_dc_t,opvp_linejoin_t);
+ opvp_result_t (*opvpGetLineJoin)(opvp_dc_t,opvp_linejoin_t*);
+ opvp_result_t (*opvpSetMiterLimit)(opvp_dc_t,opvp_fix_t);
+ opvp_result_t (*opvpGetMiterLimit)(opvp_dc_t,opvp_fix_t*);
+ opvp_result_t (*opvpSetPaintMode)(opvp_dc_t,opvp_paintmode_t);
+ opvp_result_t (*opvpGetPaintMode)(opvp_dc_t,opvp_paintmode_t*);
+ opvp_result_t (*opvpSetStrokeColor)(opvp_dc_t,const opvp_brush_t*);
+ opvp_result_t (*opvpSetFillColor)(opvp_dc_t,const opvp_brush_t*);
+ opvp_result_t (*opvpSetBgColor)(opvp_dc_t,const opvp_brush_t*);
+ opvp_result_t (*opvpNewPath)(opvp_dc_t);
+ opvp_result_t (*opvpEndPath)(opvp_dc_t);
+ opvp_result_t (*opvpStrokePath)(opvp_dc_t);
+ opvp_result_t (*opvpFillPath)(opvp_dc_t);
+ opvp_result_t (*opvpStrokeFillPath)(opvp_dc_t);
+ opvp_result_t (*opvpSetClipPath)(opvp_dc_t,opvp_cliprule_t);
+ opvp_result_t (*opvpResetClipPath)(opvp_dc_t);
+ opvp_result_t (*opvpSetCurrentPoint)(opvp_dc_t,opvp_fix_t,opvp_fix_t);
+ opvp_result_t (*opvpLinePath)(opvp_dc_t,opvp_pathmode_t,opvp_int_t,const opvp_point_t*);
+ opvp_result_t (*opvpPolygonPath)(opvp_dc_t,opvp_int_t,const opvp_int_t*,const opvp_point_t*);
+ opvp_result_t (*opvpRectanglePath)(opvp_dc_t,opvp_int_t,const opvp_rectangle_t*);
+ opvp_result_t (*opvpRoundRectanglePath)(opvp_dc_t,opvp_int_t,const opvp_roundrectangle_t*);
+ opvp_result_t (*opvpBezierPath)(opvp_dc_t,opvp_int_t,const opvp_point_t*);
+ opvp_result_t (*opvpArcPath)(opvp_dc_t,opvp_arcmode_t,opvp_arcdir_t,opvp_fix_t,opvp_fix_t,opvp_fix_t,opvp_fix_t,opvp_fix_t,opvp_fix_t,opvp_fix_t,opvp_fix_t);
+ opvp_result_t (*opvpDrawImage)(opvp_dc_t,opvp_int_t,opvp_int_t,opvp_int_t,opvp_imageformat_t,opvp_int_t, opvp_int_t ,const void*);
+ opvp_result_t (*opvpStartDrawImage)(opvp_dc_t,opvp_int_t,opvp_int_t,opvp_int_t,opvp_imageformat_t,opvp_int_t, opvp_int_t);
+ opvp_result_t (*opvpTransferDrawImage)(opvp_dc_t,opvp_int_t,const void*);
+ opvp_result_t (*opvpEndDrawImage)(opvp_dc_t);
+ opvp_result_t (*opvpStartScanline)(opvp_dc_t,opvp_int_t);
+ opvp_result_t (*opvpScanline)(opvp_dc_t,opvp_int_t,const opvp_int_t*);
+ opvp_result_t (*opvpEndScanline)(opvp_dc_t);
+ opvp_result_t (*opvpStartRaster)(opvp_dc_t,opvp_int_t);
+ opvp_result_t (*opvpTransferRasterData)(opvp_dc_t,opvp_int_t,const opvp_byte_t*);
+ opvp_result_t (*opvpSkipRaster)(opvp_dc_t,opvp_int_t);
+ opvp_result_t (*opvpEndRaster)(opvp_dc_t);
+ opvp_result_t (*opvpStartStream)(opvp_dc_t);
+ opvp_result_t (*opvpTransferStreamData)(opvp_dc_t,opvp_int_t,const void*);
+ opvp_result_t (*opvpEndStream)(opvp_dc_t);
+} opvp_api_procs_t;
+
+/* Function prototype */
+opvp_dc_t opvpOpenPrinter(
+ opvp_int_t outputFD,
+ const opvp_char_t *printerModel,
+ const opvp_int_t apiVersion[2],
+ opvp_api_procs_t **apiProcs);
+
+/* error no */
+extern opvp_int_t opvpErrorNo;
+
+#endif /* _OPVP_H_ */
diff --git a/filter/pdftoopvp/opvp/opvp_0_2_0.h b/filter/pdftoopvp/opvp/opvp_0_2_0.h
new file mode 100644
index 000000000..2b2c4aaf3
--- /dev/null
+++ b/filter/pdftoopvp/opvp/opvp_0_2_0.h
@@ -0,0 +1,298 @@
+/*
+
+Copyright (c) 2003-2004, AXE, Inc. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+/* opvp_common.h ver.1.00 rel.1.0 26 Nov 2004 */
+/* OpenPrinting Vector Printer Driver Glue Code */
+
+#ifndef _FSGPD_0_2_0_H
+#define _FSGPD_0_2_0_H
+
+#define _PDAPI_VERSION_MAJOR_ 0
+#define _PDAPI_VERSION_MINOR_ 2
+
+/* Return Values */
+#define OPVP_OK 0 /* error is -1 */
+
+/* Error Codes */
+#define OPVP_FATALERROR -101 /* unrecoverable error occurred within the */
+ /* library */
+#define OPVP_BADREQUEST -102 /* invalid function parameters */
+#define OPVP_BADCONTEXT -103 /* bad parameter precontext */
+#define OPVP_NOTSUPPORTED -104 /* printer or driver request not supported */
+#define OPVP_JOBCANCELED -105 /* job cancelled */
+#define OPVP_PARAMERROR -106 /* illegal parameter combination */
+
+/* Info params */
+#define OPVP_INFO_PREFIX "updf:"
+
+/* Fix */
+#define OPVP_FIX_FRACT_WIDTH 8
+#define OPVP_FIX_FRACT_DENOM (1<<OPVP_FIX_FRACT_WIDTH)
+#define OPVP_FIX_FLOOR_WIDTH (sizeof(int)*8-OPVP_FIX_FRACT_WIDTH)
+#if 0
+typedef struct {
+ unsigned int fract : OPVP_FIX_FRACT_WIDTH;
+ signed int floor : OPVP_FIX_FLOOR_WIDTH;
+} OPVP_Fix;
+#define OPVP_i2Fix(i,fix) (fix.fract=0,fix.floor=i)
+#define OPVP_Fix2f(fix,f) (f=(double)fix.floor\
+ +(double)(fix.fract)/OPVP_FIX_FRACT_DENOM)
+#define OPVP_f2Fix(f,fix) (fix.fract=(f-floor(f))*OPVP_FIX_FRACT_DENOM,\
+ fix.floor=floor(f))
+#else
+typedef int OPVP_Fix;
+#define OPVP_i2Fix(i,fix) (fix=(i)<<8)
+#define OPVP_f2Fix(f,fix) (fix=((int)floor(f)<<8)\
+ |((int)(((f)-floor(f))*OPVP_FIX_FRACT_DENOM)\
+ &0x000000ff))
+#endif
+
+/* Basic Types */
+typedef struct _OPVP_Point {
+ OPVP_Fix x;
+ OPVP_Fix y;
+} OPVP_Point;
+
+typedef struct _OPVP_Rectangle {
+ OPVP_Point p0; /* start point */
+ OPVP_Point p1; /* end point */
+} OPVP_Rectangle;
+
+typedef struct _OPVP_RoundRectangle {
+ OPVP_Point p0; /* start point */
+ OPVP_Point p1; /* end point */
+ OPVP_Fix xellipse;
+ OPVP_Fix yellipse;
+} OPVP_RoundRectangle;
+
+/* Image Formats */
+typedef enum _OPVP_ImageFormat {
+ OPVP_iformatRaw = 0,
+ OPVP_iformatRLE = 1,
+ OPVP_iformatJPEG = 2,
+ OPVP_iformatPNG = 3
+} OPVP_ImageFormat;
+
+/* Color Presentation */
+typedef enum _OPVP_ColorMapping {
+ OPVP_cmapDirect = 0,
+ OPVP_cmapIndexed = 1
+} OPVP_ColorMapping;
+
+typedef enum _OPVP_ColorSpace {
+ OPVP_cspaceBW = 0,
+ OPVP_cspaceDeviceGray = 1,
+ OPVP_cspaceDeviceCMY = 2,
+ OPVP_cspaceDeviceCMYK = 3,
+ OPVP_cspaceDeviceRGB = 4,
+ OPVP_cspaceStandardRGB = 5,
+ OPVP_cspaceStandardRGB64 = 6
+} OPVP_ColorSpace;
+
+/* Raster Operation modes */
+typedef enum _OPVP_ROP {
+ OPVP_ropPset = 0,
+ OPVP_ropPreset = 1,
+ OPVP_ropOr = 2,
+ OPVP_ropAnd = 3,
+ OPVP_ropXor = 4
+} OPVP_ROP;
+
+/* Fill, Paint, Clip */
+typedef enum _OPVP_FillMode {
+ OPVP_fillModeEvenOdd = 0,
+ OPVP_fillModeWinding = 1
+} OPVP_FillMode;
+
+typedef enum _OPVP_PaintMode {
+ OPVP_paintModeOpaque = 0,
+ OPVP_paintModeTransparent = 1
+} OPVP_PaintMode;
+
+typedef enum _OPVP_ClipRule {
+ OPVP_clipRuleEvenOdd = 0,
+ OPVP_clipRuleWinding = 1
+} OPVP_ClipRule;
+
+/* Line */
+typedef enum _OPVP_LineStyle {
+ OPVP_lineStyleSolid = 0,
+ OPVP_lineStyleDash = 1
+} OPVP_LineStyle;
+
+typedef enum _OPVP_LineCap {
+ OPVP_lineCapButt = 0,
+ OPVP_lineCapRound = 1,
+ OPVP_lineCapSquare = 2
+} OPVP_LineCap;
+
+typedef enum _OPVP_LineJoin {
+ OPVP_lineJoinMiter = 0,
+ OPVP_lineJoinRound = 1,
+ OPVP_lineJoinBevel = 2
+} OPVP_LineJoin;
+
+/* Brush */
+typedef enum _OPVP_BrushDataType {
+ OPVP_bdtypeNormal = 0
+} OPVP_BrushDataType;
+
+typedef struct _OPVP_BrushData {
+ OPVP_BrushDataType type;
+ int width;
+ int height;
+ int pitch;
+#if (_PDAPI_VERSION_MAJOR_ == 0 && _PDAPI_VERSION_MINOR_ < 2)
+ void *data; /* pointer to actual data */
+#else
+ char data[1];
+#endif
+} OPVP_BrushData;
+
+typedef struct _OPVP_Brush {
+ OPVP_ColorSpace colorSpace;
+ int color[4]; /* aRGB quadruplet */
+#if (_PDAPI_VERSION_MAJOR_ == 0 && _PDAPI_VERSION_MINOR_ < 2)
+ OPVP_BrushData *pbrush; /* pointer to brush data */
+ /* solid brush used, if null */
+ int xorg; /* brush origin */
+ int yorg; /* ignored for SetBgColor */
+#else
+ int xorg; /* brush origin */
+ int yorg; /* ignored for SetBgColor */
+ OPVP_BrushData *pbrush; /* pointer to brush data */
+ /* solid brush used, if null */
+#endif
+} OPVP_Brush;
+
+/* Misc. Flags */
+#define OPVP_Arc 0 /* circular arc */
+#define OPVP_Chord 1 /* arch */
+#define OPVP_Pie 2 /* pie section */
+#define OPVP_Clockwise 0 /* clockwise */
+#define OPVP_Counterclockwise 1 /* counter-clockwise */
+#define OPVP_PathClose 0 /* Close path when using LinePath */
+#define OPVP_PathOpen 1 /* Do not close path when using LinePath */
+
+/* CTM */
+typedef struct _OPVP_CTM {
+ float a;
+ float b;
+ float c;
+ float d;
+ float e;
+ float f;
+} OPVP_CTM;
+
+/* Vector Driver API Proc. Entries */
+typedef struct _OPVP_api_procs {
+ int (*OpenPrinter)(int,char *,int *,struct _OPVP_api_procs **);
+ int (*ClosePrinter)(int);
+ int (*StartJob)(int,char *);
+ int (*EndJob)(int);
+ int (*StartDoc)(int,char *);
+ int (*EndDoc)(int);
+ int (*StartPage)(int,char *);
+ int (*EndPage)(int);
+#if (_PDAPI_VERSION_MAJOR_ > 0 || _PDAPI_VERSION_MINOR_ >= 2)
+ int (*QueryDeviceCapability)(int,int,int,char *);
+ int (*QueryDeviceInfo)(int,int,int,char *);
+#endif
+ int (*ResetCTM)(int);
+ int (*SetCTM)(int,OPVP_CTM *);
+ int (*GetCTM)(int,OPVP_CTM *);
+ int (*InitGS)(int);
+ int (*SaveGS)(int);
+ int (*RestoreGS)(int);
+ int (*QueryColorSpace)(int,OPVP_ColorSpace *,int *);
+ int (*SetColorSpace)(int,OPVP_ColorSpace);
+ int (*GetColorSpace)(int,OPVP_ColorSpace *);
+ int (*QueryROP)(int,int *,int *);
+ int (*SetROP)(int,int);
+ int (*GetROP)(int,int *);
+ int (*SetFillMode)(int,OPVP_FillMode);
+ int (*GetFillMode)(int,OPVP_FillMode *);
+ int (*SetAlphaConstant)(int,float);
+ int (*GetAlphaConstant)(int,float *);
+ int (*SetLineWidth)(int,OPVP_Fix);
+ int (*GetLineWidth)(int,OPVP_Fix *);
+ int (*SetLineDash)(int,OPVP_Fix *,int);
+ int (*GetLineDash)(int,OPVP_Fix *,int *);
+ int (*SetLineDashOffset)(int,OPVP_Fix);
+ int (*GetLineDashOffset)(int,OPVP_Fix *);
+ int (*SetLineStyle)(int,OPVP_LineStyle);
+ int (*GetLineStyle)(int,OPVP_LineStyle *);
+ int (*SetLineCap)(int,OPVP_LineCap);
+ int (*GetLineCap)(int,OPVP_LineCap *);
+ int (*SetLineJoin)(int,OPVP_LineJoin);
+ int (*GetLineJoin)(int,OPVP_LineJoin *);
+ int (*SetMiterLimit)(int,OPVP_Fix);
+ int (*GetMiterLimit)(int,OPVP_Fix *);
+ int (*SetPaintMode)(int,OPVP_PaintMode);
+ int (*GetPaintMode)(int,OPVP_PaintMode *);
+ int (*SetStrokeColor)(int,OPVP_Brush *);
+ int (*SetFillColor)(int,OPVP_Brush *);
+ int (*SetBgColor)(int,OPVP_Brush *);
+ int (*NewPath)(int);
+ int (*EndPath)(int);
+ int (*StrokePath)(int);
+ int (*FillPath)(int);
+ int (*StrokeFillPath)(int);
+ int (*SetClipPath)(int,OPVP_ClipRule);
+#if (_PDAPI_VERSION_MAJOR_ > 0 || _PDAPI_VERSION_MINOR_ >= 2)
+ int (*ResetClipPath)(int);
+#endif
+ int (*SetCurrentPoint)(int,OPVP_Fix,OPVP_Fix);
+ int (*LinePath)(int,int,int,OPVP_Point *);
+ int (*PolygonPath)(int,int,int *,OPVP_Point *);
+ int (*RectanglePath)(int,int,OPVP_Rectangle *);
+ int (*RoundRectanglePath)(int,int,OPVP_RoundRectangle *);
+#if (_PDAPI_VERSION_MAJOR_ == 0 && _PDAPI_VERSION_MINOR_ < 2)
+ int (*BezierPath)(int,int *,OPVP_Point *);
+#else
+ int (*BezierPath)(int,int,OPVP_Point *);
+#endif
+ int (*ArcPath)(int,int,int,OPVP_Fix,OPVP_Fix,OPVP_Fix,OPVP_Fix,
+ OPVP_Fix,OPVP_Fix,OPVP_Fix,OPVP_Fix);
+ int (*DrawBitmapText)(int,int,int,int,void *);
+ int (*DrawImage)(int,int,int,int,
+ OPVP_ImageFormat,OPVP_Rectangle,int,void *);
+ int (*StartDrawImage)(int,int,int,int,
+ OPVP_ImageFormat,OPVP_Rectangle);
+ int (*TransferDrawImage)(int,int,void *);
+ int (*EndDrawImage)(int);
+ int (*StartScanline)(int,int);
+ int (*Scanline)(int,int,int *);
+ int (*EndScanline)(int);
+ int (*StartRaster)(int,int);
+ int (*TransferRasterData)(int,int,unsigned char *);
+ int (*SkipRaster)(int,int);
+ int (*EndRaster)(int);
+ int (*StartStream)(int);
+ int (*TransferStreamData)(int,int,void *);
+ int (*EndStream)(int);
+} OPVP_api_procs;
+
+#endif /* _OPVP_COMMON_H_ */
+
diff --git a/filter/pdftoopvp/opvp/opvp_common.h b/filter/pdftoopvp/opvp/opvp_common.h
new file mode 100644
index 000000000..5d65b3208
--- /dev/null
+++ b/filter/pdftoopvp/opvp/opvp_common.h
@@ -0,0 +1,54 @@
+/*
+
+Copyright (c) 2003-2004, AXE, Inc. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+/* OpenPrinting Vector Printer Driver Glue Code */
+
+#ifndef _OPVP_COMMON_H_
+#define _OPVP_COMMON_H_
+
+#include "opvp_0_2_0.h"
+#undef _PDAPI_VERSION_MAJOR_
+#undef _PDAPI_VERSION_MINOR_
+/* undefine conflicted macros */
+#undef OPVP_INFO_PREFIX
+#undef OPVP_OK
+#undef OPVP_FATALERROR
+#undef OPVP_BADREQUEST
+#undef OPVP_BADCONTEXT
+#undef OPVP_NOTSUPPORTED
+#undef OPVP_JOBCANCELED
+#undef OPVP_PARAMERROR
+/* define 0_2 error no as different macros */
+#define OPVP_FATALERROR_0_2 -101
+#define OPVP_BADREQUEST_0_2 -102
+#define OPVP_BADCONTEXT_0_2 -103
+#define OPVP_NOTSUPPORTED_0_2 -104
+#define OPVP_JOBCANCELED_0_2 -105
+#define OPVP_PARAMERROR_0_2 -106
+
+#include "opvp.h"
+#define OPVP_INFO_PREFIX ""
+
+#endif /* _OPVP_COMMON_H_ */
+
diff --git a/filter/pdftoopvp/pdftoopvp.cxx b/filter/pdftoopvp/pdftoopvp.cxx
new file mode 100644
index 000000000..024941ab0
--- /dev/null
+++ b/filter/pdftoopvp/pdftoopvp.cxx
@@ -0,0 +1,791 @@
+//========================================================================
+//
+// pdftoopvp.cc
+//
+// Copyright 2005 AXE,Inc.
+//
+// 2007,2008,2009 Modified by BBR Inc.
+//========================================================================
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <math.h>
+#ifdef HAVE_CPP_POPPLER_VERSION_H
+#include "cpp/poppler-version.h"
+#endif
+#include "goo/GooString.h"
+#define GSTRING_H // for old GooString.h
+#include "goo/gmem.h"
+#include "GlobalParams.h"
+#include "Object.h"
+#include "PDFDoc.h"
+#include "splash/SplashBitmap.h"
+#include "OPRS.h"
+#include "OPVPOutputDev.h"
+#include "Gfx.h"
+#include <cups/cups.h>
+#include <cups/ppd.h>
+#include "OPVPError.h"
+
+#define MMPERINCH (25.4)
+
+static int resolution = 300;
+static int hResolution = 0;
+static int vResolution = 0;
+static GBool mono = gFalse;
+static GBool reverse = gFalse;
+static GBool gray = gFalse;
+static char enableFreeTypeStr[16] = "";
+static GBool quiet = gFalse;
+static char outputOrderStr[256] = "";
+static GBool oldLipsDriver = gFalse;
+static GBool HPDriver = gFalse;
+static GBool NECDriver = gFalse;
+static GBool clipPathNotSaved = gFalse;
+static GBool noShearImage = gFalse;
+static GBool noLineStyle = gFalse;
+static GBool noImageMask = gFalse;
+static GBool noClipPath = gFalse;
+static GBool ignoreMiterLimit = gFalse;
+static GBool noMiterLimit = gFalse;
+static char printerDriver[1024] = "";
+static char printerModel[1024] = "";
+static char jobInfo[4096] = "";
+static char docInfo[1024] = "";
+static char pageInfo[1024] = "";
+static GBool noBitmapChar = gFalse;
+static char bitmapCharThreshold[20] = "2000";
+static char maxClipPathLength[20] = "2000";
+static char maxFillPathLength[20] = "4000";
+static int pageWidth = -1;
+static int pageHeight = -1;
+
+static int outOnePage(PDFDoc *doc, OPVPOutputDev *opvpOut, int pg)
+{
+ char buf[1024];
+ char *p;
+ double pw = doc->getPageMediaWidth(pg);
+ double ph = doc->getPageMediaHeight(pg);
+ int paperWidth;
+ int paperHeight;
+
+ if (pw != pageWidth || ph != pageHeight) {
+ if (pageInfo[0] != '\0') {
+ snprintf(buf,sizeof(buf),"%s;MediaSize=%dx%dmm",pageInfo,
+ (int)(pw*MMPERINCH/72),
+ (int)(ph*MMPERINCH/72));
+ } else {
+ snprintf(buf,sizeof(buf),"MediaSize=%dx%dmm",
+ (int)(pw*MMPERINCH/72),
+ (int)(ph*MMPERINCH/72));
+ }
+ p = buf;
+ } else {
+ pw = pageWidth;
+ ph = pageHeight;
+ p = pageInfo;
+ }
+
+ paperWidth = (int)(pw*hResolution/72+0.5);
+ paperHeight = (int)(ph*vResolution/72+0.5);
+ if (opvpOut->OPVPStartPage(p,paperWidth,paperHeight) < 0) {
+ opvpError(-1,"Start Page failed");
+ return 2;
+ }
+ opvpOut->setScale(1.0,1.0,0,0,0,0,paperHeight);
+ doc->displayPage(opvpOut, pg, resolution, resolution,
+ 0, gTrue, gTrue, gFalse);
+ if (opvpOut->outSlice() < 0) {
+ opvpError(-1,"OutSlice failed");
+ return 2;
+ }
+ if (opvpOut->OPVPEndPage() < 0) {
+ opvpError(-1,"End Page failed");
+ return 2;
+ }
+ return 0;
+}
+
+#define MAX_OPVP_OPTIONS 20
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 23
+void CDECL myErrorFun(void *data, ErrorCategory category,
+ Goffset pos, char *msg)
+#else
+void CDECL myErrorFun(void *data, ErrorCategory category,
+ int pos, char *msg)
+#endif
+{
+ if (pos >= 0) {
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 23
+ fprintf(stderr, "ERROR (%lld): ", pos);
+#else
+ fprintf(stderr, "ERROR (%d): ", pos);
+#endif
+ } else {
+ fprintf(stderr, "ERROR: ");
+ }
+ fprintf(stderr, "%s\n",msg);
+ fflush(stderr);
+}
+#else
+void CDECL myErrorFun(int pos, char *msg, va_list args)
+{
+ if (pos >= 0) {
+ fprintf(stderr, "ERROR (%d): ", pos);
+ } else {
+ fprintf(stderr, "ERROR: ");
+ }
+ vfprintf(stderr, msg, args);
+ fprintf(stderr, "\n");
+ fflush(stderr);
+}
+#endif
+
+static GBool getColorProfilePath(ppd_file_t *ppd, GooString *path)
+{
+ // get color profile path
+ const char *colorModel;
+ const char *cupsICCQualifier2;
+ const char *cupsICCQualifier2Choice;
+ const char *cupsICCQualifier3;
+ const char *cupsICCQualifier3Choice;
+ ppd_attr_t *attr;
+ ppd_choice_t *choice;
+ const char *datadir;
+
+ if ((attr = ppdFindAttr(ppd,"ColorModel",NULL)) != NULL) {
+ colorModel = attr->value;
+ } else {
+ colorModel = NULL;
+ }
+ if ((attr = ppdFindAttr(ppd,"cupsICCQualifier2",NULL)) != NULL) {
+ cupsICCQualifier2 = attr->value;
+ } else {
+ cupsICCQualifier2 = "MediaType";
+ }
+ if ((choice = ppdFindMarkedChoice(ppd,cupsICCQualifier2)) != NULL) {
+ cupsICCQualifier2Choice = choice->choice;
+ } else {
+ cupsICCQualifier2Choice = NULL;
+ }
+ if ((attr = ppdFindAttr(ppd,"cupsICCQualifier3",NULL)) != NULL) {
+ cupsICCQualifier3 = attr->value;
+ } else {
+ cupsICCQualifier3 = "Resolution";
+ }
+ if ((choice = ppdFindMarkedChoice(ppd,cupsICCQualifier3)) != NULL) {
+ cupsICCQualifier3Choice = choice->choice;
+ } else {
+ cupsICCQualifier3Choice = NULL;
+ }
+
+ for (attr = ppdFindAttr(ppd,"cupsICCProfile",NULL);attr != NULL;
+ attr = ppdFindNextAttr(ppd,"cupsICCProfile",NULL)) {
+ // check color model
+ char buf[PPD_MAX_NAME];
+ char *p, *r;
+
+ strncpy(buf,attr->spec,sizeof(buf));
+ if ((p = strchr(buf,'.')) != NULL) {
+ *p = '\0';
+ }
+ if (colorModel != NULL && buf[0] != '\0'
+ && strcasecmp(buf,colorModel) != 0) continue;
+ if (p == NULL) {
+ break;
+ } else {
+ p++;
+ if ((r = strchr(p,'.')) != 0) {
+ *r = '\0';
+ }
+ }
+ if (cupsICCQualifier2Choice != NULL && p[0] != '\0'
+ && strcasecmp(p,cupsICCQualifier2Choice) != 0) continue;
+ if (r == NULL) {
+ break;
+ } else {
+ r++;
+ if ((p = strchr(r,'.')) != 0) {
+ *p = '\0';
+ }
+ }
+ if (cupsICCQualifier3Choice == NULL || r[0] == '\0'
+ || strcasecmp(r,cupsICCQualifier3Choice) == 0) break;
+ }
+ if (attr != NULL) {
+ // matched
+ path->clear();
+ if (attr->value[0] != '/') {
+ if ((datadir = getenv("CUPS_DATADIR")) == NULL)
+ datadir = CUPS_DATADIR;
+ path->append(datadir);
+ path->append("/profiles/");
+ }
+ path->append(attr->value);
+ return gTrue;
+ }
+ return gFalse;
+}
+
+int main(int argc, char *argv[]) {
+/* mtrace(); */
+ int exitCode;
+{
+ PDFDoc *doc;
+ SplashColor paperColor;
+ OPVPOutputDev *opvpOut;
+ GBool ok = gTrue;
+ int pg;
+ const char *optionKeys[MAX_OPVP_OPTIONS];
+ const char *optionVals[MAX_OPVP_OPTIONS];
+ int nOptions = 0;
+ int numPages;
+ int i;
+ GooString fileName;
+ GooString colorProfilePath("opvp.icc");
+
+ exitCode = 99;
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+ setErrorCallback(::myErrorFun,NULL);
+#else
+ setErrorFunction(::myErrorFun);
+#endif
+
+ // parse args
+ int num_options;
+ cups_option_t *options;
+ const char *val;
+ char *ppdFileName;
+ ppd_file_t *ppd = 0;
+ ppd_attr_t *attr;
+ GooString jobInfoStr;
+ GooString docInfoStr;
+ GooString pageInfoStr;
+ GBool colorProfile = gFalse;
+
+
+ if (argc < 6 || argc > 7) {
+ opvpError(-1,"ERROR: %s job-id user title copies options [file]",
+ argv[0]);
+ return (1);
+ }
+
+ if ((ppdFileName = getenv("PPD")) != 0) {
+ if ((ppd = ppdOpenFile(ppdFileName)) != 0) {
+ /* get attributes from PPD File */
+ if ((attr = ppdFindAttr(ppd,"opvpJobInfo",0)) != 0) {
+ jobInfoStr.append(attr->value);
+ }
+ if ((attr = ppdFindAttr(ppd,"opvpDocInfo",0)) != 0) {
+ docInfoStr.append(attr->value);
+ }
+ if ((attr = ppdFindAttr(ppd,"opvpPageInfo",0)) != 0) {
+ pageInfoStr.append(attr->value);
+ }
+ if ((attr = ppdFindAttr(ppd,"pdftoopvpOldLipsDriver",0)) != 0) {
+ if (strcasecmp(attr->value,"true") == 0) {
+ oldLipsDriver = gTrue;
+ } else {
+ oldLipsDriver = gFalse;
+ }
+ }
+ if ((attr = ppdFindAttr(ppd,"pdftoopvpHPDriver",0)) != 0) {
+ if (strcasecmp(attr->value,"true") == 0) {
+ HPDriver = gTrue;
+ } else {
+ HPDriver = gFalse;
+ }
+ }
+ if ((attr = ppdFindAttr(ppd,"pdftoopvpNECDriver",0)) != 0) {
+ if (strcasecmp(attr->value,"true") == 0) {
+ NECDriver = gTrue;
+ } else {
+ NECDriver = gFalse;
+ }
+ }
+ if ((attr = ppdFindAttr(ppd,"pdftoopvpClipPathNotSaved",0)) != 0) {
+ if (strcasecmp(attr->value,"true") == 0) {
+ clipPathNotSaved = gTrue;
+ } else {
+ clipPathNotSaved = gFalse;
+ }
+ }
+ if ((attr = ppdFindAttr(ppd,"pdftoopvpShearImage",0)) != 0) {
+ if (strcasecmp(attr->value,"true") == 0) {
+ noShearImage = gFalse;
+ } else {
+ noShearImage = gTrue;
+ }
+ }
+ if ((attr = ppdFindAttr(ppd,"pdftoopvpLineStyle",0)) != 0) {
+ if (strcasecmp(attr->value,"true") == 0) {
+ noLineStyle = gFalse;
+ } else {
+ noLineStyle = gTrue;
+ }
+ }
+ if ((attr = ppdFindAttr(ppd,"pdftoopvpImageMask",0)) != 0) {
+ if (strcasecmp(attr->value,"true") == 0) {
+ noImageMask = gFalse;
+ } else {
+ noImageMask = gTrue;
+ }
+ }
+ if ((attr = ppdFindAttr(ppd,"pdftoopvpClipPath",0)) != 0) {
+ if (strcasecmp(attr->value,"true") == 0) {
+ noClipPath = gFalse;
+ } else {
+ noClipPath = gTrue;
+ }
+ }
+ if ((attr = ppdFindAttr(ppd,"pdftoopvpMiterLimit",0)) != 0) {
+ if (strcasecmp(attr->value,"true") == 0) {
+ noMiterLimit = gFalse;
+ } else {
+ noMiterLimit = gTrue;
+ }
+ }
+ if ((attr = ppdFindAttr(ppd,"pdftoopvpIgnoreMiterLimit",0)) != 0) {
+ if (strcasecmp(attr->value,"true") == 0) {
+ ignoreMiterLimit = gTrue;
+ } else {
+ ignoreMiterLimit = gFalse;
+ }
+ }
+ if ((attr = ppdFindAttr(ppd,"pdftoopvpBitmapCharThreshold",0)) != 0) {
+ strncpy(bitmapCharThreshold,attr->value,
+ sizeof(bitmapCharThreshold)-1);
+ }
+ if ((attr = ppdFindAttr(ppd,"pdftoopvpMaxClipPathLength",0)) != 0) {
+ strncpy(maxClipPathLength,attr->value,
+ sizeof(maxClipPathLength)-1);
+ }
+ if ((attr = ppdFindAttr(ppd,"pdftoopvpMaxFillPathLength",0)) != 0) {
+ strncpy(maxFillPathLength,attr->value,
+ sizeof(maxFillPathLength)-1);
+ }
+ if ((attr = ppdFindAttr(ppd,"pdftoopvpBitmapChar",0)) != 0) {
+ if (strcasecmp(attr->value,"true") == 0) {
+ noBitmapChar = gFalse;
+ } else {
+ noBitmapChar = gTrue;
+ }
+ }
+ if ((attr = ppdFindAttr(ppd,"opvpDriver",0)) != 0) {
+ strncpy(printerDriver,attr->value,sizeof(printerDriver)-1);
+ printerDriver[sizeof(printerDriver)-1] = '\0';
+ }
+ if ((attr = ppdFindAttr(ppd,"opvpModel",0)) != 0) {
+ strncpy(printerModel,attr->value,sizeof(printerModel)-1);
+ printerModel[sizeof(printerModel)-1] = '\0';
+ }
+ ppdMarkDefaults(ppd);
+ }
+ }
+ /* get attributes and options from command line option */
+ num_options = cupsParseOptions(argv[5],0,&options);
+ cupsMarkOptions(ppd,num_options,options);
+
+ for (i = 0;i < num_options;i++) {
+ if (strcasecmp(options[i].name,"Resolution") == 0) {
+ resolution = atoi(options[i].value);
+ } else if (strcasecmp(options[i].name,"pdftoopvpOldLipsDriver") == 0) {
+ oldLipsDriver = gTrue;
+ } else if (strcasecmp(options[i].name,"pdftoopvpHPDriver") == 0) {
+ HPDriver = gTrue;
+ } else if (strcasecmp(options[i].name,"pdftoopvpNECDriver") == 0) {
+ NECDriver = gTrue;
+ } else if (strcasecmp(options[i].name,"pdftoopvpClipPathNotSaved") == 0) {
+ clipPathNotSaved = gTrue;
+ } else if (strcasecmp(options[i].name,"pdftoopvpShearImage") == 0) {
+ if (strcasecmp(options[i].value,"false") == 0) {
+ noShearImage = gTrue;
+ }
+ } else if (strcasecmp(options[i].name,"pdftoopvpLineStyle") == 0) {
+ if (strcasecmp(options[i].value,"false") == 0) {
+ noLineStyle = gTrue;
+ }
+ } else if (strcasecmp(options[i].name,"pdftoopvpImageMask") == 0) {
+ if (strcasecmp(options[i].value,"false") == 0) {
+ noImageMask = gTrue;
+ }
+ } else if (strcasecmp(options[i].name,"pdftoopvpClipPath") == 0) {
+ if (strcasecmp(options[i].value,"false") == 0) {
+ noClipPath = gTrue;
+ }
+ } else if (strcasecmp(options[i].name,"pdftoopvpMiterLimit") == 0) {
+ if (strcasecmp(options[i].value,"false") == 0) {
+ noMiterLimit = gTrue;
+ }
+ } else if (strcasecmp(options[i].name,"pdftoopvpIgnoreMiterLimit") == 0) {
+ if (strcasecmp(options[i].value,"true") == 0) {
+ ignoreMiterLimit = gTrue;
+ }
+ }
+ else if (strcasecmp(options[i].name,"pdftoopvpBitmapChar") == 0) {
+ if (strcasecmp(options[i].value,"false") == 0) {
+ noBitmapChar = gTrue;
+ }
+ } else if (strcasecmp(options[i].name,"pdftoopvpBitmapCharThreshold") == 0) {
+ strncpy(bitmapCharThreshold,options[i].value,
+ sizeof(bitmapCharThreshold)-1);
+ } else if (strcasecmp(options[i].name,"pdftoopvpMaxClipPathLength") == 0) {
+ strncpy(maxClipPathLength,options[i].value,
+ sizeof(maxClipPathLength)-1);
+ } else if (strcasecmp(options[i].name,"pdftoopvpMaxFillPathLength") == 0) {
+ strncpy(maxFillPathLength,options[i].value,
+ sizeof(maxFillPathLength)-1);
+ } else if (strcasecmp(options[i].name,"opvpDriver") == 0) {
+ strncpy(printerDriver,options[i].value,sizeof(printerDriver)-1);
+ printerDriver[sizeof(printerDriver)-1] = '\0';
+ } else if (strcasecmp(options[i].name,"opvpModel") == 0) {
+ strncpy(printerModel,options[i].value,sizeof(printerModel)-1);
+ printerModel[sizeof(printerModel)-1] = '\0';
+ } else if (strcasecmp(options[i].name,"opvpJobInfo") == 0) {
+ /* do nothing here */;
+ } else if (strcasecmp(options[i].name,"opvpDocInfo") == 0) {
+ /* do nothing here */;
+ } else if (strcasecmp(options[i].name,"opvpPageInfo") == 0) {
+ /* do nothing here */;
+ }
+ }
+ if (ppd != 0) {
+ int section;
+ ppd_choice_t **choices;
+ ppd_size_t *pagesize;
+
+ if ((pagesize = ppdPageSize(ppd,0)) != 0) {
+ pageWidth = (int)pagesize->width;
+ pageHeight = (int)pagesize->length;
+ }
+ for (section = (int)PPD_ORDER_ANY;
+ section <= (int)PPD_ORDER_PROLOG;section++) {
+ int n;
+
+ n = ppdCollect(ppd,(ppd_section_t)section,&choices);
+ for (i = 0;i < n;i++) {
+
+ if (strcasecmp(((ppd_option_t *)(choices[i]->option))->keyword,
+ "Resolution") == 0) {
+ resolution = atoi(choices[i]->choice);
+ }
+ }
+ if (choices != 0) free(choices);
+ }
+
+ strncpy(jobInfo,jobInfoStr.getCString(),sizeof(jobInfo)-1);
+ jobInfo[sizeof(jobInfo)-1] = '\0';
+ strncpy(docInfo,docInfoStr.getCString(),sizeof(docInfo)-1);
+ docInfo[sizeof(docInfo)-1] = '\0';
+ strncpy(pageInfo,pageInfoStr.getCString(),sizeof(pageInfo)-1);
+ pageInfo[sizeof(pageInfo)-1] = '\0';
+
+ colorProfile = getColorProfilePath(ppd,&colorProfilePath);
+
+ ppdClose(ppd);
+ }
+ if ((val = cupsGetOption("opvpJobInfo",num_options, options)) != 0) {
+ /* override ppd value */
+ strncpy(jobInfo,val,sizeof(jobInfo)-1);
+ jobInfo[sizeof(jobInfo)-1] = '\0';
+ }
+ if ((val = cupsGetOption("opvpDocInfo",num_options, options)) != 0) {
+ /* override ppd value */
+ strncpy(docInfo,val,sizeof(docInfo)-1);
+ docInfo[sizeof(docInfo)-1] = '\0';
+ }
+ if ((val = cupsGetOption("opvpPageInfo",num_options, options)) != 0) {
+ /* override ppd value */
+ strncpy(pageInfo,val,sizeof(pageInfo)-1);
+ pageInfo[sizeof(pageInfo)-1] = '\0';
+ }
+
+ cupsFreeOptions(num_options,options);
+#if 0
+ /* for debug parameters */
+ fprintf(stderr,"WARNING:resolution=%d\n",resolution);
+ fprintf(stderr,"WARNING:sliceHeight=%d\n",sliceHeight);
+ fprintf(stderr,"WARNING:oldLipsDriver=%d\n",oldLipsDriver);
+ fprintf(stderr,"WARNING:HPDriver=%d\n",HPDriver);
+ fprintf(stderr,"WARNING:NECDriver=%d\n",NECDriver);
+ fprintf(stderr,"WARNING:clipPathNotSaved=%d\n",clipPathNotSaved);
+ fprintf(stderr,"WARNING:noShearImage=%d\n",noShearImage);
+ fprintf(stderr,"WARNING:noLineStyle=%d\n",noLineStyle);
+ fprintf(stderr,"WARNING:noClipPath=%d\n",noClipPath);
+ fprintf(stderr,"WARNING:noMiterLimit=%d\n",noMiterLimit);
+ fprintf(stderr,"WARNING:printerDriver=%s\n",printerDriver);
+ fprintf(stderr,"WARNING:printerModel=%s\n",printerModel);
+ fprintf(stderr,"WARNING:jobInfo=%s\n",jobInfo);
+ fprintf(stderr,"WARNING:docInfo=%s\n",docInfo);
+ fprintf(stderr,"WARNING:pageInfo=%s\n",pageInfo);
+ fprintf(stderr,"WARNING:noBitmapChar=%d\n",noBitmapChar);
+ fprintf(stderr,"WARNING:bitmapCharThreshold=%s\n",bitmapCharThreshold);
+ fprintf(stderr,"WARNING:maxClipPathLength=%s\n",maxClipPathLength);
+ fprintf(stderr,"WARNING:maxFillPathLength=%s\n",maxFillPathLength);
+exit(0);
+#endif
+
+ if (oldLipsDriver) {
+ optionKeys[nOptions] = "OPVP_OLDLIPSDRIVER";
+ optionVals[nOptions] = "1";
+ nOptions++;
+ clipPathNotSaved = gTrue;
+ noShearImage = gTrue;
+ }
+ if (HPDriver) {
+ noClipPath = gTrue;
+ noLineStyle = gTrue;
+ noShearImage = gTrue;
+ }
+ if (NECDriver) {
+ noMiterLimit = gTrue;
+ strcpy(maxClipPathLength,"6");
+ noShearImage = gTrue;
+ }
+ if (clipPathNotSaved) {
+ optionKeys[nOptions] = "OPVP_CLIPPATHNOTSAVED";
+ optionVals[nOptions] = "1";
+ nOptions++;
+ }
+ if (noShearImage) {
+ optionKeys[nOptions] = "OPVP_NOSHEARIMAGE";
+ optionVals[nOptions] = "1";
+ nOptions++;
+ }
+ if (noLineStyle) {
+ optionKeys[nOptions] = "OPVP_NOLINESTYLE";
+ optionVals[nOptions] = "1";
+ nOptions++;
+ }
+ if (noImageMask) {
+ optionKeys[nOptions] = "OPVP_NOIMAGEMASK";
+ optionVals[nOptions] = "1";
+ nOptions++;
+ }
+ if (noClipPath) {
+ optionKeys[nOptions] = "OPVP_NOCLIPPATH";
+ optionVals[nOptions] = "1";
+ nOptions++;
+ }
+ if (noMiterLimit) {
+ optionKeys[nOptions] = "OPVP_NOMITERLIMIT";
+ optionVals[nOptions] = "1";
+ nOptions++;
+ }
+ if (noBitmapChar) {
+ optionKeys[nOptions] = "OPVP_NOBITMAPCHAR";
+ optionVals[nOptions] = "1";
+ nOptions++;
+ }
+ if (ignoreMiterLimit) {
+ optionKeys[nOptions] = "OPVP_IGNOREMITERLIMIT";
+ optionVals[nOptions] = "1";
+ nOptions++;
+ }
+ optionKeys[nOptions] = "OPVP_BITMAPCHARTHRESHOLD";
+ optionVals[nOptions] = bitmapCharThreshold;
+ nOptions++;
+ optionKeys[nOptions] = "OPVP_MAXCLIPPATHLENGTH";
+ optionVals[nOptions] = maxClipPathLength;
+ nOptions++;
+ optionKeys[nOptions] = "OPVP_MAXFILLPATHLENGTH";
+ optionVals[nOptions] = maxFillPathLength;
+ nOptions++;
+ if (hResolution == 0) hResolution = resolution;
+ if (hResolution == 0) hResolution = resolution;
+ if (vResolution == 0) vResolution = resolution;
+ if (strcasecmp(outputOrderStr,"reverse") == 0) {
+ reverse = gTrue;
+ }
+
+ if (argc > 6) {
+ fileName.append(argv[6]);
+ } else {
+ fileName.append("-");
+ }
+
+ // read config file
+ globalParams = new GlobalParams();
+ if (enableFreeTypeStr[0]) {
+ if (!globalParams->setEnableFreeType(enableFreeTypeStr)) {
+ opvpError(-1,"Bad '-freetype' value on command line");
+ ok = gFalse;
+ }
+ }
+#if POPPLER_VERSION_MAJOR == 0 && POPPLER_VERSION_MINOR <= 30
+ globalParams->setAntialias("no");
+#endif
+ if (quiet) {
+ globalParams->setErrQuiet(quiet);
+ }
+ if (!ok) {
+ exitCode = 2;
+ goto err0;
+ }
+
+ if (fileName.cmp("-") == 0) {
+ /* stdin */
+ char *s;
+ GooString name;
+ int fd;
+ char buf[4096];
+ int n;
+
+ /* create a tmp file */
+ if ((s = getenv("TMPDIR")) != 0) {
+ name.append(s);
+ } else {
+ name.append("/tmp");
+ }
+ name.append("/XXXXXX");
+ fd = mkstemp(name.getCString());
+ if (fd < 0) {
+ opvpError(-1,"Can't create temporary file");
+ exitCode = 2;
+ goto err0;
+ }
+
+ /* check JCL */
+ while (fgets(buf,sizeof(buf)-1,stdin) != NULL
+ && strncmp(buf,"%PDF",4) != 0) {
+ if (strncmp(buf,"pdftoopvp jobInfo:",18) == 0) {
+ /* JCL jobInfo exists, override jobInfo */
+ strncpy(jobInfo,buf+18,sizeof(jobInfo)-1);
+ for (i = sizeof(jobInfo)-2;i >= 0
+ && (jobInfo[i] == 0 || jobInfo[i] == '\n' || jobInfo[i] == ';')
+ ;i--);
+ jobInfo[i+1] = 0;
+ }
+ }
+ if (strncmp(buf,"%PDF",4) != 0) {
+ opvpError(-1,"Can't find PDF header");
+ exitCode = 2;
+ goto err0;
+ }
+ /* copy PDF header */
+ n = strlen(buf);
+ if (write(fd,buf,n) != n) {
+ opvpError(-1,"Can't copy stdin to temporary file");
+ close(fd);
+ exitCode = 2;
+ goto err0;
+ }
+ /* copy rest stdin to the tmp file */
+ while ((n = fread(buf,1,sizeof(buf),stdin)) > 0) {
+ if (write(fd,buf,n) != n) {
+ opvpError(-1,"Can't copy stdin to temporary file");
+ close(fd);
+ exitCode = 2;
+ goto err0;
+ }
+ }
+ close(fd);
+ doc = new PDFDoc(&name);
+ /* remove name */
+ unlink(name.getCString());
+ } else {
+ /* no jcl check */
+ doc = new PDFDoc(fileName.copy());
+ }
+ if (!doc->isOk()) {
+ opvpError(-1," Parsing PDF failed: error code %d",
+ doc->getErrorCode());
+ exitCode = 2;
+ goto err05;
+ }
+
+ if (doc->isEncrypted() && !doc->okToPrint()) {
+ opvpError(-1,"Print Permission Denied");
+ exitCode = 2;
+ goto err05;
+ }
+
+ /* paperColor is white */
+ paperColor[0] = 255;
+ paperColor[1] = 255;
+ paperColor[2] = 255;
+#ifdef USE_CMS
+ /* set color profile file name */
+ GfxColorSpace::setDisplayProfileName(&colorProfilePath);
+#endif
+ opvpOut = new OPVPOutputDev();
+ if (opvpOut->init(mono ? splashModeMono1 :
+ gray ? splashModeMono8 :
+ splashModeRGB8,
+ colorProfile,
+ gFalse, paperColor,
+ printerDriver,1,printerModel,
+ nOptions,optionKeys,optionVals) < 0) {
+ opvpError(-1,"OPVPOutputDev Initialize fail");
+ exitCode = 2;
+ goto err1;
+ }
+
+ opvpOut->startDoc(doc->getXRef());
+
+#if 0
+fprintf(stderr,"JobInfo=%s\n",jobInfo);
+#endif
+ if (opvpOut->OPVPStartJob(jobInfo) < 0) {
+ opvpError(-1,"Start job failed");
+ exitCode = 2;
+ goto err1;
+ }
+ if (opvpOut->OPVPStartDoc(docInfo) < 0) {
+ opvpError(-1,"Start Document failed");
+ exitCode = 2;
+ goto err2;
+ }
+ numPages = doc->getNumPages();
+ for (pg = 1; pg <= numPages; ++pg) {
+ if ((exitCode = outOnePage(doc,opvpOut,pg)) != 0) break;
+ }
+ if (opvpOut->OPVPEndDoc() < 0) {
+ opvpError(-1,"End Document failed");
+ exitCode = 2;
+ }
+err2:
+ if (opvpOut->OPVPEndJob() < 0) {
+ opvpError(-1,"End job failed");
+ exitCode = 2;
+ }
+
+ // clean up
+ err1:
+ delete opvpOut;
+ err05:
+ delete doc;
+ err0:
+ delete globalParams;
+
+ // check for memory leaks
+ Object::memCheck(stderr);
+ gMemReport(stderr);
+
+}
+/* muntrace(); */
+ return exitCode;
+}
+
+/* for memory debug */
+/* For compatibility with g++ >= 4.7 compilers _GLIBCXX_THROW
+ * should be used as a guard, otherwise use traditional definition */
+#ifndef _GLIBCXX_THROW
+#define _GLIBCXX_THROW throw
+#endif
+
+void * operator new(size_t size) _GLIBCXX_THROW (std::bad_alloc)
+{
+ void *p = malloc(size);
+ return p;
+}
+
+void operator delete(void *p) throw ()
+{
+ free(p);
+}
diff --git a/filter/pdftopdf/intervalset.cc b/filter/pdftopdf/intervalset.cc
new file mode 100644
index 000000000..2967d597a
--- /dev/null
+++ b/filter/pdftopdf/intervalset.cc
@@ -0,0 +1,121 @@
+#include "intervalset.h"
+#include <stdio.h>
+#include <assert.h>
+#include <limits>
+#include <algorithm>
+
+const IntervalSet::key_t IntervalSet::npos=std::numeric_limits<IntervalSet::key_t>::max();
+
+void IntervalSet::clear() // {{{
+{
+ data.clear();
+}
+// }}}
+
+void IntervalSet::add(key_t start,key_t end) // {{{
+{
+ if (start<end) {
+ data.push_back(std::make_pair(start,end));
+ }
+}
+// }}}
+
+void IntervalSet::finish() // {{{
+{
+ data_t::iterator it=data.begin(),end=data.end(),pos=it;
+ if (it==end) {
+ return;
+ }
+
+ std::sort(it,end);
+
+ while (1) {
+ ++it;
+ if (it==end) {
+ ++pos;
+ break;
+ }
+ if (pos->second>=it->first) {
+ pos->second=it->second;
+ } else {
+ ++pos;
+ if (pos!=it) {
+ *pos=*it;
+ }
+ }
+ }
+
+ data.erase(pos,data.end());
+}
+// }}}
+
+bool IntervalSet::contains(key_t val) const // {{{
+{
+ data_t::const_iterator it=std::upper_bound(data.begin(),data.end(),std::make_pair(val,npos));
+ if (it==data.begin()) {
+ return false;
+ }
+ --it;
+ return (val<it->second);
+}
+// }}}
+
+IntervalSet::key_t IntervalSet::next(key_t val) const // {{{
+{
+ val++;
+ data_t::const_iterator it=std::upper_bound(data.begin(),data.end(),std::make_pair(val,npos));
+ if (it==data.begin()) {
+ if (it==data.end()) { // empty
+ return npos;
+ }
+ return it->first;
+ }
+ --it;
+ if (val<it->second) {
+ return val;
+ }
+ ++it;
+ if (it==data.end()) {
+ return npos;
+ }
+ return it->first;
+}
+// }}}
+
+bool IntervalSet::intersect(const value_t &a,const value_t &b) const // {{{
+{
+ return ((a.first>=b.first) && (a.first<b.second)) ||
+ ((b.first>=a.first) && (b.first<a.second));
+}
+// }}}
+
+void IntervalSet::unite(value_t &aret,const value_t &b) const // {{{
+{
+ assert(intersect(aret,b));
+ if (b.first<aret.first) {
+ aret.first=b.first;
+ }
+ if (b.second>aret.second) {
+ aret.second=b.second;
+ }
+}
+// }}}
+
+void IntervalSet::dump() const // {{{
+{
+ int len=data.size();
+ if (len==0) {
+ fprintf(stderr,"(empty)\n");
+ return;
+ }
+ len--;
+ for (int iA=0;iA<len;iA++) {
+ fprintf(stderr,"[%d,%d),",data[iA].first,data[iA].second);
+ }
+ if (data[len].second==npos) {
+ fprintf(stderr,"[%d,inf)\n",data[len].first);
+ } else {
+ fprintf(stderr,"[%d,%d)\n",data[len].first,data[len].second);
+ }
+}
+// }}}
diff --git a/filter/pdftopdf/intervalset.h b/filter/pdftopdf/intervalset.h
new file mode 100644
index 000000000..67b486fff
--- /dev/null
+++ b/filter/pdftopdf/intervalset.h
@@ -0,0 +1,34 @@
+#ifndef INTERVALSET_H_
+#define INTERVALSET_H_
+
+#include <stddef.h>
+#include <vector>
+
+class IntervalSet {
+ typedef int key_t; // TODO?! template <typename T>
+ typedef std::pair<key_t,key_t> value_t;
+ typedef std::vector<value_t> data_t;
+ public:
+ static const key_t npos;
+
+ void clear();
+ // [start;end) !
+ void add(key_t start,key_t end=npos);
+ void finish();
+
+ size_t size() const { return data.size(); }
+
+ // only after finish() has been called:
+ bool contains(key_t val) const;
+ key_t next(key_t val) const;
+
+ void dump() const;
+ private:
+ // currently not used
+ bool intersect(const value_t &a,const value_t &b) const;
+ void unite(value_t &aret,const value_t &b) const;
+ private:
+ data_t data;
+};
+
+#endif
diff --git a/filter/pdftopdf/nup.cc b/filter/pdftopdf/nup.cc
new file mode 100644
index 000000000..8be9b86c1
--- /dev/null
+++ b/filter/pdftopdf/nup.cc
@@ -0,0 +1,265 @@
+#include "nup.h"
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <utility>
+
+void NupParameters::dump() const // {{{
+{
+ fprintf(stderr,"NupX: %d, NupY: %d\n"
+ "width: %f, height: %f\n",
+ nupX,nupY,
+ width,height);
+
+ int opos=-1,fpos=-1,spos=-1;
+ if (xstart==Position::LEFT) { // or Bottom
+ fpos=0;
+ } else if (xstart==Position::RIGHT) { // or Top
+ fpos=1;
+ }
+ if (ystart==Position::LEFT) { // or Bottom
+ spos=0;
+ } else if (ystart==Position::RIGHT) { // or Top
+ spos=1;
+ }
+ if (first==Axis::X) {
+ fprintf(stderr,"First Axis: X\n");
+ opos=0;
+ } else if (first==Axis::Y) {
+ fprintf(stderr,"First Axis: Y\n");
+ opos=2;
+ std::swap(fpos,spos);
+ }
+
+ if ( (opos==-1)||(fpos==-1)||(spos==-1) ) {
+ fprintf(stderr,"Bad Spec: %d; start: %d, %d\n\n",
+ first,xstart,ystart);
+ } else {
+ static const char *order[4]={"lr","rl","bt","tb"};
+ fprintf(stderr,"Order: %s%s\n",
+ order[opos+fpos],order[(opos+2)%4+spos]);
+ }
+
+ fputs("Alignment: ",stderr);
+ Position_dump(xalign,Axis::X);
+ fputs("/",stderr);
+ Position_dump(yalign,Axis::Y);
+ fputs("\n",stderr);
+}
+// }}}
+
+bool NupParameters::possible(int nup) // {{{
+{
+ // 1 2 3 4 6 8 9 10 12 15 16
+ return (nup>=1)&&(nup<=16)&&
+ ( (nup!=5)&&(nup!=7)&&(nup!=11)&&(nup!=13)&&(nup!=14) );
+}
+// }}}
+
+void NupParameters::preset(int nup,NupParameters &ret) // {{{
+{
+ switch (nup) {
+ case 1:
+ ret.nupX=1;
+ ret.nupY=1;
+ break;
+ case 2:
+ ret.nupX=2;
+ ret.nupY=1;
+ ret.landscape=true;
+ break;
+ case 3:
+ ret.nupX=3;
+ ret.nupY=1;
+ ret.landscape=true;
+ break;
+ case 4:
+ ret.nupX=2;
+ ret.nupY=2;
+ break;
+ case 6:
+ ret.nupX=3;
+ ret.nupY=2;
+ ret.landscape=true;
+ break;
+ case 8:
+ ret.nupX=4;
+ ret.nupY=2;
+ ret.landscape=true;
+ break;
+ case 9:
+ ret.nupX=3;
+ ret.nupY=3;
+ break;
+ case 10:
+ ret.nupX=5;
+ ret.nupY=2;
+ ret.landscape=true;
+ break;
+ case 12:
+ ret.nupX=3;
+ ret.nupY=4;
+ break;
+ case 15:
+ ret.nupX=5;
+ ret.nupY=3;
+ ret.landscape=true;
+ break;
+ case 16:
+ ret.nupX=4;
+ ret.nupY=4;
+ break;
+ }
+}
+// }}}
+
+
+NupState::NupState(const NupParameters &param) // {{{
+ : param(param),
+ in_pages(0),out_pages(0),
+ nup(param.nupX*param.nupY),
+ subpage(nup)
+{
+ assert( (param.nupX>0)&&(param.nupY>0) );
+}
+// }}}
+
+void NupState::reset() // {{{
+{
+ in_pages=0;
+ out_pages=0;
+// nup=param.nupX*param.nupY;
+ subpage=nup;
+}
+// }}}
+
+void NupPageEdit::dump() const // {{{
+{
+ fprintf(stderr,"xpos: %f, ypos: %f, scale: %f\n",
+ xpos,ypos,scale);
+ sub.dump();
+}
+// }}}
+
+std::pair<int,int> NupState::convert_order(int subpage) const // {{{
+{
+ int subx,suby;
+ if (param.first==Axis::X) {
+ subx=subpage%param.nupX;
+ suby=subpage/param.nupX;
+ } else {
+ subx=subpage/param.nupY;
+ suby=subpage%param.nupY;
+ }
+
+ subx=(param.nupX-1)*(param.xstart+1)/2-param.xstart*subx;
+ suby=(param.nupY-1)*(param.ystart+1)/2-param.ystart*suby;
+
+ return std::make_pair(subx,suby);
+}
+// }}}
+
+static inline float lin(Position pos,float size) // {{{
+{
+ if (pos==-1) return 0;
+ else if (pos==0) return size/2;
+ else if (pos==1) return size;
+ return size*(pos+1)/2;
+}
+// }}}
+
+void NupState::calculate_edit(int subx,int suby,NupPageEdit &ret) const // {{{
+{
+ // dimensions of a "nup cell"
+ const float width=param.width/param.nupX,
+ height=param.height/param.nupY;
+
+ // first calculate only for bottom-left corner
+ ret.xpos=subx*width;
+ ret.ypos=suby*height;
+
+ const float scalex=width/ret.sub.width,
+ scaley=height/ret.sub.height;
+ float subwidth=ret.sub.width*scaley,
+ subheight=ret.sub.height*scalex;
+
+ // TODO? if ( (!fitPlot)&&(ret.scale>1) ) ret.scale=1.0;
+ if (scalex>scaley) {
+ ret.scale=scaley;
+ subheight=height;
+ ret.xpos+=lin(param.xalign,width-subwidth);
+ } else {
+ ret.scale=scalex;
+ subwidth=width;
+ ret.ypos+=lin(param.yalign,height-subheight);
+ }
+
+ ret.sub.left=ret.xpos;
+ ret.sub.bottom=ret.ypos;
+ ret.sub.right=ret.sub.left+subwidth;
+ ret.sub.top=ret.sub.bottom+subheight;
+}
+// }}}
+
+bool NupState::nextPage(float in_width,float in_height,NupPageEdit &ret) // {{{
+{
+ in_pages++;
+ subpage++;
+ if (subpage>=nup) {
+ subpage=0;
+ out_pages++;
+ }
+
+ ret.sub.width=in_width;
+ ret.sub.height=in_height;
+
+ auto sub=convert_order(subpage);
+ calculate_edit(sub.first,sub.second,ret);
+
+ return (subpage==0);
+}
+// }}}
+
+
+static std::pair<Axis,Position> parsePosition(char a,char b) // {{{ returns ,CENTER(0) on invalid
+{
+ a|=0x20; // make lowercase
+ b|=0x20;
+ if ( (a=='l')&&(b=='r') ) {
+ return std::make_pair(Axis::X,Position::LEFT);
+ } else if ( (a=='r')&&(b=='l') ) {
+ return std::make_pair(Axis::X,Position::RIGHT);
+ } else if ( (a=='t')&&(b=='b') ) {
+ return std::make_pair(Axis::Y,Position::TOP);
+ } else if ( (a=='b')&&(b=='t') ) {
+ return std::make_pair(Axis::Y,Position::BOTTOM);
+ }
+ return std::make_pair(Axis::X,Position::CENTER);
+}
+// }}}
+
+bool parseNupLayout(const char *val,NupParameters &ret) // {{{
+{
+ assert(val);
+ auto pos0=parsePosition(val[0],val[1]);
+ if (pos0.second==CENTER) {
+ return false;
+ }
+ auto pos1=parsePosition(val[2],val[3]);
+ if ( (pos1.second==CENTER)||(pos0.first==pos1.first) ) {
+ return false;
+ }
+
+ ret.first=pos0.first;
+ if (ret.first==Axis::X) {
+ ret.xstart=pos0.second;
+ ret.ystart=pos1.second;
+ } else {
+ ret.xstart=pos1.second;
+ ret.ystart=pos0.second;
+ }
+
+ return (val[4]==0); // everything seen?
+}
+// }}}
+
diff --git a/filter/pdftopdf/nup.h b/filter/pdftopdf/nup.h
new file mode 100644
index 000000000..0523cc782
--- /dev/null
+++ b/filter/pdftopdf/nup.h
@@ -0,0 +1,91 @@
+#ifndef NUP_H_
+#define NUP_H_
+
+#include "pptypes.h"
+#include <utility>
+
+// you have to provide this
+struct NupParameters {
+ NupParameters()
+ : nupX(1),nupY(1),
+ width(NAN),height(NAN),
+ landscape(false),
+ first(X),
+ xstart(LEFT),ystart(TOP),
+ xalign(CENTER),yalign(CENTER)
+ {}
+
+ // --- "calculated" parameters ---
+ int nupX,nupY;
+ float width,height;
+ bool landscape; // post-rotate!
+
+ // --- other settings ---
+ // ordering
+ Axis first;
+ Position xstart,ystart;
+
+ Position xalign,yalign;
+
+ static bool possible(int nup); // TODO? float in_ratio,float out_ratio
+ static void preset(int nup,NupParameters &ret);
+ static float calculate(int nup, float in_ratio, float out_ratio,NupParameters &ret); // returns "quality", 1 is best
+
+ void dump() const;
+};
+
+// you get this
+struct NupPageEdit {
+ // required transformation: first translate, then scale
+ float xpos,ypos; // TODO: already given by sub.left,sub.bottom [but for rotation?]
+ float scale; // uniform
+
+// ? "landscape" e.g. to rotate labels
+
+ // for border, clip, ...
+ // also stores in_width/in_height, unscaled!
+ // everything in "outer"-page coordinates
+ PageRect sub;
+
+ void dump() const;
+};
+
+/*
+ This class does the number-up calculation. Example:
+
+ NupParameters param;
+ param.xyz=...; // fill it with your data!
+
+ NupState nup(param);
+ NupPageEdit edit;
+ for (auto page : your_pages) {
+ bool newPage=nup.nextPage(page.w,page.h,edit); // w,h from input page
+ // create newPage, if required; then place current page as specified in edit
+ }
+*/
+class NupState {
+public:
+ NupState(const NupParameters &param);
+
+ void reset();
+
+ // will overwrite ret with the new parameters
+ // returns true, if a new output page should be started first
+ bool nextPage(float in_width,float in_height,NupPageEdit &ret);
+
+private:
+ std::pair<int,int> convert_order(int subpage) const;
+ void calculate_edit(int subx,int suby,NupPageEdit &ret) const;
+private:
+ NupParameters param;
+
+ int in_pages,out_pages;
+ int nup; // max. per page (==nupX*nupY)
+ int subpage; // on the current output-page
+};
+
+// TODO? elsewhere
+// parsing functions for cups parameters (will not calculate nupX,nupY!)
+bool parseNupLayout(const char *val,NupParameters &ret); // lrtb, btlr, ...
+
+#endif
diff --git a/filter/pdftopdf/pdftopdf.cc b/filter/pdftopdf/pdftopdf.cc
new file mode 100644
index 000000000..7bc152b61
--- /dev/null
+++ b/filter/pdftopdf/pdftopdf.cc
@@ -0,0 +1,1207 @@
+// Copyright (c) 2012 Tobias Hoffmann
+//
+// Copyright (c) 2006-2011, BBR Inc. All rights reserved.
+// MIT Licensed.
+
+#include <config.h>
+#include <stdio.h>
+#include <assert.h>
+#include <cups/cups.h>
+#include <cups/ppd.h>
+#if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 6)
+#define HAVE_CUPS_1_7 1
+#endif
+#ifdef HAVE_CUPS_1_7
+#include <cups/pwg.h>
+#endif /* HAVE_CUPS_1_7 */
+#include <iomanip>
+#include <sstream>
+#include <memory>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "pdftopdf_processor.h"
+#include "pdftopdf_jcl.h"
+
+#include <stdarg.h>
+static void error(const char *fmt,...) // {{{
+{
+ va_list ap;
+ va_start(ap,fmt);
+
+ fputs("ERROR: ",stderr);
+ vfprintf(stderr,fmt,ap);
+ fputs("\n",stderr);
+
+ va_end(ap);
+}
+// }}}
+
+// namespace {}
+
+void setFinalPPD(ppd_file_t *ppd,const ProcessingParameters &param)
+{
+ if ((param.booklet==BOOKLET_ON)&&(ppdFindOption(ppd,"Duplex"))) {
+ // TODO: elsewhere, better
+ ppdMarkOption(ppd,"Duplex","DuplexTumble");
+ // TODO? sides=two-sided-short-edge
+ }
+
+ // for compatibility
+ if ((param.setDuplex)&&(ppdFindOption(ppd,"Duplex")!=NULL)) {
+ ppdMarkOption(ppd,"Duplex","True");
+ ppdMarkOption(ppd,"Duplex","On");
+ }
+
+ // we do it, printer should not
+ ppd_choice_t *choice;
+ if ((choice=ppdFindMarkedChoice(ppd,"MirrorPrint")) != NULL) {
+ choice->marked=0;
+ }
+}
+
+// for choice, only overwrites ret if found in ppd
+static bool ppdGetInt(ppd_file_t *ppd,const char *name,int *ret) // {{{
+{
+ assert(ret);
+ ppd_choice_t *choice=ppdFindMarkedChoice(ppd,name); // !ppd is ok.
+ if (choice) {
+ *ret=atoi(choice->choice);
+ return true;
+ }
+ return false;
+}
+// }}}
+
+static bool optGetInt(const char *name,int num_options,cups_option_t *options,int *ret) // {{{
+{
+ assert(ret);
+ const char *val=cupsGetOption(name,num_options,options);
+ if (val) {
+ *ret=atoi(val);
+ return true;
+ }
+ return false;
+}
+// }}}
+
+static bool optGetFloat(const char *name,int num_options,cups_option_t *options,float *ret) // {{{
+{
+ assert(ret);
+ const char *val=cupsGetOption(name,num_options,options);
+ if (val) {
+ *ret=atof(val);
+ return true;
+ }
+ return false;
+}
+// }}}
+
+static bool is_false(const char *value) // {{{
+{
+ if (!value) {
+ return false;
+ }
+ return (strcasecmp(value,"no")==0)||
+ (strcasecmp(value,"off")==0)||
+ (strcasecmp(value,"false")==0);
+}
+// }}}
+
+static bool is_true(const char *value) // {{{
+{
+ if (!value) {
+ return false;
+ }
+ return (strcasecmp(value,"yes")==0)||
+ (strcasecmp(value,"on")==0)||
+ (strcasecmp(value,"true")==0);
+}
+// }}}
+
+static bool ppdGetDuplex(ppd_file_t *ppd) // {{{
+{
+ const char **option, **choice;
+ const char *option_names[] = {
+ "Duplex",
+ "JCLDuplex",
+ "EFDuplex",
+ "KD03Duplex",
+ NULL
+ };
+ const char *choice_names[] = {
+ "DuplexNoTumble",
+ "DuplexTumble",
+ "LongEdge",
+ "ShortEdge",
+ "Top",
+ "Bottom",
+ NULL
+ };
+ for (option = option_names; *option; option ++)
+ for (choice = choice_names; *choice; choice ++)
+ if (ppdIsMarked(ppd, *option, *choice))
+ return 1;
+ return 0;
+}
+// }}}
+
+// TODO: enum
+static bool ppdDefaultOrder(ppd_file_t *ppd) // {{{ -- is reverse?
+{
+ ppd_choice_t *choice;
+ ppd_attr_t *attr;
+ const char *val=NULL;
+
+ // Figure out the right default output order from the PPD file...
+ if ((choice=ppdFindMarkedChoice(ppd,"OutputOrder")) != NULL) {
+ val=choice->choice;
+ } else if (((choice=ppdFindMarkedChoice(ppd,"OutputBin")) != NULL)&&
+ ((attr=ppdFindAttr(ppd,"PageStackOrder",choice->choice)) != NULL)) {
+ val=attr->value;
+ } else if ((attr=ppdFindAttr(ppd,"DefaultOutputOrder",0)) != NULL) {
+ val=attr->value;
+ }
+ if ((!val)||(strcasecmp(val,"Normal")==0)) {
+ return false;
+ } else if (strcasecmp(val,"Reverse")==0) {
+ return true;
+ }
+ error("Unsupported output-order value %s, using 'normal'!",val);
+ return false;
+}
+// }}}
+
+static bool optGetCollate(int num_options,cups_option_t *options) // {{{
+{
+ if (is_true(cupsGetOption("Collate",num_options,options))) {
+ return true;
+ }
+
+ const char *val=NULL;
+ if ((val=cupsGetOption("multiple-document-handling",num_options,options)) != NULL) {
+ /* This IPP attribute is unnecessarily complicated:
+ * single-document, separate-documents-collated-copies, single-document-new-sheet:
+ * -> collate (true)
+ * separate-documents-uncollated-copies:
+ * -> can be uncollated (false)
+ */
+ return (strcasecmp(val,"separate-documents-uncollated-copies")!=0);
+ }
+
+ if ((val=cupsGetOption("sheet-collate",num_options,options)) != NULL) {
+ return (strcasecmp(val,"uncollated")!=0);
+ }
+
+ return false;
+}
+// }}}
+
+static bool parsePosition(const char *value,Position &xpos,Position &ypos) // {{{
+{
+ // ['center','top','left','right','top-left','top-right','bottom','bottom-left','bottom-right']
+ xpos=Position::CENTER;
+ ypos=Position::CENTER;
+ int next=0;
+ if (strcasecmp(value,"center")==0) {
+ return true;
+ } else if (strncasecmp(value,"top",3)==0) {
+ ypos=Position::TOP;
+ next=3;
+ } else if (strncasecmp(value,"bottom",6)==0) {
+ ypos=Position::BOTTOM;
+ next=6;
+ }
+ if (next) {
+ if (value[next]==0) {
+ return true;
+ } else if (value[next]!='-') {
+ return false;
+ }
+ value+=next+1;
+ }
+ if (strcasecmp(value,"left")==0) {
+ xpos=Position::LEFT;
+ } else if (strcasecmp(value,"right")==0) {
+ xpos=Position::RIGHT;
+ } else {
+ return false;
+ }
+ return true;
+}
+// }}}
+
+#include <ctype.h>
+static void parseRanges(const char *range,IntervalSet &ret) // {{{
+{
+ ret.clear();
+ if (!range) {
+ ret.add(1); // everything
+ ret.finish();
+ return;
+ }
+
+ int lower,upper;
+ while (*range) {
+ if (*range=='-') {
+ range++;
+ upper=strtol(range,(char **)&range,10);
+ if (upper>=2147483647) { // see also cups/encode.c
+ ret.add(1);
+ } else {
+ ret.add(1,upper+1);
+ }
+ } else {
+ lower=strtol(range,(char **)&range,10);
+ if (*range=='-') {
+ range++;
+ if (!isdigit(*range)) {
+ ret.add(lower);
+ } else {
+ upper=strtol(range,(char **)&range,10);
+ if (upper>=2147483647) {
+ ret.add(1);
+ } else {
+ ret.add(lower,upper+1);
+ }
+ }
+ } else {
+ ret.add(lower,lower+1);
+ }
+ }
+
+ if (*range!=',') {
+ break;
+ }
+ range++;
+ }
+ ret.finish();
+}
+// }}}
+
+static bool parseBorder(const char *val,BorderType &ret) // {{{
+{
+ assert(val);
+ if (strcasecmp(val,"none")==0) {
+ ret=BorderType::NONE;
+ } else if (strcasecmp(val,"single")==0) {
+ ret=BorderType::ONE_THIN;
+ } else if (strcasecmp(val,"single-thick")==0) {
+ ret=BorderType::ONE_THICK;
+ } else if (strcasecmp(val,"double")==0) {
+ ret=BorderType::TWO_THIN;
+ } else if (strcasecmp(val,"double-thick")==0) {
+ ret=BorderType::TWO_THICK;
+ } else {
+ return false;
+ }
+ return true;
+}
+// }}}
+
+void getParameters(ppd_file_t *ppd,int num_options,cups_option_t *options,ProcessingParameters &param) // {{{
+{
+ const char *val;
+
+ if ((val = cupsGetOption("copies",num_options,options)) != NULL) {
+ int copies = atoi(val);
+ if (copies > 0)
+ param.numCopies = copies;
+ }
+ // param.numCopies initially from commandline
+ if (param.numCopies==1) {
+ ppdGetInt(ppd,"Copies",&param.numCopies);
+ }
+ if (param.numCopies==0) {
+ param.numCopies=1;
+ }
+
+ if ((val=cupsGetOption("fitplot",num_options,options)) == NULL) {
+ if ((val=cupsGetOption("fit-to-page",num_options,options)) == NULL) {
+ val=cupsGetOption("ipp-attribute-fidelity",num_options,options);
+ }
+ }
+ // TODO? pstops checks =="true", pdftops !is_false ... pstops says: fitplot only for PS (i.e. not for PDF, cmp. cgpdftopdf)
+ param.fitplot=(val)&&(!is_false(val));
+
+ if (ppd && (ppd->landscape < 0)) { // direction the printer rotates landscape (90 or -90)
+ param.normal_landscape=ROT_270;
+ } else {
+ param.normal_landscape=ROT_90;
+ }
+
+ int ipprot;
+ param.orientation=ROT_0;
+ if ((val=cupsGetOption("landscape",num_options,options)) != NULL) {
+ if (!is_false(val)) {
+ param.orientation=param.normal_landscape;
+ }
+ } else if (optGetInt("orientation-requested",num_options,options,&ipprot)) {
+ /* IPP orientation values are:
+ * 3: 0 degrees, 4: 90 degrees, 5: -90 degrees, 6: 180 degrees
+ */
+ if ((ipprot<3)||(ipprot>6)) {
+ error("Bad value (%d) for orientation-requested, using 0 degrees",ipprot);
+ } else {
+ static const Rotation ipp2rot[4]={ROT_0, ROT_90, ROT_270, ROT_180};
+ param.orientation=ipp2rot[ipprot-3];
+ }
+ }
+
+ ppd_size_t *pagesize;
+ // param.page default is letter, border 36,18
+ if ((pagesize=ppdPageSize(ppd,0)) != NULL) { // "already rotated"
+ param.page.top=pagesize->top;
+ param.page.left=pagesize->left;
+ param.page.right=pagesize->right;
+ param.page.bottom=pagesize->bottom;
+ param.page.width=pagesize->width;
+ param.page.height=pagesize->length;
+ }
+#ifdef HAVE_CUPS_1_7
+ else {
+ if ((val = cupsGetOption("media-size", num_options, options)) != NULL ||
+ (val = cupsGetOption("MediaSize", num_options, options)) != NULL ||
+ (val = cupsGetOption("page-size", num_options, options)) != NULL ||
+ (val = cupsGetOption("PageSize", num_options, options)) != NULL) {
+ pwg_media_t *size_found = NULL;
+ fprintf(stderr, "DEBUG: Page size from command line: %s\n", val);
+ if ((size_found = pwgMediaForPWG(val)) == NULL)
+ if ((size_found = pwgMediaForPPD(val)) == NULL)
+ size_found = pwgMediaForLegacy(val);
+ if (size_found != NULL) {
+ param.page.width = size_found->width * 72.0 / 2540.0;
+ param.page.height = size_found->length * 72.0 / 2540.0;
+ param.page.top=param.page.bottom=36.0;
+ param.page.right=param.page.left=18.0;
+ param.page.right=param.page.width-param.page.right;
+ param.page.top=param.page.height-param.page.top;
+ fprintf(stderr, "DEBUG: Width: %f, Length: %f\n", param.page.width, param.page.height);
+ }
+ else
+ fprintf(stderr, "DEBUG: Unsupported page size %s.\n", val);
+ }
+ }
+#endif /* HAVE_CUPS_1_7 */
+
+ param.paper_is_landscape=(param.page.width>param.page.height);
+
+ PageRect tmp; // borders (before rotation)
+
+ optGetFloat("page-top",num_options,options,&tmp.top);
+ optGetFloat("page-left",num_options,options,&tmp.left);
+ optGetFloat("page-right",num_options,options,&tmp.right);
+ optGetFloat("page-bottom",num_options,options,&tmp.bottom);
+
+ if ((val = cupsGetOption("media-top-margin", num_options, options))
+ != NULL)
+ tmp.top = atof(val) * 72.0 / 2540.0;
+ if ((val = cupsGetOption("media-left-margin", num_options, options))
+ != NULL)
+ tmp.left = atof(val) * 72.0 / 2540.0;
+ if ((val = cupsGetOption("media-right-margin", num_options, options))
+ != NULL)
+ tmp.right = atof(val) * 72.0 / 2540.0;
+ if ((val = cupsGetOption("media-bottom-margin", num_options, options))
+ != NULL)
+ tmp.bottom = atof(val) * 72.0 / 2540.0;
+
+ if ((param.orientation==ROT_90)||(param.orientation==ROT_270)) { // unrotate page
+ // NaN stays NaN
+ tmp.right=param.page.height-tmp.right;
+ tmp.top=param.page.width-tmp.top;
+ tmp.rotate_move(param.orientation,param.page.height,param.page.width);
+ } else {
+ tmp.right=param.page.width-tmp.right;
+ tmp.top=param.page.height-tmp.top;
+ tmp.rotate_move(param.orientation,param.page.width,param.page.height);
+ }
+
+ param.page.set(tmp); // replace values, where tmp.* != NaN (because tmp needed rotation, param.page not!)
+
+ if (ppdGetDuplex(ppd)) {
+ param.duplex=true;
+ } else if (is_true(cupsGetOption("Duplex",num_options,options))) {
+ param.duplex=true;
+ param.setDuplex=true;
+ } else if ((val=cupsGetOption("sides",num_options,options)) != NULL) {
+ if ((strcasecmp(val,"two-sided-long-edge")==0)||
+ (strcasecmp(val,"two-sided-short-edge")==0)) {
+ param.duplex=true;
+ param.setDuplex=true;
+ } else if (strcasecmp(val,"one-sided")!=0) {
+ error("Unsupported sides value %s, using sides=one-sided!",val);
+ }
+ }
+
+ // default nup is 1
+ int nup=1;
+ if (optGetInt("number-up",num_options,options,&nup)) {
+ if (!NupParameters::possible(nup)) {
+ error("Unsupported number-up value %d, using number-up=1!",nup);
+ nup=1;
+ }
+// TODO ; TODO? nup enabled? ... fitplot
+// NupParameters::calculate(nup,param.nup);
+ NupParameters::preset(nup,param.nup);
+ }
+
+ if ((val=cupsGetOption("number-up-layout",num_options,options)) != NULL) {
+ if (!parseNupLayout(val,param.nup)) {
+ error("Unsupported number-up-layout %s, using number-up-layout=lrtb!",val);
+ param.nup.first=Axis::X;
+ param.nup.xstart=Position::LEFT;
+ param.nup.ystart=Position::TOP;
+ }
+ }
+
+ if ((val=cupsGetOption("page-border",num_options,options)) != NULL) {
+ if (!parseBorder(val,param.border)) {
+ error("Unsupported page-border value %s, using page-border=none!",val);
+ param.border=BorderType::NONE;
+ }
+ }
+
+ if ((val=cupsGetOption("OutputOrder",num_options,options)) != NULL ||
+ (val=cupsGetOption("page-delivery",num_options,options)) != NULL) {
+ param.reverse=(strcasecmp(val,"Reverse")==0);
+ } else if (ppd) {
+ param.reverse=ppdDefaultOrder(ppd);
+ }
+
+ std::string rawlabel;
+ char *classification = getenv("CLASSIFICATION");
+ if (classification)
+ rawlabel.append (classification);
+
+ if ((val=cupsGetOption("page-label", num_options, options)) != NULL) {
+ if (!rawlabel.empty())
+ rawlabel.append (" - ");
+ rawlabel.append(cupsGetOption("page-label",num_options,options));
+ }
+
+ std::ostringstream cookedlabel;
+ for (std::string::iterator it = rawlabel.begin();
+ it != rawlabel.end ();
+ ++it) {
+ if (*it < 32 || *it > 126)
+ cookedlabel << "\\" << std::oct << std::setfill('0') << std::setw(3) << (unsigned int) *it;
+ else
+ cookedlabel.put (*it);
+ }
+ param.pageLabel = cookedlabel.str ();
+
+ if ((val=cupsGetOption("page-set",num_options,options)) != NULL) {
+ if (strcasecmp(val,"even")==0) {
+ param.oddPages=false;
+ } else if (strcasecmp(val,"odd")==0) {
+ param.evenPages=false;
+ } else if (strcasecmp(val,"all")!=0) {
+ error("Unsupported page-set value %s, using page-set=all!",val);
+ }
+ }
+
+ if ((val=cupsGetOption("page-ranges",num_options,options)) != NULL) {
+ parseRanges(val,param.pageRange);
+ }
+
+ ppd_choice_t *choice;
+ if ((choice=ppdFindMarkedChoice(ppd,"MirrorPrint")) != NULL) {
+ val=choice->choice;
+ } else {
+ val=cupsGetOption("mirror",num_options,options);
+ }
+ param.mirror=is_true(val);
+
+ if ((val=cupsGetOption("emit-jcl",num_options,options)) != NULL) {
+ param.emitJCL=!is_false(val)&&(strcmp(val,"0")!=0);
+ }
+
+ param.booklet=BookletMode::BOOKLET_OFF;
+ if ((val=cupsGetOption("booklet",num_options,options)) != NULL) {
+ if (strcasecmp(val,"shuffle-only")==0) {
+ param.booklet=BookletMode::BOOKLET_JUSTSHUFFLE;
+ } else if (is_true(val)) {
+ param.booklet=BookletMode::BOOKLET_ON;
+ } else if (!is_false(val)) {
+ error("Unsupported booklet value %s, using booklet=off!",val);
+ }
+ }
+ param.bookSignature=-1;
+ if (optGetInt("booklet-signature",num_options,options,&param.bookSignature)) {
+ if (param.bookSignature==0) {
+ error("Unsupported booklet-signature value, using booklet-signature=-1 (all)!",val);
+ param.bookSignature=-1;
+ }
+ }
+
+ if ((val=cupsGetOption("position",num_options,options)) != NULL) {
+ if (!parsePosition(val,param.xpos,param.ypos)) {
+ error("Unrecognized position value %s, using position=center!",val);
+ param.xpos=Position::CENTER;
+ param.ypos=Position::CENTER;
+ }
+ }
+
+ param.collate=optGetCollate(num_options,options);
+ // FIXME? pdftopdf also considers if ppdCollate is set (only when cupsGetOption is /not/ given) [and if is_true overrides param.collate=true] -- pstops does not
+
+/*
+ // TODO: scaling
+ // TODO: natural-scaling
+
+ scaling
+
+
+ if ((val = cupsGetOption("scaling",num_options,options)) != 0) {
+ scaling = atoi(val) * 0.01;
+ fitplot = gTrue;
+ } else if (fitplot) {
+ scaling = 1.0;
+ }
+ if ((val = cupsGetOption("natural-scaling",num_options,options)) != 0) {
+ naturalScaling = atoi(val) * 0.01;
+ }
+
+bool checkFeature(const char *feature, int num_options, cups_option_t *options) // {{{
+{
+ const char *val;
+ ppd_attr_t *attr;
+
+ return ((val=cupsGetOption(feature,num_options,options)) != NULL && is_true(val)) ||
+ ((attr=ppdFindAttr(ppd,feature,0)) != NULL && is_true(attr->val));
+}
+// }}}
+*/
+
+ // make pages a multiple of two (only considered when duplex is on).
+ // i.e. printer has hardware-duplex, but needs pre-inserted filler pages
+ // FIXME? pdftopdf also supports it as cmdline option (via checkFeature())
+ ppd_attr_t *attr;
+ if ((attr=ppdFindAttr(ppd,"cupsEvenDuplex",0)) != NULL) {
+ param.evenDuplex=is_true(attr->value);
+ }
+
+ // TODO? pdftopdf* ?
+ // TODO?! pdftopdfAutoRotate
+
+ // TODO?! choose default by whether pdfautoratate filter has already been run (e.g. by mimetype)
+ param.autoRotate=(!is_false(cupsGetOption("pdfAutoRotate",num_options,options)) &&
+ !is_false(cupsGetOption("pdftopdfAutoRotate",num_options,options)));
+
+ // Do we have to do the page logging in page_log?
+
+ // CUPS standard is that the last filter (not the backend, usually the
+ // printer driver) does page logging in the /var/log/cups/page_log file
+ // by outputting "PAGE: <# of current page> <# of copies>" to stderr.
+
+ // pdftopdf would have to do this only for PDF printers as in this case
+ // pdftopdf is the last filter, but some of the other filters are not
+ // able to do the logging because they do not have access to the number
+ // of pages of the file to be printed, so pdftopdf overtakes their logging
+ // duty.
+
+ // The filters currently are:
+ // - foomatic-rip (lets Ghostscript convert PDF to printer's format via
+ // built-in drivers, no access to the PDF content)
+ // - gstopxl (uses Ghostscript, like foomatic-rip)
+ // - *toraster on IPP Everywhere printers (then *toraster gets the last
+ // filter, the case if FINAL_CONTENT_TYPE env var is "image/pwg-raster")
+ // - hpps (bug)
+
+ // Check whether page logging is forced or suppressed by the command line
+ if ((val=cupsGetOption("page-logging",num_options,options)) != NULL) {
+ if (strcasecmp(val,"auto") == 0) {
+ param.page_logging = -1;
+ fprintf(stderr,
+ "DEBUG: pdftopdf: Automatic page logging selected by command line.\n");
+ } else if (is_true(val)) {
+ param.page_logging = 1;
+ fprintf(stderr,
+ "DEBUG: pdftopdf: Forced page logging selected by command line.\n");
+ } else if (is_false(val)) {
+ param.page_logging = 0;
+ fprintf(stderr,
+ "DEBUG: pdftopdf: Suppressed page logging selected by command line.\n");
+ } else {
+ error("Unsupported page-logging value %s, using page-logging=auto!",val);
+ param.page_logging = -1;
+ }
+ }
+
+ if (param.page_logging == -1) {
+ // Determine the last filter in the chain via cupsFilter(2) lines of the
+ // PPD file and FINAL_CONTENT_TYPE
+ if (!ppd) {
+ // If there is no PPD do not log when not requested by command line
+ param.page_logging = 0;
+ fprintf(stderr,
+ "DEBUG: pdftopdf: No PPD file specified, could not determine whether to log pages or not, so turned off page logging.\n");
+ } else {
+ char *final_content_type = getenv("FINAL_CONTENT_TYPE");
+ char *lastfilter = NULL;
+ if (final_content_type == NULL) {
+ // No FINAL_CONTENT_TYPE env variable set, we cannot determine
+ // whether we have to log pages, so do not log.
+ param.page_logging = 0;
+ fprintf(stderr,
+ "DEBUG: pdftopdf: No FINAL_CONTENT_TYPE environment variable, could not determine whether to log pages or not, so turned off page logging.\n");
+ // Proceed depending on number of cupsFilter(2) lines in PPD
+ } else if (ppd->num_filters == 0) {
+ // No filter line, manufacturer-supplied PostScript PPD
+ // In this case pstops, called by pdftops, does the logging
+ param.page_logging = 0;
+ } else if (ppd->num_filters == 1) {
+ // One filter line, so this one filter is the last filter
+ lastfilter = ppd->filters[0];
+ } else {
+ // More than one filter line, determine the one which got
+ // actually used via FINAL_CONTENT_TYPE
+ ppd_attr_t *ppd_attr;
+ if ((ppd_attr = ppdFindAttr(ppd, "cupsFilter2", NULL)) != NULL) {
+ // We have cupsFilter2 lines, use only these
+ do {
+ // Go to the second work, which is the destination MIME type
+ char *p = ppd_attr->value;
+ while (!isspace(*p)) p ++;
+ while (isspace(*p)) p ++;
+ // Compare with FINAL_CONTEN_TYPE
+ if (!strncasecmp(final_content_type, p,
+ strlen(final_content_type))) {
+ lastfilter = ppd_attr->value;
+ break;
+ }
+ } while ((ppd_attr = ppdFindNextAttr(ppd, "cupsFilter2", NULL))
+ != NULL);
+ } else {
+ // We do not have cupsFilter2 lines, use the cupsFilter lines
+ int i;
+ for (i = 0; i < ppd->num_filters; i ++) {
+ // Compare source MIME type (first word) with FINAL_CONTENT_TYPE
+ if (!strncasecmp(final_content_type, ppd->filters[i],
+ strlen(final_content_type))) {
+ lastfilter = ppd->filters[i];
+ break;
+ }
+ }
+ }
+ }
+ if (param.page_logging == -1) {
+ if (lastfilter) {
+ // Get the name of the last filter, without mime type and cost
+ char *p = lastfilter;
+ char *q = p + strlen(p) - 1;
+ while(!isspace(*q) && *q != '/') q --;
+ lastfilter = q + 1;
+ // Check whether we have to log
+ if (!strcasecmp(lastfilter, "-")) {
+ // No filter defined in the PPD
+ // If output data (FINAL_CONTENT_TYPE) is PDF, pdftopdf is last
+ // filter (PDF printer) and has to log
+ // If output data (FINAL_CONTENT_TYPE) is PWG Raster, *toraster is
+ // last filter (IPP Everywhere printer) and pdftopdf has to log
+ if (strcasestr(final_content_type, "/pdf") ||
+ strcasestr(final_content_type, "/vnd.cups-pdf") ||
+ strcasestr(final_content_type, "/pwg-raster"))
+ param.page_logging = 1;
+ else
+ param.page_logging = 0;
+ } else if (!strcasecmp(lastfilter, "pdftopdf")) {
+ // pdftopdf is last filter (PDF printer)
+ param.page_logging = 1;
+ } else if (!strcasecmp(lastfilter, "gstopxl")) {
+ // gstopxl is last filter, this is a Ghostscript-based filter
+ // without access to the pages of the file to be printed, so we
+ // log the pages
+ param.page_logging = 1;
+ } else if (!strcasecmp(lastfilter + strlen(lastfilter) - 8,
+ "toraster")) {
+ // On IPP Everywhere printers which accept PWG Raster data one
+ // of gstoraster, pdftoraster, or mupdftoraster is the last
+ // filter. These filters do not log pages so pdftopdf has to
+ // do it
+ param.page_logging = 1;
+ } else if (!strcasecmp(lastfilter, "foomatic-rip")) {
+ // foomatic-rip is last filter, foomatic-rip is mainly used as
+ // Ghostscript wrapper to use Ghostscript's built-in printer
+ // drivers. Here there is also no access to the pages so that we
+ // delegate the logging to pdftopdf
+ param.page_logging = 1;
+ } else if (!strcasecmp(lastfilter, "hpps")) {
+ // hpps is last filter, hpps is part of HPLIP and it is a bug that
+ // it does not do the page logging.
+ param.page_logging = 1;
+ } else {
+ // All the other filters log pages as expected.
+ param.page_logging = 0;
+ }
+ } else {
+ error("pdftopdf: Last filter could not get determined, page logging turned off.");
+ param.page_logging = 0;
+ }
+ }
+ fprintf(stderr,
+ "DEBUG: pdftopdf: Last filter determined by the PPD: %s; FINAL_CONTENT_TYPE: %s => pdftopdf will %slog pages in page_log.\n",
+ (lastfilter ? lastfilter : "None"), final_content_type,
+ (param.page_logging == 0 ? "not " : ""));
+ }
+ }
+}
+// }}}
+
+static bool printerWillCollate(ppd_file_t *ppd) // {{{
+{
+ ppd_choice_t *choice;
+
+ if (((choice=ppdFindMarkedChoice(ppd,"Collate")) != NULL)&&
+ (is_true(choice->choice))) {
+
+ // printer can collate, but also for the currently marked ppd features?
+ ppd_option_t *opt=ppdFindOption(ppd,"Collate");
+ return (opt)&&(!opt->conflicted);
+ }
+ return false;
+}
+// }}}
+
+void calculate(ppd_file_t *ppd,ProcessingParameters &param) // {{{
+{
+ param.deviceReverse=false;
+ if (param.reverse) {
+ // test OutputOrder of hardware (ppd)
+ if (ppdFindOption(ppd,"OutputOrder") != NULL) {
+ param.deviceReverse=true;
+ param.reverse=false;
+ } else {
+ // Enable evenDuplex or the first page may be empty.
+ param.evenDuplex=true; // disabled later, if non-duplex
+ }
+ }
+
+ setFinalPPD(ppd,param);
+
+ if (param.numCopies==1) {
+ param.deviceCopies=1;
+ // collate is never needed for a single copy
+ param.collate=false; // (does not make a big difference for us)
+ } else if ((ppd)&&(!ppd->manual_copies)) { // hw copy generation available
+ param.deviceCopies=param.numCopies;
+ if (param.collate) { // collate requested by user
+ // check collate device, with current/final(!) ppd settings
+ param.deviceCollate=printerWillCollate(ppd);
+ if (!param.deviceCollate) {
+ // printer can't hw collate -> we must copy collated in sw
+ param.deviceCopies=1;
+ }
+ } // else: printer copies w/o collate and takes care of duplex/evenDuplex
+ } else { // sw copies
+ param.deviceCopies=1;
+ if (param.duplex) { // &&(numCopies>1)
+ // sw collate + evenDuplex must be forced to prevent copies on the backsides
+ param.collate=true;
+ param.deviceCollate=false;
+ }
+ }
+
+ // TODO? FIXME: unify code with emitJCLOptions, which does this "by-hand" now (and makes this code superfluous)
+ if (param.deviceCopies==1) {
+ // make sure any hardware copying is disabled
+ ppdMarkOption(ppd,"Copies","1");
+ ppdMarkOption(ppd,"JCLCopies","1");
+ } else { // hw copy
+ param.numCopies=1; // disable sw copy
+ }
+
+ if ((param.collate)&&(!param.deviceCollate)) { // software collate
+ ppdMarkOption(ppd,"Collate","False"); // disable any hardware-collate (in JCL)
+ param.evenDuplex=true; // fillers always needed
+ }
+
+ if (!param.duplex) {
+ param.evenDuplex=false;
+ }
+}
+// }}}
+
+// reads from stdin into temporary file. returns FILE * or NULL on error
+// TODO? to extra file (also used in pdftoijs, e.g.)
+FILE *copy_stdin_to_temp() // {{{
+{
+ char buf[BUFSIZ];
+ int n;
+
+ // FIXME: what does >buf mean here?
+ int fd=cupsTempFd(buf,sizeof(buf));
+ if (fd<0) {
+ error("Can't create temporary file");
+ return NULL;
+ }
+ // remove name
+ unlink(buf);
+
+ // copy stdin to the tmp file
+ while ((n=read(0,buf,BUFSIZ)) > 0) {
+ if (write(fd,buf,n) != n) {
+ error("Can't copy stdin to temporary file");
+ close(fd);
+ return NULL;
+ }
+ }
+ if (lseek(fd,0,SEEK_SET) < 0) {
+ error("Can't rewind temporary file");
+ close(fd);
+ return NULL;
+ }
+
+ FILE *f;
+ if ((f=fdopen(fd,"rb")) == 0) {
+ error("Can't fdopen temporary file");
+ close(fd);
+ return NULL;
+ }
+ return f;
+}
+// }}}
+
+static int
+sub_process_spawn (const char *filename,
+ cups_array_t *sub_process_args,
+ FILE *fp) // {{{
+{
+ char *argument;
+ char buf[BUFSIZ];
+ char **sub_process_argv;
+ const char* apos;
+ int fds[2];
+ int i;
+ int n;
+ int numargs;
+ int pid;
+ int status = 65536;
+ int wstatus;
+
+ /* Put sub-process command line argument into an array for the "exec()"
+ call */
+ numargs = cupsArrayCount(sub_process_args);
+ sub_process_argv = (char **)calloc(numargs + 1, sizeof(char *));
+ for (argument = (char *)cupsArrayFirst(sub_process_args), i = 0; argument;
+ argument = (char *)cupsArrayNext(sub_process_args), i++) {
+ sub_process_argv[i] = argument;
+ }
+ sub_process_argv[i] = NULL;
+
+ /* Debug output: Full sub-process command line */
+ fprintf(stderr, "DEBUG: PDF form flattening command line:");
+ for (i = 0; sub_process_argv[i]; i ++) {
+ if ((strchr(sub_process_argv[i],' ')) || (strchr(sub_process_argv[i],'\t')))
+ apos = "'";
+ else
+ apos = "";
+ fprintf(stderr, " %s%s%s", apos, sub_process_argv[i], apos);
+ }
+ fprintf(stderr, "\n");
+
+ /* Create a pipe for feeding the job into sub-process */
+ if (pipe(fds))
+ {
+ fds[0] = -1;
+ fds[1] = -1;
+ fprintf(stderr, "ERROR: Unable to establish pipe for sub-process call\n");
+ goto out;
+ }
+
+ /* Set the "close on exec" flag on each end of the pipe... */
+ if (fcntl(fds[0], F_SETFD, fcntl(fds[0], F_GETFD) | FD_CLOEXEC))
+ {
+ close(fds[0]);
+ close(fds[1]);
+ fds[0] = -1;
+ fds[1] = -1;
+ fprintf(stderr, "ERROR: Unable to set \"close on exec\" flag on read end of the pipe for sub-process call\n");
+ goto out;
+ }
+ if (fcntl(fds[1], F_SETFD, fcntl(fds[1], F_GETFD) | FD_CLOEXEC))
+ {
+ close(fds[0]);
+ close(fds[1]);
+ fprintf(stderr, "ERROR: Unable to set \"close on exec\" flag on write end of the pipe for sub-process call\n");
+ goto out;
+ }
+
+ if ((pid = fork()) == 0)
+ {
+ /* Couple pipe with STDIN of sub-process */
+ if (fds[0] != 0) {
+ close(0);
+ if (fds[0] > 0) {
+ if (dup(fds[0]) < 0) {
+ fprintf(stderr, "ERROR: Unable to couple pipe with STDIN of sub-process\n");
+ goto out;
+ }
+ } else {
+ fprintf(stderr, "ERROR: Unable to couple pipe with STDIN of sub-process\n");
+ goto out;
+ }
+ }
+ close(fds[1]);
+
+ /* Execute sub-process command line ... */
+ execvp(filename, sub_process_argv);
+ perror(filename);
+ close(fds[0]);
+ goto out;
+ }
+
+ close(fds[0]);
+ /* Feed job data into the sub-process */
+ while ((n = fread(buf, 1, BUFSIZ, fp)) > 0) {
+ int count;
+retry_write:
+ count = write(fds[1], buf, n);
+ if (count != n) {
+ if (count == -1) {
+ if (errno == EINTR) {
+ goto retry_write;
+ }
+ fprintf(stderr, "ERROR: write failed: %s\n", strerror(errno));
+ }
+ fprintf(stderr, "ERROR: Can't feed job data into the sub-process\n");
+ goto out;
+ }
+ }
+ close (fds[1]);
+
+retry_wait:
+ if (waitpid (pid, &wstatus, 0) == -1) {
+ if (errno == EINTR)
+ goto retry_wait;
+ perror ("sub-process");
+ goto out;
+ }
+
+ /* How did the sub-process terminate */
+ if (WIFEXITED(wstatus))
+ /* Via exit() anywhere or return() in the main() function */
+ status = WEXITSTATUS(wstatus);
+ else if (WIFSIGNALED(wstatus))
+ /* Via signal */
+ status = 256 * WTERMSIG(wstatus);
+
+out:
+ free(sub_process_argv);
+ return status;
+}
+// }}}
+
+int main(int argc,char **argv)
+{
+ if ((argc<6)||(argc>7)) {
+ fprintf(stderr,"Usage: %s job-id user title copies options [file]\n",argv[0]);
+#ifdef DEBUG
+ ProcessingParameters param;
+ std::unique_ptr<PDFTOPDF_Processor> proc1(PDFTOPDF_Factory::processor());
+ param.page.width=595.276; // A4
+ param.page.height=841.89;
+
+ param.page.top=param.page.bottom=36.0;
+ param.page.right=param.page.left=18.0;
+ param.page.right=param.page.width-param.page.right;
+ param.page.top=param.page.height-param.page.top;
+
+ //param.nup.calculate(4,0.707,0.707,param.nup);
+ param.nup.nupX=2;
+ param.nup.nupY=2;
+ //param.nup.yalign=TOP;
+ param.border=BorderType::NONE;
+ //param.mirror=true;
+ //param.reverse=true;
+ //param.numCopies=3;
+ if (!proc1->loadFilename("in.pdf")) return 2;
+ param.dump();
+ if (!processPDFTOPDF(*proc1,param)) return 3;
+ emitComment(*proc1,param);
+ proc1->emitFilename("out.pdf");
+#endif
+ return 1;
+ }
+
+ try {
+ ProcessingParameters param;
+
+ param.jobId=atoi(argv[1]);
+ param.user=argv[2];
+ param.title=argv[3];
+ param.numCopies=atoi(argv[4]);
+ param.copies_to_be_logged=atoi(argv[4]);
+
+ // TODO?! sanity checks
+
+ int num_options=0;
+ cups_option_t *options=NULL;
+ num_options=cupsParseOptions(argv[5],num_options,&options);
+
+ ppd_file_t *ppd=NULL;
+ ppd=ppdOpenFile(getenv("PPD")); // getenv (and thus ppd) may be null. This will not cause problems.
+ ppdMarkDefaults(ppd);
+
+ cupsMarkOptions(ppd,num_options,options);
+
+ getParameters(ppd,num_options,options,param);
+ calculate(ppd,param);
+
+#ifdef DEBUG
+ param.dump();
+#endif
+
+ cupsFreeOptions(num_options,options);
+
+ std::unique_ptr<PDFTOPDF_Processor> proc(PDFTOPDF_Factory::processor());
+
+ FILE *tmpfile = NULL;
+ if (argc==7) {
+ if (!proc->loadFilename(argv[6])) {
+ ppdClose(ppd);
+ return 1;
+ }
+ } else {
+ tmpfile = copy_stdin_to_temp();
+ if ((!tmpfile)||
+ (!proc->loadFile(tmpfile,WillStayAlive))) {
+ ppdClose(ppd);
+ return 1;
+ }
+ }
+
+ /* The input file contains a PDF form. To not loose the data filled
+ into the form during our further manipulations we need to flatten
+ the form, meaning that we integrate the filled in data into the
+ pages themselves instead of holding them in an extra layer */
+ if (proc->hasAcroForm()) {
+ /* Prepare the input file for being read by the form flattening
+ process */
+ FILE *infile = NULL;
+ if (argc == 7) {
+ /* We read from a named file */
+ infile = fopen(argv[6], "r");
+ } else {
+ /* We read from a temporary file */
+ if (tmpfile) rewind(tmpfile);
+ infile = tmpfile;
+ }
+ if (infile == NULL) {
+ error("Could not open the input file for flattening the PDF form!");
+ return 1;
+ }
+ /* Create a temporary file for the output of the flattened PDF */
+ char buf[BUFSIZ];
+ int fd = cupsTempFd(buf,sizeof(buf));
+ if (fd<0) {
+ error("Can't create temporary file for flattened PDF form!");
+ return 1;
+ }
+ FILE *outfile = NULL;
+ if ((outfile=fdopen(fd,"rb")) == 0) {
+ error("Can't fdopen temporary file for the flattened PDF form!");
+ close(fd);
+ return 1;
+ }
+ int flattening_done = 0;
+ const char *command;
+ cups_array_t *args;
+ /* Choose the utility to be used and create its command line */
+ /* Try pdftocairo first, the preferred utility for form-flattening */
+ command = CUPS_POPPLER_PDFTOCAIRO;
+ args = cupsArrayNew(NULL, NULL);
+ cupsArrayAdd(args, strdup(command));
+ cupsArrayAdd(args, strdup("-pdf"));
+ cupsArrayAdd(args, strdup("-"));
+ cupsArrayAdd(args, strdup(buf));
+ /* Run the pdftocairo form flattening process */
+ rewind(infile);
+ int status = sub_process_spawn (command, args, infile);
+ cupsArrayDelete(args);
+ if (status == 0)
+ flattening_done = 1;
+ else {
+ error("Unable to execute pdftocairo for form flattening!");
+ /* Try Ghostscript, currently the only working alternative */
+ command = CUPS_GHOSTSCRIPT;
+ args = cupsArrayNew(NULL, NULL);
+ cupsArrayAdd(args, strdup(command));
+ cupsArrayAdd(args, strdup("-dQUIET"));
+ cupsArrayAdd(args, strdup("-dPARANOIDSAFER"));
+ cupsArrayAdd(args, strdup("-dNOPAUSE"));
+ cupsArrayAdd(args, strdup("-dBATCH"));
+ cupsArrayAdd(args, strdup("-dNOINTERPOLATE"));
+ cupsArrayAdd(args, strdup("-dNOMEDIAATTRS"));
+ cupsArrayAdd(args, strdup("-sDEVICE=pdfwrite"));
+ cupsArrayAdd(args, strdup("-dShowAcroForm"));
+ cupsArrayAdd(args, strdup("-sstdout=%stderr"));
+ memmove(buf + 13, buf, sizeof(buf) - 13);
+ memcpy(buf, "-sOutputFile=", 13);
+ cupsArrayAdd(args, strdup(buf));
+ cupsArrayAdd(args, strdup("-"));
+ /* Run the Ghostscript form flattening process */
+ rewind(infile);
+ int status = sub_process_spawn (command, args, infile);
+ cupsArrayDelete(args);
+ if (status == 0)
+ flattening_done = 1;
+ else {
+ error("Unable to execute Ghostscript for form flattening!");
+ error("No suitable utility for flattening filled PDF forms available, no flattening performed. Filled in content will not be printed.");
+ rewind(infile);
+ }
+ }
+ /* Clean up */
+ fclose(infile);
+ /* Load the flattened PDF file into our PDF processor */
+ if (flattening_done) {
+ rewind(outfile);
+ unlink(buf);
+ if (!proc->loadFile(outfile,TakeOwnership)) {
+ error("Unable to create a PDF processor on the flattened form!");
+ return 1;
+ }
+ }
+ }
+
+/* TODO
+ // color management
+--- PPD:
+ copyPPDLine_(fp_dest, fp_src, "*PPD-Adobe: ");
+ copyPPDLine_(fp_dest, fp_src, "*cupsICCProfile ");
+ copyPPDLine_(fp_dest, fp_src, "*Manufacturer:");
+ copyPPDLine_(fp_dest, fp_src, "*ColorDevice:");
+ copyPPDLine_(fp_dest, fp_src, "*DefaultColorSpace:");
+ if (cupsICCProfile) {
+ proc.addCM(...,...);
+ }
+*/
+
+ if (!processPDFTOPDF(*proc,param)) {
+ ppdClose(ppd);
+ return 2;
+ }
+
+ emitPreamble(ppd,param); // ppdEmit, JCL stuff
+ emitComment(*proc,param); // pass information to subsequent filters via PDF comments
+
+ //proc->emitFile(stdout);
+ proc->emitFilename(NULL);
+
+ emitPostamble(ppd,param);
+ ppdClose(ppd);
+ } catch (std::exception &e) {
+ // TODO? exception type
+ error("Exception: %s",e.what());
+ return 5;
+ } catch (...) {
+ error("Unknown exception caught. Exiting.");
+ return 6;
+ }
+
+ return 0;
+}
diff --git a/filter/pdftopdf/pdftopdf_jcl.cc b/filter/pdftopdf/pdftopdf_jcl.cc
new file mode 100644
index 000000000..224d8b0e3
--- /dev/null
+++ b/filter/pdftopdf/pdftopdf_jcl.cc
@@ -0,0 +1,202 @@
+#include <ctype.h>
+#include "pdftopdf_processor.h"
+#include <cups/ppd.h>
+
+#include <string.h>
+
+// TODO: -currently changes ppd. (Copies)
+//
+static void emitJCLOptions(FILE *fp, ppd_file_t *ppd, int deviceCopies) // {{{
+{
+ int section;
+ ppd_choice_t **choices;
+ int i;
+ char buf[1024];
+ ppd_attr_t *attr;
+ bool withJCL=false,
+ datawritten=false;
+
+ if (!ppd) return;
+
+ if ((attr = ppdFindAttr(ppd,"pdftopdfJCLBegin",NULL)) != NULL) {
+ withJCL=true;
+ const int n=strlen(attr->value);
+ for (i = 0;i < n;i++) {
+ if (attr->value[i] == '\r' || attr->value[i] == '\n') {
+ // skip new line
+ continue;
+ }
+ fputc(attr->value[i],fp);
+ datawritten=true;
+ }
+ }
+
+ snprintf(buf,sizeof(buf),"%d",deviceCopies);
+ if (ppdFindOption(ppd,"Copies") != NULL) {
+ ppdMarkOption(ppd,"Copies",buf);
+ } else {
+ if ((attr = ppdFindAttr(ppd,"pdftopdfJCLCopies",buf)) != NULL) {
+ fputs(attr->value,fp);
+ datawritten=true;
+ } else if (withJCL) {
+ fprintf(fp,"Copies=%d;",deviceCopies);
+ datawritten=true;
+ }
+ }
+ for (section = (int)PPD_ORDER_ANY;
+ section <= (int)PPD_ORDER_PROLOG;section++) {
+ int n = ppdCollect(ppd,(ppd_section_t)section,&choices);
+ for (i = 0;i < n;i++) {
+ snprintf(buf,sizeof(buf),"pdftopdfJCL%s",
+ ((ppd_option_t *)(choices[i]->option))->keyword);
+ if ((attr = ppdFindAttr(ppd,buf,choices[i]->choice)) != NULL) {
+ fputs(attr->value,fp);
+ datawritten=true;
+ } else if (withJCL) {
+ fprintf(fp,"%s=%s;",
+ ((ppd_option_t *)(choices[i]->option))->keyword,
+ choices[i]->choice);
+ datawritten=true;
+ }
+ }
+ }
+ if (datawritten) {
+ fputc('\n',fp);
+ }
+}
+// }}}
+
+/* Copied ppd_decode() from CUPS which is not exported to the API; needed in emitPreamble() */
+// {{{ static int ppd_decode(char *string)
+static int /* O - Length of decoded string */
+ppd_decode(char *string) /* I - String to decode */
+{
+ char *inptr, /* Input pointer */
+ *outptr; /* Output pointer */
+
+ inptr = string;
+ outptr = string;
+
+ while (*inptr != '\0')
+ if (*inptr == '<' && isxdigit(inptr[1] & 255)) {
+ /*
+ * Convert hex to 8-bit values...
+ */
+
+ inptr ++;
+ while (isxdigit(*inptr & 255)) {
+ if (isalpha(*inptr))
+ *outptr = (tolower(*inptr) - 'a' + 10) << 4;
+ else
+ *outptr = (*inptr - '0') << 4;
+
+ inptr ++;
+
+ if (!isxdigit(*inptr & 255))
+ break;
+
+ if (isalpha(*inptr))
+ *outptr |= tolower(*inptr) - 'a' + 10;
+ else
+ *outptr |= *inptr - '0';
+
+ inptr ++;
+ outptr ++;
+ }
+
+ while (*inptr != '>' && *inptr != '\0')
+ inptr ++;
+ while (*inptr == '>')
+ inptr ++;
+ } else
+ *outptr++ = *inptr++;
+
+ *outptr = '\0';
+
+ return ((int)(outptr - string));
+}
+// }}}
+
+void emitPreamble(ppd_file_t *ppd,const ProcessingParameters &param) // {{{
+{
+ if (ppd == 0) return;
+
+ ppdEmit(ppd,stdout,PPD_ORDER_EXIT);
+
+ if (param.emitJCL) {
+ /* pdftopdf only adds JCL to the job if the printer is a native PDF
+ printer and the PPD is for this mode, having the "*JCLToPDFInterpreter:"
+ keyword. We need to read this keyword manually from the PPD and replace
+ the content of ppd->jcl_ps by the value of this keyword, so that
+ ppdEmitJCL() actually adds JCL based on the presence on
+ "*JCLToPDFInterpreter:". */
+ ppd_attr_t *attr;
+ char buf[1024];
+ int devicecopies_done = 0;
+ char *old_jcl_ps = ppd->jcl_ps;
+ /* If there is a "Copies" option in the PPD file, assure that hardware
+ copies are implemented as described by this option */
+ if (ppdFindOption(ppd,"Copies") != NULL &&
+ param.deviceCopies > 1) {
+ snprintf(buf,sizeof(buf),"%d",param.deviceCopies);
+ ppdMarkOption(ppd,"Copies",buf);
+ devicecopies_done = 1;
+ }
+ if ((attr=ppdFindAttr(ppd,"JCLToPDFInterpreter",NULL)) != NULL) {
+ if (param.deviceCopies > 1 && devicecopies_done == 0 && // HW copies
+ strncmp(ppd->jcl_begin, "\033%-12345X@", 10) == 0) { // PJL
+ /* Add a PJL command to implement the hardware copies */
+ const size_t size=strlen(attr->value)+1+30;
+ ppd->jcl_ps=(char *)malloc(size*sizeof(char));
+ if (param.deviceCollate) {
+ snprintf(ppd->jcl_ps, size, "@PJL SET QTY=%d\n%s",
+ param.deviceCopies, attr->value);
+ } else {
+ snprintf(ppd->jcl_ps, size, "@PJL SET COPIES=%d\n%s",
+ param.deviceCopies, attr->value);
+ }
+ } else
+ ppd->jcl_ps=strdup(attr->value);
+ ppd_decode(ppd->jcl_ps);
+ } else {
+ ppd->jcl_ps=NULL;
+ }
+ ppdEmitJCL(ppd,stdout,param.jobId,param.user,param.title);
+ emitJCLOptions(stdout,ppd,param.deviceCopies);
+ free(ppd->jcl_ps);
+ ppd->jcl_ps = old_jcl_ps; // cups uses pool allocator, not free()
+ }
+}
+// }}}
+
+void emitPostamble(ppd_file_t *ppd,const ProcessingParameters &param) // {{{
+{
+ if (param.emitJCL) {
+ ppdEmitJCLEnd(ppd,stdout);
+ }
+}
+// }}}
+
+// pass information to subsequent filters via PDF comments
+void emitComment(PDFTOPDF_Processor &proc,const ProcessingParameters &param) // {{{
+{
+ std::vector<std::string> output;
+
+ output.push_back("% This file was generated by pdftopdf");
+
+ // This is not standard, but like PostScript.
+ if (param.deviceCopies>0) {
+ char buf[256];
+ snprintf(buf,sizeof(buf),"%d",param.deviceCopies);
+ output.push_back(std::string("%%PDFTOPDFNumCopies : ")+buf);
+
+ if (param.deviceCollate) {
+ output.push_back("%%PDFTOPDFCollate : true");
+ } else {
+ output.push_back("%%PDFTOPDFCollate : false");
+ }
+ }
+
+ proc.setComments(output);
+}
+// }}}
diff --git a/filter/pdftopdf/pdftopdf_jcl.h b/filter/pdftopdf/pdftopdf_jcl.h
new file mode 100644
index 000000000..ee6e315ba
--- /dev/null
+++ b/filter/pdftopdf/pdftopdf_jcl.h
@@ -0,0 +1,12 @@
+#ifndef PDFTOPDF_JCL_H
+#define PDFTOPDF_JCL_H
+
+struct ProcessingParameters;
+class PDFTOPDF_Processor;
+
+void emitPreamble(ppd_file_t *ppd,const ProcessingParameters &param);
+void emitPostamble(ppd_file_t *ppd,const ProcessingParameters &param);
+
+void emitComment(PDFTOPDF_Processor &proc,const ProcessingParameters &param);
+
+#endif
diff --git a/filter/pdftopdf/pdftopdf_processor.cc b/filter/pdftopdf/pdftopdf_processor.cc
new file mode 100644
index 000000000..697eb4ab4
--- /dev/null
+++ b/filter/pdftopdf/pdftopdf_processor.cc
@@ -0,0 +1,363 @@
+#include "pdftopdf_processor.h"
+#include "qpdf_pdftopdf_processor.h"
+#include <stdio.h>
+#include <assert.h>
+#include <numeric>
+
+void BookletMode_dump(BookletMode bkm) // {{{
+{
+ static const char *bstr[3]={"Off","On","Shuffle-Only"};
+ if ((bkm<BOOKLET_OFF) || (bkm>BOOKLET_JUSTSHUFFLE)) {
+ fprintf(stderr,"(bad booklet mode: %d)",bkm);
+ } else {
+ fputs(bstr[bkm],stderr);
+ }
+}
+// }}}
+
+bool ProcessingParameters::withPage(int outno) const // {{{
+{
+ if (outno%2 == 0) { // 1-based
+ if (!evenPages) {
+ return false;
+ }
+ } else if (!oddPages) {
+ return false;
+ }
+ return pageRange.contains(outno);
+}
+// }}}
+
+void ProcessingParameters::dump() const // {{{
+{
+ fprintf(stderr,"jobId: %d, numCopies: %d\n",
+ jobId,numCopies);
+ fprintf(stderr,"user: %s, title: %s\n",
+ (user)?user:"(null)",(title)?title:"(null)");
+ fprintf(stderr,"fitplot: %s\n",
+ (fitplot)?"true":"false");
+
+ page.dump();
+
+ fprintf(stderr,"Rotation(CCW): ");
+ Rotation_dump(orientation);
+ fprintf(stderr,"\n");
+
+ fprintf(stderr,"paper_is_landscape: %s\n",
+ (paper_is_landscape)?"true":"false");
+
+ fprintf(stderr,"duplex: %s\n",
+ (duplex)?"true":"false");
+
+ fprintf(stderr,"Border: ");
+ BorderType_dump(border);
+ fprintf(stderr,"\n");
+
+ nup.dump();
+
+ fprintf(stderr,"reverse: %s\n",
+ (reverse)?"true":"false");
+
+ fprintf(stderr,"evenPages: %s, oddPages: %s\n",
+ (evenPages)?"true":"false",
+ (oddPages)?"true":"false");
+
+ fprintf(stderr,"page range: ");
+ pageRange.dump();
+
+ fprintf(stderr,"mirror: %s\n",
+ (mirror)?"true":"false");
+
+ fprintf(stderr,"Position: ");
+ Position_dump(xpos,Axis::X);
+ fprintf(stderr,"/");
+ Position_dump(ypos,Axis::Y);
+ fprintf(stderr,"\n");
+
+ fprintf(stderr,"collate: %s\n",
+ (collate)?"true":"false");
+
+ fprintf(stderr,"evenDuplex: %s\n",
+ (evenDuplex)?"true":"false");
+
+ fprintf(stderr,"pageLabel: %s\n",
+ pageLabel.empty () ? "(none)" : pageLabel.c_str());
+
+ fprintf(stderr,"bookletMode: ");
+ BookletMode_dump(booklet);
+ fprintf(stderr,"\nbooklet signature: %d\n",
+ bookSignature);
+
+ fprintf(stderr,"autoRotate: %s\n",
+ (autoRotate)?"true":"false");
+
+ fprintf(stderr,"emitJCL: %s\n",
+ (emitJCL)?"true":"false");
+ fprintf(stderr,"deviceCopies: %d\n",
+ deviceCopies);
+ fprintf(stderr,"deviceReverse: %s\n",
+ (deviceReverse)?"true":"false");
+ fprintf(stderr,"deviceCollate: %s\n",
+ (deviceCollate)?"true":"false");
+ fprintf(stderr,"setDuplex: %s\n",
+ (setDuplex)?"true":"false");
+}
+// }}}
+
+
+PDFTOPDF_Processor *PDFTOPDF_Factory::processor()
+{
+ return new QPDF_PDFTOPDF_Processor();
+}
+
+// (1-based)
+// 9: [*] [1] [2] [*] [*] [3] [4] [9] [8] [5] [6] [7] -> signature = 12 = 3*4 = ((9+3)/4)*4
+// 1 2 3 4 5 6 7 8 9 10 11 12
+// NOTE: psbook always fills the sig completely (results in completely white pages (4-set), depending on the input)
+
+// empty pages must be added for output values >=numPages
+std::vector<int> bookletShuffle(int numPages,int signature) // {{{
+{
+ if (signature<0) {
+ signature=(numPages+3)&~0x3;
+ }
+ assert(signature%4==0);
+
+ std::vector<int> ret;
+ ret.reserve(numPages+signature-1);
+
+ int curpage=0;
+ while (curpage<numPages) {
+ // as long as pages to be done -- i.e. multiple times the signature
+ int firstpage=curpage,
+ lastpage=curpage+signature-1;
+ // one signature
+ while (firstpage<lastpage) {
+ ret.push_back(lastpage--);
+ ret.push_back(firstpage++);
+ ret.push_back(firstpage++);
+ ret.push_back(lastpage--);
+ }
+ curpage+=signature;
+ }
+ return ret;
+}
+// }}}
+
+bool processPDFTOPDF(PDFTOPDF_Processor &proc,ProcessingParameters &param) // {{{
+{
+ if (!proc.check_print_permissions()) {
+ fprintf(stderr,"Not allowed to print\n");
+ return false;
+ }
+
+ if (param.autoRotate) {
+ const bool dst_lscape =
+ (param.paper_is_landscape ==
+ ((param.orientation == ROT_0) || (param.orientation == ROT_180)));
+ proc.autoRotateAll(dst_lscape,param.normal_landscape);
+ }
+
+ std::vector<std::shared_ptr<PDFTOPDF_PageHandle>> pages=proc.get_pages();
+ const int numOrigPages=pages.size();
+
+ // TODO FIXME? elsewhere
+ std::vector<int> shuffle;
+ if (param.booklet!=BOOKLET_OFF) {
+ shuffle=bookletShuffle(numOrigPages,param.bookSignature);
+ if (param.booklet==BOOKLET_ON) { // override options
+ // TODO? specifically "sides=two-sided-short-edge" / DuplexTumble
+ // param.duplex=true;
+ // param.setDuplex=true; ? currently done in setFinalPPD()
+ NupParameters::preset(2,param.nup); // TODO?! better
+ }
+ } else { // 0 1 2 3 ...
+ shuffle.resize(numOrigPages);
+ std::iota(shuffle.begin(),shuffle.end(),0);
+ }
+ const int numPages=std::max(shuffle.size(),pages.size());
+
+ std::shared_ptr<PDFTOPDF_PageHandle> curpage;
+ int outputpage=0;
+ int outputno=0;
+
+ if ((param.nup.nupX==1)&&(param.nup.nupY==1)&&(!param.fitplot)) {
+ // TODO? fitplot also without xobject?
+ /*
+ param.nup.width=param.page.width;
+ param.nup.height=param.page.height;
+ */
+
+ for (int iA=0;iA<numPages;iA++) {
+ if (!param.withPage(iA+1)) {
+ continue;
+ }
+
+ // Log page in /var/log/cups/page_log
+ if (param.page_logging == 1)
+ fprintf(stderr, "PAGE: %d %d\n", iA + 1, param.copies_to_be_logged);
+
+ if (shuffle[iA]>=numOrigPages) {
+ // add empty page as filler
+ proc.add_page(proc.new_page(param.page.width,param.page.height),param.reverse);
+ outputno++;
+ continue; // no border, etc.
+ }
+ auto page=pages[shuffle[iA]];
+
+ page->rotate(param.orientation);
+
+ if (param.mirror) {
+ page->mirror();
+ }
+
+ if (!param.pageLabel.empty()) {
+ page->add_label(param.page, param.pageLabel);
+ }
+
+ // place border
+ if ((param.border!=BorderType::NONE)&&(iA<numOrigPages)) {
+#if 0 // would be nice, but is not possible
+ PageRect rect=page->getRect();
+
+ rect.left+=param.page.left;
+ rect.bottom+=param.page.bottom;
+ rect.top-=param.page.top;
+ rect.right-=param.page.right;
+ // width,height not needed for add_border_rect (FIXME?)
+
+ page->add_border_rect(rect,param.border,1.0);
+#else // this is what pstops does
+ page->add_border_rect(param.page,param.border,1.0);
+#endif
+ }
+
+ proc.add_page(page,param.reverse); // reverse -> insert at beginning
+ outputno++;
+ }
+ } else {
+ param.nup.width=param.page.right-param.page.left;
+ param.nup.height=param.page.top-param.page.bottom;
+
+ double xpos=param.page.left,
+ ypos=param.page.bottom; // for whole page... TODO from position...
+
+ const bool origls=param.nup.landscape;
+ if ((param.orientation==ROT_90)||(param.orientation==ROT_270)) {
+ std::swap(param.nup.nupX,param.nup.nupY);
+ param.nup.landscape=!param.nup.landscape;
+ param.orientation=param.orientation-param.normal_landscape;
+ }
+ if (param.nup.landscape) {
+ // pages[iA]->rotate(param.normal_landscape);
+ param.orientation=param.orientation+param.normal_landscape;
+ // TODO? better
+ xpos=param.page.bottom;
+ ypos=param.page.width - param.page.right;
+ std::swap(param.page.width,param.page.height);
+ std::swap(param.nup.width,param.nup.height);
+ }
+
+ NupState nupstate(param.nup);
+ NupPageEdit pgedit;
+ for (int iA=0;iA<numPages;iA++) {
+ std::shared_ptr<PDFTOPDF_PageHandle> page;
+ if (shuffle[iA]>=numOrigPages) {
+ // add empty page as filler
+ page=proc.new_page(param.page.width,param.page.height);
+ } else {
+ page=pages[shuffle[iA]];
+ }
+
+ PageRect rect;
+ if (param.fitplot) {
+ rect=page->getRect();
+ } else {
+ rect.width=param.page.width;
+ rect.height=param.page.height;
+
+ // TODO? better
+ if (origls) {
+ std::swap(rect.width,rect.height);
+ }
+
+ rect.left=0;
+ rect.bottom=0;
+ rect.right=rect.width;
+ rect.top=rect.height;
+ }
+ // rect.dump();
+
+ bool newPage=nupstate.nextPage(rect.width,rect.height,pgedit);
+ if (newPage) {
+ if ((curpage)&&(param.withPage(outputpage))) {
+ curpage->rotate(param.orientation);
+ if (param.mirror) {
+ curpage->mirror();
+ // TODO? update rect? --- not needed any more
+ }
+ proc.add_page(curpage,param.reverse); // reverse -> insert at beginning
+ // Log page in /var/log/cups/page_log
+ outputno++;
+ if (param.page_logging == 1)
+ fprintf(stderr, "PAGE: %d %d\n", outputno,
+ param.copies_to_be_logged);
+ }
+ curpage=proc.new_page(param.page.width,param.page.height);
+ outputpage++;
+ }
+ if (shuffle[iA]>=numOrigPages) {
+ continue;
+ }
+
+ if (param.border!=BorderType::NONE) {
+ // TODO FIXME... border gets cutted away, if orignal page had wrong size
+ // page->"uncrop"(rect); // page->setMedia()
+ // Note: currently "fixed" in add_subpage(...&rect);
+ page->add_border_rect(rect,param.border,1.0/pgedit.scale);
+ }
+
+ if (!param.pageLabel.empty()) {
+ page->add_label(param.page, param.pageLabel);
+ }
+
+ if (!param.fitplot) {
+ curpage->add_subpage(page,pgedit.xpos+xpos,pgedit.ypos+ypos,pgedit.scale,&rect);
+ } else {
+ curpage->add_subpage(page,pgedit.xpos+xpos,pgedit.ypos+ypos,pgedit.scale);
+ }
+
+#ifdef DEBUG
+ if (auto dbg=dynamic_cast<QPDF_PDFTOPDF_PageHandle *>(curpage.get())) {
+ // dbg->debug(pgedit.sub,xpos,ypos);
+ }
+#endif
+
+ // pgedit.dump();
+ }
+ if ((curpage)&&(param.withPage(outputpage))) {
+ curpage->rotate(param.orientation);
+ if (param.mirror) {
+ curpage->mirror();
+ }
+ proc.add_page(curpage,param.reverse); // reverse -> insert at beginning
+ // Log page in /var/log/cups/page_log
+ outputno ++;
+ if (param.page_logging == 1)
+ fprintf(stderr, "PAGE: %d %d\n", outputno, param.copies_to_be_logged);
+ }
+ }
+
+ if ((param.evenDuplex || !param.oddPages) && (outputno & 1)) {
+ // need to output empty page to not confuse duplex
+ proc.add_page(proc.new_page(param.page.width,param.page.height),param.reverse);
+ // Log page in /var/log/cups/page_log
+ if (param.page_logging == 1)
+ fprintf(stderr, "PAGE: %d %d\n", outputno + 1, param.copies_to_be_logged);
+ }
+
+ proc.multiply(param.numCopies,param.collate);
+
+ return true;
+}
+// }}}
diff --git a/filter/pdftopdf/pdftopdf_processor.h b/filter/pdftopdf/pdftopdf_processor.h
new file mode 100644
index 000000000..bd20ba40e
--- /dev/null
+++ b/filter/pdftopdf/pdftopdf_processor.h
@@ -0,0 +1,162 @@
+#ifndef PDFTOPDF_PROCESSOR_H
+#define PDFTOPDF_PROCESSOR_H
+
+#include "pptypes.h"
+#include "nup.h"
+#include "intervalset.h"
+#include <vector>
+#include <string>
+
+enum BookletMode { BOOKLET_OFF, BOOKLET_ON, BOOKLET_JUSTSHUFFLE };
+
+struct ProcessingParameters {
+ProcessingParameters()
+: jobId(0),numCopies(1),
+ user(0),title(0),
+ fitplot(false),
+ orientation(ROT_0),normal_landscape(ROT_270),
+ paper_is_landscape(false),
+ duplex(false),
+ border(NONE),
+ reverse(false),
+
+ pageLabel(),
+ evenPages(true),oddPages(true),
+
+ mirror(false),
+
+ xpos(CENTER),ypos(CENTER),
+
+ collate(false),
+ evenDuplex(false),
+
+ booklet(BOOKLET_OFF),bookSignature(-1),
+
+ autoRotate(false),
+
+ emitJCL(true),deviceCopies(1),deviceReverse(false),
+ deviceCollate(false),setDuplex(false),
+
+ page_logging(-1)
+
+ {
+ page.width=612.0; // letter
+ page.height=792.0;
+ page.top=page.height-36.0;
+ page.bottom=36.0;
+ page.left=18.0;
+ page.right=page.width-18.0;
+
+ // everything
+ pageRange.add(1);
+ pageRange.finish();
+ }
+
+ int jobId, numCopies;
+ const char *user, *title; // will stay around
+ bool fitplot;
+ PageRect page;
+ Rotation orientation,normal_landscape; // normal_landscape (i.e. default direction) is e.g. needed for number-up=2
+ bool paper_is_landscape;
+ bool duplex;
+ BorderType border;
+ NupParameters nup;
+ bool reverse;
+
+ std::string pageLabel;
+ bool evenPages,oddPages;
+ IntervalSet pageRange;
+
+ bool mirror;
+
+ Position xpos,ypos;
+
+ bool collate;
+
+ bool evenDuplex; // make number of pages a multiple of 2
+
+ BookletMode booklet;
+ int bookSignature;
+
+ bool autoRotate;
+
+ // ppd/jcl changes
+ bool emitJCL;
+ int deviceCopies;
+ bool deviceReverse;
+ bool deviceCollate;
+ bool setDuplex;
+ // unsetMirror (always)
+
+ int page_logging;
+ int copies_to_be_logged;
+
+ // helper functions
+ bool withPage(int outno) const; // 1 based
+ void dump() const;
+};
+
+#include <stdio.h>
+#include <memory>
+
+enum ArgOwnership { WillStayAlive,MustDuplicate,TakeOwnership };
+
+class PDFTOPDF_PageHandle {
+ public:
+ virtual ~PDFTOPDF_PageHandle() {}
+ virtual PageRect getRect() const =0;
+ // fscale: inverse_scale (from nup, fitplot)
+ virtual void add_border_rect(const PageRect &rect,BorderType border,float fscale) =0;
+ // TODO?! add standalone crop(...) method (not only for subpages)
+ virtual void add_subpage(const std::shared_ptr<PDFTOPDF_PageHandle> &sub,float xpos,float ypos,float scale,const PageRect *crop=NULL) =0;
+ virtual void mirror() =0;
+ virtual void rotate(Rotation rot) =0;
+ virtual void add_label(const PageRect &rect, const std::string label) =0;
+};
+
+// TODO: ... error output?
+class PDFTOPDF_Processor { // abstract interface
+ public:
+ virtual ~PDFTOPDF_Processor() {}
+
+ // TODO: ... qpdf wants password at load time
+ virtual bool loadFile(FILE *f,ArgOwnership take=WillStayAlive) =0;
+ virtual bool loadFilename(const char *name) =0;
+
+ // TODO? virtual bool may_modify/may_print/?
+ virtual bool check_print_permissions() =0;
+
+ virtual std::vector<std::shared_ptr<PDFTOPDF_PageHandle>> get_pages() =0; // shared_ptr because of type erasure (deleter)
+
+ virtual std::shared_ptr<PDFTOPDF_PageHandle> new_page(float width,float height) =0;
+
+ virtual void add_page(std::shared_ptr<PDFTOPDF_PageHandle> page,bool front) =0; // at back/front -- either from get_pages() or new_page()+add_subpage()-calls (or [also allowed]: empty)
+
+ // void remove_page(std::shared_ptr<PDFTOPDF_PageHandle> ph); // not needed: we construct from scratch, at least conceptually.
+
+ virtual void multiply(int copies,bool collate) =0;
+
+ virtual void autoRotateAll(bool dst_lscape,Rotation normal_landscape) =0; // TODO elsewhere?!
+ virtual void addCM(const char *defaulticc,const char *outputicc) =0;
+
+ virtual void setComments(const std::vector<std::string> &comments) =0;
+
+ virtual void emitFile(FILE *dst,ArgOwnership take=WillStayAlive) =0;
+ virtual void emitFilename(const char *name) =0; // NULL -> stdout
+
+ virtual bool hasAcroForm() =0;
+};
+
+class PDFTOPDF_Factory {
+ public:
+ // never NULL, but may throw.
+ static PDFTOPDF_Processor *processor();
+};
+
+//bool checkBookletSignature(int signature) { return (signature%4==0); }
+std::vector<int> bookletShuffle(int numPages,int signature=-1);
+
+// This is all we want:
+bool processPDFTOPDF(PDFTOPDF_Processor &proc,ProcessingParameters &param);
+
+#endif
diff --git a/filter/pdftopdf/pptypes.cc b/filter/pdftopdf/pptypes.cc
new file mode 100644
index 000000000..542176685
--- /dev/null
+++ b/filter/pdftopdf/pptypes.cc
@@ -0,0 +1,177 @@
+#include "pptypes.h"
+#include <utility>
+#include <stdio.h>
+#include <assert.h>
+
+void Position_dump(Position pos) // {{{
+{
+ static const char *pstr[3]={"Left/Bottom","Center","Right/Top"};
+ if ((pos < LEFT) || (pos > RIGHT)) {
+ fprintf(stderr,"(bad position: %d)",pos);
+ } else {
+ fputs(pstr[pos+1],stderr);
+ }
+}
+// }}}
+
+void Position_dump(Position pos,Axis axis) // {{{
+{
+ assert((axis == Axis::X) || (axis == Axis::Y));
+ if ((pos < LEFT) || (pos > RIGHT)) {
+ fprintf(stderr,"(bad position: %d)",pos);
+ return;
+ }
+ if (axis==Axis::X) {
+ static const char *pxstr[3]={"Left","Center","Right"};
+ fputs(pxstr[pos+1],stderr);
+ } else {
+ static const char *pystr[3]={"Bottom","Center","Top"};
+ fputs(pystr[pos+1],stderr);
+ }
+}
+// }}}
+
+void Rotation_dump(Rotation rot) // {{{
+{
+ static const char *rstr[4]={"0 deg","90 deg","180 deg","270 deg"}; // CCW
+ if ((rot < ROT_0) || (rot > ROT_270)) {
+ fprintf(stderr,"(bad rotation: %d)",rot);
+ } else {
+ fputs(rstr[rot],stderr);
+ }
+}
+// }}}
+
+Rotation operator+(Rotation lhs,Rotation rhs) // {{{
+{
+ return (Rotation)(((int)lhs+(int)rhs)%4);
+}
+// }}}
+
+Rotation operator-(Rotation lhs,Rotation rhs) // {{{
+{
+ return (Rotation)((((int)lhs-(int)rhs)%4+4)%4);
+}
+// }}}
+
+Rotation operator-(Rotation rhs) // {{{
+{
+ return (Rotation)((4-(int)rhs)%4);
+}
+// }}}
+
+void BorderType_dump(BorderType border) // {{{
+{
+ if ((border < NONE) || (border == 1) || (border > TWO_THICK)) {
+ fprintf(stderr,"(bad border: %d)",border);
+ } else {
+ static const char *bstr[6]={"None",NULL,"one thin","one thick","two thin","two thick"};
+ fputs(bstr[border],stderr);
+ }
+}
+// }}}
+
+void PageRect::rotate_move(Rotation r,float pwidth,float pheight) // {{{
+{
+#if 1
+ if (r>=ROT_180) {
+ std::swap(top,bottom);
+ std::swap(left,right);
+ }
+ if ((r == ROT_90) || (r == ROT_270)) {
+ const float tmp=bottom;
+ bottom=left;
+ left=top;
+ top=right;
+ right=tmp;
+
+ std::swap(width,height);
+ std::swap(pwidth,pheight);
+ }
+ if ((r == ROT_90) || (r == ROT_180)) {
+ left=pwidth-left;
+ right=pwidth-right;
+ }
+ if ((r == ROT_270) || (r == ROT_180)) {
+ top=pheight-top;
+ bottom=pheight-bottom;
+ }
+#else
+ switch (r) {
+ case ROT_0: // no-op
+ break;
+ case ROT_90:
+ const float tmp0=bottom;
+ bottom=left;
+ left=pheight-top;
+ top=right;
+ right=pheight-tmp0;
+
+ std::swap(width,height);
+ break;
+ case ROT_180:
+ const float tmp1=left;
+ left=pwidth-right;
+ right=pwidth-tmp1;
+
+ const float tmp2=top;
+ top=pheight-bottom;
+ bottom=pheight-tmp2;
+ break;
+ case ROT_270:
+ const float tmp3=top;
+ top=pwidth-left;
+ left=bottom;
+ bottom=pwidth-right;
+ right=tmp3;
+
+ std::swap(width,height);
+ break;
+ }
+#endif
+}
+// }}}
+
+void PageRect::scale(float mult) // {{{
+{
+ if (mult==1.0) {
+ return;
+ }
+ assert(mult!=0.0);
+
+ bottom*=mult;
+ left*=mult;
+ top*=mult;
+ right*=mult;
+
+ width*=mult;
+ height*=mult;
+}
+// }}}
+
+void PageRect::translate(float tx,float ty) // {{{
+{
+ left+=tx;
+ bottom+=ty;
+ right+=tx;
+ top+=ty;
+}
+// }}}
+
+void PageRect::set(const PageRect &rhs) // {{{
+{
+ if (!std::isnan(rhs.top)) top=rhs.top;
+ if (!std::isnan(rhs.left)) left=rhs.left;
+ if (!std::isnan(rhs.right)) right=rhs.right;
+ if (!std::isnan(rhs.bottom)) bottom=rhs.bottom;
+}
+// }}}
+
+void PageRect::dump() const // {{{
+{
+ fprintf(stderr,"top: %f, left: %f, right: %f, bottom: %f\n"
+ "width: %f, height: %f\n",
+ top,left,right,bottom,
+ width,height);
+}
+// }}}
diff --git a/filter/pdftopdf/pptypes.h b/filter/pdftopdf/pptypes.h
new file mode 100644
index 000000000..4f4df6d4d
--- /dev/null
+++ b/filter/pdftopdf/pptypes.h
@@ -0,0 +1,39 @@
+#ifndef PPTYPES_H_
+#define PPTYPES_H_
+
+#include <cmath> // NAN
+
+// namespace PPTypes {} TODO?
+
+enum Axis { X, Y };
+enum Position { CENTER=0, LEFT=-1, RIGHT=1, TOP=1, BOTTOM=-1 }; // PS order
+void Position_dump(Position pos);
+void Position_dump(Position pos,Axis axis);
+
+enum Rotation { ROT_0, ROT_90, ROT_180, ROT_270 }; // CCW
+void Rotation_dump(Rotation rot);
+Rotation operator+(Rotation lhs,Rotation rhs);
+Rotation operator-(Rotation lhs,Rotation rhs);
+Rotation operator-(Rotation rhs);
+//Rotation operator+=(Rotation &lhs,Rotation rhs);
+
+enum BorderType { NONE=0, ONE_THIN=2, ONE_THICK=3, TWO_THIN=4, TWO_THICK=5,
+ ONE=0x02, TWO=0x04, THICK=0x01};
+void BorderType_dump(BorderType border);
+
+struct PageRect {
+PageRect() : top(NAN),left(NAN),right(NAN),bottom(NAN),width(NAN),height(NAN) {}
+ float top,left,right,bottom; // i.e. margins
+ float width,height;
+
+ void rotate_move(Rotation r,float pwidth,float pheight); // pwidth original "page size" (i.e. before rotation)
+ void scale(float mult);
+ void translate(float tx,float ty);
+
+ void set(const PageRect &rhs); // only for rhs.* != NAN
+ void dump() const;
+};
+
+// bool parseBorder(const char *val,BorderType &ret); // none,single,...,double-thick
+
+#endif
diff --git a/filter/pdftopdf/qpdf_cm.cc b/filter/pdftopdf/qpdf_cm.cc
new file mode 100644
index 000000000..f5ee6ab37
--- /dev/null
+++ b/filter/pdftopdf/qpdf_cm.cc
@@ -0,0 +1,151 @@
+#include "qpdf_cm.h"
+#include <stdio.h>
+#include <assert.h>
+
+#include <stdexcept>
+
+// TODO? instead use qpdf's StreamDataProvider, FileInputSource, Buffer etc.
+static std::string load_file(const char *filename) // {{{
+{
+ if (!filename) {
+ throw std::invalid_argument("NULL filename not allowed");
+ }
+
+ FILE *f=fopen(filename,"r");
+ if (!f) {
+ throw std::runtime_error(std::string("file ") + filename + " could not be opened");
+ }
+
+ const int bsize=2048;
+ int pos=0;
+
+ std::string ret;
+ while (!feof(f)) {
+ ret.resize(pos+bsize);
+ int res=fread(&ret[pos],1,bsize,f);
+ pos+=res;
+ if (res<bsize) {
+ ret.resize(pos);
+ break;
+ }
+ }
+
+ fclose(f);
+ return ret;
+}
+// }}}
+
+
+// TODO?
+// TODO? test
+bool hasOutputIntent(QPDF &pdf) // {{{
+{
+ auto catalog=pdf.getRoot();
+ if (!catalog.hasKey("/OutputIntents")) {
+ return false;
+ }
+ return true; // TODO?
+}
+// }}}
+
+// TODO: test
+// TODO? find existing , replace and return (?)
+void addOutputIntent(QPDF &pdf,const char *filename) // {{{
+{
+ std::string icc=load_file(filename);
+ // TODO: check icc fitness
+ // ICC data, subject to "version limitations" per pdf version...
+
+ QPDFObjectHandle outicc=QPDFObjectHandle::newStream(&pdf,icc);
+
+ auto sdict=outicc.getDict();
+ sdict.replaceKey("/N",QPDFObjectHandle::newInteger(4)); // must match ICC
+ // /Range ? // must match ICC, default [0.0 1.0 ...]
+ // /Alternate ? (/DeviceCMYK for N=4)
+
+ auto intent=QPDFObjectHandle::parse(
+ "<<"
+ " /Type /OutputIntent" // Must be so (the standard requires).
+ " /S /GTS_PDFX" // Must be so (the standard requires).
+ " /OutputCondition (Commercial and specialty printing)" // TODO: Customize [optional(?)]
+ " /Info (none)" // TODO: Customize
+ " /OutputConditionIdentifier (CGATS TR001)" // TODO: FIXME: Customize
+ " /RegistryName (http://www.color.org)" // Must be so (the standard requires).
+ " /DestOutputProfile null "
+ ">>");
+ intent.replaceKey("/DestOutputProfile",outicc);
+
+ auto catalog=pdf.getRoot();
+ if (!catalog.hasKey("/OutputIntents")) {
+ catalog.replaceKey("/OutputIntents",QPDFObjectHandle::newArray());
+ }
+ catalog.getKey("/OutputIntents").appendItem(intent);
+}
+// }}}
+
+
+/* for color management:
+ Use /DefaultGray, /DefaultRGB, /DefaultCMYK ... from *current* resource dictionary ...
+ i.e. set
+ /Resources <<
+ /ColorSpace << --- can use just one indirect ref for this (probably)
+ /DefaultRGB [/ICCBased 5 0 R] ... sensible use is sRGB for DefaultRGB, etc.
+ >>
+ >>
+ for every page (what with form /XObjects?) and most importantly RGB (leave CMYK, Gray for now, as this is already printer native(?))
+
+ ? also every form XObject, pattern, type3 font, annotation appearance stream(=form xobject +X)
+
+ ? what if page already defines /Default? -- probably keep!
+
+ ? maybe we need to set /ColorSpace in /Images ? [gs idea is to just add the /Default-key and then reprocess...]
+
+*/
+
+// TODO? test
+void addDefaultRGB(QPDF &pdf,QPDFObjectHandle srcicc) // {{{
+{
+ srcicc.assertStream();
+
+ auto pages=pdf.getAllPages();
+ for (auto it=pages.begin(),end=pages.end();it!=end;++it) {
+ if (!it->hasKey("/Resources")) {
+ it->replaceKey("/Resources",QPDFObjectHandle::newDictionary());
+ }
+ auto rdict=it->getKey("/Resources");
+
+ if (!rdict.hasKey("/ColorSpace")) {
+ rdict.replaceKey("/ColorSpace",QPDFObjectHandle::newDictionary());
+ }
+ auto cdict=rdict.getKey("/ColorSpace");
+
+ if (!cdict.hasKey("/DefaultRGB")) {
+ cdict.replaceKey("/DefaultRGB",QPDFObjectHandle::parse("[/ICCBased ]"));
+ cdict.getKey("/DefaultRGB").appendItem(srcicc);
+ }
+ }
+}
+// }}}
+
+// TODO? test
+// TODO: find existing , replace and return (?)
+// TODO: check icc fitness
+QPDFObjectHandle setDefaultICC(QPDF &pdf,const char *filename) // {{{
+{
+ // TODO: find existing , replace and return (?)
+
+ std::string icc=load_file(filename);
+ // TODO: check icc fitness
+ // ICC data, subject to "version limitations" per pdf version...
+
+ QPDFObjectHandle ret=QPDFObjectHandle::newStream(&pdf,icc);
+
+ auto sdict=ret.getDict();
+ sdict.replaceKey("/N",QPDFObjectHandle::newInteger(3)); // must match ICC
+ // /Range ? // must match ICC, default [0.0 1.0 ...]
+ // /Alternate ? (/DeviceRGB for N=3)
+
+ return ret;
+}
+// }}}
+
diff --git a/filter/pdftopdf/qpdf_cm.h b/filter/pdftopdf/qpdf_cm.h
new file mode 100644
index 000000000..5eb27596f
--- /dev/null
+++ b/filter/pdftopdf/qpdf_cm.h
@@ -0,0 +1,12 @@
+#ifndef QPDF_CM_H_
+#define QPDF_CM_H_
+
+#include <qpdf/QPDF.hh>
+
+bool hasOutputIntent(QPDF &pdf);
+void addOutputIntent(QPDF &pdf,const char *filename);
+
+void addDefaultRGB(QPDF &pdf,QPDFObjectHandle srcicc);
+QPDFObjectHandle setDefaultICC(QPDF &pdf,const char *filename);
+
+#endif
diff --git a/filter/pdftopdf/qpdf_pdftopdf.cc b/filter/pdftopdf/qpdf_pdftopdf.cc
new file mode 100644
index 000000000..68cd8ef41
--- /dev/null
+++ b/filter/pdftopdf/qpdf_pdftopdf.cc
@@ -0,0 +1,225 @@
+#include "qpdf_pdftopdf.h"
+#include <assert.h>
+#include <stdexcept>
+#include <qpdf/QUtil.hh>
+
+PageRect getBoxAsRect(QPDFObjectHandle box) // {{{
+{
+ PageRect ret;
+
+ ret.left=box.getArrayItem(0).getNumericValue();
+ ret.bottom=box.getArrayItem(1).getNumericValue();
+ ret.right=box.getArrayItem(2).getNumericValue();
+ ret.top=box.getArrayItem(3).getNumericValue();
+
+ ret.width=ret.right-ret.left;
+ ret.height=ret.top-ret.bottom;
+
+ return ret;
+}
+// }}}
+
+Rotation getRotate(QPDFObjectHandle page) // {{{
+{
+ if (!page.hasKey("/Rotate")) {
+ return ROT_0;
+ }
+ double rot=page.getKey("/Rotate").getNumericValue();
+ rot=fmod(rot,360.0);
+ if (rot<0) {
+ rot+=360.0;
+ }
+ if (rot==90.0) { // CW
+ return ROT_270; // CCW
+ } else if (rot==180.0) {
+ return ROT_180;
+ } else if (rot==270.0) {
+ return ROT_90;
+ } else if (rot!=0.0) {
+ throw std::runtime_error("Unexpected /Rotation value: "+QUtil::double_to_string(rot));
+ }
+ return ROT_0;
+}
+// }}}
+
+double getUserUnit(QPDFObjectHandle page) // {{{
+{
+ if (!page.hasKey("/UserUnit")) {
+ return 1.0;
+ }
+ return page.getKey("/UserUnit").getNumericValue();
+}
+// }}}
+
+QPDFObjectHandle makeRotate(Rotation rot) // {{{
+{
+ switch (rot) {
+ case ROT_0:
+ return QPDFObjectHandle::newNull();
+ case ROT_90: // CCW
+ return QPDFObjectHandle::newInteger(270); // CW
+ case ROT_180:
+ return QPDFObjectHandle::newInteger(180);
+ case ROT_270:
+ return QPDFObjectHandle::newInteger(90);
+ default:
+ throw std::invalid_argument("Bad rotation");
+ }
+}
+// }}}
+
+#include "qpdf_tools.h"
+
+QPDFObjectHandle getRectAsBox(const PageRect &rect) // {{{
+{
+ return makeBox(rect.left,rect.bottom,rect.right,rect.top);
+}
+// }}}
+
+#include <qpdf/QUtil.hh>
+
+Matrix::Matrix() // {{{
+ : ctm{1,0,0,1,0,0}
+{
+}
+// }}}
+
+Matrix::Matrix(QPDFObjectHandle ar) // {{{
+{
+ if (ar.getArrayNItems()!=6) {
+ throw std::runtime_error("Not a ctm matrix");
+ }
+ for (int iA=0;iA<6;iA++) {
+ ctm[iA]=ar.getArrayItem(iA).getNumericValue();
+ }
+}
+// }}}
+
+Matrix &Matrix::rotate(Rotation rot) // {{{
+{
+ switch (rot) {
+ case ROT_0:
+ break;
+ case ROT_90:
+ std::swap(ctm[0],ctm[2]);
+ std::swap(ctm[1],ctm[3]);
+ ctm[2]=-ctm[2];
+ ctm[3]=-ctm[3];
+ break;
+ case ROT_180:
+ ctm[0]=-ctm[0];
+ ctm[3]=-ctm[3];
+ break;
+ case ROT_270:
+ std::swap(ctm[0],ctm[2]);
+ std::swap(ctm[1],ctm[3]);
+ ctm[0]=-ctm[0];
+ ctm[1]=-ctm[1];
+ break;
+ default:
+ assert(0);
+ }
+ return *this;
+}
+// }}}
+
+// TODO: test
+Matrix &Matrix::rotate_move(Rotation rot,double width,double height) // {{{
+{
+ rotate(rot);
+ switch (rot) {
+ case ROT_0:
+ break;
+ case ROT_90:
+ translate(width,0);
+ break;
+ case ROT_180:
+ translate(width,height);
+ break;
+ case ROT_270:
+ translate(0,height);
+ break;
+ }
+ return *this;
+}
+// }}}
+
+Matrix &Matrix::rotate(double rad) // {{{
+{
+ Matrix tmp;
+
+ tmp.ctm[0]=cos(rad);
+ tmp.ctm[1]=sin(rad);
+ tmp.ctm[2]=-sin(rad);
+ tmp.ctm[3]=cos(rad);
+
+ return (*this*=tmp);
+}
+// }}}
+
+Matrix &Matrix::translate(double tx,double ty) // {{{
+{
+ ctm[4]+=ctm[0]*tx+ctm[2]*ty;
+ ctm[5]+=ctm[1]*tx+ctm[3]*ty;
+ return *this;
+}
+// }}}
+
+Matrix &Matrix::scale(double sx,double sy) // {{{
+{
+ ctm[0]*=sx;
+ ctm[1]*=sx;
+ ctm[2]*=sy;
+ ctm[3]*=sy;
+ return *this;
+}
+// }}}
+
+Matrix &Matrix::operator*=(const Matrix &rhs) // {{{
+{
+ double tmp[6];
+ std::copy(ctm,ctm+6,tmp);
+
+ ctm[0] = tmp[0]*rhs.ctm[0] + tmp[2]*rhs.ctm[1];
+ ctm[1] = tmp[1]*rhs.ctm[0] + tmp[3]*rhs.ctm[1];
+
+ ctm[2] = tmp[0]*rhs.ctm[2] + tmp[2]*rhs.ctm[3];
+ ctm[3] = tmp[1]*rhs.ctm[2] + tmp[3]*rhs.ctm[3];
+
+ ctm[4] = tmp[0]*rhs.ctm[4] + tmp[2]*rhs.ctm[5] + tmp[4];
+ ctm[5] = tmp[1]*rhs.ctm[4] + tmp[3]*rhs.ctm[5] + tmp[5];
+
+ return *this;
+}
+// }}}
+
+QPDFObjectHandle Matrix::get() const // {{{
+{
+ QPDFObjectHandle ret=QPDFObjectHandle::newArray();
+ ret.appendItem(QPDFObjectHandle::newReal(ctm[0]));
+ ret.appendItem(QPDFObjectHandle::newReal(ctm[1]));
+ ret.appendItem(QPDFObjectHandle::newReal(ctm[2]));
+ ret.appendItem(QPDFObjectHandle::newReal(ctm[3]));
+ ret.appendItem(QPDFObjectHandle::newReal(ctm[4]));
+ ret.appendItem(QPDFObjectHandle::newReal(ctm[5]));
+ return ret;
+}
+// }}}
+
+std::string Matrix::get_string() const // {{{
+{
+ std::string ret;
+ ret.append(QUtil::double_to_string(ctm[0]));
+ ret.append(" ");
+ ret.append(QUtil::double_to_string(ctm[1]));
+ ret.append(" ");
+ ret.append(QUtil::double_to_string(ctm[2]));
+ ret.append(" ");
+ ret.append(QUtil::double_to_string(ctm[3]));
+ ret.append(" ");
+ ret.append(QUtil::double_to_string(ctm[4]));
+ ret.append(" ");
+ ret.append(QUtil::double_to_string(ctm[5]));
+ return ret;
+}
+// }}}
diff --git a/filter/pdftopdf/qpdf_pdftopdf.h b/filter/pdftopdf/qpdf_pdftopdf.h
new file mode 100644
index 000000000..9cb1536bc
--- /dev/null
+++ b/filter/pdftopdf/qpdf_pdftopdf.h
@@ -0,0 +1,41 @@
+#ifndef QPDF_PDFTOPDF_H
+#define QPDF_PDFTOPDF_H
+
+#include <qpdf/QPDFObjectHandle.hh>
+#include "pptypes.h"
+
+// helper functions
+
+PageRect getBoxAsRect(QPDFObjectHandle box);
+QPDFObjectHandle getRectAsBox(const PageRect &rect);
+
+// Note that PDF specification is CW, but our Rotation is CCW
+Rotation getRotate(QPDFObjectHandle page);
+QPDFObjectHandle makeRotate(Rotation rot); // Integer
+
+double getUserUnit(QPDFObjectHandle page);
+
+// PDF CTM
+class Matrix {
+ public:
+ Matrix(); // identity
+ Matrix(QPDFObjectHandle ar);
+
+ Matrix &rotate(Rotation rot);
+ Matrix &rotate_move(Rotation rot,double width,double height);
+ Matrix &rotate(double rad);
+ // Matrix &rotate_deg(double deg);
+
+ Matrix &translate(double tx,double ty);
+ Matrix &scale(double sx,double sy);
+ Matrix &scale(double s) { return scale(s,s); }
+
+ Matrix &operator*=(const Matrix &rhs);
+
+ QPDFObjectHandle get() const;
+ std::string get_string() const;
+ private:
+ double ctm[6];
+};
+
+#endif
diff --git a/filter/pdftopdf/qpdf_pdftopdf_processor.cc b/filter/pdftopdf/qpdf_pdftopdf_processor.cc
new file mode 100644
index 000000000..73e4f0669
--- /dev/null
+++ b/filter/pdftopdf/qpdf_pdftopdf_processor.cc
@@ -0,0 +1,663 @@
+#include "qpdf_pdftopdf_processor.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <stdexcept>
+#include <qpdf/QPDFWriter.hh>
+#include <qpdf/QUtil.hh>
+#include "qpdf_tools.h"
+#include "qpdf_xobject.h"
+#include "qpdf_pdftopdf.h"
+
+// Use: content.append(debug_box(pe.sub,xpos,ypos));
+static std::string debug_box(const PageRect &box,float xshift,float yshift) // {{{
+{
+ return std::string("q 1 w 0.1 G\n ")+
+ QUtil::double_to_string(box.left+xshift)+" "+QUtil::double_to_string(box.bottom+yshift)+" m "+
+ QUtil::double_to_string(box.right+xshift)+" "+QUtil::double_to_string(box.top+yshift)+" l "+"S \n "+
+
+ QUtil::double_to_string(box.right+xshift)+" "+QUtil::double_to_string(box.bottom+yshift)+" m "+
+ QUtil::double_to_string(box.left+xshift)+" "+QUtil::double_to_string(box.top+yshift)+" l "+"S \n "+
+
+ QUtil::double_to_string(box.left+xshift)+" "+QUtil::double_to_string(box.bottom+yshift)+" "+
+ QUtil::double_to_string(box.right-box.left)+" "+QUtil::double_to_string(box.top-box.bottom)+" re "+"S Q\n";
+}
+// }}}
+
+QPDF_PDFTOPDF_PageHandle::QPDF_PDFTOPDF_PageHandle(QPDFObjectHandle page,int orig_no) // {{{
+ : page(page),
+ no(orig_no),
+ rotation(ROT_0)
+{
+}
+// }}}
+
+QPDF_PDFTOPDF_PageHandle::QPDF_PDFTOPDF_PageHandle(QPDF *pdf,float width,float height) // {{{
+ : no(0),
+ rotation(ROT_0)
+{
+ assert(pdf);
+ page=QPDFObjectHandle::parse(
+ "<<"
+ " /Type /Page"
+ " /Resources <<"
+ " /XObject null "
+ " >>"
+ " /MediaBox null "
+ " /Contents null "
+ ">>");
+ page.replaceKey("/MediaBox",makeBox(0,0,width,height));
+ page.replaceKey("/Contents",QPDFObjectHandle::newStream(pdf));
+ // xobjects: later (in get())
+ content.assign("q\n"); // TODO? different/not needed
+
+ page=pdf->makeIndirectObject(page); // stores *pdf
+}
+// }}}
+
+// Note: PDFTOPDF_Processor always works with "/Rotate"d and "/UserUnit"-scaled pages/coordinates/..., having 0,0 at left,bottom of the TrimBox
+PageRect QPDF_PDFTOPDF_PageHandle::getRect() const // {{{
+{
+ page.assertInitialized();
+ PageRect ret=getBoxAsRect(getTrimBox(page));
+ ret.translate(-ret.left,-ret.bottom);
+ ret.rotate_move(getRotate(page),ret.width,ret.height);
+ ret.scale(getUserUnit(page));
+ return ret;
+}
+// }}}
+
+bool QPDF_PDFTOPDF_PageHandle::isExisting() const // {{{
+{
+ page.assertInitialized();
+ return content.empty();
+}
+// }}}
+
+QPDFObjectHandle QPDF_PDFTOPDF_PageHandle::get() // {{{
+{
+ QPDFObjectHandle ret=page;
+ if (!isExisting()) { // finish up page
+ page.getKey("/Resources").replaceKey("/XObject",QPDFObjectHandle::newDictionary(xobjs));
+ content.append("Q\n");
+ page.getKey("/Contents").replaceStreamData(content,QPDFObjectHandle::newNull(),QPDFObjectHandle::newNull());
+ page.replaceOrRemoveKey("/Rotate",makeRotate(rotation));
+ } else {
+ Rotation rot=getRotate(page)+rotation;
+ page.replaceOrRemoveKey("/Rotate",makeRotate(rot));
+ }
+ page=QPDFObjectHandle(); // i.e. uninitialized
+ return ret;
+}
+// }}}
+
+// TODO: we probably need a function "ungetRect()" to transform to page/form space
+// TODO: as member
+static PageRect ungetRect(PageRect rect,const QPDF_PDFTOPDF_PageHandle &ph,Rotation rotation,QPDFObjectHandle page)
+{
+ PageRect pg1=ph.getRect();
+ PageRect pg2=getBoxAsRect(getTrimBox(page));
+
+ // we have to invert /Rotate, /UserUnit and the left,bottom (TrimBox) translation
+ //Rotation_dump(rotation);
+ //Rotation_dump(getRotate(page));
+ rect.width=pg1.width;
+ rect.height=pg1.height;
+ //std::swap(rect.width,rect.height);
+ //rect.rotate_move(-rotation,rect.width,rect.height);
+
+ rect.rotate_move(-getRotate(page),pg1.width,pg1.height);
+ rect.scale(1.0/getUserUnit(page));
+
+ // PageRect pg2=getBoxAsRect(getTrimBox(page));
+ rect.translate(pg2.left,pg2.bottom);
+ //rect.dump();
+
+ return rect;
+}
+
+// TODO FIXME rotations are strange ... (via ungetRect)
+// TODO? for non-existing (either drop comment or facility to create split streams needed)
+void QPDF_PDFTOPDF_PageHandle::add_border_rect(const PageRect &_rect,BorderType border,float fscale) // {{{
+{
+ assert(isExisting());
+ assert(border!=BorderType::NONE);
+
+ // straight from pstops
+ const double lw=(border&THICK)?0.5:0.24;
+ double line_width=lw*fscale;
+ double margin=2.25*fscale;
+ // (PageLeft+margin,PageBottom+margin) rect (PageRight-PageLeft-2*margin,...) ... for nup>1: PageLeft=0,etc.
+ // if (double) margin+=2*fscale ...rect...
+
+ PageRect rect=ungetRect(_rect,*this,rotation,page);
+
+ assert(rect.left<=rect.right);
+ assert(rect.bottom<=rect.top);
+
+ std::string boxcmd="q\n";
+ boxcmd+=" "+QUtil::double_to_string(line_width)+" w 0 G \n";
+ boxcmd+=" "+QUtil::double_to_string(rect.left+margin)+" "+QUtil::double_to_string(rect.bottom+margin)+" "+
+ QUtil::double_to_string(rect.right-rect.left-2*margin)+" "+QUtil::double_to_string(rect.top-rect.bottom-2*margin)+" re S \n";
+ if (border&TWO) {
+ margin+=2*fscale;
+ boxcmd+=" "+QUtil::double_to_string(rect.left+margin)+" "+QUtil::double_to_string(rect.bottom+margin)+" "+
+ QUtil::double_to_string(rect.right-rect.left-2*margin)+" "+QUtil::double_to_string(rect.top-rect.bottom-2*margin)+" re S \n";
+ }
+ boxcmd+="Q\n";
+
+ // if (!isExisting()) {
+ // // TODO: only after
+ // return;
+ // }
+
+ assert(page.getOwningQPDF()); // existing pages are always indirect
+#ifdef DEBUG // draw it on top
+ static const char *pre="%pdftopdf q\n"
+ "q\n",
+ *post="%pdftopdf Q\n"
+ "Q\n";
+
+ QPDFObjectHandle stm1=QPDFObjectHandle::newStream(page.getOwningQPDF(),pre),
+ stm2=QPDFObjectHandle::newStream(page.getOwningQPDF(),std::string(post)+boxcmd);
+
+ page.addPageContents(stm1,true); // before
+ page.addPageContents(stm2,false); // after
+#else
+ QPDFObjectHandle stm=QPDFObjectHandle::newStream(page.getOwningQPDF(),boxcmd);
+ page.addPageContents(stm,true); // before
+#endif
+}
+// }}}
+
+// TODO: better cropping
+// TODO: test/fix with qsub rotation
+void QPDF_PDFTOPDF_PageHandle::add_subpage(const std::shared_ptr<PDFTOPDF_PageHandle> &sub,float xpos,float ypos,float scale,const PageRect *crop) // {{{
+{
+ auto qsub=dynamic_cast<QPDF_PDFTOPDF_PageHandle *>(sub.get());
+ assert(qsub);
+
+ std::string xoname="/X"+QUtil::int_to_string((qsub->no!=-1)?qsub->no:++no);
+ if (crop) {
+ PageRect pg=qsub->getRect(),tmp=*crop;
+ // we need to fix a too small cropbox.
+ tmp.width=tmp.right-tmp.left;
+ tmp.height=tmp.top-tmp.bottom;
+ tmp.rotate_move(-getRotate(qsub->page),tmp.width,tmp.height); // TODO TODO (pg.width? / unneeded?)
+ // TODO: better
+ // TODO: we need to obey page./Rotate
+ if (pg.width<tmp.width) {
+ pg.right=pg.left+tmp.width;
+ }
+ if (pg.height<tmp.height) {
+ pg.top=pg.bottom+tmp.height;
+ }
+
+ PageRect rect=ungetRect(pg,*qsub,ROT_0,qsub->page);
+
+ qsub->page.replaceKey("/TrimBox",makeBox(rect.left,rect.bottom,rect.right,rect.top));
+ // TODO? do everything for cropping here?
+ }
+ xobjs[xoname]=makeXObject(qsub->page.getOwningQPDF(),qsub->page); // trick: should be the same as page->getOwningQPDF() [only after it's made indirect]
+
+ Matrix mtx;
+ mtx.translate(xpos,ypos);
+ mtx.scale(scale);
+ mtx.rotate(qsub->rotation); // TODO? -sub.rotation ? // TODO FIXME: this might need another translation!?
+ if (crop) { // TODO? other technique: set trim-box before makeXObject (but this modifies original page)
+ mtx.translate(crop->left,crop->bottom);
+ // crop->dump();
+ }
+
+ content.append("q\n ");
+ content.append(mtx.get_string()+" cm\n ");
+ if (crop) {
+ content.append("0 0 "+QUtil::double_to_string(crop->right-crop->left)+" "+QUtil::double_to_string(crop->top-crop->bottom)+" re W n\n ");
+ // content.append("0 0 "+QUtil::double_to_string(crop->right-crop->left)+" "+QUtil::double_to_string(crop->top-crop->bottom)+" re S\n ");
+ }
+ content.append(xoname+" Do\n");
+ content.append("Q\n");
+}
+// }}}
+
+void QPDF_PDFTOPDF_PageHandle::mirror() // {{{
+{
+ PageRect orig=getRect();
+
+ if (isExisting()) {
+ // need to wrap in XObject to keep patterns correct
+ // TODO? refactor into internal ..._subpage fn ?
+ std::string xoname="/X"+QUtil::int_to_string(no);
+
+ QPDFObjectHandle subpage=get(); // this->page, with rotation
+
+ // replace all our data
+ *this=QPDF_PDFTOPDF_PageHandle(subpage.getOwningQPDF(),orig.width,orig.height);
+
+ xobjs[xoname]=makeXObject(subpage.getOwningQPDF(),subpage); // we can only now set this->xobjs
+
+ // content.append(std::string("1 0 0 1 0 0 cm\n ");
+ content.append(xoname+" Do\n");
+
+ assert(!isExisting());
+ }
+
+ static const char *pre="%pdftopdf cm\n";
+ // Note: we don't change (TODO need to?) the media box
+ std::string mrcmd("-1 0 0 1 "+
+ QUtil::double_to_string(orig.right)+" 0 cm\n");
+
+ content.insert(0,std::string(pre)+mrcmd);
+}
+// }}}
+
+void QPDF_PDFTOPDF_PageHandle::rotate(Rotation rot) // {{{
+{
+ rotation=rot; // "rotation += rot;" ?
+}
+// }}}
+
+void QPDF_PDFTOPDF_PageHandle::add_label(const PageRect &_rect, const std::string label) // {{{
+{
+ assert(isExisting());
+
+ PageRect rect = ungetRect (_rect, *this, rotation, page);
+
+ assert (rect.left <= rect.right);
+ assert (rect.bottom <= rect.top);
+
+ // TODO: Only add in the font once, not once per page.
+ QPDFObjectHandle font = page.getOwningQPDF()->makeIndirectObject
+ (QPDFObjectHandle::parse(
+ "<<"
+ " /Type /Font"
+ " /Subtype /Type1"
+ " /Name /pagelabel-font"
+ " /BaseFont /Helvetica" // TODO: support UTF-8 labels?
+ ">>"));
+ QPDFObjectHandle resources = page.getKey ("/Resources");
+ QPDFObjectHandle rfont = resources.getKey ("/Font");
+ rfont.replaceKey ("/pagelabel-font", font);
+
+ double margin = 2.25;
+ double height = 12;
+
+ std::string boxcmd = "q\n";
+
+ // White filled rectangle (top)
+ boxcmd += " 1 1 1 rg\n";
+ boxcmd += " " +
+ QUtil::double_to_string(rect.left + margin) + " " +
+ QUtil::double_to_string(rect.top - height - 2 * margin) + " " +
+ QUtil::double_to_string(rect.right - rect.left - 2 * margin) + " " +
+ QUtil::double_to_string(height + 2 * margin) + " re f\n";
+
+ // White filled rectangle (bottom)
+ boxcmd += " " +
+ QUtil::double_to_string(rect.left + margin) + " " +
+ QUtil::double_to_string(rect.bottom + height + margin) + " " +
+ QUtil::double_to_string(rect.right - rect.left - 2 * margin) + " " +
+ QUtil::double_to_string(height + 2 * margin) + " re f\n";
+
+ // Black outline (top)
+ boxcmd += " 0 0 0 RG\n";
+ boxcmd += " " +
+ QUtil::double_to_string(rect.left + margin) + " " +
+ QUtil::double_to_string(rect.top - height - 2 * margin) + " " +
+ QUtil::double_to_string(rect.right - rect.left - 2 * margin) + " " +
+ QUtil::double_to_string(height + 2 * margin) + " re S\n";
+
+ // Black outline (bottom)
+ boxcmd += " " +
+ QUtil::double_to_string(rect.left + margin) + " " +
+ QUtil::double_to_string(rect.bottom + height + margin) + " " +
+ QUtil::double_to_string(rect.right - rect.left - 2 * margin) + " " +
+ QUtil::double_to_string(height + 2 * margin) + " re S\n";
+
+ // Black text (top)
+ boxcmd += " 0 0 0 rg\n";
+ boxcmd += " BT\n";
+ boxcmd += " /pagelabel-font 12 Tf\n";
+ boxcmd += " " +
+ QUtil::double_to_string(rect.left + 2 * margin) + " " +
+ QUtil::double_to_string(rect.top - height - margin) + " Td\n";
+ boxcmd += " (" + label + ") Tj\n";
+ boxcmd += " ET\n";
+
+ // Black text (bottom)
+ boxcmd += " BT\n";
+ boxcmd += " /pagelabel-font 12 Tf\n";
+ boxcmd += " " +
+ QUtil::double_to_string(rect.left + 2 * margin) + " " +
+ QUtil::double_to_string(rect.bottom + height + 2 * margin) + " Td\n";
+ boxcmd += " (" + label + ") Tj\n";
+ boxcmd += " ET\n";
+
+ boxcmd += "Q\n";
+
+ assert(page.getOwningQPDF()); // existing pages are always indirect
+ static const char *pre="%pdftopdf q\n"
+ "q\n",
+ *post="%pdftopdf Q\n"
+ "Q\n";
+
+ QPDFObjectHandle stm1=QPDFObjectHandle::newStream(page.getOwningQPDF(),
+ std::string(pre)),
+ stm2=QPDFObjectHandle::newStream(page.getOwningQPDF(),
+ std::string(post) + boxcmd);
+
+ page.addPageContents(stm1,true); // before
+ page.addPageContents(stm2,false); // after
+}
+// }}}
+
+void QPDF_PDFTOPDF_PageHandle::debug(const PageRect &rect,float xpos,float ypos) // {{{
+{
+ assert(!isExisting());
+ content.append(debug_box(rect,xpos,ypos));
+}
+// }}}
+
+void QPDF_PDFTOPDF_Processor::closeFile() // {{{
+{
+ pdf.reset();
+ hasCM=false;
+}
+// }}}
+
+void QPDF_PDFTOPDF_Processor::error(const char *fmt,...) // {{{
+{
+ va_list ap;
+
+ va_start(ap,fmt);
+ fputs("ERROR: ",stderr);
+ vfprintf(stderr,fmt,ap);
+ fputs("\n",stderr);
+ va_end(ap);
+}
+// }}}
+
+// TODO? try/catch for PDF parsing errors?
+
+bool QPDF_PDFTOPDF_Processor::loadFile(FILE *f,ArgOwnership take) // {{{
+{
+ closeFile();
+ if (!f) {
+ throw std::invalid_argument("loadFile(NULL,...) not allowed");
+ }
+ try {
+ pdf.reset(new QPDF);
+ } catch (...) {
+ if (take==TakeOwnership) {
+ fclose(f);
+ }
+ throw;
+ }
+ switch (take) {
+ case WillStayAlive:
+ try {
+ pdf->processFile("temp file",f,false);
+ } catch (const std::exception &e) {
+ error("loadFile failed: %s",e.what());
+ return false;
+ }
+ break;
+ case TakeOwnership:
+ try {
+ pdf->processFile("temp file",f,true);
+ } catch (const std::exception &e) {
+ error("loadFile failed: %s",e.what());
+ return false;
+ }
+ break;
+ case MustDuplicate:
+ error("loadFile with MustDuplicate is not supported");
+ return false;
+ }
+ start();
+ return true;
+}
+// }}}
+
+bool QPDF_PDFTOPDF_Processor::loadFilename(const char *name) // {{{
+{
+ closeFile();
+ try {
+ pdf.reset(new QPDF);
+ pdf->processFile(name);
+ } catch (const std::exception &e) {
+ error("loadFilename failed: %s",e.what());
+ return false;
+ }
+ start();
+ return true;
+}
+// }}}
+
+void QPDF_PDFTOPDF_Processor::start() // {{{
+{
+ assert(pdf);
+
+ pdf->pushInheritedAttributesToPage();
+ orig_pages=pdf->getAllPages();
+
+ // remove them (just unlink, data still there)
+ const int len=orig_pages.size();
+ for (int iA=0;iA<len;iA++) {
+ pdf->removePage(orig_pages[iA]);
+ }
+
+ // we remove stuff that becomes defunct (probably) TODO
+ pdf->getRoot().removeKey("/PageMode");
+ pdf->getRoot().removeKey("/Outlines");
+ pdf->getRoot().removeKey("/OpenAction");
+ pdf->getRoot().removeKey("/PageLabels");
+}
+// }}}
+
+bool QPDF_PDFTOPDF_Processor::check_print_permissions() // {{{
+{
+ if (!pdf) {
+ error("No PDF loaded");
+ return false;
+ }
+ return pdf->allowPrintHighRes() || pdf->allowPrintLowRes(); // from legacy pdftopdf
+}
+// }}}
+
+std::vector<std::shared_ptr<PDFTOPDF_PageHandle>> QPDF_PDFTOPDF_Processor::get_pages() // {{{
+{
+ std::vector<std::shared_ptr<PDFTOPDF_PageHandle>> ret;
+ if (!pdf) {
+ error("No PDF loaded");
+ assert(0);
+ return ret;
+ }
+ const int len=orig_pages.size();
+ ret.reserve(len);
+ for (int iA=0;iA<len;iA++) {
+ ret.push_back(std::shared_ptr<PDFTOPDF_PageHandle>(new QPDF_PDFTOPDF_PageHandle(orig_pages[iA],iA+1)));
+ }
+ return ret;
+}
+// }}}
+
+std::shared_ptr<PDFTOPDF_PageHandle> QPDF_PDFTOPDF_Processor::new_page(float width,float height) // {{{
+{
+ if (!pdf) {
+ error("No PDF loaded");
+ assert(0);
+ return std::shared_ptr<PDFTOPDF_PageHandle>();
+ }
+ return std::shared_ptr<QPDF_PDFTOPDF_PageHandle>(new QPDF_PDFTOPDF_PageHandle(pdf.get(),width,height));
+ // return std::make_shared<QPDF_PDFTOPDF_PageHandle>(pdf.get(),width,height);
+ // problem: make_shared not friend
+}
+// }}}
+
+void QPDF_PDFTOPDF_Processor::add_page(std::shared_ptr<PDFTOPDF_PageHandle> page,bool front) // {{{
+{
+ assert(pdf);
+ auto qpage=dynamic_cast<QPDF_PDFTOPDF_PageHandle *>(page.get());
+ if (qpage) {
+ pdf->addPage(qpage->get(),front);
+ }
+}
+// }}}
+
+#if 0
+// we remove stuff now probably defunct TODO
+pdf->getRoot().removeKey("/PageMode");
+pdf->getRoot().removeKey("/Outlines");
+pdf->getRoot().removeKey("/OpenAction");
+pdf->getRoot().removeKey("/PageLabels");
+#endif
+
+void QPDF_PDFTOPDF_Processor::multiply(int copies,bool collate) // {{{
+{
+ assert(pdf);
+ assert(copies>0);
+
+ std::vector<QPDFObjectHandle> pages=pdf->getAllPages(); // need copy
+ const int len=pages.size();
+
+ if (collate) {
+ for (int iA=1;iA<copies;iA++) {
+ for (int iB=0;iB<len;iB++) {
+ pdf->addPage(pages[iB].shallowCopy(),false);
+ }
+ }
+ } else {
+ for (int iB=0;iB<len;iB++) {
+ for (int iA=1;iA<copies;iA++) {
+ pdf->addPageAt(pages[iB].shallowCopy(),false,pages[iB]);
+ }
+ }
+ }
+}
+// }}}
+
+// TODO? elsewhere?
+void QPDF_PDFTOPDF_Processor::autoRotateAll(bool dst_lscape,Rotation normal_landscape) // {{{
+{
+ assert(pdf);
+
+ const int len=orig_pages.size();
+ for (int iA=0;iA<len;iA++) {
+ QPDFObjectHandle page=orig_pages[iA];
+
+ Rotation src_rot=getRotate(page);
+
+ // copy'n'paste from QPDF_PDFTOPDF_PageHandle::getRect
+ PageRect ret=getBoxAsRect(getTrimBox(page));
+ // ret.translate(-ret.left,-ret.bottom);
+ ret.rotate_move(src_rot,ret.width,ret.height);
+ // ret.scale(getUserUnit(page));
+
+ const bool src_lscape=(ret.width>ret.height);
+ if (src_lscape!=dst_lscape) {
+ Rotation rotation=normal_landscape;
+ // TODO? other rotation direction, e.g. if (src_rot==ROT_0)&&(param.orientation==ROT_270) ... etc.
+ // rotation=ROT_270;
+
+ page.replaceOrRemoveKey("/Rotate",makeRotate(src_rot+rotation));
+ }
+ }
+}
+// }}}
+
+#include "qpdf_cm.h"
+
+// TODO
+void QPDF_PDFTOPDF_Processor::addCM(const char *defaulticc,const char *outputicc) // {{{
+{
+ assert(pdf);
+
+ if (hasOutputIntent(*pdf)) {
+ return; // nothing to do
+ }
+
+ QPDFObjectHandle srcicc=setDefaultICC(*pdf,defaulticc); // TODO? rename to putDefaultICC?
+ addDefaultRGB(*pdf,srcicc);
+
+ addOutputIntent(*pdf,outputicc);
+
+ hasCM=true;
+}
+// }}}
+
+void QPDF_PDFTOPDF_Processor::setComments(const std::vector<std::string> &comments) // {{{
+{
+ extraheader.clear();
+ const int len=comments.size();
+ for (int iA=0;iA<len;iA++) {
+ assert(comments[iA].at(0)=='%');
+ extraheader.append(comments[iA]);
+ extraheader.push_back('\n');
+ }
+}
+// }}}
+
+void QPDF_PDFTOPDF_Processor::emitFile(FILE *f,ArgOwnership take) // {{{
+{
+ if (!pdf) {
+ return;
+ }
+ QPDFWriter out(*pdf);
+ switch (take) {
+ case WillStayAlive:
+ out.setOutputFile("temp file",f,false);
+ break;
+ case TakeOwnership:
+ out.setOutputFile("temp file",f,true);
+ break;
+ case MustDuplicate:
+ error("emitFile with MustDuplicate is not supported");
+ return;
+ }
+ if (hasCM) {
+ out.setMinimumPDFVersion("1.4");
+ } else {
+ out.setMinimumPDFVersion("1.2");
+ }
+ if (!extraheader.empty()) {
+ out.setExtraHeaderText(extraheader);
+ }
+ out.write();
+}
+// }}}
+
+void QPDF_PDFTOPDF_Processor::emitFilename(const char *name) // {{{
+{
+ if (!pdf) {
+ return;
+ }
+ // special case: name==NULL -> stdout
+ QPDFWriter out(*pdf,name);
+ if (hasCM) {
+ out.setMinimumPDFVersion("1.4");
+ } else {
+ out.setMinimumPDFVersion("1.2");
+ }
+ if (!extraheader.empty()) {
+ out.setExtraHeaderText(extraheader);
+ }
+ out.write();
+}
+// }}}
+
+// TODO:
+// loadPDF(); success?
+
+bool QPDF_PDFTOPDF_Processor::hasAcroForm() // {{{
+{
+ if (!pdf) {
+ return false;
+ }
+ QPDFObjectHandle root=pdf->getRoot();
+ if (!root.hasKey("/AcroForm")) {
+ return false;
+ }
+ return true;
+}
+// }}}
diff --git a/filter/pdftopdf/qpdf_pdftopdf_processor.h b/filter/pdftopdf/qpdf_pdftopdf_processor.h
new file mode 100644
index 000000000..485b595ee
--- /dev/null
+++ b/filter/pdftopdf/qpdf_pdftopdf_processor.h
@@ -0,0 +1,73 @@
+#ifndef QPDF_PDFTOPDF_PROCESSOR_H
+#define QPDF_PDFTOPDF_PROCESSOR_H
+
+#include "pdftopdf_processor.h"
+#include <qpdf/QPDF.hh>
+
+class QPDF_PDFTOPDF_PageHandle : public PDFTOPDF_PageHandle {
+ public:
+ virtual PageRect getRect() const;
+ virtual void add_border_rect(const PageRect &rect,BorderType border,float fscale);
+ virtual void add_subpage(const std::shared_ptr<PDFTOPDF_PageHandle> &sub,float xpos,float ypos,float scale,const PageRect *crop=NULL);
+ virtual void mirror();
+ virtual void rotate(Rotation rot);
+ virtual void add_label(const PageRect &rect, const std::string label);
+
+ void debug(const PageRect &rect,float xpos,float ypos);
+ private:
+ bool isExisting() const;
+ QPDFObjectHandle get(); // only once!
+ private:
+ friend class QPDF_PDFTOPDF_Processor;
+ // 1st mode: existing
+ QPDF_PDFTOPDF_PageHandle(QPDFObjectHandle page,int orig_no=-1);
+ QPDFObjectHandle page;
+ int no;
+
+ // 2nd mode: create new
+ QPDF_PDFTOPDF_PageHandle(QPDF *pdf,float width,float height);
+ std::map<std::string,QPDFObjectHandle> xobjs;
+ std::string content;
+
+ Rotation rotation;
+};
+
+class QPDF_PDFTOPDF_Processor : public PDFTOPDF_Processor {
+ public:
+ virtual bool loadFile(FILE *f,ArgOwnership take=WillStayAlive);
+ virtual bool loadFilename(const char *name);
+
+ // TODO: virtual bool may_modify/may_print/?
+ virtual bool check_print_permissions();
+
+ // virtual bool setProcess(const ProcessingParameters &param) =0;
+
+ virtual std::vector<std::shared_ptr<PDFTOPDF_PageHandle>> get_pages();
+ virtual std::shared_ptr<PDFTOPDF_PageHandle> new_page(float width,float height);
+
+ virtual void add_page(std::shared_ptr<PDFTOPDF_PageHandle> page,bool front);
+
+ virtual void multiply(int copies,bool collate);
+
+ virtual void autoRotateAll(bool dst_lscape,Rotation normal_landscape);
+ virtual void addCM(const char *defaulticc,const char *outputicc);
+
+ virtual void setComments(const std::vector<std::string> &comments);
+
+ virtual void emitFile(FILE *dst,ArgOwnership take=WillStayAlive);
+ virtual void emitFilename(const char *name);
+
+ virtual bool hasAcroForm();
+ private:
+ void closeFile();
+ void error(const char *fmt,...);
+ void start();
+ private:
+ std::unique_ptr<QPDF> pdf;
+ std::vector<QPDFObjectHandle> orig_pages;
+
+ bool hasCM;
+ std::string extraheader;
+};
+
+#endif
diff --git a/filter/pdftopdf/qpdf_tools.cc b/filter/pdftopdf/qpdf_tools.cc
new file mode 100644
index 000000000..44cb98189
--- /dev/null
+++ b/filter/pdftopdf/qpdf_tools.cc
@@ -0,0 +1,69 @@
+#include "qpdf_tools.h"
+
+QPDFObjectHandle getMediaBox(QPDFObjectHandle page) // {{{
+{
+ return page.getKey("/MediaBox");
+}
+// }}}
+
+QPDFObjectHandle getCropBox(QPDFObjectHandle page) // {{{
+{
+ if (page.hasKey("/CropBox")) {
+ return page.getKey("/CropBox");
+ }
+ return page.getKey("/MediaBox");
+}
+// }}}
+
+QPDFObjectHandle getBleedBox(QPDFObjectHandle page) // {{{
+{
+ if (page.hasKey("/BleedBox")) {
+ return page.getKey("/BleedBox");
+ }
+ return getCropBox(page);
+}
+// }}}
+
+QPDFObjectHandle getTrimBox(QPDFObjectHandle page) // {{{
+{
+ if (page.hasKey("/TrimBox")) {
+ return page.getKey("/TrimBox");
+ }
+ return getCropBox(page);
+}
+// }}}
+
+QPDFObjectHandle getArtBox(QPDFObjectHandle page) // {{{
+{
+ if (page.hasKey("/ArtBox")) {
+ return page.getKey("/ArtBox");
+ }
+ return getCropBox(page);
+}
+// }}}
+
+QPDFObjectHandle makePage(QPDF &pdf,const std::map<std::string,QPDFObjectHandle> &xobjs,QPDFObjectHandle mediabox,const std::string &content) // {{{
+{
+ QPDFObjectHandle ret=QPDFObjectHandle::newDictionary();
+ ret.replaceKey("/Type",QPDFObjectHandle::newName("/Page"));
+
+ auto resdict=QPDFObjectHandle::newDictionary();
+ resdict.replaceKey("/XObject",QPDFObjectHandle::newDictionary(xobjs));
+ ret.replaceKey("/Resources",resdict);
+ ret.replaceKey("/MediaBox",mediabox);
+ ret.replaceKey("/Contents",QPDFObjectHandle::newStream(&pdf,content));
+
+ return ret;
+}
+// }}}
+
+QPDFObjectHandle makeBox(double x1,double y1,double x2,double y2) // {{{
+{
+ QPDFObjectHandle ret=QPDFObjectHandle::newArray();
+ ret.appendItem(QPDFObjectHandle::newReal(x1));
+ ret.appendItem(QPDFObjectHandle::newReal(y1));
+ ret.appendItem(QPDFObjectHandle::newReal(x2));
+ ret.appendItem(QPDFObjectHandle::newReal(y2));
+ return ret;
+}
+// }}}
diff --git a/filter/pdftopdf/qpdf_tools.h b/filter/pdftopdf/qpdf_tools.h
new file mode 100644
index 000000000..20a19fb2a
--- /dev/null
+++ b/filter/pdftopdf/qpdf_tools.h
@@ -0,0 +1,18 @@
+#ifndef QPDF_TOOLS_H_
+#define QPDF_TOOLS_H_
+
+#include <qpdf/QPDFObjectHandle.hh>
+#include <map>
+#include <string>
+
+QPDFObjectHandle getMediaBox(QPDFObjectHandle page);
+QPDFObjectHandle getCropBox(QPDFObjectHandle page);
+QPDFObjectHandle getBleedBox(QPDFObjectHandle page);
+QPDFObjectHandle getTrimBox(QPDFObjectHandle page);
+QPDFObjectHandle getArtBox(QPDFObjectHandle page);
+
+QPDFObjectHandle makePage(QPDF &pdf,const std::map<std::string,QPDFObjectHandle> &xobjs,QPDFObjectHandle mediabox,const std::string &content);
+
+QPDFObjectHandle makeBox(double x1,double y1,double x2,double y2);
+
+#endif
diff --git a/filter/pdftopdf/qpdf_xobject.cc b/filter/pdftopdf/qpdf_xobject.cc
new file mode 100644
index 000000000..cc33f43a5
--- /dev/null
+++ b/filter/pdftopdf/qpdf_xobject.cc
@@ -0,0 +1,170 @@
+#include "qpdf_xobject.h"
+//#include <qpdf/Types.h>
+#include <qpdf/QPDF.hh>
+#include <qpdf/Pl_Discard.hh>
+#include <qpdf/Pl_Count.hh>
+#include <qpdf/Pl_Concatenate.hh>
+#include "qpdf_tools.h"
+#include "qpdf_pdftopdf.h"
+
+// TODO: need to remove Struct Parent stuff (or fix)
+
+// NOTE: use /TrimBox to position content inside Nup cell, /BleedBox to clip against
+
+class CombineFromContents_Provider : public QPDFObjectHandle::StreamDataProvider {
+public:
+ CombineFromContents_Provider(const std::vector<QPDFObjectHandle> &contents);
+
+ void provideStreamData(int objid, int generation, Pipeline* pipeline);
+private:
+ std::vector<QPDFObjectHandle> contents;
+};
+
+CombineFromContents_Provider::CombineFromContents_Provider(const std::vector<QPDFObjectHandle> &contents)
+ : contents(contents)
+{
+}
+
+void CombineFromContents_Provider::provideStreamData(int objid, int generation, Pipeline* pipeline)
+{
+ Pl_Concatenate concat("concat", pipeline);
+ const int clen=contents.size();
+ for (int iA=0;iA<clen;iA++) {
+ contents[iA].pipeStreamData(&concat, true, false, false);
+ }
+ concat.manualFinish();
+}
+
+/*
+ To convert a page to an XObject there are several keys to consider:
+
+ /Type /Page -> /Type /XObject (/Type optional for XObject)
+ -> /Subtype /Form
+ -> [/FormType 1] (optional)
+ /Parent ? ? R -> remove
+ /Resources dict -> copy
+ /MediaBox rect [/CropBox /BleedBox /TrimBox /ArtBox]
+ -> /BBox (use TrimBox [+ Bleed consideration?], with fallback to /MediaBox)
+ note that /BBox is in *Form Space*, see /Matrix!
+ [/BoxColorInfo dict] (used for guidelines that may be shown by viewer)
+ -> ignore/remove
+ [/Contents asfd] -> concatenate into stream data of the XObject (page is a dict, XObject a stream)
+
+ [/Rotate 90] ... must be handled (either use CTM where XObject is /used/ -- or set /Matrix)
+ [/UserUnit] (PDF 1.6) -> to /Matrix ? -- it MUST be handled.
+
+ [/Group dict] -> copy
+ [/Thumb stream] -> remove, not needed any more / would have to be regenerated (combined)
+ [/B] article beads -- ignore for now
+ [/Dur] -> remove (transition duration)
+ [/Trans] -> remove (transitions)
+ [/AA] -> remove (additional-actions)
+
+ [/Metadata] what shall we do?? (kill: we can't combine XML)
+ [/PieceInfo] -> remove, we can't combine private app data (?)
+ [/LastModified date] (opt except /PieceInfo) -> see there
+
+ [/PZ] -> remove, can't combine/keep (preferred zoom level)
+ [/SeparationInfo] -> remove, no way to keep this (needed for separation)
+
+ [/ID] related to web capture -- ignore/kill?
+ [/StructParents] (opt except pdf contains "structural content items")
+ -> copy (is this correct?)
+
+ [/Annots] annotations -- ignore for now
+ [/Tabs] tab order for annotations (/R row, /C column, /S structure order) -- see /Annots
+
+ [/TemplateInstantiated] (reqd, if page was created from named page obj, 1.5) -- ? just ignore?
+ [/PresSteps] -> remove (sub-page navigation for presentations) [no subpage navigation for printing / nup]
+ [/VP] viewport rects -- ignore/drop or recalculate into new page
+
+*/
+QPDFObjectHandle makeXObject(QPDF *pdf,QPDFObjectHandle page)
+{
+ page.assertPageObject();
+
+ QPDFObjectHandle ret=QPDFObjectHandle::newStream(pdf);
+ QPDFObjectHandle dict=ret.getDict();
+
+ dict.replaceKey("/Type",QPDFObjectHandle::newName("/XObject")); // optional
+ dict.replaceKey("/Subtype",QPDFObjectHandle::newName("/Form")); // required
+ // dict.replaceKey("/FormType",QPDFObjectHandle::newInteger(1)); // optional
+
+ QPDFObjectHandle box=getTrimBox(page); // already in "form space"
+ dict.replaceKey("/BBox",box); // reqd
+
+ // [/Matrix .] ... default is [1 0 0 1 0 0]; we incorporate /UserUnit and /Rotate here
+ Matrix mtx;
+ if (page.hasKey("/UserUnit")) {
+ mtx.scale(page.getKey("/UserUnit").getNumericValue());
+ }
+
+ // transform, so that bbox is [0 0 w h] (in outer space, but after UserUnit)
+ Rotation rot=getRotate(page);
+
+ // calculate rotation effect on [0 0 w h]
+ PageRect bbox=getBoxAsRect(box),tmp;
+ tmp.left=0;
+ tmp.bottom=0;
+ tmp.right=0;
+ tmp.top=0;
+ tmp.rotate_move(rot,bbox.width,bbox.height);
+ // tmp.rotate_move moves the bbox; we must achieve this move with the matrix.
+ mtx.translate(tmp.left,tmp.bottom); // 1. move origin to end up at left,bottom after rotation
+
+ mtx.rotate(rot); // 2. rotate coordinates according to /Rotate
+ mtx.translate(-bbox.left,-bbox.bottom); // 3. move origin from 0,0 to "form space"
+
+ dict.replaceKey("/Matrix",mtx.get());
+
+ dict.replaceKey("/Resources",page.getKey("/Resources"));
+ if (page.hasKey("/Group")) {
+ dict.replaceKey("/Group",page.getKey("/Group")); // (transparency); opt, copy if there
+ }
+
+ // ?? /StructParents ... can basically copy from page, but would need fixup in Structure Tree
+ // FIXME: remove (globally) Tagged spec (/MarkInfo), and Structure Tree
+
+ // Note: [/Name] (reqd. only in 1.0 -- but there we even can't use our normal img/patter procedures)
+
+ // none:
+ // QPDFObjectHandle filter=QPDFObjectHandle::newArray();
+ // QPDFObjectHandle decode_parms=QPDFObjectHandle::newArray();
+ // null leads to use of "default filters" from qpdf's settings
+ QPDFObjectHandle filter=QPDFObjectHandle::newNull();
+ QPDFObjectHandle decode_parms=QPDFObjectHandle::newNull();
+
+ std::vector<QPDFObjectHandle> contents=page.getPageContents(); // (will assertPageObject)
+
+ auto ph=PointerHolder<QPDFObjectHandle::StreamDataProvider>(new CombineFromContents_Provider(contents));
+ ret.replaceStreamData(ph,filter,decode_parms);
+
+ return ret;
+}
+
+/*
+ we will have to fix up the structure tree (e.g. /K in element), when copying /StructParents;
+ (there is /Pg, which has to point to the containing page, /Stm when it's not part of the page's content stream
+ i.e. when it is in our XObject!; then there is /StmOwn ...)
+ when not copying, we have to remove the structure tree completely (also /MarkInfo dict)
+ Still this might not be sufficient(?), as there are probably BDC and EMC operators in the stream.
+*/
+
+/* /XObject /Form has
+ [/Type /XObject]
+ /Subtype /Form
+ [/FormType 1]
+ /BBox rect from crop box, or recalculate
+ [/Matrix .] ... default is [1 0 0 1 0 0] --- we have to incorporate /UserUnit here?!
+ [/Resources dict] from page.
+ [/Group dict] used for transparency -- can copy from page
+ [/Ref dict] not needed; for external reference
+ [/Metadata] not, as long we can not combine.
+ [/PieceInfo] can copy, but not combine
+ [/LastModified date] copy if /PieceInfo there
+ [/StructParent] . don't want to be one ... have to read more spec
+ [/StructParents] . copy from page!
+ [/OPI] no opi version. don't set
+ [/OC] is this optional content? NO! not needed.
+ [/Name] (only reqd. in 1.0 -- but there we even can't use our normal img/patter procedures)
+*/
diff --git a/filter/pdftopdf/qpdf_xobject.h b/filter/pdftopdf/qpdf_xobject.h
new file mode 100644
index 000000000..096b56d8b
--- /dev/null
+++ b/filter/pdftopdf/qpdf_xobject.h
@@ -0,0 +1,8 @@
+#ifndef QPDF_XOBJECT_H_
+#define QPDF_XOBJECT_H_
+
+#include <qpdf/QPDFObjectHandle.hh>
+
+QPDFObjectHandle makeXObject(QPDF *pdf,QPDFObjectHandle page);
+
+#endif
diff --git a/filter/pdftops.c b/filter/pdftops.c
new file mode 100644
index 000000000..55d2ec164
--- /dev/null
+++ b/filter/pdftops.c
@@ -0,0 +1,1667 @@
+/*
+ * PDF to PostScript filter front-end for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1997-2006 by Easy Software Products.
+ * Copyright 2011-2013 by Till Kamppeter
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * parsePDFTOPDFComment() - Check whether we are executed after pdftopdf
+ * remove_options() - Remove unwished entries from an option list
+ * log_command_line() - Log the command line of a program which we call
+ * main() - Main entry for filter...
+ * cancel_job() - Flag the job as canceled.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <config.h>
+#include <cups/cups.h>
+#include <cups/ppd.h>
+#include <cups/file.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <ctype.h>
+#include <cupsfilters/image-private.h>
+
+#define MAX_CHECK_COMMENT_LINES 20
+
+/*
+ * Type definitions
+ */
+
+typedef unsigned renderer_t;
+enum renderer_e {GS = 0, PDFTOPS = 1, ACROREAD = 2, PDFTOCAIRO = 3, MUPDF = 4, HYBRID = 5};
+
+/*
+ * Local functions...
+ */
+
+static void cancel_job(int sig);
+
+
+/*
+ * Local globals...
+ */
+
+static int job_canceled = 0;
+int pdftopdfapplied = 0;
+char deviceCopies[32] = "1";
+int deviceCollate = 0;
+char make_model[128] = "";
+
+
+/*
+ * When calling the "pstops" filter we exclude the following options from its
+ * command line as we have applied these options already to the PDF input,
+ * either on the "pdftops"/Ghostscript call in this filter or by use of the
+ * "pdftopdf" filter before this filter.
+ */
+
+const char *pstops_exclude_general[] = {
+ "fitplot",
+ "fit-to-page",
+ "landscape",
+ "orientation-requested",
+ NULL
+};
+
+const char *pstops_exclude_page_management[] = {
+ "brightness",
+ "Collate",
+ "cupsEvenDuplex",
+ "gamma",
+ "hue",
+ "ipp-attribute-fidelity",
+ "MirrorPrint",
+ "mirror",
+ "multiple-document-handling",
+ "natural-scaling",
+ "number-up",
+ "number-up-layout",
+ "OutputOrder",
+ "page-border",
+ "page-bottom",
+ "page-label",
+ "page-left",
+ "page-ranges",
+ "page-right",
+ "page-set",
+ "page-top",
+ "position",
+ "saturation",
+ "scaling",
+ NULL
+};
+
+
+/*
+ * Options which we do not pass on to the mupdftoraster and rastertops
+ * filters when we render via MuPDF
+ */
+
+const char *mupdf_exclude_general[] = {
+ "Resolution",
+ NULL
+};
+
+
+/*
+ * Check whether we were called after the "pdftopdf" filter and extract
+ * parameters passed over by "pdftopdf" in the header comments of the PDF
+ * file
+ */
+
+static void parsePDFTOPDFComment(char *filename)
+{
+ char buf[4096];
+ int i;
+ FILE *fp;
+
+ if ((fp = fopen(filename,"rb")) == 0) {
+ fprintf(stderr, "ERROR: pdftops - cannot open print file \"%s\"\n",
+ filename);
+ return;
+ }
+
+ /* skip until PDF start header */
+ while (fgets(buf,sizeof(buf),fp) != 0) {
+ if (strncmp(buf,"%PDF",4) == 0) {
+ break;
+ }
+ }
+ for (i = 0;i < MAX_CHECK_COMMENT_LINES;i++) {
+ if (fgets(buf,sizeof(buf),fp) == 0) break;
+ if (strncmp(buf,"%%PDFTOPDFNumCopies",19) == 0) {
+ char *p;
+
+ p = strchr(buf+19,':') + 1;
+ while (*p == ' ' || *p == '\t') p++;
+ strncpy(deviceCopies, p, sizeof(deviceCopies));
+ deviceCopies[sizeof(deviceCopies) - 1] = '\0';
+ p = deviceCopies + strlen(deviceCopies) - 1;
+ while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') p--;
+ *(p + 1) = '\0';
+ pdftopdfapplied = 1;
+ } else if (strncmp(buf,"%%PDFTOPDFCollate",17) == 0) {
+ char *p;
+
+ p = strchr(buf+17,':') + 1;
+ while (*p == ' ' || *p == '\t') p++;
+ if (strncasecmp(p,"true",4) == 0) {
+ deviceCollate = 1;
+ } else {
+ deviceCollate = 0;
+ }
+ pdftopdfapplied = 1;
+ } else if (strcmp(buf,"% This file was generated by pdftopdf") == 0) {
+ pdftopdfapplied = 1;
+ }
+ }
+
+ fclose(fp);
+}
+
+
+/*
+ * Remove all options in option_list from the string option_str, including
+ * option values after an "=" sign and preceded "no" before boolean options
+ */
+
+void remove_options(char *options_str, const char **option_list)
+{
+ const char **option; /* Option to be removed now */
+ char *option_start, /* Start of option in string */
+ *option_end; /* End of option in string */
+
+ for (option = option_list; *option; option ++)
+ {
+ option_start = options_str;
+
+ while ((option_start = strcasestr(option_start, *option)) != NULL)
+ {
+ if (!option_start[strlen(*option)] ||
+ isspace(option_start[strlen(*option)] & 255) ||
+ option_start[strlen(*option)] == '=')
+ {
+ /*
+ * Strip option...
+ */
+
+ option_end = option_start + strlen(*option);
+
+ /* Remove preceding "no" of boolean option */
+ if ((option_start - options_str) >= 2 &&
+ !strncasecmp(option_start - 2, "no", 2))
+ option_start -= 2;
+
+ /* Is match of the searched option name really at the beginning of
+ the name of the option in the command line? */
+ if ((option_start > options_str) &&
+ (!isspace(*(option_start - 1) & 255)))
+ {
+ /* Prevent the same option to be found again. */
+ option_start += 1;
+ /* Skip */
+ continue;
+ }
+
+ /* Remove "=" and value */
+ while (*option_end && !isspace(*option_end & 255))
+ option_end ++;
+
+ /* Remove spaces up to next option */
+ while (*option_end && isspace(*option_end & 255))
+ option_end ++;
+
+ memmove(option_start, option_end, strlen(option_end) + 1);
+ } else {
+ /* Prevent the same option to be found again. */
+ option_start += 1;
+ }
+ }
+ }
+}
+
+
+/*
+ * Before calling any command line utility, log its command line in CUPS'
+ * debug mode
+ */
+
+void
+log_command_line(const char* file, char *const argv[])
+{
+ int i;
+ char *apos;
+
+ /* Debug output: Full command line of program to be called */
+ fprintf(stderr, "DEBUG: Running command line for %s:",
+ (file ? file : argv[0]));
+ if (file)
+ fprintf(stderr, " %s", file);
+ for (i = (file ? 1 : 0); argv[i]; i ++) {
+ if ((strchr(argv[i],' ')) || (strchr(argv[i],'\t')))
+ apos = "'";
+ else
+ apos = "";
+ fprintf(stderr, " %s%s%s", apos, argv[i], apos);
+ }
+ fprintf(stderr, "\n");
+}
+
+
+/*
+ * 'main()' - Main entry for filter...
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line args */
+ char *argv[]) /* I - Command-line arguments */
+{
+ renderer_t renderer = CUPS_PDFTOPS_RENDERER; /* Renderer: gs or pdftops or acroread or pdftocairo or hybrid */
+ int fd = 0; /* Copy file descriptor */
+ char *filename, /* PDF file to convert */
+ tempfile[1024]; /* Temporary file */
+ char buffer[8192]; /* Copy buffer */
+ int bytes; /* Bytes copied */
+ int num_options; /* Number of options */
+ cups_option_t *options; /* Options */
+ const char *val; /* Option value */
+ ppd_file_t *ppd; /* PPD file */
+ char resolution[128] = ""; /* Output resolution */
+ int xres = 0, yres = 0, /* resolution values */
+ mres, res,
+ maxres = CUPS_PDFTOPS_MAX_RESOLUTION,
+ /* Maximum image rendering resolution */
+ numvalues; /* Number of values actually read */
+ ppd_choice_t *choice;
+ ppd_attr_t *attr;
+ cups_page_header2_t header;
+ cups_file_t *fp; /* Post-processing input file */
+ int pdf_pid, /* Process ID for pdftops/gs */
+ pdf_argc = 0, /* Number of args for pdftops/gs */
+ pstops_pid, /* Process ID of pstops filter */
+ pstops_pipe[2], /* Pipe to pstops filter */
+ need_post_proc = 0, /* Post-processing needed? */
+ post_proc_pid = 0, /* Process ID of post-processing */
+ post_proc_pipe[2], /* Pipe to post-processing */
+ need_rastertops = 0, /* rastertops (for MuPDF) needed */
+ rastertops_pid = 0, /* Process ID of rastertops */
+ rastertops_pipe[2], /* Pipe to rastertops */
+ wait_children, /* Number of child processes left */
+ wait_pid, /* Process ID from wait() */
+ wait_status, /* Status from child */
+ exit_status = 0; /* Exit status */
+ char *pdf_argv[100], /* Arguments for pdftops/gs */
+ pstops_path[1024], /* Path to pstops program */
+ *pstops_argv[7], /* Arguments for pstops filter */
+ *pstops_options, /* Options for pstops filter */
+ *pstops_end, /* End of pstops filter option */
+ rastertops_path[1024], /* Path to rastertops program */
+ *rastertops_argv[7], /* Arguments for rastertops filter */
+ mupdftoraster_path[1024], /* Path to mupdftoraster program */
+ *mupdf_options, /* Options for mupdftoraster and
+ rastertops filters */
+ *mupdf_end, /* End of mupdftoraster and rastertops
+ filter option */
+ *ptr; /* Pointer into value */
+ const char *cups_serverbin; /* CUPS_SERVERBIN environment
+ variable */
+ int duplex, tumble; /* Duplex settings for PPD-less
+ printing */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Ignore broken pipe signals...
+ */
+
+ signal(SIGPIPE, SIG_IGN);
+
+ /*
+ * Make sure we have the right number of arguments for CUPS!
+ */
+
+ if (argc < 6 || argc > 7)
+ {
+ fprintf(stderr, "Usage: %s job user title copies options [file]\n",
+ argv[0]);
+ return (1);
+ }
+
+ /*
+ * Register a signal handler to cleanly cancel a job.
+ */
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, cancel_job);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = cancel_job;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, cancel_job);
+#endif /* HAVE_SIGSET */
+
+ /*
+ * Copy stdin if needed...
+ */
+
+ if (argc == 6)
+ {
+ /*
+ * Copy stdin to a temp file...
+ */
+
+ if ((fd = cupsTempFd(tempfile, sizeof(tempfile))) < 0)
+ {
+ perror("DEBUG: Unable to copy PDF file");
+ return (1);
+ }
+
+ fprintf(stderr, "DEBUG: pdftops - copying to temp print file \"%s\"\n",
+ tempfile);
+
+ while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
+ bytes = write(fd, buffer, bytes);
+
+ close(fd);
+
+ filename = tempfile;
+ }
+ else
+ {
+ /*
+ * Use the filename on the command-line...
+ */
+
+ filename = argv[6];
+ tempfile[0] = '\0';
+ }
+
+ /*
+ * Read out copy counts and collate setting passed over by pdftopdf
+ */
+
+ parsePDFTOPDFComment(filename);
+
+ /*
+ * Read out the options from the fifth command line argument
+ */
+
+ num_options = cupsParseOptions(argv[5], 0, &options);
+
+ /*
+ * Load the PPD file and mark options...
+ */
+
+ ppd = ppdOpenFile(getenv("PPD"));
+ if (ppd)
+ {
+ ppdMarkDefaults(ppd);
+ cupsMarkOptions(ppd, num_options, options);
+ }
+
+ if ((val = cupsGetOption("make-and-model", num_options, options)) != NULL)
+ {
+ strncpy(make_model, val, sizeof(make_model));
+ for (ptr = make_model; *ptr; ptr ++)
+ if (*ptr == '-') *ptr = ' ';
+ }
+ else if (ppd)
+ {
+ snprintf(make_model, sizeof(make_model), "%s %s", ppd->manufacturer,
+ ppd->product + 1);
+ make_model[strlen(make_model) - 1] = '\0';
+ }
+ fprintf(stderr, "DEBUG: Printer make and model: %s\n", make_model);
+
+ /*
+ * Select the PDF renderer: Ghostscript (gs), Poppler (pdftops),
+ * Adobe Reader (arcoread), Poppler with Cairo (pdftocairo), or
+ * Hybrid (hybrid, Poppler for Brother, Minolta, Konica Minolta, Dell, and
+ * old HP LaserJets and Ghostscript otherwise)
+ */
+
+ if ((val = cupsGetOption("pdftops-renderer", num_options, options)) != NULL)
+ {
+ if (strcasecmp(val, "gs") == 0)
+ renderer = GS;
+ else if (strcasecmp(val, "pdftops") == 0)
+ renderer = PDFTOPS;
+ else if (strcasecmp(val, "acroread") == 0)
+ renderer = ACROREAD;
+ else if (strcasecmp(val, "pdftocairo") == 0)
+ renderer = PDFTOCAIRO;
+ else if (strcasecmp(val, "mupdf") == 0)
+ renderer = MUPDF;
+ else if (strcasecmp(val, "hybrid") == 0)
+ renderer = HYBRID;
+ else
+ fprintf(stderr,
+ "WARNING: Invalid value for \"pdftops-renderer\": \"%s\"\n", val);
+ }
+
+ if (renderer == HYBRID)
+ {
+ if (make_model[0] &&
+ (!strncasecmp(make_model, "Brother", 7) ||
+ !strncasecmp(make_model, "Dell", 4) ||
+ strcasestr(make_model, "Minolta") ||
+ (!strncasecmp(make_model, "Apple", 5) &&
+ (ptr = strcasestr(make_model, "LaserWriter")) &&
+ (ptr = strcasestr(ptr + 11, "12")) &&
+ (ptr = strcasestr(ptr + 2, "640")))))
+ {
+ fprintf(stderr, "DEBUG: Switching to Poppler's pdftops instead of Ghostscript for Brother, Minolta, Konica Minolta, Dell, and Apple LaserWriter 12/640 to work around bugs in the printer's PS interpreters\n");
+ renderer = PDFTOPS;
+ }
+ else
+ renderer = GS;
+ /*
+ * Use Poppler instead of Ghostscript for old HP LaserJet printers due to
+ * a bug in their PS interpreters. They are very slow with Ghostscript.
+ * A LaserJet is considered old if its model number does not have a letter
+ * in the beginning, like LaserJet 3 or LaserJet 4000, not LaserJet P2015.
+ * See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=742765
+ */
+ if (make_model[0] &&
+ ((!strncasecmp(make_model, "HP", 2) ||
+ !strncasecmp(make_model, "Hewlett-Packard", 15) ||
+ !strncasecmp(make_model, "Hewlett Packard", 15)) &&
+ (ptr = strcasestr(make_model, "LaserJet"))))
+ {
+ for (ptr += 8; *ptr; ptr ++)
+ {
+ if (isspace(*ptr)) continue;
+ if (isdigit(*ptr))
+ {
+ fprintf(stderr, "DEBUG: Switching to Poppler's pdftops instead of Ghostscript for old HP LaserJet (\"LaserJet <number>\", no letters before <number>) printers to work around bugs in the printer's PS interpreters\n");
+ renderer = PDFTOPS;
+ }
+ break;
+ }
+ }
+ }
+
+ /*
+ * Build the pstops command-line...
+ */
+
+ if ((cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL)
+ cups_serverbin = CUPS_SERVERBIN;
+
+ snprintf(pstops_path, sizeof(pstops_path), "%s/filter/pstops",
+ cups_serverbin);
+
+ pstops_options = strdup(argv[5]);
+
+ /*
+ * Strip options which "pstops" does not need to apply any more
+ */
+ remove_options(pstops_options, pstops_exclude_general);
+ if (pdftopdfapplied)
+ remove_options(pstops_options, pstops_exclude_page_management);
+
+ if (pdftopdfapplied && deviceCollate)
+ {
+ /*
+ * Add collate option to the pstops call if pdftopdf has found out that the
+ * printer does hardware collate.
+ */
+
+ pstops_options = realloc(pstops_options, strlen(pstops_options) + 9);
+ if (!pstops_options) {
+ fprintf(stderr, "ERROR: Can't allocate pstops_options\n");
+ exit(2);
+ }
+ pstops_end = pstops_options + strlen(pstops_options);
+ strcpy(pstops_end, " Collate");
+ }
+
+ pstops_argv[0] = argv[0]; /* Printer */
+ pstops_argv[1] = argv[1]; /* Job */
+ pstops_argv[2] = argv[2]; /* User */
+ pstops_argv[3] = argv[3]; /* Title */
+ if (pdftopdfapplied)
+ pstops_argv[4] = deviceCopies; /* Copies */
+ else
+ pstops_argv[4] = argv[4]; /* Copies */
+ pstops_argv[5] = pstops_options; /* Options */
+ pstops_argv[6] = NULL;
+
+ log_command_line("pstops", pstops_argv);
+
+ /*
+ * Build the rastertops command-line (MuPDF only)...
+ */
+
+ if (renderer == MUPDF)
+ {
+ if ((cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL)
+ cups_serverbin = CUPS_SERVERBIN;
+
+ snprintf(rastertops_path, sizeof(rastertops_path), "%s/filter/rastertops",
+ cups_serverbin);
+
+ mupdf_options = strdup(argv[5]);
+ remove_options(mupdf_options, mupdf_exclude_general);
+
+ rastertops_argv[0] = argv[0]; /* Printer */
+ rastertops_argv[1] = argv[1]; /* Job */
+ rastertops_argv[2] = argv[2]; /* User */
+ rastertops_argv[3] = argv[3]; /* Title */
+ if (pdftopdfapplied)
+ rastertops_argv[4] = deviceCopies; /* Copies */
+ else
+ rastertops_argv[4] = argv[4]; /* Copies */
+ rastertops_argv[5] = mupdf_options; /* Options */
+ rastertops_argv[6] = NULL;
+
+ log_command_line("rastertops", rastertops_argv);
+ }
+
+ /*
+ * Build the command-line for the pdftops, gs, pdftocairo, or
+ * acroread filter...
+ */
+
+ if (renderer == PDFTOPS)
+ {
+ pdf_argv[0] = (char *)"pdftops";
+ pdf_argc = 1;
+ }
+ else if (renderer == GS)
+ {
+ pdf_argv[0] = (char *)"gs";
+ pdf_argv[1] = (char *)"-q";
+ pdf_argv[2] = (char *)"-dNOPAUSE";
+ pdf_argv[3] = (char *)"-dBATCH";
+ pdf_argv[4] = (char *)"-dSAFER";
+ pdf_argv[5] = (char *)"-dNOMEDIAATTRS";
+# ifdef HAVE_GHOSTSCRIPT_PS2WRITE
+ pdf_argv[6] = (char *)"-sDEVICE=ps2write";
+# else
+ pdf_argv[6] = (char *)"-sDEVICE=pswrite";
+# endif /* HAVE_GHOSTSCRIPT_PS2WRITE */
+ pdf_argv[7] = (char *)"-dShowAcroForm";
+ pdf_argv[8] = (char *)"-sOUTPUTFILE=%stdout";
+ pdf_argc = 9;
+ }
+ else if (renderer == PDFTOCAIRO)
+ {
+ pdf_argv[0] = (char *)"pdftocairo";
+ pdf_argv[1] = (char *)"-ps";
+ pdf_argc = 2;
+ }
+ else if (renderer == ACROREAD)
+ {
+ pdf_argv[0] = (char *)"acroread";
+ pdf_argv[1] = (char *)"-toPostScript";
+ pdf_argc = 2;
+ }
+ else if (renderer == MUPDF)
+ {
+ snprintf(mupdftoraster_path, sizeof(mupdftoraster_path),
+ "%s/filter/mupdftoraster", cups_serverbin);
+ pdf_argv[0] = "mupdftoraster";
+ pdf_argv[1] = argv[1]; /* Job */
+ pdf_argv[2] = argv[2]; /* User */
+ pdf_argv[3] = argv[3]; /* Title */
+ if (pdftopdfapplied)
+ pdf_argv[4] = deviceCopies; /* Copies */
+ else
+ pdf_argv[4] = argv[4]; /* Copies */
+ pdf_argv[5] = mupdf_options; /* Options */
+ pdf_argv[6] = filename;
+ pdf_argv[7] = NULL;
+ pdf_argc = 8;
+ }
+
+ /*
+ * Set language level and TrueType font handling...
+ */
+
+ if (ppd)
+ {
+ if (ppd->language_level == 1)
+ {
+ if (renderer == PDFTOPS)
+ {
+ pdf_argv[pdf_argc++] = (char *)"-level1";
+ pdf_argv[pdf_argc++] = (char *)"-noembtt";
+ }
+ else if (renderer == GS)
+ pdf_argv[pdf_argc++] = (char *)"-dLanguageLevel=1";
+ else if (renderer == PDFTOCAIRO)
+ fprintf(stderr, "WARNING: Level 1 PostScript not supported by pdftocairo.");
+ else if (renderer == ACROREAD)
+ fprintf(stderr, "WARNING: Level 1 PostScript not supported by acroread.");
+ else if (renderer == MUPDF)
+ fprintf(stderr, "WARNING: Level 1 PostScript not supported by rastertops.");
+ }
+ else if (ppd->language_level == 2)
+ {
+ if (renderer == PDFTOPS)
+ {
+ pdf_argv[pdf_argc++] = (char *)"-level2";
+ if (!ppd->ttrasterizer)
+ pdf_argv[pdf_argc++] = (char *)"-noembtt";
+ }
+ else if (renderer == GS)
+ pdf_argv[pdf_argc++] = (char *)"-dLanguageLevel=2";
+ else /* PDFTOCAIRO || ACROREAD */
+ pdf_argv[pdf_argc++] = (char *)"-level2";
+ }
+ else
+ {
+ if (renderer == PDFTOPS)
+ {
+ /* Do not emit PS Level 3 with Poppler on HP PostScript laser printers
+ as some do not like it. See https://bugs.launchpad.net/bugs/277404.*/
+ if (!make_model[0] ||
+ ((!strncasecmp(make_model, "HP", 2) ||
+ !strncasecmp(make_model, "Hewlett-Packard", 15) ||
+ !strncasecmp(make_model, "Hewlett Packard", 15)) &&
+ (strcasestr(make_model, "LaserJet"))))
+ pdf_argv[pdf_argc++] = (char *)"-level2";
+ else
+ pdf_argv[pdf_argc++] = (char *)"-level3";
+ }
+ else if (renderer == GS)
+ pdf_argv[pdf_argc++] = (char *)"-dLanguageLevel=3";
+ else /* PDFTOCAIRO || ACROREAD */
+ pdf_argv[pdf_argc++] = (char *)"-level3";
+ }
+ }
+ else
+ {
+ if (renderer == PDFTOPS)
+ {
+ /* Do not emit PS Level 3 with Poppler on HP PostScript laser printers
+ as some do not like it. See https://bugs.launchpad.net/bugs/277404.*/
+ if (!make_model[0] ||
+ ((!strncasecmp(make_model, "HP", 2) ||
+ !strncasecmp(make_model, "Hewlett-Packard", 15) ||
+ !strncasecmp(make_model, "Hewlett Packard", 15)) &&
+ (strcasestr(make_model, "LaserJet"))))
+ pdf_argv[pdf_argc++] = (char *)"-level2";
+ else
+ pdf_argv[pdf_argc++] = (char *)"-level3";
+ pdf_argv[pdf_argc++] = (char *)"-noembtt";
+ }
+ else if (renderer == GS)
+ pdf_argv[pdf_argc++] = (char *)"-dLanguageLevel=3";
+ else /* PDFTOCAIRO || ACROREAD */
+ pdf_argv[pdf_argc++] = (char *)"-level3";
+ }
+
+#ifdef HAVE_POPPLER_PDFTOPS_WITH_ORIGPAGESIZES
+ if ((renderer == PDFTOPS) || (renderer == PDFTOCAIRO))
+ {
+ /*
+ * Use the page sizes of the original PDF document, this way documents
+ * which contain pages of different sizes can be printed correctly
+ */
+
+ pdf_argv[pdf_argc++] = (char *)"-origpagesizes";
+ pdf_argv[pdf_argc++] = (char *)"-nocenter";
+ }
+ else
+#endif /* HAVE_POPPLER_PDFTOPS_WITH_ORIGPAGESIZES */
+ if (renderer == ACROREAD)
+ {
+ /*
+ * Use the page sizes of the original PDF document, this way documents
+ * which contain pages of different sizes can be printed correctly
+ */
+
+ pdf_argv[pdf_argc++] = (char *)"-choosePaperByPDFPageSize";
+ }
+
+ /*
+ * Set output resolution ...
+ */
+
+ if (ppd)
+ {
+ /* Ignore error exits of cupsRasterInterpretPPD(), if it found a resolution
+ setting before erroring it is OK for us */
+ cupsRasterInterpretPPD(&header, ppd, num_options, options, NULL);
+ /* 100 dpi is default, this means that if we have 100 dpi here this
+ method failed to find the printing resolution */
+ if (header.HWResolution[0] > 100 && header.HWResolution[1] > 100)
+ {
+ xres = header.HWResolution[0];
+ yres = header.HWResolution[1];
+ }
+ else if ((choice = ppdFindMarkedChoice(ppd, "Resolution")) != NULL)
+ strncpy(resolution, choice->choice, sizeof(resolution));
+ else if ((attr = ppdFindAttr(ppd,"DefaultResolution",NULL)) != NULL)
+ strncpy(resolution, attr->value, sizeof(resolution));
+ resolution[sizeof(resolution)-1] = '\0';
+ if ((xres == 0) && (yres == 0) &&
+ ((numvalues = sscanf(resolution, "%dx%d", &xres, &yres)) <= 0))
+ fprintf(stderr,
+ "DEBUG: No resolution information found in the PPD file.\n");
+ }
+ if ((xres == 0) && (yres == 0))
+ {
+ if ((val = cupsGetOption("printer-resolution", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("Resolution", num_options, options)) != NULL)
+ {
+ xres = yres = strtol(val, (char **)&ptr, 10);
+ if (ptr > val && xres > 0)
+ {
+ if (*ptr == 'x')
+ yres = strtol(ptr + 1, (char **)&ptr, 10);
+ }
+
+ if (ptr <= val || xres <= 0 || yres <= 0 || !ptr ||
+ (*ptr != '\0' &&
+ strcasecmp(ptr, "dpi") &&
+ strcasecmp(ptr, "dpc") &&
+ strcasecmp(ptr, "dpcm")))
+ {
+ fprintf(stderr, "DEBUG: Bad resolution value \"%s\".\n", val);
+ }
+ else
+ {
+ if (!strcasecmp(ptr, "dpc") ||
+ !strcasecmp(ptr, "dpcm"))
+ {
+ xres = xres * 254 / 100;
+ yres = yres * 254 / 100;
+ }
+ }
+ }
+ }
+ if ((xres > 0) || (yres > 0))
+ {
+ if (yres == 0) yres = xres;
+ if (xres == 0) xres = yres;
+ if (xres > yres)
+ res = yres;
+ else
+ res = xres;
+ }
+ else
+ res = 300;
+
+ /*
+ * Get the ceiling for the image rendering resolution
+ */
+
+ if ((val = cupsGetOption("pdftops-max-image-resolution", num_options, options)) != NULL)
+ {
+ if ((numvalues = sscanf(val, "%d", &mres)) > 0)
+ maxres = mres;
+ else
+ fprintf(stderr,
+ "WARNING: Invalid value for \"pdftops-max-image-resolution\": \"%s\"\n", val);
+ }
+
+ /*
+ * Reduce the image rendering resolution to not exceed a given maximum
+ * to make processing of jobs by the PDF->PS converter and the printer faster
+ *
+ * maxres = 0 means no limit
+ */
+
+ if (maxres)
+ while (res > maxres)
+ res = res / 2;
+
+ if ((renderer == PDFTOPS) || (renderer == PDFTOCAIRO))
+ {
+#ifdef HAVE_POPPLER_PDFTOPS_WITH_RESOLUTION
+ /*
+ * Set resolution to avoid slow processing by the printer when the
+ * resolution of embedded images does not match the printer's resolution
+ */
+ pdf_argv[pdf_argc++] = (char *)"-r";
+ snprintf(resolution, sizeof(resolution), "%d", res);
+ pdf_argv[pdf_argc++] = resolution;
+ fprintf(stderr, "DEBUG: Using image rendering resolution %d dpi\n", res);
+#endif /* HAVE_POPPLER_PDFTOPS_WITH_RESOLUTION */
+ pdf_argv[pdf_argc++] = filename;
+ pdf_argv[pdf_argc++] = (char *)"-";
+ }
+ else if (renderer == GS)
+ {
+ /*
+ * Set resolution to avoid slow processing by the printer when the
+ * resolution of embedded images does not match the printer's resolution
+ */
+ snprintf(resolution, 127, "-r%d", res);
+ pdf_argv[pdf_argc++] = resolution;
+ fprintf(stderr, "DEBUG: Using image rendering resolution %d dpi\n", res);
+ /*
+ * PostScript debug mode: If you send a job with "lpr -o psdebug" Ghostscript
+ * will not compress the pages, so that the PostScript code can get
+ * analysed. This is especially important if a PostScript printer errors or
+ * misbehaves on Ghostscript's output.
+ * On Kyocera and Utax (uses Kyocera hard- and software) printers we always
+ * suppress page compression, to avoid slow processing of raster images.
+ */
+ val = cupsGetOption("psdebug", num_options, options);
+ if ((val && strcasecmp(val, "no") && strcasecmp(val, "off") &&
+ strcasecmp(val, "false")) ||
+ (make_model[0] &&
+ (!strncasecmp(make_model, "Kyocera", 7) ||
+ !strncasecmp(make_model, "Utax", 4))))
+ {
+ fprintf(stderr, "DEBUG: Deactivated compression of pages in Ghostscript's PostScript output (\"psdebug\" debug mode or Kyocera/Utax printer)\n");
+ pdf_argv[pdf_argc++] = (char *)"-dCompressPages=false";
+ }
+ /*
+ * The PostScript interpreters on many printers have bugs which make
+ * the interpreter crash, error out, or otherwise misbehave on too
+ * heavily compressed input files, especially if code with compressed
+ * elements is compressed again. Therefore we reduce compression here.
+ */
+ pdf_argv[pdf_argc++] = (char *)"-dCompressFonts=false";
+ pdf_argv[pdf_argc++] = (char *)"-dNoT3CCITT";
+ if (make_model[0] &&
+ !strncasecmp(make_model, "Brother", 7))
+ {
+ fprintf(stderr, "DEBUG: Deactivation of Ghostscript's image compression for Brother printers to workarounmd PS interpreter bug\n");
+ pdf_argv[pdf_argc++] = (char *)"-dEncodeMonoImages=false";
+ pdf_argv[pdf_argc++] = (char *)"-dEncodeColorImages=false";
+ }
+ /*
+ * Toshiba's PS interpreters have an issue with how we handle
+ * TrueType/Type42 fonts, therefore we add command line options to turn
+ * the TTF outlines into bitmaps, usually Type 3 PostScript fonts, only
+ * large glyphs into normal image data.
+ * See https://bugs.launchpad.net/bugs/978120
+ */
+ if (make_model[0] &&
+ !strncasecmp(make_model, "Toshiba", 7))
+ {
+ fprintf(stderr, "DEBUG: To work around a bug in Toshiba's PS interpreters turn TTF font glyphs into bitmaps, usually Type 3 PS fonts, or images for large characters\n");
+ pdf_argv[pdf_argc++] = (char *)"-dHaveTrueTypes=false";
+ }
+ pdf_argv[pdf_argc++] = (char *)"-dNOINTERPOLATE";
+ pdf_argv[pdf_argc++] = (char *)"-c";
+ if (make_model[0] &&
+ !strncasecmp(make_model, "Toshiba", 7))
+ pdf_argv[pdf_argc++] = (char *)"<< /MaxFontItem 500000 >> setuserparams";
+ pdf_argv[pdf_argc++] = (char *)"save pop";
+ pdf_argv[pdf_argc++] = (char *)"-f";
+ pdf_argv[pdf_argc++] = filename;
+ }
+ else if (renderer == MUPDF)
+ {
+ /*
+ * Add Resolution option to avoid slow processing by the printer when the
+ * resolution of embedded images does not match the printer's resolution
+ */
+ mupdf_options = realloc(mupdf_options, strlen(mupdf_options) + 30);
+ if (!mupdf_options) {
+ fprintf(stderr, "ERROR: Can't allocate mupdf_options\n");
+ exit(2);
+ }
+ mupdf_end = mupdf_options + strlen(mupdf_options);
+ snprintf(mupdf_end, 30, " Resolution=%ddpi", res);
+ pdf_argv[5] = mupdf_options;
+ rastertops_argv[5] = mupdf_options;
+ }
+
+ pdf_argv[pdf_argc] = NULL;
+
+ log_command_line(NULL, pdf_argv);
+
+ /*
+ * Do we need post-processing of the PostScript output to work around bugs
+ * of the printer's PostScript interpreter?
+ */
+
+ if ((renderer == PDFTOPS) || (renderer == PDFTOCAIRO) ||
+ (renderer == MUPDF))
+ need_post_proc = 0;
+ else if (renderer == GS)
+ need_post_proc =
+ (make_model[0] &&
+ (!strncasecmp(make_model, "Kyocera", 7) ||
+ !strncasecmp(make_model, "Utax", 4) ||
+ !strncasecmp(make_model, "Brother", 7)) ? 1 : 0);
+ else
+ need_post_proc = 1;
+
+ /*
+ * Do we need post-processing of the PostScript output to apply option
+ * settings when doing PPD-less printing?
+ */
+
+ if (!ppd)
+ need_post_proc = 1;
+
+ /*
+ * Do we need to run rastertops when we are using mupdftoraster as PDF
+ * renderer
+ */
+
+ if (renderer == MUPDF)
+ need_rastertops = 1;
+
+ /*
+ * Execute "pdftops/gs/mupdftoraster [ | rastertops ] [ | PS post-processing ]
+ * | pstops"...
+ */
+
+
+ /*
+ * Create a pipe for each pair of subsequent processes. The variables
+ * are named by the receiving process.
+ */
+
+ if (pipe(pstops_pipe))
+ {
+ perror("DEBUG: Unable to create pipe for pstops");
+
+ exit_status = 1;
+ goto error;
+ }
+
+ if (need_rastertops)
+ {
+ if (pipe(rastertops_pipe))
+ {
+ perror("DEBUG: Unable to create pipe for rastertops");
+
+ exit_status = 1;
+ goto error;
+ }
+ }
+
+ if (need_post_proc)
+ {
+ if (pipe(post_proc_pipe))
+ {
+ perror("DEBUG: Unable to create pipe for post-processing");
+
+ exit_status = 1;
+ goto error;
+ }
+ }
+
+ if ((pdf_pid = fork()) == 0)
+ {
+ /*
+ * Child comes here...
+ */
+
+ if (need_rastertops)
+ {
+ dup2(rastertops_pipe[1], 1);
+ close(rastertops_pipe[0]);
+ close(rastertops_pipe[1]);
+ if (need_post_proc)
+ {
+ close(post_proc_pipe[0]);
+ close(post_proc_pipe[1]);
+ }
+ }
+ else if (need_post_proc)
+ {
+ dup2(post_proc_pipe[1], 1);
+ close(post_proc_pipe[0]);
+ close(post_proc_pipe[1]);
+ }
+ else
+ dup2(pstops_pipe[1], 1);
+ close(pstops_pipe[0]);
+ close(pstops_pipe[1]);
+
+ if (renderer == PDFTOPS)
+ {
+ execvp(CUPS_POPPLER_PDFTOPS, pdf_argv);
+ perror("DEBUG: Unable to execute pdftops program");
+ }
+ else if (renderer == GS)
+ {
+ execvp(CUPS_GHOSTSCRIPT, pdf_argv);
+ perror("DEBUG: Unable to execute gs program");
+ }
+ else if (renderer == PDFTOCAIRO)
+ {
+ execvp(CUPS_POPPLER_PDFTOCAIRO, pdf_argv);
+ perror("DEBUG: Unable to execute pdftocairo program");
+ }
+ else if (renderer == ACROREAD)
+ {
+ /*
+ * use filename as stdin for acroread to force output to stdout
+ */
+
+ if ((fd = open(filename, O_RDONLY)))
+ {
+ dup2(fd, 0);
+ close(fd);
+ }
+
+ execvp(CUPS_ACROREAD, pdf_argv);
+ perror("DEBUG: Unable to execute acroread program");
+ }
+ else if (renderer == MUPDF)
+ {
+ execvp(mupdftoraster_path, pdf_argv);
+ perror("DEBUG: Unable to execute mupdftoraster program");
+ }
+
+ exit(1);
+ }
+ else if (pdf_pid < 0)
+ {
+ /*
+ * Unable to fork!
+ */
+
+ if (renderer == PDFTOPS)
+ perror("DEBUG: Unable to execute pdftops program");
+ else if (renderer == GS)
+ perror("DEBUG: Unable to execute gs program");
+ else if (renderer == PDFTOCAIRO)
+ perror("DEBUG: Unable to execute pdftocairo program");
+ else if (renderer == ACROREAD)
+ perror("DEBUG: Unable to execute acroread program");
+ else if (renderer == MUPDF)
+ perror("DEBUG: Unable to execute mupdftoraster program");
+
+ exit_status = 1;
+ goto error;
+ }
+
+ fprintf(stderr, "DEBUG: Started filter %s (PID %d)\n", pdf_argv[0], pdf_pid);
+
+ if (need_rastertops)
+ {
+ if ((rastertops_pid = fork()) == 0)
+ {
+ /*
+ * Child comes here...
+ */
+
+ dup2(rastertops_pipe[0], 0);
+ close(rastertops_pipe[0]);
+ close(rastertops_pipe[1]);
+ if (need_post_proc)
+ {
+ dup2(post_proc_pipe[1], 1);
+ close(post_proc_pipe[0]);
+ close(post_proc_pipe[1]);
+ }
+ else
+ dup2(pstops_pipe[1], 1);
+ close(pstops_pipe[0]);
+ close(pstops_pipe[1]);
+
+ execvp(rastertops_path, rastertops_argv);
+ perror("DEBUG: Unable to execute rastertops program");
+ }
+ else if (post_proc_pid < 0)
+ {
+ /*
+ * Unable to fork!
+ */
+
+ perror("DEBUG: Unable to execute rastertops program");
+
+ exit_status = 1;
+ goto error;
+ }
+
+ fprintf(stderr, "DEBUG: Started filter rastertops (PID %d)\n",
+ rastertops_pid);
+ }
+
+ if (need_post_proc)
+ {
+ if ((post_proc_pid = fork()) == 0)
+ {
+ /*
+ * Child comes here...
+ */
+
+ dup2(post_proc_pipe[0], 0);
+ close(post_proc_pipe[0]);
+ close(post_proc_pipe[1]);
+ dup2(pstops_pipe[1], 1);
+ close(pstops_pipe[0]);
+ close(pstops_pipe[1]);
+ if (need_rastertops)
+ {
+ close(rastertops_pipe[0]);
+ close(rastertops_pipe[1]);
+ }
+
+ fp = cupsFileStdin();
+
+ if (renderer == ACROREAD)
+ {
+ /*
+ * Set %Title and %For from filter arguments since acroread inserts
+ * garbage for these when using -toPostScript
+ */
+
+ while ((bytes = cupsFileGetLine(fp, buffer, sizeof(buffer))) > 0 &&
+ strncmp(buffer, "%%BeginProlog", 13))
+ {
+ if (strncmp(buffer, "%%Title", 7) == 0)
+ printf("%%%%Title: %s\n", argv[3]);
+ else if (strncmp(buffer, "%%For", 5) == 0)
+ printf("%%%%For: %s\n", argv[2]);
+ else
+ printf("%s", buffer);
+ }
+
+ /*
+ * Copy the rest of the file
+ */
+ while ((bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0)
+ fwrite(buffer, 1, bytes, stdout);
+ }
+ else
+ {
+
+ /*
+ * Copy everything until after initial comments (Prolog section)
+ */
+ while ((bytes = cupsFileGetLine(fp, buffer, sizeof(buffer))) > 0 &&
+ strncmp(buffer, "%%BeginProlog", 13) &&
+ strncmp(buffer, "%%EndProlog", 11) &&
+ strncmp(buffer, "%%BeginSetup", 12) &&
+ strncmp(buffer, "%%Page:", 7))
+ printf("%s", buffer);
+
+ if (bytes > 0)
+ {
+ /*
+ * Insert PostScript interpreter bug fix code in the beginning of
+ * the Prolog section (before the first active PostScript code)
+ */
+ if (strncmp(buffer, "%%BeginProlog", 13))
+ {
+ /* No Prolog section, create one */
+ fprintf(stderr, "DEBUG: Adding Prolog section for workaround PostScript code\n");
+ puts("%%BeginProlog");
+ }
+ else
+ printf("%s", buffer);
+
+ if (renderer == GS && make_model[0])
+ {
+
+ /*
+ * Kyocera (and Utax) printers have a bug in their PostScript
+ * interpreter making them crashing on PostScript input data
+ * generated by Ghostscript's "ps2write" output device.
+ *
+ * The problem can be simply worked around by preceding the
+ * PostScript code with some extra bits.
+ *
+ * See https://bugs.launchpad.net/bugs/951627
+ *
+ * In addition, at least some of Kyocera's PostScript printers are
+ * very slow on rendering images which request interpolation. So we
+ * also add some code to eliminate interpolation requests.
+ *
+ * See https://bugs.launchpad.net/bugs/1026974
+ */
+
+ if (!strncasecmp(make_model, "Kyocera", 7) ||
+ !strncasecmp(make_model, "Utax", 4))
+ {
+ fprintf(stderr, "DEBUG: Inserted workaround PostScript code for Kyocera and Utax printers\n");
+ puts("% ===== Workaround insertion by pdftops CUPS filter =====");
+ puts("% Kyocera's/Utax's PostScript interpreter crashes on early name binding,");
+ puts("% so eliminate all \"bind\"s by redefining \"bind\" to no-op");
+ puts("/bind {} bind def");
+ puts("% Some Kyocera and Utax printers have an unacceptably slow implementation");
+ puts("% of image interpolation.");
+ puts("/image");
+ puts("{");
+ puts(" dup /Interpolate known");
+ puts(" {");
+ puts(" dup /Interpolate undef");
+ puts(" } if");
+ puts(" systemdict /image get exec");
+ puts("} def");
+ puts("% =====");
+ }
+
+ /*
+ * Brother printers have a bug in their PostScript interpreter
+ * making them printing one blank page if PostScript input data
+ * generated by Ghostscript's "ps2write" output device is used.
+ *
+ * The problem can be simply worked around by preceding the PostScript
+ * code with some extra bits.
+ *
+ * See https://bugs.launchpad.net/bugs/950713
+ */
+
+ else if (!strncasecmp(make_model, "Brother", 7))
+ {
+ fprintf(stderr, "DEBUG: Inserted workaround PostScript code for Brother printers\n");
+ puts("% ===== Workaround insertion by pdftops CUPS filter =====");
+ puts("% Brother's PostScript interpreter spits out the current page");
+ puts("% and aborts the job on the \"currenthalftone\" operator, so redefine");
+ puts("% it to null");
+ puts("/currenthalftone {//null} bind def");
+ puts("/orig.sethalftone systemdict /sethalftone get def");
+ puts("/sethalftone {dup //null eq not {//orig.sethalftone}{pop} ifelse} bind def");
+ puts("% =====");
+ }
+ }
+
+ if (strncmp(buffer, "%%BeginProlog", 13))
+ {
+ /* Close newly created Prolog section */
+ if (strncmp(buffer, "%%EndProlog", 11))
+ puts("%%EndProlog");
+ printf("%s", buffer);
+ }
+
+ if (!ppd)
+ {
+ /*
+ * Copy everything until the setup section
+ */
+ while (bytes > 0 &&
+ strncmp(buffer, "%%BeginSetup", 12) &&
+ strncmp(buffer, "%%EndSetup", 10) &&
+ strncmp(buffer, "%%Page:", 7))
+ {
+ bytes = cupsFileGetLine(fp, buffer, sizeof(buffer));
+ if (strncmp(buffer, "%%Page:", 7) &&
+ strncmp(buffer, "%%EndSetup", 10))
+ printf("%s", buffer);
+ }
+
+ if (bytes > 0)
+ {
+ /*
+ * Insert option PostScript code in Setup section
+ */
+ if (strncmp(buffer, "%%BeginSetup", 12))
+ {
+ /* No Setup section, create one */
+ fprintf(stderr, "DEBUG: Adding Setup section for option PostScript code\n");
+ puts("%%BeginSetup");
+ }
+
+ /*
+ * Duplex
+ */
+ duplex = 0;
+ tumble = 0;
+ if ((val = cupsGetOption("sides", num_options, options)) != NULL ||
+ (val = cupsGetOption("Duplex", num_options, options)) != NULL)
+ {
+ if (!strcasecmp(val, "On") ||
+ !strcasecmp(val, "True") || !strcasecmp(val, "Yes") ||
+ !strncasecmp(val, "two-sided", 9) ||
+ !strncasecmp(val, "TwoSided", 8) ||
+ !strncasecmp(val, "Duplex", 6))
+ {
+ duplex = 1;
+ if (!strncasecmp(val, "DuplexTumble", 12))
+ tumble = 1;
+ }
+ }
+
+ if ((val = cupsGetOption("sides", num_options, options)) != NULL ||
+ (val = cupsGetOption("Tumble", num_options, options)) != NULL)
+ {
+ if (!strcasecmp(val, "None") || !strcasecmp(val, "Off") ||
+ !strcasecmp(val, "False") || !strcasecmp(val, "No") ||
+ !strcasecmp(val, "one-sided") || !strcasecmp(val, "OneSided") ||
+ !strcasecmp(val, "two-sided-long-edge") ||
+ !strcasecmp(val, "TwoSidedLongEdge") ||
+ !strcasecmp(val, "DuplexNoTumble"))
+ tumble = 0;
+ else if (!strcasecmp(val, "On") ||
+ !strcasecmp(val, "True") || !strcasecmp(val, "Yes") ||
+ !strcasecmp(val, "two-sided-short-edge") ||
+ !strcasecmp(val, "TwoSidedShortEdge") ||
+ !strcasecmp(val, "DuplexTumble"))
+ tumble = 1;
+ }
+
+ if (duplex)
+ {
+ if (tumble)
+ puts("<</Duplex true /Tumble true>> setpagedevice");
+ else
+ puts("<</Duplex true /Tumble false>> setpagedevice");
+ }
+ else
+ puts("<</Duplex false>> setpagedevice");
+
+ /*
+ * Resolution
+ */
+ if ((xres > 0) && (yres > 0))
+ printf("<</HWResolution[%d %d]>> setpagedevice\n", xres, yres);
+
+ /*
+ * InputSlot/MediaSource
+ */
+ if ((val = cupsGetOption("media-position", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("MediaPosition", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("media-source", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("MediaSource", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("InputSlot", num_options,
+ options)) != NULL)
+ {
+ if (!strncasecmp(val, "Auto", 4) ||
+ !strncasecmp(val, "Default", 7))
+ puts("<</ManualFeed false /MediaPosition 7>> setpagedevice");
+ else if (!strcasecmp(val, "Main"))
+ puts("<</MediaPosition 0 /ManualFeed false>> setpagedevice");
+ else if (!strcasecmp(val, "Alternate"))
+ puts("<</MediaPosition 1 /ManualFeed false>> setpagedevice");
+ else if (!strcasecmp(val, "Manual"))
+ puts("<</MediaPosition 3 /ManualFeed true>> setpagedevice");
+ else if (!strcasecmp(val, "Top"))
+ puts("<</MediaPosition 0 /ManualFeed false>> setpagedevice");
+ else if (!strcasecmp(val, "Bottom"))
+ puts("<</MediaPosition 1 /ManualFeed false>> setpagedevice");
+ else if (!strcasecmp(val, "ByPassTray"))
+ puts("<</MediaPosition 3 /ManualFeed false>> setpagedevice");
+ else if (!strcasecmp(val, "Tray1"))
+ puts("<</MediaPosition 3 /ManualFeed false>> setpagedevice");
+ else if (!strcasecmp(val, "Tray2"))
+ puts("<</MediaPosition 0 /ManualFeed false>> setpagedevice");
+ else if (!strcasecmp(val, "Tray3"))
+ puts("<</MediaPosition 1 /ManualFeed false>> setpagedevice");
+ }
+
+ /*
+ * ColorModel
+ */
+ if ((val = cupsGetOption("pwg-raster-document-type", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("PwgRasterDocumentType", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("print-color-mode", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("PrintColorMode", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("color-space", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("ColorSpace", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("color-model", num_options,
+ options)) != NULL ||
+ (val = cupsGetOption("ColorModel", num_options,
+ options)) != NULL)
+ {
+ if (!strncasecmp(val, "Black", 5))
+ puts("<</ProcessColorModel /DeviceGray>> setpagedevice");
+ else if (!strncasecmp(val, "Cmyk", 4))
+ puts("<</ProcessColorModel /DeviceCMYK>> setpagedevice");
+ else if (!strncasecmp(val, "Cmy", 3))
+ puts("<</ProcessColorModel /DeviceCMY>> setpagedevice");
+ else if (!strncasecmp(val, "Rgb", 3))
+ puts("<</ProcessColorModel /DeviceRGB>> setpagedevice");
+ else if (!strncasecmp(val, "Gray", 4))
+ puts("<</ProcessColorModel /DeviceGray>> setpagedevice");
+ else if (!strncasecmp(val, "Color", 5))
+ puts("<</ProcessColorModel /DeviceRGB>> setpagedevice");
+ }
+
+ if (strncmp(buffer, "%%BeginSetup", 12))
+ {
+ /* Close newly created Setup section */
+ if (strncmp(buffer, "%%EndSetup", 10))
+ puts("%%EndSetup");
+ printf("%s", buffer);
+ }
+ }
+ }
+
+ /*
+ * Copy the rest of the file
+ */
+ while ((bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0)
+ fwrite(buffer, 1, bytes, stdout);
+ }
+ }
+
+ exit(0);
+ }
+ else if (post_proc_pid < 0)
+ {
+ /*
+ * Unable to fork!
+ */
+
+ perror("DEBUG: Unable to execute post-processing process");
+
+ exit_status = 1;
+ goto error;
+ }
+
+ fprintf(stderr, "DEBUG: Started post-processing (PID %d)\n", post_proc_pid);
+ }
+
+ if ((pstops_pid = fork()) == 0)
+ {
+ /*
+ * Child comes here...
+ */
+
+ dup2(pstops_pipe[0], 0);
+ close(pstops_pipe[0]);
+ close(pstops_pipe[1]);
+ if (need_rastertops)
+ {
+ close(rastertops_pipe[0]);
+ close(rastertops_pipe[1]);
+ }
+ if (need_post_proc)
+ {
+ close(post_proc_pipe[0]);
+ close(post_proc_pipe[1]);
+ }
+
+ execvp(pstops_path, pstops_argv);
+ perror("DEBUG: Unable to execute pstops program");
+
+ exit(1);
+ }
+ else if (pstops_pid < 0)
+ {
+ /*
+ * Unable to fork!
+ */
+
+ perror("DEBUG: Unable to execute pstops program");
+
+ exit_status = 1;
+ goto error;
+ }
+
+ fprintf(stderr, "DEBUG: Started filter pstops (PID %d)\n", pstops_pid);
+
+ close(pstops_pipe[0]);
+ close(pstops_pipe[1]);
+ if (need_post_proc)
+ {
+ close(post_proc_pipe[0]);
+ close(post_proc_pipe[1]);
+ }
+ if (need_rastertops)
+ {
+ close(rastertops_pipe[0]);
+ close(rastertops_pipe[1]);
+ }
+
+ /*
+ * Wait for the child processes to exit...
+ */
+
+ wait_children = 2 + need_rastertops + need_post_proc;
+
+ while (wait_children > 0)
+ {
+ /*
+ * Wait until we get a valid process ID or the job is canceled...
+ */
+
+ while ((wait_pid = wait(&wait_status)) < 0 && errno == EINTR)
+ {
+ if (job_canceled)
+ {
+ kill(pdf_pid, SIGTERM);
+ if (need_rastertops)
+ kill(rastertops_pid, SIGTERM);
+ if (need_post_proc)
+ kill(post_proc_pid, SIGTERM);
+ kill(pstops_pid, SIGTERM);
+
+ job_canceled = 0;
+ }
+ }
+
+ if (wait_pid < 0)
+ break;
+
+ wait_children --;
+
+ /*
+ * Report child status...
+ */
+
+ if (wait_status)
+ {
+ if (WIFEXITED(wait_status))
+ {
+ exit_status = WEXITSTATUS(wait_status);
+
+ fprintf(stderr, "DEBUG: PID %d (%s) stopped with status %d!\n",
+ wait_pid,
+ wait_pid == pdf_pid ?
+ (renderer == PDFTOPS ? "pdftops" :
+ (renderer == PDFTOCAIRO ? "pdftocairo" :
+ (renderer == GS ? "gs" :
+ (renderer == ACROREAD ? "acroread" :
+ (renderer == MUPDF ? "mupdftoraster" :
+ "Unknown renderer"))))) :
+ (wait_pid == pstops_pid ? "pstops" :
+ (wait_pid == rastertops_pid ? "rastertops" :
+ (wait_pid == post_proc_pid ? "Post-processing" :
+ "Unknown process"))),
+ exit_status);
+ }
+ else if (WTERMSIG(wait_status) == SIGTERM)
+ {
+ fprintf(stderr,
+ "DEBUG: PID %d (%s) was terminated normally with signal %d!\n",
+ wait_pid,
+ wait_pid == pdf_pid ?
+ (renderer == PDFTOPS ? "pdftops" :
+ (renderer == PDFTOCAIRO ? "pdftocairo" :
+ (renderer == GS ? "gs" :
+ (renderer == ACROREAD ? "acroread" :
+ (renderer == MUPDF ? "mupdftoraster" :
+ "Unknown renderer"))))) :
+ (wait_pid == pstops_pid ? "pstops" :
+ (wait_pid == rastertops_pid ? "rastertops" :
+ (wait_pid == post_proc_pid ? "Post-processing" :
+ "Unknown process"))),
+ exit_status);
+ }
+ else
+ {
+ exit_status = WTERMSIG(wait_status);
+
+ fprintf(stderr, "DEBUG: PID %d (%s) crashed on signal %d!\n",
+ wait_pid,
+ wait_pid == pdf_pid ?
+ (renderer == PDFTOPS ? "pdftops" :
+ (renderer == PDFTOCAIRO ? "pdftocairo" :
+ (renderer == GS ? "gs" :
+ (renderer == ACROREAD ? "acroread" :
+ (renderer == MUPDF ? "mupdftoraster" :
+ "Unknown renderer"))))) :
+ (wait_pid == pstops_pid ? "pstops" :
+ (wait_pid == rastertops_pid ? "rastertops" :
+ (wait_pid == post_proc_pid ? "Post-processing" :
+ "Unknown process"))),
+ exit_status);
+ }
+ }
+ else
+ {
+ fprintf(stderr, "DEBUG: PID %d (%s) exited with no errors.\n",
+ wait_pid,
+ wait_pid == pdf_pid ?
+ (renderer == PDFTOPS ? "pdftops" :
+ (renderer == PDFTOCAIRO ? "pdftocairo" :
+ (renderer == GS ? "gs" :
+ (renderer == ACROREAD ? "acroread" :
+ (renderer == MUPDF ? "mupdftoraster" :
+ "Unknown renderer"))))) :
+ (wait_pid == pstops_pid ? "pstops" :
+ (wait_pid == rastertops_pid ? "rastertops" :
+ (wait_pid == post_proc_pid ? "Post-processing" :
+ "Unknown process"))));
+ }
+ }
+
+ /*
+ * Cleanup and exit...
+ */
+
+ error:
+
+ if (tempfile[0])
+ unlink(tempfile);
+
+ return (exit_status);
+}
+
+
+/*
+ * 'cancel_job()' - Flag the job as canceled.
+ */
+
+static void
+cancel_job(int sig) /* I - Signal number (unused) */
+{
+ (void)sig;
+
+ job_canceled = 1;
+}
+
diff --git a/filter/pdftoraster.cxx b/filter/pdftoraster.cxx
new file mode 100644
index 000000000..4cd656ad1
--- /dev/null
+++ b/filter/pdftoraster.cxx
@@ -0,0 +1,2195 @@
+/*
+Copyright (c) 2008-2011 BBR Inc. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+/*
+ pdftoraster.cc
+ pdf to raster filter
+*/
+
+#include <config.h>
+#include <cups/cups.h>
+#if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 6)
+#define HAVE_CUPS_1_7 1
+#endif
+
+#define USE_CMS
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_CPP_POPPLER_VERSION_H
+#include "cpp/poppler-version.h"
+#endif
+#include "goo/GooString.h"
+#include "goo/gmem.h"
+#include "Object.h"
+#include "Stream.h"
+#include "PDFDoc.h"
+#include "SplashOutputDev.h"
+#include "GfxState.h"
+#include <cups/ppd.h>
+#include <stdarg.h>
+#include "PDFError.h"
+#include "GlobalParams.h"
+#include <cups/raster.h>
+#include <cupsfilters/image.h>
+#include <cupsfilters/raster.h>
+#include <cupsfilters/colormanager.h>
+#include <splash/SplashTypes.h>
+#include <splash/SplashBitmap.h>
+#include <strings.h>
+#include <math.h>
+#ifdef USE_LCMS1
+#include <lcms.h>
+#define cmsColorSpaceSignature icColorSpaceSignature
+#define cmsSetLogErrorHandler cmsSetErrorHandler
+#define cmsToneCurve LPGAMMATABLE
+#define cmsSigXYZData icSigXYZData
+#define cmsSigLuvData icSigLuvData
+#define cmsSigLabData icSigLabData
+#define cmsSigYCbCrData icSigYCbCrData
+#define cmsSigYxyData icSigYxyData
+#define cmsSigRgbData icSigRgbData
+#define cmsSigHsvData icSigHsvData
+#define cmsSigHlsData icSigHlsData
+#define cmsSigCmyData icSigCmyData
+#define cmsSig3colorData icSig3colorData
+#define cmsSigGrayData icSigGrayData
+#define cmsSigCmykData icSigCmykData
+#define cmsSig4colorData icSig4colorData
+#define cmsSig2colorData icSig2colorData
+#define cmsSig5colorData icSig5colorData
+#define cmsSig6colorData icSig6colorData
+#define cmsSig7colorData icSig7colorData
+#define cmsSig8colorData icSig8colorData
+#define cmsSig9colorData icSig9colorData
+#define cmsSig10colorData icSig10colorData
+#define cmsSig11colorData icSig11colorData
+#define cmsSig12colorData icSig12colorData
+#define cmsSig13colorData icSig13colorData
+#define cmsSig14colorData icSig14colorData
+#define cmsSig15colorData icSig15colorData
+#else
+#include <lcms2.h>
+#endif
+
+#define MAX_CHECK_COMMENT_LINES 20
+#define MAX_BYTES_PER_PIXEL 32
+
+namespace {
+ typedef unsigned char *(*ConvertLineFunc)(unsigned char *src,
+ unsigned char *dst, unsigned int row, unsigned int plane,
+ unsigned int pixels, unsigned int size);
+ typedef unsigned char *(*ConvertCSpaceFunc)(unsigned char *src,
+ unsigned char *pixelBuf, unsigned int x, unsigned int y);
+ typedef unsigned char *(*ConvertBitsFunc)(unsigned char *src,
+ unsigned char *dst, unsigned int x, unsigned int y);
+ typedef void (*WritePixelFunc)(unsigned char *dst,
+ unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf);
+
+ int exitCode = 0;
+ int pwgraster = 0;
+ int deviceCopies = 1;
+ bool deviceCollate = false;
+ cups_page_header2_t header;
+ ppd_file_t *ppd = 0;
+ unsigned int bitmapoffset[2];
+ unsigned int popplerBitsPerPixel;
+ unsigned int popplerNumColors;
+ /* image swapping */
+ bool swap_image_x = false;
+ bool swap_image_y = false;
+ /* margin swapping */
+ bool swap_margin_x = false;
+ bool swap_margin_y = false;
+ bool allocLineBuf = false;
+ ConvertLineFunc convertLineOdd;
+ ConvertLineFunc convertLineEven;
+ ConvertCSpaceFunc convertCSpace;
+ ConvertBitsFunc convertBits;
+ WritePixelFunc writePixel;
+ unsigned int nplanes;
+ unsigned int nbands;
+ unsigned int bytesPerLine; /* number of bytes per line */
+ /* Note: When CUPS_ORDER_BANDED,
+ cupsBytesPerLine = bytesPerLine*cupsNumColors */
+ unsigned char revTable[256] = {
+0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0,0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0,
+0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8,0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8,
+0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4,0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4,
+0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec,0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc,
+0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2,0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2,
+0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea,0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa,
+0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6,0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6,
+0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee,0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe,
+0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1,0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1,
+0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9,0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9,
+0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5,0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5,
+0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed,0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd,
+0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3,0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3,
+0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb,0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb,
+0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7,0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7,
+0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef,0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff
+ };
+ unsigned int dither1[16][16] = {
+ {0,128,32,160,8,136,40,168,2,130,34,162,10,138,42,170},
+ {192,64,224,96,200,72,232,104,194,66,226,98,202,74,234,106},
+ {48,176,16,144,56,184,24,152,50,178,18,146,58,186,26,154},
+ {240,112,208,80,248,120,216,88,242,114,210,82,250,122,218,90},
+ {12,140,44,172,4,132,36,164,14,142,46,174,6,134,38,166},
+ {204,76,236,108,196,68,228,100,206,78,238,110,198,70,230,102},
+ {60,188,28,156,52,180,20,148,62,190,30,158,54,182,22,150},
+ {252,124,220,92,244,116,212,84,254,126,222,94,246,118,214,86},
+ {3,131,35,163,11,139,43,171,1,129,33,161,9,137,41,169},
+ {195,67,227,99,203,75,235,107,193,65,225,97,201,73,233,105},
+ {51,179,19,147,59,187,27,155,49,177,17,145,57,185,25,153},
+ {243,115,211,83,251,123,219,91,241,113,209,81,249,121,217,89},
+ {15,143,47,175,7,135,39,167,13,141,45,173,5,133,37,165},
+ {207,79,239,111,199,71,231,103,205,77,237,109,197,69,229,101},
+ {63,191,31,159,55,183,23,151,61,189,29,157,53,181,21,149},
+ {255,127,223,95,247,119,215,87,253,125,221,93,245,117,213,85}
+ };
+ unsigned int dither2[8][8] = {
+ {0,32,8,40,2,34,10,42},
+ {48,16,56,24,50,18,58,26},
+ {12,44,4,36,14,46,6,38},
+ {60,28,52,20,62,30,54,22},
+ {3,35,11,43,1,33,9,41},
+ {51,19,59,27,49,17,57,25},
+ {15,47,7,39,13,45,5,37},
+ {63,31,55,23,61,29,53,21}
+ };
+ unsigned int dither4[4][4] = {
+ {0,8,2,10},
+ {12,4,14,6},
+ {3,11,1,9},
+ {15,7,13,5}
+ };
+
+ /* for color profiles */
+ cmsHPROFILE colorProfile = NULL;
+ cmsHPROFILE popplerColorProfile = NULL;
+ cmsHTRANSFORM colorTransform = NULL;
+ cmsCIEXYZ D65WhitePoint;
+ int renderingIntent = INTENT_PERCEPTUAL;
+ int cm_disabled = 0;
+ cm_calibration_t cm_calibrate;
+}
+
+cmsCIExyY adobergb_wp()
+{
+ double * xyY = cmWhitePointAdobeRgb();
+ cmsCIExyY wp;
+
+ wp.x = xyY[0];
+ wp.y = xyY[1];
+ wp.Y = xyY[2];
+
+ return wp;
+}
+
+cmsCIExyY sgray_wp()
+{
+ double * xyY = cmWhitePointSGray();
+ cmsCIExyY wp;
+
+ wp.x = xyY[0];
+ wp.y = xyY[1];
+ wp.Y = xyY[2];
+
+ return wp;
+}
+
+cmsCIExyYTRIPLE adobergb_matrix()
+{
+ cmsCIExyYTRIPLE m;
+
+ double * matrix = cmMatrixAdobeRgb();
+
+ m.Red.x = matrix[0];
+ m.Red.y = matrix[1];
+ m.Red.Y = matrix[2];
+ m.Green.x = matrix[3];
+ m.Green.y = matrix[4];
+ m.Green.Y = matrix[5];
+ m.Blue.x = matrix[6];
+ m.Blue.y = matrix[7];
+ m.Blue.Y = matrix[8];
+
+ return m;
+}
+
+cmsHPROFILE adobergb_profile()
+{
+ cmsHPROFILE adobergb;
+
+ cmsCIExyY wp;
+ cmsCIExyYTRIPLE primaries;
+
+#if USE_LCMS1
+ cmsToneCurve Gamma = cmsBuildGamma(256, 2.2);
+ cmsToneCurve Gamma3[3];
+#else
+ cmsToneCurve * Gamma = cmsBuildGamma(NULL, 2.2);
+ cmsToneCurve * Gamma3[3];
+#endif
+ Gamma3[0] = Gamma3[1] = Gamma3[2] = Gamma;
+
+ // Build AdobeRGB profile
+ primaries = adobergb_matrix();
+ wp = adobergb_wp();
+ adobergb = cmsCreateRGBProfile(&wp, &primaries, Gamma3);
+
+ return adobergb;
+}
+
+cmsHPROFILE sgray_profile()
+{
+ cmsHPROFILE sgray;
+
+ cmsCIExyY wp;
+
+#if USE_LCMS1
+ cmsToneCurve Gamma = cmsBuildGamma(256, 2.2);
+#else
+ cmsToneCurve * Gamma = cmsBuildGamma(NULL, 2.2);
+#endif
+ // Build sGray profile
+ wp = sgray_wp();
+ sgray = cmsCreateGrayProfile(&wp, Gamma);
+
+ return sgray;
+}
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 23
+void CDECL myErrorFun(void *data, ErrorCategory category,
+ Goffset pos, char *msg)
+#else
+void CDECL myErrorFun(void *data, ErrorCategory category,
+ int pos, char *msg)
+#endif
+{
+ if (pos >= 0) {
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 23
+ fprintf(stderr, "ERROR (%lld): ", pos);
+#else
+ fprintf(stderr, "ERROR (%d): ", pos);
+#endif
+ } else {
+ fprintf(stderr, "ERROR: ");
+ }
+ fprintf(stderr, "%s\n",msg);
+ fflush(stderr);
+}
+#else
+void CDECL myErrorFun(int pos, char *msg, va_list args)
+{
+ if (pos >= 0) {
+ fprintf(stderr, "ERROR (%d): ", pos);
+ } else {
+ fprintf(stderr, "ERROR: ");
+ }
+ vfprintf(stderr, msg, args);
+ fprintf(stderr, "\n");
+ fflush(stderr);
+}
+#endif
+
+#ifdef USE_LCMS1
+static int lcmsErrorHandler(int ErrorCode, const char *ErrorText)
+{
+ fprintf(stderr, "ERROR: %s\n",ErrorText);
+ return 1;
+}
+#else
+static void lcmsErrorHandler(cmsContext contextId, cmsUInt32Number ErrorCode,
+ const char *ErrorText)
+{
+ fprintf(stderr, "ERROR: %s\n",ErrorText);
+}
+#endif
+
+
+#if 0
+static GBool getColorProfilePath(ppd_file_t *ppd, GooString *path)
+{
+ // get color profile path
+ const char *colorModel;
+ const char *cupsICCQualifier2;
+ const char *cupsICCQualifier2Choice;
+ const char *cupsICCQualifier3;
+ const char *cupsICCQualifier3Choice;
+ ppd_attr_t *attr;
+ ppd_choice_t *choice;
+
+ if ((choice = ppdFindMarkedChoice(ppd,"ColorModel")) != NULL) {
+ colorModel = choice->choice;
+ } else {
+ colorModel = NULL;
+ }
+ if ((attr = ppdFindAttr(ppd,"cupsICCQualifier2",NULL)) != NULL) {
+ cupsICCQualifier2 = attr->value;
+ } else {
+ cupsICCQualifier2 = "MediaType";
+ }
+ if ((choice = ppdFindMarkedChoice(ppd,cupsICCQualifier2)) != NULL) {
+ cupsICCQualifier2Choice = choice->choice;
+ } else {
+ cupsICCQualifier2Choice = NULL;
+ }
+ if ((attr = ppdFindAttr(ppd,"cupsICCQualifier3",NULL)) != NULL) {
+ cupsICCQualifier3 = attr->value;
+ } else {
+ cupsICCQualifier3 = "Resolution";
+ }
+ if ((choice = ppdFindMarkedChoice(ppd,cupsICCQualifier3)) != NULL) {
+ cupsICCQualifier3Choice = choice->choice;
+ } else {
+ cupsICCQualifier3Choice = NULL;
+ }
+
+ for (attr = ppdFindAttr(ppd,"cupsICCProfile",NULL);attr != NULL;
+ attr = ppdFindNextAttr(ppd,"cupsICCProfile",NULL)) {
+ // check color model
+ char buf[PPD_MAX_NAME];
+ char *p, *r;
+ char *datadir;
+
+ strncpy(buf,attr->spec,sizeof(buf));
+ if ((p = strchr(buf,'.')) != NULL) {
+ *p = '\0';
+ }
+ if (colorModel != NULL && buf[0] != '\0'
+ && strcasecmp(buf,colorModel) != 0) continue;
+ if (p == NULL) {
+ break;
+ } else {
+ p++;
+ if ((r = strchr(p,'.')) != 0) {
+ *r = '\0';
+ }
+ }
+ if (cupsICCQualifier2Choice != NULL && p[0] != '\0'
+ && strcasecmp(p,cupsICCQualifier2Choice) != 0) continue;
+ if (r == NULL) {
+ break;
+ } else {
+ r++;
+ if ((p = strchr(r,'.')) != 0) {
+ *p = '\0';
+ }
+ }
+ if (cupsICCQualifier3Choice == NULL || r[0] == '\0'
+ || strcasecmp(r,cupsICCQualifier3Choice) == 0) break;
+ }
+ if (attr != NULL) {
+ // matched
+ path->clear();
+ if (attr->value[0] != '/') {
+ if ((datadir = getenv("CUPS_DATADIR")) == NULL)
+ datadir = CUPS_DATADIR;
+ path->append(datadir);
+ path->append("/profiles/");
+ }
+ path->append(attr->value);
+ return gTrue;
+ }
+ return gFalse;
+}
+#endif
+
+static void handleRqeuiresPageRegion() {
+ ppd_choice_t *mf;
+ ppd_choice_t *is;
+ ppd_attr_t *rregions = NULL;
+ ppd_size_t *size;
+
+ if ((size = ppdPageSize(ppd,NULL)) == NULL) return;
+ mf = ppdFindMarkedChoice(ppd,"ManualFeed");
+ if ((is = ppdFindMarkedChoice(ppd,"InputSlot")) != NULL) {
+ rregions = ppdFindAttr(ppd,"RequiresPageRegion",is->choice);
+ }
+ if (rregions == NULL) {
+ rregions = ppdFindAttr(ppd,"RequiresPageRegion","All");
+ }
+ if (!strcasecmp(size->name,"Custom") || (!mf && !is) ||
+ (mf && !strcasecmp(mf->choice,"False") &&
+ (!is || (is->code && !is->code[0]))) ||
+ (!rregions && ppd->num_filters > 0)) {
+ ppdMarkOption(ppd,"PageSize",size->name);
+ } else if (rregions && rregions->value
+ && !strcasecmp(rregions->value,"True")) {
+ ppdMarkOption(ppd,"PageRegion",size->name);
+ } else {
+ ppd_choice_t *page;
+
+ if ((page = ppdFindMarkedChoice(ppd,"PageSize")) != NULL) {
+ page->marked = 0;
+ cupsArrayRemove(ppd->marked,page);
+ }
+ if ((page = ppdFindMarkedChoice(ppd,"PageRegion")) != NULL) {
+ page->marked = 0;
+ cupsArrayRemove(ppd->marked, page);
+ }
+ }
+}
+
+static void parseOpts(int argc, char **argv)
+{
+ int num_options = 0;
+ cups_option_t *options = 0;
+ GooString profilePath;
+ char *profile = 0;
+ const char *t = NULL;
+ ppd_attr_t *attr;
+
+ if (argc < 6 || argc > 7) {
+ pdfError(-1,const_cast<char *>("%s job-id user title copies options [file]"),
+ argv[0]);
+ exit(1);
+ }
+
+#ifdef HAVE_CUPS_1_7
+ t = getenv("FINAL_CONTENT_TYPE");
+ if (t && strcasestr(t, "pwg"))
+ pwgraster = 1;
+#endif /* HAVE_CUPS_1_7 */
+
+ ppd = ppdOpenFile(getenv("PPD"));
+ if (ppd == NULL)
+ fprintf(stderr, "DEBUG: PPD file is not specified.\n");
+ if (ppd)
+ ppdMarkDefaults(ppd);
+ options = NULL;
+ num_options = cupsParseOptions(argv[5],0,&options);
+ if (ppd) {
+ cupsMarkOptions(ppd,num_options,options);
+ handleRqeuiresPageRegion();
+ cupsRasterInterpretPPD(&header,ppd,num_options,options,0);
+ attr = ppdFindAttr(ppd,"pdftorasterRenderingIntent",NULL);
+ if (attr != NULL && attr->value != NULL) {
+ if (strcasecmp(attr->value,"PERCEPTUAL") != 0) {
+ renderingIntent = INTENT_PERCEPTUAL;
+ } else if (strcasecmp(attr->value,"RELATIVE_COLORIMETRIC") != 0) {
+ renderingIntent = INTENT_RELATIVE_COLORIMETRIC;
+ } else if (strcasecmp(attr->value,"SATURATION") != 0) {
+ renderingIntent = INTENT_SATURATION;
+ } else if (strcasecmp(attr->value,"ABSOLUTE_COLORIMETRIC") != 0) {
+ renderingIntent = INTENT_ABSOLUTE_COLORIMETRIC;
+ }
+ }
+ if (header.Duplex) {
+ /* analyze options relevant to Duplex */
+ const char *backside = "";
+ /* APDuplexRequiresFlippedMargin */
+ enum {
+ FM_NO, FM_FALSE, FM_TRUE
+ } flippedMargin = FM_NO;
+
+ attr = ppdFindAttr(ppd,"cupsBackSide",NULL);
+ if (attr != NULL && attr->value != NULL) {
+ ppd->flip_duplex = 0;
+ backside = attr->value;
+ } else if (ppd->flip_duplex) {
+ backside = "Rotated"; /* compatible with Max OS and GS 8.71 */
+ }
+
+ attr = ppdFindAttr(ppd,"APDuplexRequiresFlippedMargin",NULL);
+ if (attr != NULL && attr->value != NULL) {
+ if (strcasecmp(attr->value,"true") == 0) {
+ flippedMargin = FM_TRUE;
+ } else {
+ flippedMargin = FM_FALSE;
+ }
+ }
+ if (strcasecmp(backside,"ManualTumble") == 0 && header.Tumble) {
+ swap_image_x = swap_image_y = true;
+ swap_margin_x = swap_margin_y = true;
+ if (flippedMargin == FM_TRUE) {
+ swap_margin_y = false;
+ }
+ } else if (strcasecmp(backside,"Rotated") == 0 && !header.Tumble) {
+ swap_image_x = swap_image_y = true;
+ swap_margin_x = swap_margin_y = true;
+ if (flippedMargin == FM_TRUE) {
+ swap_margin_y = false;
+ }
+ } else if (strcasecmp(backside,"Flipped") == 0) {
+ if (header.Tumble) {
+ swap_image_x = true;
+ swap_margin_x = swap_margin_y = true;
+ } else {
+ swap_image_y = true;
+ }
+ if (flippedMargin == FM_FALSE) {
+ swap_margin_y = !swap_margin_y;
+ }
+ }
+ }
+
+ /* support the CUPS "cm-calibration" option */
+ cm_calibrate = cmGetCupsColorCalibrateMode(options, num_options);
+
+ if (cm_calibrate == CM_CALIBRATION_ENABLED)
+ cm_disabled = 1;
+ else
+ cm_disabled = cmIsPrinterCmDisabled(getenv("PRINTER"));
+
+ if (!cm_disabled)
+ cmGetPrinterIccProfile(getenv("PRINTER"), &profile, ppd);
+
+ if (profile != NULL)
+ colorProfile = cmsOpenProfileFromFile(profile,"r");
+
+#ifdef HAVE_CUPS_1_7
+ if ((attr = ppdFindAttr(ppd,"PWGRaster",0)) != 0 &&
+ (!strcasecmp(attr->value, "true")
+ || !strcasecmp(attr->value, "on") ||
+ !strcasecmp(attr->value, "yes")))
+ pwgraster = 1;
+ if (pwgraster == 1)
+ cupsRasterParseIPPOptions(&header, num_options, options, pwgraster, 0);
+#endif /* HAVE_CUPS_1_7 */
+ } else {
+#ifdef HAVE_CUPS_1_7
+ pwgraster = 1;
+ t = cupsGetOption("media-class", num_options, options);
+ if (t == NULL)
+ t = cupsGetOption("MediaClass", num_options, options);
+ if (t != NULL)
+ {
+ if (strcasestr(t, "pwg"))
+ pwgraster = 1;
+ else
+ pwgraster = 0;
+ }
+ cupsRasterParseIPPOptions(&header,num_options,options,pwgraster,1);
+#else
+ fprintf(stderr, "ERROR: No PPD file specified.\n");
+ exit(1);
+#endif /* HAVE_CUPS_1_7 */
+ }
+}
+
+static void parsePDFTOPDFComment(FILE *fp)
+{
+ char buf[4096];
+ int i;
+
+ /* skip until PDF start header */
+ while (fgets(buf,sizeof(buf),fp) != 0) {
+ if (strncmp(buf,"%PDF",4) == 0) {
+ break;
+ }
+ }
+ for (i = 0;i < MAX_CHECK_COMMENT_LINES;i++) {
+ if (fgets(buf,sizeof(buf),fp) == 0) break;
+ if (strncmp(buf,"%%PDFTOPDFNumCopies",19) == 0) {
+ char *p;
+
+ p = strchr(buf+19,':');
+ deviceCopies = atoi(p+1);
+ } else if (strncmp(buf,"%%PDFTOPDFCollate",17) == 0) {
+ char *p;
+
+ p = strchr(buf+17,':');
+ while (*p == ' ' || *p == '\t') p++;
+ if (strncasecmp(p,"true",4) == 0) {
+ deviceCollate = true;
+ } else {
+ deviceCollate = false;
+ }
+ }
+ }
+}
+
+static unsigned char *reverseLine(unsigned char *src, unsigned char *dst,
+ unsigned int row, unsigned int plane, unsigned int pixels,
+ unsigned int size)
+{
+ unsigned char *p = src;
+
+ for (unsigned int j = 0;j < size;j++,p++) {
+ *p = ~*p;
+ }
+ return src;
+}
+
+static unsigned char *reverseLineSwapByte(unsigned char *src,
+ unsigned char *dst, unsigned int row, unsigned int plane,
+ unsigned int pixels, unsigned int size)
+{
+ unsigned char *bp = src+size-1;
+ unsigned char *dp = dst;
+
+ for (unsigned int j = 0;j < size;j++,bp--,dp++) {
+ *dp = ~*bp;
+ }
+ return dst;
+}
+
+
+static unsigned char *reverseLineSwapBit(unsigned char *src,
+ unsigned char *dst, unsigned int row, unsigned int plane,
+ unsigned int pixels, unsigned int size)
+{
+ unsigned char *bp;
+ unsigned char *dp;
+ unsigned int npadbits = (size*8)-pixels;
+
+ if (npadbits == 0) {
+ bp = src+size-1;
+ dp = dst;
+ for (unsigned int j = 0;j < size;j++,bp--,dp++) {
+ *dp = revTable[(unsigned char)(~*bp)];
+ }
+ } else {
+ unsigned int pd,d;
+ unsigned int sw;
+
+ size = (pixels+7)/8;
+ sw = (size*8)-pixels;
+ bp = src+size-1;
+ dp = dst;
+
+ pd = *bp--;
+ for (unsigned int j = 1;j < size;j++,bp--,dp++) {
+ d = *bp;
+ *dp = ~revTable[(((d << 8) | pd) >> sw) & 0xff];
+ pd = d;
+ }
+ *dp = ~revTable[(pd >> sw) & 0xff];
+ }
+ return dst;
+}
+
+static unsigned char *rgbToCMYKLine(unsigned char *src, unsigned char *dst,
+ unsigned int row, unsigned int plane, unsigned int pixels,
+ unsigned int size)
+{
+ cupsImageRGBToCMYK(src,dst,pixels);
+ return dst;
+}
+
+static unsigned char *rgbToCMYKLineSwap(unsigned char *src, unsigned char *dst,
+ unsigned int row, unsigned int plane, unsigned int pixels,
+ unsigned int size)
+{
+ unsigned char *bp = src+(pixels-1)*3;
+ unsigned char *dp = dst;
+
+ for (unsigned int i = 0;i < pixels;i++, bp -= 3, dp += 4) {
+ cupsImageRGBToCMYK(bp,dp,1);
+ }
+ return dst;
+}
+
+static unsigned char *rgbToCMYLine(unsigned char *src, unsigned char *dst,
+ unsigned int row, unsigned int plane, unsigned int pixels,
+ unsigned int size)
+{
+ cupsImageRGBToCMY(src,dst,pixels);
+ return dst;
+}
+
+static unsigned char *rgbToCMYLineSwap(unsigned char *src, unsigned char *dst,
+ unsigned int row, unsigned int plane, unsigned int pixels,
+ unsigned int size)
+{
+ unsigned char *bp = src+size-3;
+ unsigned char *dp = dst;
+
+ for (unsigned int i = 0;i < pixels;i++, bp -= 3, dp += 3) {
+ cupsImageRGBToCMY(bp,dp,1);
+ }
+ return dst;
+}
+
+static unsigned char *rgbToKCMYLine(unsigned char *src, unsigned char *dst,
+ unsigned int row, unsigned int plane, unsigned int pixels,
+ unsigned int size)
+{
+ unsigned char *bp = src;
+ unsigned char *dp = dst;
+ unsigned char d;
+
+ cupsImageRGBToCMYK(src,dst,pixels);
+ /* CMYK to KCMY */
+ for (unsigned int i = 0;i < pixels;i++, bp += 3, dp += 4) {
+ d = dp[3];
+ dp[3] = dp[2];
+ dp[2] = dp[1];
+ dp[1] = dp[0];
+ dp[0] = d;
+ }
+ return dst;
+}
+
+static unsigned char *rgbToKCMYLineSwap(unsigned char *src, unsigned char *dst,
+ unsigned int row, unsigned int plane, unsigned int pixels,
+ unsigned int size)
+{
+ unsigned char *bp = src+(pixels-1)*3;
+ unsigned char *dp = dst;
+ unsigned char d;
+
+ for (unsigned int i = 0;i < pixels;i++, bp -= 3, dp += 4) {
+ cupsImageRGBToCMYK(bp,dp,1);
+ /* CMYK to KCMY */
+ d = dp[3];
+ dp[3] = dp[2];
+ dp[2] = dp[1];
+ dp[1] = dp[0];
+ dp[0] = d;
+ }
+ return dst;
+}
+
+static unsigned char *lineNoop(unsigned char *src, unsigned char *dst,
+ unsigned int row, unsigned int plane, unsigned int pixels,
+ unsigned int size)
+{
+ /* do nothing */
+ return src;
+}
+
+static unsigned char *lineSwap24(unsigned char *src, unsigned char *dst,
+ unsigned int row, unsigned int plane, unsigned int pixels,
+ unsigned int size)
+{
+ unsigned char *bp = src+size-3;
+ unsigned char *dp = dst;
+
+ for (unsigned int i = 0;i < pixels;i++, bp -= 3, dp += 3) {
+ dp[0] = bp[0];
+ dp[1] = bp[1];
+ dp[2] = bp[2];
+ }
+ return dst;
+}
+
+static unsigned char *lineSwapByte(unsigned char *src, unsigned char *dst,
+ unsigned int row, unsigned int plane, unsigned int pixels,
+ unsigned int size)
+{
+ unsigned char *bp = src+size-1;
+ unsigned char *dp = dst;
+
+ for (unsigned int j = 0;j < size;j++,bp--,dp++) {
+ *dp = *bp;
+ }
+ return dst;
+}
+
+static unsigned char *lineSwapBit(unsigned char *src, unsigned char *dst,
+ unsigned int row, unsigned int plane, unsigned int pixels,
+ unsigned int size)
+{
+ unsigned char *bp;
+ unsigned char *dp;
+ unsigned int npadbits = (size*8)-pixels;
+
+ if (npadbits == 0) {
+ bp = src+size-1;
+ dp = dst;
+ for (unsigned int j = 0;j < size;j++,bp--,dp++) {
+ *dp = revTable[*bp];
+ }
+ } else {
+ unsigned int pd,d;
+ unsigned int sw;
+
+ size = (pixels+7)/8;
+ sw = (size*8)-pixels;
+ bp = src+size-1;
+ dp = dst;
+
+ pd = *bp--;
+ for (unsigned int j = 1;j < size;j++,bp--,dp++) {
+ d = *bp;
+ *dp = revTable[(((d << 8) | pd) >> sw) & 0xff];
+ pd = d;
+ }
+ *dp = revTable[(pd >> sw) & 0xff];
+ }
+ return dst;
+}
+
+typedef struct _funcTable {
+ enum cups_cspace_e cspace;
+ unsigned int bitsPerPixel;
+ unsigned int bitsPerColor;
+ ConvertLineFunc convertLine;
+ bool allocLineBuf;
+ ConvertLineFunc convertLineSwap;
+ bool allocLineBufSwap;
+} FuncTable;
+
+static FuncTable specialCaseFuncs[] = {
+ {CUPS_CSPACE_K,8,8,reverseLine,false,reverseLineSwapByte,true},
+ {CUPS_CSPACE_K,1,1,reverseLine,false,reverseLineSwapBit,true},
+ {CUPS_CSPACE_GOLD,8,8,reverseLine,false,reverseLineSwapByte,true},
+ {CUPS_CSPACE_GOLD,1,1,reverseLine,false,reverseLineSwapBit,true},
+ {CUPS_CSPACE_SILVER,8,8,reverseLine,false,reverseLineSwapByte,true},
+ {CUPS_CSPACE_SILVER,1,1,reverseLine,false,reverseLineSwapBit,true},
+ {CUPS_CSPACE_CMYK,32,8,rgbToCMYKLine,true,rgbToCMYKLineSwap,true},
+ {CUPS_CSPACE_KCMY,32,8,rgbToKCMYLine,true,rgbToKCMYLineSwap,true},
+ {CUPS_CSPACE_CMY,24,8,rgbToCMYLine,true,rgbToCMYLineSwap,true},
+ {CUPS_CSPACE_RGB,24,8,lineNoop,false,lineSwap24,true},
+ {CUPS_CSPACE_SRGB,24,8,lineNoop,false,lineSwap24,true},
+ {CUPS_CSPACE_ADOBERGB,24,8,lineNoop,false,lineSwap24,true},
+ {CUPS_CSPACE_W,8,8,lineNoop,false,lineSwapByte,true},
+ {CUPS_CSPACE_W,1,1,lineNoop,false,lineSwapBit,true},
+ {CUPS_CSPACE_SW,8,8,lineNoop,false,lineSwapByte,true},
+ {CUPS_CSPACE_SW,1,1,lineNoop,false,lineSwapBit,true},
+ {CUPS_CSPACE_WHITE,8,8,lineNoop,false,lineSwapByte,true},
+ {CUPS_CSPACE_WHITE,1,1,lineNoop,false,lineSwapBit,true},
+ {CUPS_CSPACE_RGB,0,0,NULL,false,NULL,false} /* end mark */
+};
+
+static unsigned char *convertCSpaceNone(unsigned char *src,
+ unsigned char *pixelBuf, unsigned int x, unsigned int y)
+{
+ return src;
+}
+
+static unsigned char *convertCSpaceWithProfiles(unsigned char *src,
+ unsigned char *pixelBuf, unsigned int x, unsigned int y)
+{
+ cmsDoTransform(colorTransform,src,pixelBuf,1);
+ return pixelBuf;
+}
+
+static unsigned char *convertCSpaceXYZ8(unsigned char *src,
+ unsigned char *pixelBuf, unsigned int x, unsigned int y)
+{
+ double alab[3];
+
+ cmsDoTransform(colorTransform,src,alab,1);
+ cmsCIELab lab;
+ cmsCIEXYZ xyz;
+
+ lab.L = alab[0];
+ lab.a = alab[1];
+ lab.b = alab[2];
+
+ cmsLab2XYZ(&D65WhitePoint,&xyz,&lab);
+ pixelBuf[0] = 231.8181*xyz.X+0.5;
+ pixelBuf[1] = 231.8181*xyz.Y+0.5;
+ pixelBuf[2] = 231.8181*xyz.Z+0.5;
+ return pixelBuf;
+}
+
+static unsigned char *convertCSpaceXYZ16(unsigned char *src,
+ unsigned char *pixelBuf, unsigned int x, unsigned int y)
+{
+ double alab[3];
+ unsigned short *sd = (unsigned short *)pixelBuf;
+
+ cmsDoTransform(colorTransform,src,alab,1);
+ cmsCIELab lab;
+ cmsCIEXYZ xyz;
+
+ lab.L = alab[0];
+ lab.a = alab[1];
+ lab.b = alab[2];
+
+ cmsLab2XYZ(&D65WhitePoint,&xyz,&lab);
+ sd[0] = 59577.2727*xyz.X+0.5;
+ sd[1] = 59577.2727*xyz.Y+0.5;
+ sd[2] = 59577.2727*xyz.Z+0.5;
+ return pixelBuf;
+}
+
+static unsigned char *convertCSpaceLab8(unsigned char *src,
+ unsigned char *pixelBuf, unsigned int x, unsigned int y)
+{
+ double lab[3];
+ cmsDoTransform(colorTransform,src,lab,1);
+ pixelBuf[0] = 2.55*lab[0]+0.5;
+ pixelBuf[1] = lab[1]+128.5;
+ pixelBuf[2] = lab[2]+128.5;
+ return pixelBuf;
+}
+
+static unsigned char *convertCSpaceLab16(unsigned char *src,
+ unsigned char *pixelBuf, unsigned int x, unsigned int y)
+{
+ double lab[3];
+ cmsDoTransform(colorTransform,src,lab,1);
+ unsigned short *sd = (unsigned short *)pixelBuf;
+ sd[0] = 655.35*lab[0]+0.5;
+ sd[1] = 256*(lab[1]+128)+0.5;
+ sd[2] = 256*(lab[2]+128)+0.5;
+ return pixelBuf;
+}
+
+static unsigned char *RGB8toRGBA(unsigned char *src, unsigned char *pixelBuf,
+ unsigned int x, unsigned int y)
+{
+ unsigned char *dp = pixelBuf;
+
+ for (int i = 0;i < 3;i++) {
+ *dp++ = *src++;
+ }
+ *dp = 255;
+ return pixelBuf;
+}
+
+static unsigned char *RGB8toRGBW(unsigned char *src, unsigned char *pixelBuf,
+ unsigned int x, unsigned int y)
+{
+ unsigned char cmyk[4];
+ unsigned char *dp = pixelBuf;
+
+ cupsImageRGBToCMYK(src,cmyk,1);
+ for (int i = 0;i < 4;i++) {
+ *dp++ = ~cmyk[i];
+ }
+ return pixelBuf;
+}
+
+static unsigned char *RGB8toCMYK(unsigned char *src, unsigned char *pixelBuf,
+ unsigned int x, unsigned int y)
+{
+ cupsImageRGBToCMYK(src,pixelBuf,1);
+ return pixelBuf;
+}
+
+static unsigned char *RGB8toCMY(unsigned char *src, unsigned char *pixelBuf,
+ unsigned int x, unsigned int y)
+{
+ cupsImageRGBToCMY(src,pixelBuf,1);
+ return pixelBuf;
+}
+
+static unsigned char *RGB8toYMC(unsigned char *src, unsigned char *pixelBuf,
+ unsigned int x, unsigned int y)
+{
+ cupsImageRGBToCMY(src,pixelBuf,1);
+ /* swap C and Y */
+ unsigned char d = pixelBuf[0];
+ pixelBuf[0] = pixelBuf[2];
+ pixelBuf[2] = d;
+ return pixelBuf;
+}
+
+static unsigned char *RGB8toKCMY(unsigned char *src, unsigned char *pixelBuf,
+ unsigned int x, unsigned int y)
+{
+ cupsImageRGBToCMYK(src,pixelBuf,1);
+ unsigned char d = pixelBuf[3];
+ pixelBuf[3] = pixelBuf[2];
+ pixelBuf[2] = pixelBuf[1];
+ pixelBuf[1] = pixelBuf[0];
+ pixelBuf[0] = d;
+ return pixelBuf;
+}
+
+static unsigned char *RGB8toKCMYcm(unsigned char *src, unsigned char *pixelBuf,
+ unsigned int x, unsigned int y)
+{
+ unsigned char cmyk[4];
+ unsigned char c;
+ unsigned char d;
+
+ cupsImageRGBToCMYK(src,cmyk,1);
+ c = 0;
+ d = dither1[y & 0xf][x & 0xf];
+ /* K */
+ if (cmyk[3] > d) {
+ c |= 0x20;
+ }
+ /* C */
+ if (cmyk[0] > d) {
+ c |= 0x10;
+ }
+ /* M */
+ if (cmyk[1] > d) {
+ c |= 0x08;
+ }
+ /* Y */
+ if (cmyk[2] > d) {
+ c |= 0x04;
+ }
+ if (c == 0x18) { /* Blue */
+ c = 0x11; /* cyan + light magenta */
+ } else if (c == 0x14) { /* Green */
+ c = 0x06; /* light cyan + yellow */
+ }
+ *pixelBuf = c;
+ return pixelBuf;
+}
+
+static unsigned char *RGB8toYMCK(unsigned char *src, unsigned char *pixelBuf,
+ unsigned int x, unsigned int y)
+{
+ cupsImageRGBToCMYK(src,pixelBuf,1);
+ /* swap C and Y */
+ unsigned char d = pixelBuf[0];
+ pixelBuf[0] = pixelBuf[2];
+ pixelBuf[2] = d;
+ return pixelBuf;
+}
+
+static unsigned char *W8toK8(unsigned char *src, unsigned char *pixelBuf,
+ unsigned int x, unsigned int y)
+{
+ *pixelBuf = ~(*src);
+ return pixelBuf;
+}
+
+static unsigned char *convertBitsNoop(unsigned char *src, unsigned char *dst,
+ unsigned int x, unsigned int y)
+{
+ return src;
+}
+
+static unsigned char *convert8to1(unsigned char *src, unsigned char *dst,
+ unsigned int x, unsigned int y)
+{
+ unsigned char c = 0;
+ /* assumed that max number of colors is 4 */
+ for (unsigned int i = 0;i < header.cupsNumColors;i++) {
+ c <<= 1;
+ /* ordered dithering */
+ if (src[i] > dither1[y & 0xf][x & 0xf]) {
+ c |= 0x1;
+ }
+ }
+ *dst = c;
+ return dst;
+}
+
+static unsigned char *convert8to2(unsigned char *src, unsigned char *dst,
+ unsigned int x, unsigned int y)
+{
+ unsigned char c = 0;
+ /* assumed that max number of colors is 4 */
+ for (unsigned int i = 0;i < header.cupsNumColors;i++) {
+ unsigned int d;
+
+ c <<= 2;
+ /* ordered dithering */
+ d = src[i] + dither2[y & 0x7][x & 0x7];
+ if (d > 255) d = 255;
+ c |= d >> 6;
+ }
+ *dst = c;
+ return dst;
+}
+
+static unsigned char *convert8to4(unsigned char *src, unsigned char *dst,
+ unsigned int x, unsigned int y)
+{
+ unsigned short c = 0;
+
+ /* assumed that max number of colors is 4 */
+ for (unsigned int i = 0;i < header.cupsNumColors;i++) {
+ unsigned int d;
+
+ c <<= 4;
+ /* ordered dithering */
+ d = src[i] + dither4[y & 0x3][x & 0x3];
+ if (d > 255) d = 255;
+ c |= d >> 4;
+ }
+ if (header.cupsNumColors < 3) {
+ dst[0] = c;
+ } else {
+ dst[0] = c >> 8;
+ dst[1] = c;
+ }
+ return dst;
+}
+
+static unsigned char *convert8to16(unsigned char *src, unsigned char *dst,
+ unsigned int x, unsigned int y)
+{
+ /* assumed that max number of colors is 4 */
+ for (unsigned int i = 0;i < header.cupsNumColors;i++) {
+ dst[i*2] = src[i];
+ dst[i*2+1] = src[i];
+ }
+ return dst;
+}
+
+static void writePixel1(unsigned char *dst,
+ unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf)
+{
+ switch (header.cupsNumColors) {
+ case 1:
+ {
+ unsigned int bo = pixeli & 0x7;
+ if ((pixeli & 7) == 0) dst[pixeli/8] = 0;
+ dst[pixeli/8] |= *pixelBuf << (7-bo);
+ }
+ break;
+ case 6:
+ dst[pixeli] = *pixelBuf;
+ break;
+ case 3:
+ case 4:
+ default:
+ {
+ unsigned int qo = (pixeli & 0x1)*4;
+ if ((pixeli & 1) == 0) dst[pixeli/2] = 0;
+ dst[pixeli/2] |= *pixelBuf << (4-qo);
+ }
+ break;
+ }
+}
+
+static void writePlanePixel1(unsigned char *dst,
+ unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf)
+{
+ unsigned int bo = pixeli & 0x7;
+ unsigned char so = header.cupsNumColors - plane - 1;
+ if ((pixeli & 7) == 0) dst[pixeli/8] = 0;
+ dst[pixeli/8] |= ((*pixelBuf >> so) & 1) << (7-bo);
+}
+
+static void writePixel2(unsigned char *dst,
+ unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf)
+{
+ switch (header.cupsNumColors) {
+ case 1:
+ {
+ unsigned int bo = (pixeli & 0x3)*2;
+ if ((pixeli & 3) == 0) dst[pixeli/4] = 0;
+ dst[pixeli/4] |= *pixelBuf << (6-bo);
+ }
+ break;
+ case 3:
+ case 4:
+ default:
+ dst[pixeli] = *pixelBuf;
+ break;
+ }
+}
+
+static void writePlanePixel2(unsigned char *dst,
+ unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf)
+{
+ unsigned int bo = (pixeli & 0x3)*2;
+ unsigned char so = (header.cupsNumColors - plane - 1)*2;
+ if ((pixeli & 3) == 0) dst[pixeli/4] = 0;
+ dst[pixeli/4] |= ((*pixelBuf >> so) & 3) << (6-bo);
+}
+
+static void writePixel4(unsigned char *dst,
+ unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf)
+{
+ switch (header.cupsNumColors) {
+ case 1:
+ {
+ unsigned int bo = (pixeli & 0x1)*4;
+ if ((pixeli & 1) == 0) dst[pixeli/2] = 0;
+ dst[pixeli/2] |= *pixelBuf << (4-bo);
+ }
+ break;
+ case 3:
+ case 4:
+ default:
+ dst[pixeli*2] = pixelBuf[0];
+ dst[pixeli*2+1] = pixelBuf[1];
+ break;
+ }
+}
+
+static void writePlanePixel4(unsigned char *dst,
+ unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf)
+{
+ unsigned short c = (pixelBuf[0] << 8) | pixelBuf[1];
+ unsigned int bo = (pixeli & 0x1)*4;
+ unsigned char so = (header.cupsNumColors - plane - 1)*4;
+ if ((pixeli & 1) == 0) dst[pixeli/2] = 0;
+ dst[pixeli/2] |= ((c >> so) & 0xf) << (4-bo);
+}
+
+static void writePixel8(unsigned char *dst,
+ unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf)
+{
+ unsigned char *dp = dst + pixeli*header.cupsNumColors;
+ for (unsigned int i = 0;i < header.cupsNumColors;i++) {
+ dp[i] = pixelBuf[i];
+ }
+}
+
+static void writePlanePixel8(unsigned char *dst,
+ unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf)
+{
+ dst[pixeli] = pixelBuf[plane];
+}
+
+static void writePixel16(unsigned char *dst,
+ unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf)
+{
+ unsigned char *dp = dst + pixeli*header.cupsNumColors*2;
+ for (unsigned int i = 0;i < header.cupsNumColors*2;i++) {
+ dp[i] = pixelBuf[i];
+ }
+}
+
+static void writePlanePixel16(unsigned char *dst,
+ unsigned int plane, unsigned int pixeli, unsigned char *pixelBuf)
+{
+ dst[pixeli*2] = pixelBuf[plane*2];
+ dst[pixeli*2+1] = pixelBuf[plane*2+1];
+}
+
+static unsigned char *convertLineChunked(unsigned char *src, unsigned char *dst,
+ unsigned int row, unsigned int plane, unsigned int pixels,
+ unsigned int size)
+{
+ /* Assumed that BitsPerColor is 8 */
+ for (unsigned int i = 0;i < pixels;i++) {
+ unsigned char pixelBuf1[MAX_BYTES_PER_PIXEL];
+ unsigned char pixelBuf2[MAX_BYTES_PER_PIXEL];
+ unsigned char *pb;
+
+ pb = convertCSpace(src+i*popplerNumColors,pixelBuf1,i,row);
+ pb = convertBits(pb,pixelBuf2,i,row);
+ writePixel(dst,0,i,pb);
+ }
+ return dst;
+}
+
+static unsigned char *convertLineChunkedSwap(unsigned char *src,
+ unsigned char *dst, unsigned int row, unsigned int plane,
+ unsigned int pixels, unsigned int size)
+{
+ /* Assumed that BitsPerColor is 8 */
+ for (unsigned int i = 0;i < pixels;i++) {
+ unsigned char pixelBuf1[MAX_BYTES_PER_PIXEL];
+ unsigned char pixelBuf2[MAX_BYTES_PER_PIXEL];
+ unsigned char *pb;
+
+ pb = convertCSpace(src+(pixels-i-1)*popplerNumColors,pixelBuf1,i,row);
+ pb = convertBits(pb,pixelBuf2,i,row);
+ writePixel(dst,0,i,pb);
+ }
+ return dst;
+}
+
+static unsigned char *convertLinePlane(unsigned char *src, unsigned char *dst,
+ unsigned int row, unsigned int plane, unsigned int pixels,
+ unsigned int size)
+{
+ /* Assumed that BitsPerColor is 8 */
+ for (unsigned int i = 0;i < pixels;i++) {
+ unsigned char pixelBuf1[MAX_BYTES_PER_PIXEL];
+ unsigned char pixelBuf2[MAX_BYTES_PER_PIXEL];
+ unsigned char *pb;
+
+ pb = convertCSpace(src+i*popplerNumColors,pixelBuf1,i,row);
+ pb = convertBits(pb,pixelBuf2,i,row);
+ writePixel(dst,plane,i,pb);
+ }
+ return dst;
+}
+
+static unsigned char *convertLinePlaneSwap(unsigned char *src,
+ unsigned char *dst, unsigned int row, unsigned int plane,
+ unsigned int pixels, unsigned int size)
+{
+ for (unsigned int i = 0;i < pixels;i++) {
+ unsigned char pixelBuf1[MAX_BYTES_PER_PIXEL];
+ unsigned char pixelBuf2[MAX_BYTES_PER_PIXEL];
+ unsigned char *pb;
+
+ pb = convertCSpace(src+(pixels-i-1)*popplerNumColors,pixelBuf1,i,row);
+ pb = convertBits(pb,pixelBuf2,i,row);
+ writePixel(dst,plane,i,pb);
+ }
+ return dst;
+}
+
+/* handle special cases which are appear in gutenprint's PPDs. */
+static bool selectSpecialCase()
+{
+ int i;
+
+ for (i = 0;specialCaseFuncs[i].bitsPerPixel > 0;i++) {
+ if (header.cupsColorSpace == specialCaseFuncs[i].cspace
+ && header.cupsBitsPerPixel == specialCaseFuncs[i].bitsPerPixel
+ && header.cupsBitsPerColor == specialCaseFuncs[i].bitsPerColor) {
+ convertLineOdd = specialCaseFuncs[i].convertLine;
+ if (header.Duplex && swap_image_x) {
+ convertLineEven = specialCaseFuncs[i].convertLineSwap;
+ allocLineBuf = specialCaseFuncs[i].allocLineBufSwap;
+ } else {
+ convertLineEven = specialCaseFuncs[i].convertLine;
+ allocLineBuf = specialCaseFuncs[i].allocLineBuf;
+ }
+ return true; /* found */
+ }
+ }
+ return false;
+}
+
+static unsigned int getCMSColorSpaceType(cmsColorSpaceSignature cs)
+{
+ switch (cs) {
+ case cmsSigXYZData:
+ return PT_XYZ;
+ break;
+ case cmsSigLabData:
+ return PT_Lab;
+ break;
+ case cmsSigLuvData:
+ return PT_YUV;
+ break;
+ case cmsSigYCbCrData:
+ return PT_YCbCr;
+ break;
+ case cmsSigYxyData:
+ return PT_Yxy;
+ break;
+ case cmsSigRgbData:
+ return PT_RGB;
+ break;
+ case cmsSigGrayData:
+ return PT_GRAY;
+ break;
+ case cmsSigHsvData:
+ return PT_HSV;
+ break;
+ case cmsSigHlsData:
+ return PT_HLS;
+ break;
+ case cmsSigCmykData:
+ return PT_CMYK;
+ break;
+ case cmsSigCmyData:
+ return PT_CMY;
+ break;
+ case cmsSig2colorData:
+ case cmsSig3colorData:
+ case cmsSig4colorData:
+ case cmsSig5colorData:
+ case cmsSig6colorData:
+ case cmsSig7colorData:
+ case cmsSig8colorData:
+ case cmsSig9colorData:
+ case cmsSig10colorData:
+ case cmsSig11colorData:
+ case cmsSig12colorData:
+ case cmsSig13colorData:
+ case cmsSig14colorData:
+ case cmsSig15colorData:
+ default:
+ break;
+ }
+ return PT_RGB;
+}
+
+/* select convertLine function */
+static void selectConvertFunc(cups_raster_t *raster)
+{
+ if ((colorProfile == NULL || popplerColorProfile == colorProfile)
+ && (header.cupsColorOrder == CUPS_ORDER_CHUNKED
+ || header.cupsNumColors == 1)) {
+ if (selectSpecialCase()) return;
+ }
+
+ switch (header.cupsColorOrder) {
+ case CUPS_ORDER_BANDED:
+ case CUPS_ORDER_PLANAR:
+ if (header.cupsNumColors > 1) {
+ convertLineEven = convertLinePlaneSwap;
+ convertLineOdd = convertLinePlane;
+ break;
+ }
+ default:
+ case CUPS_ORDER_CHUNKED:
+ convertLineEven = convertLineChunkedSwap;
+ convertLineOdd = convertLineChunked;
+ break;
+ }
+ if (!header.Duplex || !swap_image_x) {
+ convertLineEven = convertLineOdd;
+ }
+ allocLineBuf = true;
+
+ if (colorProfile != NULL && popplerColorProfile != colorProfile) {
+ unsigned int bytes;
+
+ switch (header.cupsColorSpace) {
+ case CUPS_CSPACE_CIELab:
+ case CUPS_CSPACE_ICC1:
+ case CUPS_CSPACE_ICC2:
+ case CUPS_CSPACE_ICC3:
+ case CUPS_CSPACE_ICC4:
+ case CUPS_CSPACE_ICC5:
+ case CUPS_CSPACE_ICC6:
+ case CUPS_CSPACE_ICC7:
+ case CUPS_CSPACE_ICC8:
+ case CUPS_CSPACE_ICC9:
+ case CUPS_CSPACE_ICCA:
+ case CUPS_CSPACE_ICCB:
+ case CUPS_CSPACE_ICCC:
+ case CUPS_CSPACE_ICCD:
+ case CUPS_CSPACE_ICCE:
+ case CUPS_CSPACE_ICCF:
+ if (header.cupsBitsPerColor == 8) {
+ convertCSpace = convertCSpaceLab8;
+ } else {
+ /* 16 bits */
+ convertCSpace = convertCSpaceLab16;
+ }
+ bytes = 0; /* double */
+ break;
+ case CUPS_CSPACE_CIEXYZ:
+ if (header.cupsBitsPerColor == 8) {
+ convertCSpace = convertCSpaceXYZ8;
+ } else {
+ /* 16 bits */
+ convertCSpace = convertCSpaceXYZ16;
+ }
+ bytes = 0; /* double */
+ break;
+ default:
+ convertCSpace = convertCSpaceWithProfiles;
+ bytes = header.cupsBitsPerColor/8;
+ break;
+ }
+ convertBits = convertBitsNoop; /* convert bits in convertCSpace */
+ if (popplerColorProfile == NULL) {
+ popplerColorProfile = cmsCreate_sRGBProfile();
+ }
+ unsigned int dcst = getCMSColorSpaceType(cmsGetColorSpace(colorProfile));
+ if ((colorTransform = cmsCreateTransform(popplerColorProfile,
+ COLORSPACE_SH(PT_RGB) |CHANNELS_SH(3) | BYTES_SH(1),
+ colorProfile,
+ COLORSPACE_SH(dcst) |
+ CHANNELS_SH(header.cupsNumColors) | BYTES_SH(bytes),
+ renderingIntent,0)) == 0) {
+ pdfError(-1,const_cast<char *>("Can't create color transform"));
+ exit(1);
+ }
+ } else {
+ /* select convertCSpace function */
+ switch (header.cupsColorSpace) {
+ case CUPS_CSPACE_CIELab:
+ case CUPS_CSPACE_ICC1:
+ case CUPS_CSPACE_ICC2:
+ case CUPS_CSPACE_ICC3:
+ case CUPS_CSPACE_ICC4:
+ case CUPS_CSPACE_ICC5:
+ case CUPS_CSPACE_ICC6:
+ case CUPS_CSPACE_ICC7:
+ case CUPS_CSPACE_ICC8:
+ case CUPS_CSPACE_ICC9:
+ case CUPS_CSPACE_ICCA:
+ case CUPS_CSPACE_ICCB:
+ case CUPS_CSPACE_ICCC:
+ case CUPS_CSPACE_ICCD:
+ case CUPS_CSPACE_ICCE:
+ case CUPS_CSPACE_ICCF:
+ case CUPS_CSPACE_CIEXYZ:
+ convertCSpace = convertCSpaceNone;
+ break;
+ case CUPS_CSPACE_CMY:
+ convertCSpace = RGB8toCMY;
+ break;
+ case CUPS_CSPACE_YMC:
+ convertCSpace = RGB8toYMC;
+ break;
+ case CUPS_CSPACE_CMYK:
+ convertCSpace = RGB8toCMYK;
+ break;
+ case CUPS_CSPACE_KCMY:
+ convertCSpace = RGB8toKCMY;
+ break;
+ case CUPS_CSPACE_KCMYcm:
+ if (header.cupsBitsPerColor > 1) {
+ convertCSpace = RGB8toKCMY;
+ } else {
+ convertCSpace = RGB8toKCMYcm;
+ }
+ break;
+ case CUPS_CSPACE_GMCS:
+ case CUPS_CSPACE_GMCK:
+ case CUPS_CSPACE_YMCK:
+ convertCSpace = RGB8toYMCK;
+ break;
+ case CUPS_CSPACE_RGBW:
+ convertCSpace = RGB8toRGBW;
+ break;
+ case CUPS_CSPACE_RGBA:
+ convertCSpace = RGB8toRGBA;
+ break;
+ case CUPS_CSPACE_RGB:
+ case CUPS_CSPACE_SRGB:
+ case CUPS_CSPACE_ADOBERGB:
+ convertCSpace = convertCSpaceNone;
+ break;
+ case CUPS_CSPACE_W:
+ case CUPS_CSPACE_SW:
+ case CUPS_CSPACE_WHITE:
+ convertCSpace = convertCSpaceNone;
+ break;
+ case CUPS_CSPACE_K:
+ case CUPS_CSPACE_GOLD:
+ case CUPS_CSPACE_SILVER:
+ convertCSpace = W8toK8;
+ break;
+ default:
+ pdfError(-1,const_cast<char *>("Specified ColorSpace is not supported"));
+ exit(1);
+ break;
+ }
+ /* select convertBits function */
+ switch (header.cupsBitsPerColor) {
+ case 2:
+ convertBits = convert8to2;
+ break;
+ case 4:
+ convertBits = convert8to4;
+ break;
+ case 16:
+ convertBits = convert8to16;
+ break;
+ case 1:
+ if (header.cupsNumColors == 1
+ || header.cupsColorSpace == CUPS_CSPACE_KCMYcm) {
+ convertBits = convertBitsNoop;
+ } else {
+ convertBits = convert8to1;
+ }
+ break;
+ case 8:
+ default:
+ convertBits = convertBitsNoop;
+ break;
+ }
+ }
+ /* select writePixel function */
+ switch (header.cupsBitsPerColor) {
+ case 2:
+ if (header.cupsColorOrder == CUPS_ORDER_CHUNKED
+ || header.cupsNumColors == 1) {
+ writePixel = writePixel2;
+ } else {
+ writePixel = writePlanePixel2;
+ }
+ break;
+ case 4:
+ if (header.cupsColorOrder == CUPS_ORDER_CHUNKED
+ || header.cupsNumColors == 1) {
+ writePixel = writePixel4;
+ } else {
+ writePixel = writePlanePixel4;
+ }
+ break;
+ case 16:
+ if (header.cupsColorOrder == CUPS_ORDER_CHUNKED
+ || header.cupsNumColors == 1) {
+ writePixel = writePixel16;
+ } else {
+ writePixel = writePlanePixel16;
+ }
+ break;
+ case 1:
+ if (header.cupsColorOrder == CUPS_ORDER_CHUNKED
+ || header.cupsNumColors == 1) {
+ writePixel = writePixel1;
+ } else {
+ writePixel = writePlanePixel1;
+ }
+ break;
+ case 8:
+ default:
+ if (header.cupsColorOrder == CUPS_ORDER_CHUNKED
+ || header.cupsNumColors == 1) {
+ writePixel = writePixel8;
+ } else {
+ writePixel = writePlanePixel8;
+ }
+ break;
+ }
+}
+
+static void writePageImage(cups_raster_t *raster, SplashBitmap *bitmap,
+ int pageNo)
+{
+ ConvertLineFunc convertLine;
+ unsigned char *lineBuf = NULL;
+ unsigned char *dp;
+ unsigned int rowsize = bitmap->getRowSize();
+
+ if (allocLineBuf) lineBuf = new unsigned char [bytesPerLine];
+ if ((pageNo & 1) == 0) {
+ convertLine = convertLineEven;
+ } else {
+ convertLine = convertLineOdd;
+ }
+ if (header.Duplex && (pageNo & 1) == 0 && swap_image_y) {
+ for (unsigned int plane = 0;plane < nplanes;plane++) {
+ unsigned char *bp = (unsigned char *)(bitmap->getDataPtr());
+
+ bp += rowsize * (bitmapoffset[1] + header.cupsHeight - 1) +
+ popplerBitsPerPixel * bitmapoffset[0] / 8;
+ for (unsigned int h = header.cupsHeight;h > 0;h--) {
+ for (unsigned int band = 0;band < nbands;band++) {
+ dp = convertLine(bp,lineBuf,h,plane+band,header.cupsWidth,
+ bytesPerLine);
+ cupsRasterWritePixels(raster,dp,bytesPerLine);
+ }
+ bp -= rowsize;
+ }
+ }
+ } else {
+ for (unsigned int plane = 0;plane < nplanes;plane++) {
+ unsigned char *bp = (unsigned char *)(bitmap->getDataPtr());
+
+ bp += rowsize * bitmapoffset[1] +
+ popplerBitsPerPixel * bitmapoffset[0] / 8;
+ for (unsigned int h = 0;h < header.cupsHeight;h++) {
+ for (unsigned int band = 0;band < nbands;band++) {
+ dp = convertLine(bp,lineBuf,h,plane+band,header.cupsWidth,
+ bytesPerLine);
+ cupsRasterWritePixels(raster,dp,bytesPerLine);
+ }
+ bp += rowsize;
+ }
+ }
+ }
+ if (allocLineBuf) delete[] lineBuf;
+}
+
+static void outPage(PDFDoc *doc, Catalog *catalog, int pageNo,
+ SplashOutputDev *out, cups_raster_t *raster)
+{
+ SplashBitmap *bitmap;
+ Page *page = catalog->getPage(pageNo);
+ PDFRectangle *mediaBox = page->getMediaBox();
+ int rotate = page->getRotate();
+ double paperdimensions[2], /* Physical size of the paper */
+ margins[4]; /* Physical margins of print */
+ ppd_size_t *size; /* Page size */
+ double l, swap;
+ int i;
+ bool landscape = 0;
+
+ fprintf(stderr, "DEBUG: mediaBox = [ %f %f %f %f ]; rotate = %d\n",
+ mediaBox->x1, mediaBox->y1, mediaBox->x2, mediaBox->y2, rotate);
+ l = mediaBox->x2 - mediaBox->x1;
+ if (l < 0) l = -l;
+ if (rotate == 90 || rotate == 270)
+ header.PageSize[1] = (unsigned)l;
+ else
+ header.PageSize[0] = (unsigned)l;
+ l = mediaBox->y2 - mediaBox->y1;
+ if (l < 0) l = -l;
+ if (rotate == 90 || rotate == 270)
+ header.PageSize[0] = (unsigned)l;
+ else
+ header.PageSize[1] = (unsigned)l;
+
+ memset(paperdimensions, 0, sizeof(paperdimensions));
+ memset(margins, 0, sizeof(margins));
+ if (ppd) {
+ for (i = ppd->num_sizes, size = ppd->sizes;
+ i > 0;
+ i --, size ++) {
+ /* Skip page sizes which conflict with settings of the other options */
+ /* TODO XXX */
+ /* Find size of document's page under the PPD page sizes */
+ if (fabs(header.PageSize[1] - size->length) < 5.0 &&
+ fabs(header.PageSize[0] - size->width) < 5.0)
+ break;
+ }
+ if (i > 0) {
+ /*
+ * Standard size...
+ */
+ fprintf(stderr, "DEBUG: size = %s\n", size->name);
+ landscape = 0;
+ paperdimensions[0] = size->width;
+ paperdimensions[1] = size->length;
+ if (pwgraster == 0) {
+ margins[0] = size->left;
+ margins[1] = size->bottom;
+ margins[2] = size->width - size->right;
+ margins[3] = size->length - size->top;
+ }
+ strncpy(header.cupsPageSizeName, size->name, 64);
+ } else {
+ /*
+ * No matching portrait size; look for a matching size in
+ * landscape orientation...
+ */
+
+ for (i = ppd->num_sizes, size = ppd->sizes;
+ i > 0;
+ i --, size ++)
+ if (fabs(header.PageSize[0] - size->length) < 5.0 &&
+ fabs(header.PageSize[1] - size->width) < 5.0)
+ break;
+
+ if (i > 0) {
+ /*
+ * Standard size in landscape orientation...
+ */
+ fprintf(stderr, "DEBUG: landscape size = %s\n", size->name);
+ landscape = 1;
+ paperdimensions[0] = size->width;
+ paperdimensions[1] = size->length;
+ if (pwgraster == 0) {
+ margins[0] = size->left;
+ margins[1] = size->bottom;
+ margins[2] = size->width - size->right;
+ margins[3] = size->length - size->top;
+ }
+ strncpy(header.cupsPageSizeName, size->name, 64);
+ } else {
+ /*
+ * Custom size...
+ */
+ fprintf(stderr, "DEBUG: size = Custom\n");
+ landscape = 0;
+ paperdimensions[1] = size->length;
+ for (i = 0; i < 2; i ++)
+ paperdimensions[i] = header.PageSize[i];
+ if (pwgraster == 0)
+ for (i = 0; i < 4; i ++)
+ margins[i] = ppd->custom_margins[i];
+ header.cupsPageSizeName[0] = '\0';
+ }
+ }
+ } else {
+ for (i = 0; i < 2; i ++)
+ paperdimensions[i] = header.PageSize[i];
+ if (header.cupsImagingBBox[3] > 0.0) {
+ /* Set margins if we have a bounding box defined ... */
+ if (pwgraster == 0) {
+ margins[0] = header.cupsImagingBBox[0];
+ margins[1] = header.cupsImagingBBox[1];
+ margins[2] = paperdimensions[0] - header.cupsImagingBBox[2];
+ margins[3] = paperdimensions[1] - header.cupsImagingBBox[3];
+ }
+ } else
+ /* ... otherwise use zero margins */
+ for (i = 0; i < 4; i ++)
+ margins[i] = 0.0;
+ /*margins[0] = 0.0;
+ margins[1] = 0.0;
+ margins[2] = header.PageSize[0];
+ margins[3] = header.PageSize[1];*/
+ }
+
+ if (header.Duplex && (pageNo & 1) == 0) {
+ /* backside: change margin if needed */
+ if (swap_margin_x) {
+ swap = margins[2]; margins[2] = margins[0]; margins[0] = swap;
+ }
+ if (swap_margin_y) {
+ swap = margins[3]; margins[3] = margins[1]; margins[1] = swap;
+ }
+ }
+
+ doc->displayPage(out,pageNo,header.HWResolution[0],
+ header.HWResolution[1],(landscape == 0 ? 0 : 90),
+ gTrue,gTrue,gTrue);
+ bitmap = out->getBitmap();
+ bitmapoffset[0] = margins[0] / 72.0 * header.HWResolution[0];
+ bitmapoffset[1] = margins[3] / 72.0 * header.HWResolution[1];
+
+ /* write page header */
+ if (pwgraster == 0) {
+ header.cupsWidth = ((paperdimensions[0] - margins[0] - margins[2]) /
+ 72.0 * header.HWResolution[0]) + 0.5;
+ header.cupsHeight = ((paperdimensions[1] - margins[1] - margins[3]) /
+ 72.0 * header.HWResolution[1]) + 0.5;
+ } else {
+ header.cupsWidth = (paperdimensions[0] /
+ 72.0 * header.HWResolution[0]) + 0.5;
+ header.cupsHeight = (paperdimensions[1] /
+ 72.0 * header.HWResolution[1]) + 0.5;
+ }
+ for (i = 0; i < 2; i ++) {
+ header.cupsPageSize[i] = paperdimensions[i];
+ header.PageSize[i] = (unsigned int)(header.cupsPageSize[i] + 0.5);
+ if (pwgraster == 0)
+ header.Margins[i] = margins[i] + 0.5;
+ else
+ header.Margins[i] = 0;
+ }
+ if (pwgraster == 0) {
+ header.cupsImagingBBox[0] = margins[0];
+ header.cupsImagingBBox[1] = margins[1];
+ header.cupsImagingBBox[2] = paperdimensions[0] - margins[2];
+ header.cupsImagingBBox[3] = paperdimensions[1] - margins[3];
+ for (i = 0; i < 4; i ++)
+ header.ImagingBoundingBox[i] =
+ (unsigned int)(header.cupsImagingBBox[i] + 0.5);
+ } else
+ for (i = 0; i < 4; i ++) {
+ header.cupsImagingBBox[i] = 0.0;
+ header.ImagingBoundingBox[i] = 0;
+ }
+
+ bytesPerLine = header.cupsBytesPerLine = (header.cupsBitsPerPixel *
+ header.cupsWidth + 7) / 8;
+ if (header.cupsColorOrder == CUPS_ORDER_BANDED) {
+ header.cupsBytesPerLine *= header.cupsNumColors;
+ }
+ if (!cupsRasterWriteHeader2(raster,&header)) {
+ pdfError(-1,const_cast<char *>("Can't write page %d header"),pageNo);
+ exit(1);
+ }
+
+ /* write page image */
+ writePageImage(raster,bitmap,pageNo);
+}
+
+static void setPopplerColorProfile()
+{
+ if (header.cupsBitsPerColor != 8 && header.cupsBitsPerColor != 16) {
+ /* color Profile is not supported */
+ return;
+ }
+ /* set poppler color profile */
+ switch (header.cupsColorSpace) {
+ case CUPS_CSPACE_CIELab:
+ case CUPS_CSPACE_ICC1:
+ case CUPS_CSPACE_ICC2:
+ case CUPS_CSPACE_ICC3:
+ case CUPS_CSPACE_ICC4:
+ case CUPS_CSPACE_ICC5:
+ case CUPS_CSPACE_ICC6:
+ case CUPS_CSPACE_ICC7:
+ case CUPS_CSPACE_ICC8:
+ case CUPS_CSPACE_ICC9:
+ case CUPS_CSPACE_ICCA:
+ case CUPS_CSPACE_ICCB:
+ case CUPS_CSPACE_ICCC:
+ case CUPS_CSPACE_ICCD:
+ case CUPS_CSPACE_ICCE:
+ case CUPS_CSPACE_ICCF:
+ if (colorProfile == NULL) {
+ cmsCIExyY wp;
+#ifdef USE_LCMS1
+ cmsWhitePointFromTemp(6504,&wp); /* D65 White point */
+#else
+ cmsWhitePointFromTemp(&wp,6504); /* D65 White point */
+#endif
+ colorProfile = cmsCreateLab4Profile(&wp);
+ }
+ break;
+ case CUPS_CSPACE_CIEXYZ:
+ if (colorProfile == NULL) {
+ /* tansform color space via CIELab */
+ cmsCIExyY wp;
+#ifdef USE_LCMS1
+ cmsWhitePointFromTemp(6504,&wp); /* D65 White point */
+#else
+ cmsWhitePointFromTemp(&wp,6504); /* D65 White point */
+#endif
+ cmsxyY2XYZ(&D65WhitePoint,&wp);
+ colorProfile = cmsCreateLab4Profile(&wp);
+ }
+ break;
+ case CUPS_CSPACE_SRGB:
+ colorProfile = cmsCreate_sRGBProfile();
+ break;
+ case CUPS_CSPACE_ADOBERGB:
+ colorProfile = adobergb_profile();
+ break;
+ case CUPS_CSPACE_SW:
+ colorProfile = sgray_profile();
+ break;
+ case CUPS_CSPACE_RGB:
+ case CUPS_CSPACE_K:
+ case CUPS_CSPACE_W:
+ case CUPS_CSPACE_WHITE:
+ case CUPS_CSPACE_GOLD:
+ case CUPS_CSPACE_SILVER:
+ /* We can set specified profile to poppler profile */
+ popplerColorProfile = colorProfile;
+ break;
+ case CUPS_CSPACE_CMYK:
+ case CUPS_CSPACE_KCMY:
+ case CUPS_CSPACE_KCMYcm:
+ case CUPS_CSPACE_YMCK:
+ case CUPS_CSPACE_RGBA:
+ case CUPS_CSPACE_RGBW:
+ case CUPS_CSPACE_GMCK:
+ case CUPS_CSPACE_GMCS:
+ case CUPS_CSPACE_CMY:
+ case CUPS_CSPACE_YMC:
+ /* use standard RGB */
+ popplerColorProfile = NULL;
+ break;
+ default:
+ pdfError(-1,const_cast<char *>("Specified ColorSpace is not supported"));
+ exit(1);
+ break;
+ }
+ if (popplerColorProfile != NULL) {
+ GfxColorSpace::setDisplayProfile(popplerColorProfile);
+ }
+}
+
+int main(int argc, char *argv[]) {
+ PDFDoc *doc;
+ SplashOutputDev *out;
+ SplashColor paperColor;
+ int i;
+ int npages;
+ cups_raster_t *raster;
+ enum SplashColorMode cmode;
+ int rowpad;
+ Catalog *catalog;
+
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+ setErrorCallback(::myErrorFun,NULL);
+#else
+ setErrorFunction(::myErrorFun);
+#endif
+ cmsSetLogErrorHandler(lcmsErrorHandler);
+ globalParams = new GlobalParams();
+ parseOpts(argc, argv);
+
+ if (argc == 6) {
+ /* stdin */
+ int fd;
+ char name[BUFSIZ];
+ char buf[BUFSIZ];
+ int n;
+
+ fd = cupsTempFd(name,sizeof(name));
+ if (fd < 0) {
+ pdfError(-1,const_cast<char *>("Can't create temporary file"));
+ exit(1);
+ }
+
+ /* copy stdin to the tmp file */
+ while ((n = read(0,buf,BUFSIZ)) > 0) {
+ if (write(fd,buf,n) != n) {
+ pdfError(-1,const_cast<char *>("Can't copy stdin to temporary file"));
+ close(fd);
+ exit(1);
+ }
+ }
+ close(fd);
+ doc = new PDFDoc(new GooString(name));
+ /* remove name */
+ unlink(name);
+ } else {
+ GooString *fileName = new GooString(argv[6]);
+ /* argc == 7 filenmae is specified */
+ FILE *fp;
+
+ if ((fp = fopen(argv[6],"rb")) == 0) {
+ pdfError(-1,const_cast<char *>("Can't open input file %s"),argv[6]);
+ exit(1);
+ }
+ parsePDFTOPDFComment(fp);
+ fclose(fp);
+ doc = new PDFDoc(fileName,NULL,NULL);
+ }
+
+ if (!doc->isOk()) {
+ exitCode = 1;
+ goto err1;
+ }
+
+ catalog = doc->getCatalog();
+ npages = doc->getNumPages();
+
+ /* fix NumCopies, Collate ccording to PDFTOPDFComments */
+ header.NumCopies = deviceCopies;
+ header.Collate = deviceCollate ? CUPS_TRUE : CUPS_FALSE;
+ /* fixed other values that pdftopdf handles */
+ header.MirrorPrint = CUPS_FALSE;
+ header.Orientation = CUPS_ORIENT_0;
+
+ if (header.cupsBitsPerColor != 1
+ && header.cupsBitsPerColor != 2
+ && header.cupsBitsPerColor != 4
+ && header.cupsBitsPerColor != 8
+ && header.cupsBitsPerColor != 16) {
+ pdfError(-1,const_cast<char *>("Specified color format is not supported"));
+ exit(1);
+ }
+ if (header.cupsColorOrder == CUPS_ORDER_PLANAR) {
+ nplanes = header.cupsNumColors;
+ } else {
+ nplanes = 1;
+ }
+ if (header.cupsColorOrder == CUPS_ORDER_BANDED) {
+ nbands = header.cupsNumColors;
+ } else {
+ nbands = 1;
+ }
+ /* set image's values */
+ switch (header.cupsColorSpace) {
+ case CUPS_CSPACE_CIELab:
+ case CUPS_CSPACE_ICC1:
+ case CUPS_CSPACE_ICC2:
+ case CUPS_CSPACE_ICC3:
+ case CUPS_CSPACE_ICC4:
+ case CUPS_CSPACE_ICC5:
+ case CUPS_CSPACE_ICC6:
+ case CUPS_CSPACE_ICC7:
+ case CUPS_CSPACE_ICC8:
+ case CUPS_CSPACE_ICC9:
+ case CUPS_CSPACE_ICCA:
+ case CUPS_CSPACE_ICCB:
+ case CUPS_CSPACE_ICCC:
+ case CUPS_CSPACE_ICCD:
+ case CUPS_CSPACE_ICCE:
+ case CUPS_CSPACE_ICCF:
+ case CUPS_CSPACE_CIEXYZ:
+ if (header.cupsColorOrder != CUPS_ORDER_CHUNKED
+ || (header.cupsBitsPerColor != 8
+ && header.cupsBitsPerColor != 16)) {
+ pdfError(-1,const_cast<char *>("Specified color format is not supported"));
+ exit(1);
+ }
+ case CUPS_CSPACE_RGB:
+ case CUPS_CSPACE_SRGB:
+ case CUPS_CSPACE_ADOBERGB:
+ case CUPS_CSPACE_CMY:
+ case CUPS_CSPACE_YMC:
+ case CUPS_CSPACE_CMYK:
+ case CUPS_CSPACE_KCMY:
+ case CUPS_CSPACE_KCMYcm:
+ case CUPS_CSPACE_YMCK:
+ case CUPS_CSPACE_RGBA:
+ case CUPS_CSPACE_RGBW:
+ case CUPS_CSPACE_GMCK:
+ case CUPS_CSPACE_GMCS:
+ cmode = splashModeRGB8;
+ rowpad = 4;
+ /* set paper color white */
+ paperColor[0] = 255;
+ paperColor[1] = 255;
+ paperColor[2] = 255;
+ popplerBitsPerPixel = 24;
+ popplerNumColors = 3;
+ break;
+ case CUPS_CSPACE_K:
+ case CUPS_CSPACE_W:
+ case CUPS_CSPACE_SW:
+ case CUPS_CSPACE_WHITE:
+ case CUPS_CSPACE_GOLD:
+ case CUPS_CSPACE_SILVER:
+ if (header.cupsBitsPerColor == 1
+ && header.cupsBitsPerPixel == 1) {
+ cmode = splashModeMono1;
+ popplerBitsPerPixel = 1;
+ } else {
+ cmode = splashModeMono8;
+ popplerBitsPerPixel = 8;
+ }
+ /* set paper color white */
+ paperColor[0] = 255;
+ rowpad = 1;
+ popplerNumColors = 1;
+ break;
+ default:
+ pdfError(-1,const_cast<char *>("Specified ColorSpace is not supported"));
+ exit(1);
+ break;
+ }
+
+ if (!cm_disabled) {
+ setPopplerColorProfile();
+ }
+
+ out = new SplashOutputDev(cmode,rowpad/* row padding */,
+ gFalse,paperColor,gTrue
+#if POPPLER_VERSION_MAJOR == 0 && POPPLER_VERSION_MINOR <= 30
+ ,gFalse
+#endif
+ );
+#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
+ out->startDoc(doc);
+#else
+ out->startDoc(doc->getXRef());
+#endif
+
+ if ((raster = cupsRasterOpen(1, pwgraster ? CUPS_RASTER_WRITE_PWG :
+ CUPS_RASTER_WRITE)) == 0) {
+ pdfError(-1,const_cast<char *>("Can't open raster stream"));
+ exit(1);
+ }
+ selectConvertFunc(raster);
+ for (i = 1;i <= npages;i++) {
+ outPage(doc,catalog,i,out,raster);
+ }
+ cupsRasterClose(raster);
+
+ delete out;
+err1:
+ delete doc;
+ if (ppd != NULL) {
+ ppdClose(ppd);
+ }
+ if (colorProfile != NULL) {
+ cmsCloseProfile(colorProfile);
+ }
+ if (popplerColorProfile != NULL && popplerColorProfile != colorProfile) {
+ cmsCloseProfile(popplerColorProfile);
+ }
+ if (colorTransform != NULL) {
+ cmsDeleteTransform(colorTransform);
+ }
+
+ // Check for memory leaks
+ Object::memCheck(stderr);
+ gMemReport(stderr);
+
+ return exitCode;
+}
+
+/* replace memory allocation methods for memory check */
+/* For compatibility with g++ >= 4.7 compilers _GLIBCXX_THROW
+ * should be used as a guard, otherwise use traditional definition */
+#ifndef _GLIBCXX_THROW
+#define _GLIBCXX_THROW throw
+#endif
+
+void * operator new(size_t size) _GLIBCXX_THROW (std::bad_alloc)
+{
+ return gmalloc(size);
+}
+
+void operator delete(void *p) throw ()
+{
+ gfree(p);
+}
+
+void * operator new[](size_t size) _GLIBCXX_THROW (std::bad_alloc)
+{
+ return gmalloc(size);
+}
+
+void operator delete[](void *p) throw ()
+{
+ gfree(p);
+}
diff --git a/filter/pdfutils.c b/filter/pdfutils.c
new file mode 100644
index 000000000..8dbf65d21
--- /dev/null
+++ b/filter/pdfutils.c
@@ -0,0 +1,431 @@
+/*
+ * PDF file output routines.
+ *
+ * Copyright 2008 by Tobias Hoffmann.
+ *
+ * This file is licensed as noted in "COPYING"
+ * which should have been included with this file.
+ *
+ */
+#include <stdio.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <memory.h>
+#include <stdlib.h>
+#include <string.h>
+#include "pdfutils.h"
+#include "fontembed/embed.h"
+
+void pdfOut_printf(pdfOut *pdf,const char *fmt,...) // {{{
+{
+ assert(pdf);
+ int len;
+ va_list ap;
+
+ va_start(ap,fmt);
+ len=vprintf(fmt,ap);
+ va_end(ap);
+ pdf->filepos+=len;
+}
+// }}}
+
+void pdfOut_putString(pdfOut *pdf,const char *str,int len) // {{{ - >len==-1: strlen()
+{
+ assert(pdf);
+ assert(str);
+ if (len==-1) {
+ len=strlen(str);
+ }
+ putc('(',stdout);
+ // escape special chars: \0 \\ \( \) -- don't bother about balanced parens
+ int iA=0;
+ for (;len>0;iA++,len--) {
+ if ( (str[iA]<32)||(str[iA]>126) ) {
+ fwrite(str,1,iA,stdout);
+ fprintf(stdout,"\\%03o",(unsigned char)str[iA]);
+ pdf->filepos+=iA+4;
+ str+=iA+1;
+ iA=-1;
+ } else if ( (str[iA]=='(')||(str[iA]==')')||(str[iA]=='\\') ) {
+ fwrite(str,1,iA,stdout);
+ fprintf(stdout,"\\%c",str[iA]);
+ pdf->filepos+=iA+2;
+ str+=iA+1;
+ iA=-1;
+ }
+ }
+ pdf->filepos+=iA+2;
+ fwrite(str,1,iA,stdout);
+ putc(')',stdout);
+}
+// }}}
+
+void pdfOut_putHexString(pdfOut *pdf,const char *str,int len) // {{{ - >len==-1: strlen()
+{
+ assert(pdf);
+ assert(str);
+ if (len==-1) {
+ len=strlen(str);
+ }
+ pdf->filepos+=2*len+2;
+ putc('<',stdout);
+ for (;len>0;str++,len--) {
+ fprintf(stdout,"%02x",(unsigned char)*str);
+ }
+ putc('>',stdout);
+}
+// }}}
+
+pdfOut *pdfOut_new() // {{{ - NULL on error
+{
+ pdfOut *ret=malloc(sizeof(pdfOut));
+ if (ret) {
+ memset(ret,0,sizeof(pdfOut));
+ }
+
+ return ret;
+}
+// }}}
+
+// NOTE: uses statically allocated buffer
+const char *pdfOut_to_pdfdate(struct tm *curtm) // {{{
+{
+ static char curdate[250];
+ if (!curtm) {
+ time_t curtime;
+ curtime = time(NULL);
+ curtm = localtime(&curtime);
+ }
+ strftime(curdate, sizeof(curdate), "D:%Y%m%d%H%M%S%z", curtm);
+ curdate[23]=0;
+ curdate[22]='\'';
+ curdate[21]=curdate[18];
+ curdate[20]=curdate[17];
+ curdate[19]='\'';
+ return curdate;
+}
+// }}}
+
+int pdfOut_add_xref(pdfOut *pdf) // {{{ - returns obj_no
+{
+ assert(pdf);
+ assert(pdf->xrefsize<=pdf->xrefalloc);
+
+ if (pdf->xrefsize==pdf->xrefalloc) {
+ long *tmp;
+ pdf->xrefalloc+=50;
+ tmp=realloc(pdf->xref,sizeof(long)*pdf->xrefalloc);
+ if (!tmp) {
+ pdf->xrefalloc=-1;
+ return -1;
+ }
+ pdf->xref=tmp;
+ }
+ pdf->xref[pdf->xrefsize++]=pdf->filepos;
+ return pdf->xrefsize; // xrefsize+1
+}
+// }}}
+
+int pdfOut_add_page(pdfOut *pdf,int obj) // {{{ - returns false on error
+{
+ assert(pdf);
+ assert(obj>0);
+ assert(pdf->pagessize<=pdf->pagesalloc);
+
+ if (pdf->pagessize==pdf->pagesalloc) {
+ int *tmp;
+ pdf->pagesalloc+=10;
+ tmp=realloc(pdf->pages,sizeof(int)*pdf->pagesalloc);
+ if (!tmp) {
+ pdf->pagesalloc=-1;
+ return 0;
+ }
+ pdf->pages=tmp;
+ }
+ pdf->pages[pdf->pagessize++]=obj;
+ return 1;
+}
+// }}}
+
+int pdfOut_add_kv(pdfOut *pdf,const char *key,const char *val) // {{{ - returns false on error
+{
+ assert(pdf);
+ assert(pdf->kvsize<=pdf->kvalloc);
+
+ if (pdf->kvsize==pdf->kvalloc) {
+ struct keyval_t *tmp;
+ pdf->kvalloc+=10;
+ tmp=realloc(pdf->kv,sizeof(struct keyval_t)*pdf->kvalloc);
+ if (!tmp) {
+ pdf->kvalloc=-1;
+ return 0;
+ }
+ pdf->kv=tmp;
+ }
+ pdf->kv[pdf->kvsize].key=strdup(key);
+ pdf->kv[pdf->kvsize].value=strdup(val);
+ if ( (!pdf->kv[pdf->kvsize].key)||(!pdf->kv[pdf->kvsize].value) ) {
+ return 0;
+ }
+ pdf->kvsize++;
+ return 1;
+}
+// }}}
+
+int pdfOut_begin_pdf(pdfOut *pdf) // ,...output_device?...) // {{{ - false on error
+{
+ assert(pdf);
+ assert(pdf->kvsize==0); // otherwise: finish_pdf has not been called
+ int pages_obj;
+
+ pdf->xrefsize=pdf->pagessize=0;
+ pdf->filepos=0;
+ pages_obj=pdfOut_add_xref(pdf); // fixed later
+ if (pages_obj!=1) {
+ return 0;
+ }
+ pdfOut_printf(pdf,"%%PDF-1.3\n");
+ return 1;
+}
+// }}}
+
+void pdfOut_finish_pdf(pdfOut *pdf) // {{{
+{
+ int iA;
+ int root_obj,info_obj=0,xref_start;
+ assert( (pdf)&&(pdf->filepos!=-1) );
+
+ // pages
+ const int pages_obj=1;
+ pdf->xref[0]=pdf->filepos; // now fix it
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "<</Type/Pages\n"
+ " /Count %d\n"
+ " /Kids [",
+ pages_obj,pdf->pagessize);
+ for (iA=0;iA<pdf->pagessize;iA++) {
+ pdfOut_printf(pdf,"%d 0 R ",pdf->pages[iA]);
+ }
+ pdfOut_printf(pdf,"]\n"
+ ">>\n"
+ "endobj\n");
+
+ // rootdict
+ root_obj=pdfOut_add_xref(pdf);
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "<</Type/Catalog\n"
+ " /Pages %d 0 R\n"
+ ">>\n"
+ "endobj\n",
+ root_obj,pages_obj);
+
+ // info
+ if (pdf->kvsize) {
+ info_obj=pdfOut_add_xref(pdf);
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "<<\n",
+ info_obj);
+ for (iA=0;iA<pdf->kvsize;iA++) {
+ pdfOut_printf(pdf," /%s ",pdf->kv[iA].key);
+ pdfOut_putString(pdf,pdf->kv[iA].value,-1);
+ pdfOut_printf(pdf,"\n");
+ }
+ pdfOut_printf(pdf,">>\n"
+ "endobj\n");
+ }
+ // TODO: some return-value checking (??)
+
+ // write xref
+ xref_start=pdf->filepos;
+ pdfOut_printf(pdf,"xref\n"
+ "%d %d\n"
+ "%010d 65535 f \n",
+ 0,pdf->xrefsize+1,0);
+ for (iA=0;iA<pdf->xrefsize;iA++) {
+ pdfOut_printf(pdf,"%010ld 00000 n \n",
+ pdf->xref[iA]);
+ }
+ pdfOut_printf(pdf,"trailer\n"
+ "<<\n"
+ " /Size %d\n"
+ " /Root %d 0 R\n",
+ pdf->xrefsize+1,
+ root_obj);
+ if (info_obj) {
+ pdfOut_printf(pdf," /Info %d 0 R\n",info_obj);
+ }
+ pdfOut_printf(pdf,">>\n"
+ "startxref\n"
+ "%d\n"
+ "%%%%EOF\n",
+ xref_start);
+
+ // set to done
+ pdf->filepos=-1;
+ for (iA=0;iA<pdf->kvsize;iA++) {
+ free(pdf->kv[iA].key);
+ free(pdf->kv[iA].value);
+ }
+ pdf->kvsize=0;
+}
+// }}}
+
+void pdfOut_free(pdfOut *pdf) // {{{
+{
+ if (pdf) {
+ assert(pdf->kvsize==0); // otherwise: finish_pdf has not been called
+ free(pdf->kv);
+ free(pdf->pages);
+ free(pdf->xref);
+ free(pdf);
+ }
+}
+// }}}
+
+static void pdfOut_outfn(const char *buf,int len,void *context) // {{{
+{
+ pdfOut *pdf=(pdfOut *)context;
+
+ if (fwrite(buf,1,len,stdout)!=len) {
+ perror("Short write");
+ assert(0);
+ return;
+ }
+ pdf->filepos+=len;
+}
+// }}}
+
+int pdfOut_write_font(pdfOut *pdf,EMB_PARAMS *emb) // {{{
+{
+ assert(pdf);
+ assert(emb);
+
+ EMB_PDF_FONTDESCR *fdes=emb_pdf_fontdescr(emb);
+ if (!fdes) {
+ if (emb->outtype==EMB_FMT_STDFONT) { // std-14 font
+ const int f_obj=pdfOut_add_xref(pdf);
+ char *res=emb_pdf_simple_stdfont(emb);
+ if (!res) {
+ return 0;
+ }
+
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "%s"
+ "endobj\n"
+ ,f_obj,res);
+ free(res);
+ return f_obj;
+ }
+ return 0;
+ }
+
+ const int ff_obj=pdfOut_add_xref(pdf);
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "<</Length %d 0 R\n"
+ ,ff_obj,ff_obj+1);
+ if (emb_pdf_get_fontfile_subtype(emb)) {
+ pdfOut_printf(pdf," /Subtype /%s\n",
+ emb_pdf_get_fontfile_subtype(emb));
+ }
+ if (emb->outtype==EMB_FMT_TTF) {
+ pdfOut_printf(pdf," /Length1 %d 0 R\n"
+ ,ff_obj+2);
+ } else if (emb->outtype==EMB_FMT_T1) { // TODO
+ pdfOut_printf(pdf," /Length1 ?\n"
+ " /Length2 ?\n"
+ " /Length3 ?\n"
+ );
+ }
+ pdfOut_printf(pdf,">>\n"
+ "stream\n");
+ long streamsize=-pdf->filepos;
+ const int outlen=emb_embed(emb,pdfOut_outfn,pdf);
+ streamsize+=pdf->filepos;
+ pdfOut_printf(pdf,"\nendstream\n"
+ "endobj\n");
+
+ const int l0_obj=pdfOut_add_xref(pdf);
+ assert(l0_obj==ff_obj+1);
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "%ld\n"
+ "endobj\n"
+ ,l0_obj,streamsize);
+
+ if (emb->outtype==EMB_FMT_TTF) {
+ const int l1_obj=pdfOut_add_xref(pdf);
+ assert(l1_obj==ff_obj+2);
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "%d\n"
+ "endobj\n"
+ ,l1_obj,outlen);
+ }
+
+ const int fd_obj=pdfOut_add_xref(pdf);
+ char *res=emb_pdf_simple_fontdescr(emb,fdes,ff_obj);
+ if (!res) {
+ free(fdes);
+ return 0;
+ }
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "%s"
+ "endobj\n"
+ ,fd_obj,res);
+ free(res);
+
+ EMB_PDF_FONTWIDTHS *fwid=emb_pdf_fontwidths(emb);
+ if (!fwid) {
+ free(fdes);
+ return 0;
+ }
+ const int f_obj=pdfOut_add_xref(pdf);
+ res=emb_pdf_simple_font(emb,fdes,fwid,fd_obj);
+ if (!res) {
+ free(fwid);
+ free(fdes);
+ return 0;
+ }
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "%s"
+ "endobj\n"
+ ,f_obj,res);
+ free(res);
+ free(fwid);
+
+ if (emb->plan&EMB_A_MULTIBYTE) {
+ res=emb_pdf_simple_cidfont(emb,fdes->fontname,f_obj);
+ if (!res) {
+ free(fdes);
+ return 0;
+ }
+ const int cf_obj=pdfOut_add_xref(pdf);
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "%s"
+ "endobj\n"
+ ,cf_obj,res);
+ free(res);
+ free(fdes);
+ return cf_obj;
+ }
+
+ free(fdes);
+ return f_obj;
+}
+// }}}
+
+#if 0
+one_page(...parent,resources,mediabox,contents);
+{
+// " /Resources %d 0 R\n"
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "<</Type/Page\n"
+ " /Parent 1 0 R\n"
+ " /MediaBox [0 0 %d %d]\n"
+ " /Contents %d 0 R\n"
+ ">>\n"
+ "endobj\n"
+ ,,,PageWidth,PageLength // TODO: into pdf->
+ ...
+}
+
+... pfb_embedder ... pfa?
+#endif
diff --git a/filter/pdfutils.h b/filter/pdfutils.h
new file mode 100644
index 000000000..7c53477de
--- /dev/null
+++ b/filter/pdfutils.h
@@ -0,0 +1,80 @@
+/*
+ * PDF file output routines.
+ *
+ * Copyright 2008 by Tobias Hoffmann.
+ *
+ * This file is licensed as noted in "COPYING"
+ * which should have been included with this file.
+ *
+ */
+#include <time.h>
+
+struct keyval_t {
+ char *key,*value;
+};
+
+typedef struct {
+ long filepos;
+
+ int pagessize,pagesalloc;
+ int *pages;
+
+ int xrefsize,xrefalloc;
+ long *xref;
+
+ int kvsize,kvalloc;
+ struct keyval_t *kv;
+} pdfOut;
+
+/* allocates a new pdfOut structure
+ * returns NULL on error
+ */
+pdfOut *pdfOut_new();
+void pdfOut_free(pdfOut *pdf);
+
+/* start outputting a pdf
+ * returns false on error
+ */
+int pdfOut_begin_pdf(pdfOut *pdf);
+void pdfOut_finish_pdf(pdfOut *pdf);
+
+/* General output routine for our pdf.
+ * Keeps track of characters actually written out
+ */
+void pdfOut_printf(pdfOut *pdf,const char *fmt,...)
+ __attribute__((format(printf, 2, 3)));
+
+/* write out an escaped pdf string: e.g. (Text \(Test\)\n)
+ * >len==-1: use strlen(str)
+ */
+void pdfOut_putString(pdfOut *pdf,const char *str,int len);
+void pdfOut_putHexString(pdfOut *pdf,const char *str,int len);
+
+/* Format the broken up timestamp according to
+ * pdf requirements for /CreationDate
+ * NOTE: uses statically allocated buffer
+ */
+const char *pdfOut_to_pdfdate(struct tm *curtm);
+
+/* begin a new object at current point of the
+ * output stream and add it to the xref table.
+ * returns the obj number.
+ */
+int pdfOut_add_xref(pdfOut *pdf);
+
+/* adds page dictionary >obj to the global Pages tree
+ * returns false on error
+ */
+int pdfOut_add_page(pdfOut *pdf,int obj);
+
+/* add a >key,>val pair to the document's Info dictionary
+ * returns false on error
+ */
+int pdfOut_add_kv(pdfOut *pdf,const char *key,const char *val);
+
+/* Writes the font >emb including descriptor to the pdf
+ * and returns the object number.
+ * On error 0 is returned.
+ */
+struct _EMB_PARAMS;
+int pdfOut_write_font(pdfOut *pdf,struct _EMB_PARAMS *emb);
diff --git a/filter/rastertoescpx.c b/filter/rastertoescpx.c
new file mode 100644
index 000000000..5a3e5df68
--- /dev/null
+++ b/filter/rastertoescpx.c
@@ -0,0 +1,1912 @@
+/*
+ * Advanced EPSON ESC/P raster driver for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * Setup() - Prepare the printer for graphics output.
+ * StartPage() - Start a page of graphics.
+ * EndPage() - Finish a page of graphics.
+ * Shutdown() - Shutdown a printer.
+ * CancelJob() - Cancel the current job...
+ * CompressData() - Compress a line of graphics.
+ * OutputBand() - Output a band of graphics.
+ * ProcessLine() - Read graphics from the page stream and output
+ * as needed.
+ * main() - Main entry and processing of driver.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <cupsfilters/driver.h>
+#include "escp.h"
+#include <signal.h>
+#include <string.h>
+#include <ctype.h>
+
+
+/*
+ * Softweave data...
+ */
+
+typedef struct cups_weave_str
+{
+ struct cups_weave_str *prev, /* Previous band */
+ *next; /* Next band */
+ int x, y, /* Column/Line on the page */
+ plane, /* Color plane */
+ dirty, /* Is this buffer dirty? */
+ row, /* Row in the buffer */
+ count; /* Max rows this pass */
+ unsigned char *buffer; /* Data buffer */
+} cups_weave_t;
+
+
+/*
+ * Globals...
+ */
+
+cups_rgb_t *RGB; /* RGB color separation data */
+cups_cmyk_t *CMYK; /* CMYK color separation data */
+unsigned char *PixelBuffer, /* Pixel buffer */
+ *CMYKBuffer, /* CMYK buffer */
+ *OutputBuffers[7], /* Output buffers */
+ *DotBuffers[7], /* Dot buffers */
+ *CompBuffer; /* Compression buffer */
+short *InputBuffer; /* Color separation buffer */
+cups_weave_t *DotAvailList, /* Available buffers */
+ *DotUsedList, /* Used buffers */
+ *DotBands[128][7]; /* Buffers in use */
+int DotBufferSize, /* Size of dot buffers */
+ DotRowMax, /* Maximum row number in buffer */
+ DotColStep, /* Step for each output column */
+ DotRowStep, /* Step for each output line */
+ DotRowFeed, /* Amount to feed for interleave */
+ DotRowCount, /* Number of rows to output */
+ DotRowOffset[7], /* Offset for each color on print head */
+ DotRowCurrent, /* Current row */
+ DotSize; /* Dot size (Pro 5000 only) */
+int PrinterPlanes, /* # of color planes */
+ BitPlanes, /* # of bit planes per color */
+ PrinterTop, /* Top of page */
+ PrinterLength; /* Length of page */
+cups_lut_t *DitherLuts[7]; /* Lookup tables for dithering */
+cups_dither_t *DitherStates[7]; /* Dither state tables */
+int OutputFeed; /* Number of lines to skip */
+int Canceled; /* Is the job canceled? */
+
+
+/*
+ * Prototypes...
+ */
+
+void Setup(ppd_file_t *);
+void StartPage(ppd_file_t *, cups_page_header2_t *);
+void EndPage(ppd_file_t *, cups_page_header2_t *);
+void Shutdown(ppd_file_t *);
+
+void AddBand(cups_weave_t *band);
+void CancelJob(int sig);
+void CompressData(ppd_file_t *, const unsigned char *, const int,
+ int, int, const int, const int, const int,
+ const int);
+void OutputBand(ppd_file_t *, cups_page_header2_t *,
+ cups_weave_t *band);
+void ProcessLine(ppd_file_t *, cups_raster_t *,
+ cups_page_header2_t *, const int y);
+
+
+/*
+ * 'Setup()' - Prepare a printer for graphics output.
+ */
+
+void
+Setup(ppd_file_t *ppd) /* I - PPD file */
+{
+ /*
+ * Some EPSON printers need an additional command issued at the
+ * beginning of each job to exit from USB "packet" mode...
+ */
+
+ if (ppd->model_number & ESCP_USB)
+ cupsWritePrintData("\000\000\000\033\001@EJL 1284.4\n@EJL \n\033@", 29);
+}
+
+
+/*
+ * 'StartPage()' - Start a page of graphics.
+ */
+
+void
+StartPage(ppd_file_t *ppd, /* I - PPD file */
+ cups_page_header2_t *header) /* I - Page header */
+{
+ int i, y; /* Looping vars */
+ int subrow, /* Current subrow */
+ modrow, /* Subrow modulus */
+ plane; /* Current color plane */
+ unsigned char *ptr; /* Pointer into dot buffer */
+ int bands; /* Number of bands to allocate */
+ int units; /* Units for resolution */
+ cups_weave_t *band; /* Current band */
+ const char *colormodel; /* Color model string */
+ char resolution[PPD_MAX_NAME],
+ /* Resolution string */
+ spec[PPD_MAX_NAME]; /* PPD attribute name */
+ ppd_attr_t *attr; /* Attribute from PPD file */
+ const float default_lut[2] = /* Default dithering lookup table */
+ {
+ 0.0,
+ 1.0
+ };
+
+
+ fprintf(stderr, "DEBUG: StartPage...\n");
+ fprintf(stderr, "DEBUG: MediaClass = \"%s\"\n", header->MediaClass);
+ fprintf(stderr, "DEBUG: MediaColor = \"%s\"\n", header->MediaColor);
+ fprintf(stderr, "DEBUG: MediaType = \"%s\"\n", header->MediaType);
+ fprintf(stderr, "DEBUG: OutputType = \"%s\"\n", header->OutputType);
+
+ fprintf(stderr, "DEBUG: AdvanceDistance = %d\n", header->AdvanceDistance);
+ fprintf(stderr, "DEBUG: AdvanceMedia = %d\n", header->AdvanceMedia);
+ fprintf(stderr, "DEBUG: Collate = %d\n", header->Collate);
+ fprintf(stderr, "DEBUG: CutMedia = %d\n", header->CutMedia);
+ fprintf(stderr, "DEBUG: Duplex = %d\n", header->Duplex);
+ fprintf(stderr, "DEBUG: HWResolution = [ %d %d ]\n", header->HWResolution[0],
+ header->HWResolution[1]);
+ fprintf(stderr, "DEBUG: ImagingBoundingBox = [ %d %d %d %d ]\n",
+ header->ImagingBoundingBox[0], header->ImagingBoundingBox[1],
+ header->ImagingBoundingBox[2], header->ImagingBoundingBox[3]);
+ fprintf(stderr, "DEBUG: InsertSheet = %d\n", header->InsertSheet);
+ fprintf(stderr, "DEBUG: Jog = %d\n", header->Jog);
+ fprintf(stderr, "DEBUG: LeadingEdge = %d\n", header->LeadingEdge);
+ fprintf(stderr, "DEBUG: Margins = [ %d %d ]\n", header->Margins[0],
+ header->Margins[1]);
+ fprintf(stderr, "DEBUG: ManualFeed = %d\n", header->ManualFeed);
+ fprintf(stderr, "DEBUG: MediaPosition = %d\n", header->MediaPosition);
+ fprintf(stderr, "DEBUG: MediaWeight = %d\n", header->MediaWeight);
+ fprintf(stderr, "DEBUG: MirrorPrint = %d\n", header->MirrorPrint);
+ fprintf(stderr, "DEBUG: NegativePrint = %d\n", header->NegativePrint);
+ fprintf(stderr, "DEBUG: NumCopies = %d\n", header->NumCopies);
+ fprintf(stderr, "DEBUG: Orientation = %d\n", header->Orientation);
+ fprintf(stderr, "DEBUG: OutputFaceUp = %d\n", header->OutputFaceUp);
+ fprintf(stderr, "DEBUG: PageSize = [ %d %d ]\n", header->PageSize[0],
+ header->PageSize[1]);
+ fprintf(stderr, "DEBUG: Separations = %d\n", header->Separations);
+ fprintf(stderr, "DEBUG: TraySwitch = %d\n", header->TraySwitch);
+ fprintf(stderr, "DEBUG: Tumble = %d\n", header->Tumble);
+ fprintf(stderr, "DEBUG: cupsWidth = %d\n", header->cupsWidth);
+ fprintf(stderr, "DEBUG: cupsHeight = %d\n", header->cupsHeight);
+ fprintf(stderr, "DEBUG: cupsMediaType = %d\n", header->cupsMediaType);
+ fprintf(stderr, "DEBUG: cupsBitsPerColor = %d\n", header->cupsBitsPerColor);
+ fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d\n", header->cupsBitsPerPixel);
+ fprintf(stderr, "DEBUG: cupsBytesPerLine = %d\n", header->cupsBytesPerLine);
+ fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", header->cupsColorOrder);
+ fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", header->cupsColorSpace);
+ fprintf(stderr, "DEBUG: cupsCompression = %d\n", header->cupsCompression);
+ fprintf(stderr, "DEBUG: cupsRowCount = %d\n", header->cupsRowCount);
+ fprintf(stderr, "DEBUG: cupsRowFeed = %d\n", header->cupsRowFeed);
+ fprintf(stderr, "DEBUG: cupsRowStep = %d\n", header->cupsRowStep);
+
+ /*
+ * Figure out the color model and spec strings...
+ */
+
+ switch (header->cupsColorSpace)
+ {
+ case CUPS_CSPACE_K :
+ colormodel = "Black";
+ break;
+ case CUPS_CSPACE_W :
+ colormodel = "Gray";
+ break;
+ default :
+ case CUPS_CSPACE_RGB :
+ colormodel = "RGB";
+ break;
+ case CUPS_CSPACE_CMYK :
+ colormodel = "CMYK";
+ break;
+ }
+
+ if (header->HWResolution[0] != header->HWResolution[1])
+ snprintf(resolution, sizeof(resolution), "%dx%ddpi",
+ header->HWResolution[0], header->HWResolution[1]);
+ else
+ snprintf(resolution, sizeof(resolution), "%ddpi",
+ header->HWResolution[0]);
+
+ if (!header->MediaType[0])
+ strcpy(header->MediaType, "Plain");
+
+ /*
+ * Load the appropriate color profiles...
+ */
+
+ RGB = NULL;
+ CMYK = NULL;
+
+ fputs("DEBUG: Attempting to load color profiles using the following values:\n", stderr);
+ fprintf(stderr, "DEBUG: ColorModel = %s\n", colormodel);
+ fprintf(stderr, "DEBUG: MediaType = %s\n", header->MediaType);
+ fprintf(stderr, "DEBUG: Resolution = %s\n", resolution);
+
+ if (header->cupsColorSpace == CUPS_CSPACE_RGB ||
+ header->cupsColorSpace == CUPS_CSPACE_W)
+ RGB = cupsRGBLoad(ppd, colormodel, header->MediaType, resolution);
+ else
+ RGB = NULL;
+
+ CMYK = cupsCMYKLoad(ppd, colormodel, header->MediaType, resolution);
+
+ if (RGB)
+ fputs("DEBUG: Loaded RGB separation from PPD.\n", stderr);
+
+ if (CMYK)
+ fputs("DEBUG: Loaded CMYK separation from PPD.\n", stderr);
+ else
+ {
+ fputs("DEBUG: Loading default CMYK separation.\n", stderr);
+ CMYK = cupsCMYKNew(4);
+ }
+
+ PrinterPlanes = CMYK->num_channels;
+
+ fprintf(stderr, "DEBUG: PrinterPlanes = %d\n", PrinterPlanes);
+
+ /*
+ * Get the dithering parameters...
+ */
+
+ switch (PrinterPlanes)
+ {
+ case 1 : /* K */
+ DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Black");
+ break;
+
+ case 2 : /* Kk */
+ DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Black");
+ DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "LightBlack");
+ break;
+
+ case 3 : /* CMY */
+ DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Cyan");
+ DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Magenta");
+ DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Yellow");
+ break;
+
+ case 4 : /* CMYK */
+ DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Cyan");
+ DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Magenta");
+ DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Yellow");
+ DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Black");
+ break;
+
+ case 6 : /* CcMmYK */
+ DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Cyan");
+ DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "LightCyan");
+ DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Magenta");
+ DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "LightMagenta");
+ DitherLuts[4] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Yellow");
+ DitherLuts[5] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Black");
+ break;
+
+ case 7 : /* CcMmYKk */
+ DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Cyan");
+ DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "LightCyan");
+ DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Magenta");
+ DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "LightMagenta");
+ DitherLuts[4] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Yellow");
+ DitherLuts[5] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Black");
+ DitherLuts[6] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "LightBlack");
+ break;
+ }
+
+ for (plane = 0; plane < PrinterPlanes; plane ++)
+ {
+ DitherStates[plane] = cupsDitherNew(header->cupsWidth);
+
+ if (!DitherLuts[plane])
+ DitherLuts[plane] = cupsLutNew(2, default_lut);
+ }
+
+ if (DitherLuts[0][4095].pixel > 1)
+ BitPlanes = 2;
+ else
+ BitPlanes = 1;
+
+ /*
+ * Initialize the printer...
+ */
+
+ printf("\033@");
+
+ if (ppd->model_number & ESCP_REMOTE)
+ {
+ /*
+ * Go into remote mode...
+ */
+
+ cupsWritePrintData("\033(R\010\000\000REMOTE1", 13);
+
+ /*
+ * Disable status reporting...
+ */
+
+ cupsWritePrintData("ST\002\000\000\000", 6);
+
+ /*
+ * Enable borderless printing...
+ */
+
+ if ((attr = ppdFindAttr(ppd, "cupsESCPFP", NULL)) != NULL && attr->value)
+ {
+ /*
+ * Set horizontal offset...
+ */
+
+ i = atoi(attr->value);
+
+ cupsWritePrintData("FP\003\000\000", 5);
+ putchar(i & 255);
+ putchar(i >> 8);
+ }
+
+ /*
+ * Set media type...
+ */
+
+ if (header->cupsMediaType)
+ {
+ sprintf(spec, "%d", header->cupsMediaType);
+
+ if ((attr = ppdFindAttr(ppd, "cupsESCPSN0", spec)) != NULL && attr->value)
+ {
+ /*
+ * Set feed sequence...
+ */
+
+ cupsWritePrintData("SN\003\000\000\000", 6);
+ putchar(atoi(attr->value));
+ }
+
+ if ((attr = ppdFindAttr(ppd, "cupsESCPSN1", spec)) != NULL && attr->value)
+ {
+ /*
+ * Set platten gap...
+ */
+
+ cupsWritePrintData("SN\003\000\000\001", 6);
+ putchar(atoi(attr->value));
+ }
+
+ if ((attr = ppdFindAttr(ppd, "cupsESCPSN2", spec)) != NULL && attr->value)
+ {
+ /*
+ * Paper feeding/ejecting sequence...
+ */
+
+ cupsWritePrintData("SN\003\000\000\002", 6);
+ putchar(atoi(attr->value));
+ }
+
+ if ((attr = ppdFindAttr(ppd, "cupsESCPSN6", spec)) != NULL && attr->value)
+ {
+ /*
+ * Eject delay...
+ */
+
+ cupsWritePrintData("SN\003\000\000\006", 6);
+ putchar(atoi(attr->value));
+ }
+
+ if ((attr = ppdFindAttr(ppd, "cupsESCPMT", spec)) != NULL && attr->value)
+ {
+ /*
+ * Set media type.
+ */
+
+ cupsWritePrintData("MT\003\000\000\000", 6);
+ putchar(atoi(attr->value));
+ }
+
+ if ((attr = ppdFindAttr(ppd, "cupsESCPPH", spec)) != NULL && attr->value)
+ {
+ /*
+ * Set paper thickness.
+ */
+
+ cupsWritePrintData("PH\002\000\000", 5);
+ putchar(atoi(attr->value));
+ }
+ }
+
+ sprintf(spec, "%d", header->MediaPosition);
+
+ if (header->MediaPosition)
+ {
+ if ((attr = ppdFindAttr(ppd, "cupsESCPPC", spec)) != NULL && attr->value)
+ {
+ /*
+ * Paper check.
+ */
+
+ cupsWritePrintData("PC\002\000\000", 5);
+ putchar(atoi(attr->value));
+ }
+
+ if ((attr = ppdFindAttr(ppd, "cupsESCPPP", spec)) != NULL && attr->value)
+ {
+ /*
+ * Paper path.
+ */
+
+ int a, b;
+
+ a = b = 0;
+ sscanf(attr->value, "%d%d", &a, &b);
+
+ cupsWritePrintData("PP\003\000\000", 5);
+ putchar(a);
+ putchar(b);
+ }
+
+ if ((attr = ppdFindAttr(ppd, "cupsESCPEX", spec)) != NULL && attr->value)
+ {
+ /*
+ * Set media position.
+ */
+
+ cupsWritePrintData("EX\006\000\000\000\000\000\005", 9);
+ putchar(atoi(attr->value));
+ }
+ }
+
+ if ((attr = ppdFindAttr(ppd, "cupsESCPMS", spec)) != NULL && attr->value)
+ {
+ /*
+ * Set media size...
+ */
+
+ cupsWritePrintData("MS\010\000\000", 5);
+ putchar(atoi(attr->value));
+
+ switch (header->PageSize[1])
+ {
+ case 1191 : /* A3 */
+ putchar(0x01);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ break;
+ case 1032 : /* B4 */
+ putchar(0x02);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ break;
+ case 842 : /* A4 */
+ putchar(0x03);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ break;
+ case 595 : /* A4.Transverse */
+ putchar(0x03);
+ putchar(0x01);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ break;
+ case 729 : /* B5 */
+ putchar(0x04);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ break;
+ case 516 : /* B5.Transverse */
+ putchar(0x04);
+ putchar(0x01);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ break;
+ case 1369 : /* Super A3/B */
+ putchar(0x20);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ break;
+ case 792 : /* Letter */
+ putchar(0x08);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ break;
+ case 612 : /* Letter.Transverse */
+ putchar(0x08);
+ putchar(0x01);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ break;
+ case 1004 : /* Legal */
+ putchar(0x0a);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ break;
+ case 1224 : /* Tabloid */
+ putchar(0x2d);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ putchar(0x00);
+ break;
+ default : /* Custom size */
+ putchar(0xff);
+ putchar(0xff);
+ i = 360 * header->PageSize[0] / 72;
+ putchar(i);
+ putchar(i >> 8);
+ i = 360 * header->PageSize[1] / 72;
+ putchar(i);
+ putchar(i >> 8);
+ break;
+ }
+ }
+
+ sprintf(spec, "%d", header->CutMedia);
+
+ if ((attr = ppdFindAttr(ppd, "cupsESCPAC", spec)) != NULL && attr->value)
+ {
+ /*
+ * Enable/disable cutter.
+ */
+
+ cupsWritePrintData("AC\002\000\000", 5);
+ putchar(atoi(attr->value));
+
+ if ((attr = ppdFindAttr(ppd, "cupsESCPSN80", header->MediaType)) != NULL && attr->value)
+ {
+ /*
+ * Cutting method...
+ */
+
+ cupsWritePrintData("SN\003\000\000\200", 6);
+ putchar(atoi(attr->value));
+ }
+
+ if ((attr = ppdFindAttr(ppd, "cupsESCPSN81", header->MediaType)) != NULL && attr->value)
+ {
+ /*
+ * Cutting pressure...
+ */
+
+ cupsWritePrintData("SN\003\000\000\201", 6);
+ putchar(atoi(attr->value));
+ }
+ }
+
+ if ((attr = ppdFindAttr(ppd, "cupsESCPCO", spec)) != NULL && attr->value)
+ {
+ /*
+ * Enable/disable cutter.
+ */
+
+ cupsWritePrintData("CO\010\000\000\000", 6);
+ putchar(atoi(attr->value));
+ cupsWritePrintData("\000\000\000\000\000", 5);
+ }
+
+ /*
+ * Exit remote mode...
+ */
+
+ cupsWritePrintData("\033\000\000\000", 4);
+ }
+
+ /*
+ * Enter graphics mode...
+ */
+
+ cupsWritePrintData("\033(G\001\000\001", 6);
+
+ /*
+ * Set the line feed increment...
+ */
+
+ /* TODO: get this from the PPD file... */
+ for (units = 1440; units < header->HWResolution[0]; units *= 2);
+
+ if (ppd->model_number & ESCP_EXT_UNITS)
+ {
+ cupsWritePrintData("\033(U\005\000", 5);
+ putchar(units / header->HWResolution[1]);
+ putchar(units / header->HWResolution[1]);
+ putchar(units / header->HWResolution[0]);
+ putchar(units);
+ putchar(units >> 8);
+ }
+ else
+ {
+ cupsWritePrintData("\033(U\001\000", 5);
+ putchar(3600 / header->HWResolution[1]);
+ }
+
+ /*
+ * Set the page length...
+ */
+
+ PrinterLength = header->PageSize[1] * header->HWResolution[1] / 72;
+
+ if (ppd->model_number & ESCP_PAGE_SIZE)
+ {
+ /*
+ * Set page size (expands bottom margin)...
+ */
+
+ cupsWritePrintData("\033(S\010\000", 5);
+
+ i = header->PageSize[0] * header->HWResolution[1] / 72;
+ putchar(i);
+ putchar(i >> 8);
+ putchar(i >> 16);
+ putchar(i >> 24);
+
+ i = header->PageSize[1] * header->HWResolution[1] / 72;
+ putchar(i);
+ putchar(i >> 8);
+ putchar(i >> 16);
+ putchar(i >> 24);
+ }
+ else
+ {
+ cupsWritePrintData("\033(C\002\000", 5);
+ putchar(PrinterLength & 255);
+ putchar(PrinterLength >> 8);
+ }
+
+ /*
+ * Set the top and bottom margins...
+ */
+
+ PrinterTop = (int)((ppd->sizes[1].length - ppd->sizes[1].top) *
+ header->HWResolution[1] / 72.0);
+
+ if (ppd->model_number & ESCP_EXT_MARGINS)
+ {
+ cupsWritePrintData("\033(c\010\000", 5);
+
+ putchar(PrinterTop);
+ putchar(PrinterTop >> 8);
+ putchar(PrinterTop >> 16);
+ putchar(PrinterTop >> 24);
+
+ putchar(PrinterLength);
+ putchar(PrinterLength >> 8);
+ putchar(PrinterLength >> 16);
+ putchar(PrinterLength >> 24);
+ }
+ else
+ {
+ cupsWritePrintData("\033(c\004\000", 5);
+
+ putchar(PrinterTop & 255);
+ putchar(PrinterTop >> 8);
+
+ putchar(PrinterLength & 255);
+ putchar(PrinterLength >> 8);
+ }
+
+ /*
+ * Set the top position...
+ */
+
+ cupsWritePrintData("\033(V\002\000\000\000", 7);
+
+ /*
+ * Enable unidirectional printing depending on the mode...
+ */
+
+ if ((attr = cupsFindAttr(ppd, "cupsESCPDirection", colormodel,
+ header->MediaType, resolution, spec,
+ sizeof(spec))) != NULL)
+ printf("\033U%c", atoi(attr->value));
+
+ /*
+ * Enable/disable microweaving as needed...
+ */
+
+ if ((attr = cupsFindAttr(ppd, "cupsESCPMicroWeave", colormodel,
+ header->MediaType, resolution, spec,
+ sizeof(spec))) != NULL)
+ printf("\033(i\001%c%c", 0, atoi(attr->value));
+
+ /*
+ * Set the dot size and print speed as needed...
+ */
+
+ if ((attr = cupsFindAttr(ppd, "cupsESCPDotSize", colormodel,
+ header->MediaType, resolution, spec,
+ sizeof(spec))) != NULL)
+ printf("\033(e\002%c%c%c", 0, 0, atoi(attr->value));
+
+ if (ppd->model_number & ESCP_ESCK)
+ {
+ /*
+ * Set the print mode...
+ */
+
+ if (PrinterPlanes == 1)
+ {
+ /*
+ * Fast black printing.
+ */
+
+ cupsWritePrintData("\033(K\002\000\000\001", 7);
+ }
+ else
+ {
+ /*
+ * Color printing.
+ */
+
+ cupsWritePrintData("\033(K\002\000\000\002", 7);
+ }
+ }
+
+ /*
+ * Get softweave settings from header...
+ */
+
+ if (header->cupsRowCount <= 1)
+ {
+ DotRowCount = 1;
+ DotColStep = 1;
+ DotRowStep = 1;
+ DotRowFeed = 1;
+ }
+ else
+ {
+ DotRowCount = header->cupsRowCount;
+ DotRowFeed = header->cupsRowFeed;
+ DotRowStep = header->cupsRowStep % 100;
+ DotColStep = header->cupsRowStep / 100;
+
+ if (DotColStep == 0)
+ DotColStep ++;
+ }
+
+ /*
+ * Setup softweave parameters...
+ */
+
+ DotRowCurrent = 0;
+ DotRowMax = DotRowCount * DotRowStep;
+ DotBufferSize = (header->cupsWidth / DotColStep * BitPlanes + 7) / 8;
+
+ fprintf(stderr, "DEBUG: DotBufferSize = %d\n", DotBufferSize);
+ fprintf(stderr, "DEBUG: DotColStep = %d\n", DotColStep);
+ fprintf(stderr, "DEBUG: DotRowMax = %d\n", DotRowMax);
+ fprintf(stderr, "DEBUG: DotRowStep = %d\n", DotRowStep);
+ fprintf(stderr, "DEBUG: DotRowFeed = %d\n", DotRowFeed);
+ fprintf(stderr, "DEBUG: DotRowCount = %d\n", DotRowCount);
+
+ DotAvailList = NULL;
+ DotUsedList = NULL;
+ DotBuffers[0] = NULL;
+
+ fprintf(stderr, "DEBUG: model_number = %x\n", ppd->model_number);
+
+ if (DotRowMax > 1)
+ {
+ /*
+ * Compute offsets for the color jets on the print head...
+ */
+
+ bands = DotRowStep * DotColStep * PrinterPlanes * 4;
+
+ memset(DotRowOffset, 0, sizeof(DotRowOffset));
+
+ if (PrinterPlanes == 1)
+ {
+ /*
+ * Use full height of print head...
+ */
+
+ if ((attr = ppdFindAttr(ppd, "cupsESCPBlack", resolution)) != NULL &&
+ attr->value)
+ {
+ /*
+ * Use custom black head data...
+ */
+
+ sscanf(attr->value, "%d%d", &DotRowCount, &DotRowStep);
+ }
+ }
+ else if (ppd->model_number & ESCP_STAGGER)
+ {
+ /*
+ * Use staggered print head...
+ */
+
+ fputs("DEBUG: Offset head detected...\n", stderr);
+
+ if ((attr = ppdFindAttr(ppd, "cupsESCPOffsets", resolution)) != NULL &&
+ attr->value)
+ {
+ /*
+ * Use only 1/3 of the print head when printing color...
+ */
+
+ sscanf(attr->value, "%d%d%d%d", DotRowOffset + 0,
+ DotRowOffset + 1, DotRowOffset + 2, DotRowOffset + 3);
+ }
+ }
+
+ for (i = 0; i < PrinterPlanes; i ++)
+ fprintf(stderr, "DEBUG: DotRowOffset[%d] = %d\n", i, DotRowOffset[i]);
+
+ /*
+ * Allocate bands...
+ */
+
+ for (i = 0; i < bands; i ++)
+ {
+ band = (cups_weave_t *)calloc(1, sizeof(cups_weave_t));
+ band->next = DotAvailList;
+ DotAvailList = band;
+
+ band->buffer = calloc(DotRowCount, DotBufferSize);
+ }
+
+ if (!DotAvailList)
+ {
+ fputs("ERROR: Unable to allocate band list\n", stderr);
+ exit(1);
+ }
+
+ fputs("DEBUG: Pointer list at start of page...\n", stderr);
+
+ for (band = DotAvailList; band != NULL; band = band->next)
+ fprintf(stderr, "DEBUG: %p\n", (void*)band);
+
+ fputs("DEBUG: ----END----\n", stderr);
+
+ /*
+ * Fill the initial bands...
+ */
+
+ modrow = DotColStep * DotRowStep;
+
+ if (DotRowFeed == 0)
+ {
+ /*
+ * Automatically compute the optimal feed value...
+ */
+
+ DotRowFeed = DotRowCount / DotColStep - DotRowStep;
+
+ while ((((DotRowFeed % 2) == 0) == ((DotRowCount % 2) == 0) ||
+ ((DotRowFeed % 3) == 0) == ((DotRowCount % 3) == 0) ||
+ ((DotRowFeed % 5) == 0) == ((DotRowCount % 5) == 0)) &&
+ DotRowFeed > 1)
+ DotRowFeed --;
+
+ if (DotRowFeed < 1)
+ DotRowFeed = 1;
+
+ fprintf(stderr, "DEBUG: Auto DotRowFeed = %d, modrow=%d...\n",
+ DotRowFeed, modrow);
+ }
+
+ memset(DotBands, 0, sizeof(DotBands));
+
+ for (i = modrow, subrow = modrow - 1, y = DotRowFeed;
+ i > 0;
+ i --, y += DotRowFeed)
+ {
+ while (DotBands[subrow][0])
+ {
+ /*
+ * This subrow is already used, move to another one...
+ */
+
+ subrow = (subrow + 1) % modrow;
+ }
+
+ for (plane = 0; plane < PrinterPlanes; plane ++)
+ {
+ /*
+ * Pull the next available band from the list...
+ */
+
+ band = DotAvailList;
+ DotAvailList = DotAvailList->next;
+ DotBands[subrow][plane] = band;
+
+ /*
+ * Start the band in the first few passes, with the number of rows
+ * varying to allow for a nice interleaved pattern...
+ */
+
+ band->x = subrow / DotRowStep;
+ band->y = (subrow % DotRowStep) + DotRowOffset[plane];
+ band->plane = plane;
+ band->row = 0;
+ band->count = DotRowCount - y / DotRowStep;
+
+ if (band->count < 1)
+ band->count = 1;
+ else if (band->count > DotRowCount)
+ band->count = DotRowCount;
+
+ fprintf(stderr, "DEBUG: DotBands[%d][%d] = %p, x = %d, y = %d, plane = %d, count = %d\n",
+ subrow, plane, (void*)band, band->x, band->y, band->plane, band->count);
+ }
+
+ subrow = (subrow + DotRowFeed) % modrow;
+ }
+ }
+ else
+ {
+ /*
+ * Allocate memory for a single line of graphics...
+ */
+
+ ptr = calloc(PrinterPlanes, DotBufferSize);
+
+ for (plane = 0; plane < PrinterPlanes; plane ++, ptr += DotBufferSize)
+ DotBuffers[plane] = ptr;
+ }
+
+ /*
+ * Set the output resolution...
+ */
+
+ cupsWritePrintData("\033(D\004\000", 5);
+ putchar(units);
+ putchar(units >> 8);
+ putchar(units * DotRowStep / header->HWResolution[1]);
+ putchar(units * DotColStep / header->HWResolution[0]);
+
+ /*
+ * Set the top of form...
+ */
+
+ OutputFeed = 0;
+
+ /*
+ * Allocate buffers as needed...
+ */
+
+ PixelBuffer = malloc(header->cupsBytesPerLine);
+ InputBuffer = malloc(header->cupsWidth * PrinterPlanes * 2);
+ OutputBuffers[0] = malloc(PrinterPlanes * header->cupsWidth);
+
+ for (i = 1; i < PrinterPlanes; i ++)
+ OutputBuffers[i] = OutputBuffers[0] + i * header->cupsWidth;
+
+ if (RGB)
+ CMYKBuffer = malloc(header->cupsWidth * PrinterPlanes);
+
+ CompBuffer = malloc(10 * DotBufferSize * DotRowMax);
+}
+
+
+/*
+ * 'EndPage()' - Finish a page of graphics.
+ */
+
+void
+EndPage(ppd_file_t *ppd, /* I - PPD file */
+ cups_page_header2_t *header) /* I - Page header */
+{
+ int i; /* Looping var */
+ cups_weave_t *band, /* Current band */
+ *next; /* Next band in list */
+ int plane; /* Current plane */
+ int subrow; /* Current subrow */
+ int subrows; /* Number of subrows */
+
+
+ /*
+ * Output the last bands of print data as necessary...
+ */
+
+ if (DotRowMax > 1)
+ {
+ /*
+ * Move the remaining bands to the used or avail lists...
+ */
+
+ subrows = DotRowStep * DotColStep;
+
+ for (subrow = 0; subrow < subrows; subrow ++)
+ for (plane = 0; plane < PrinterPlanes; plane ++)
+ {
+ if (DotBands[subrow][plane]->dirty)
+ {
+ /*
+ * Insert into the used list...
+ */
+
+ DotBands[subrow][plane]->count = DotBands[subrow][plane]->row;
+
+ AddBand(DotBands[subrow][plane]);
+ }
+ else
+ {
+ /*
+ * Nothing here, so move it to the available list...
+ */
+
+ DotBands[subrow][plane]->next = DotAvailList;
+ DotAvailList = DotBands[subrow][plane];
+ }
+
+ DotBands[subrow][plane] = NULL;
+ }
+
+ /*
+ * Loop until all bands are written...
+ */
+
+ fputs("DEBUG: Pointer list at end of page...\n", stderr);
+
+ for (band = DotUsedList; band != NULL; band = band->next)
+ fprintf(stderr, "DEBUG: %p (used)\n", (void*)band);
+ for (band = DotAvailList; band != NULL; band = band->next)
+ fprintf(stderr, "DEBUG: %p (avail)\n", (void*)band);
+
+ fputs("DEBUG: ----END----\n", stderr);
+
+ for (band = DotUsedList; band != NULL; band = next)
+ {
+ next = band->next;
+
+ OutputBand(ppd, header, band);
+
+ fprintf(stderr, "DEBUG: freeing used band %p, prev = %p, next = %p\n",
+ (void*)band, (void*)band->prev, (void*)band->next);
+
+ free(band->buffer);
+ free(band);
+ }
+
+ /*
+ * Free memory for the available bands, if any...
+ */
+
+ for (band = DotAvailList; band != NULL; band = next)
+ {
+ next = band->next;
+
+ fprintf(stderr, "DEBUG: freeing avail band %p, prev = %p, next = %p\n",
+ (void*)band, (void*)band->prev, (void*)band->next);
+
+ free(band->buffer);
+ free(band);
+ }
+ }
+ else
+ free(DotBuffers[0]);
+
+ /*
+ * Output a page eject sequence...
+ */
+
+ putchar(12);
+
+ /*
+ * Free memory for the page...
+ */
+
+ for (i = 0; i < PrinterPlanes; i ++)
+ {
+ cupsDitherDelete(DitherStates[i]);
+ cupsLutDelete(DitherLuts[i]);
+ }
+
+ free(OutputBuffers[0]);
+
+ free(PixelBuffer);
+ free(InputBuffer);
+ free(CompBuffer);
+
+ cupsCMYKDelete(CMYK);
+
+ if (RGB)
+ {
+ cupsRGBDelete(RGB);
+ free(CMYKBuffer);
+ }
+}
+
+
+/*
+ * 'Shutdown()' - Shutdown a printer.
+ */
+
+void
+Shutdown(ppd_file_t *ppd) /* I - PPD file */
+{
+ /*
+ * Reset the printer...
+ */
+
+ printf("\033@");
+
+ if (ppd->model_number & ESCP_REMOTE)
+ {
+ /*
+ * Go into remote mode...
+ */
+
+ cupsWritePrintData("\033(R\010\000\000REMOTE1", 13);
+
+ /*
+ * Load defaults...
+ */
+
+ cupsWritePrintData("LD\000\000", 4);
+
+ /*
+ * Exit remote mode...
+ */
+
+ cupsWritePrintData("\033\000\000\000", 4);
+ }
+}
+
+
+/*
+ * 'AddBand()' - Add a band of data to the used list.
+ */
+
+void
+AddBand(cups_weave_t *band) /* I - Band to add */
+{
+ cups_weave_t *current, /* Current band */
+ *prev; /* Previous band */
+
+
+ if (band->count < 1)
+ return;
+
+ for (current = DotUsedList, prev = NULL;
+ current != NULL;
+ prev = current, current = current->next)
+ if (band->y < current->y ||
+ (band->y == current->y && band->x < current->x) ||
+ (band->y == current->y && band->x == current->x &&
+ band->plane < current->plane))
+ break;
+
+ if (current != NULL)
+ {
+ /*
+ * Insert the band...
+ */
+
+ band->next = current;
+ band->prev = prev;
+ current->prev = band;
+
+ if (prev != NULL)
+ prev->next = band;
+ else
+ DotUsedList = band;
+ }
+ else if (prev != NULL)
+ {
+ /*
+ * Append the band to the end...
+ */
+
+ band->prev = prev;
+ prev->next = band;
+ band->next = NULL;
+ }
+ else
+ {
+ /*
+ * First band in list...
+ */
+
+ DotUsedList = band;
+ band->prev = NULL;
+ band->next = NULL;
+ }
+}
+
+
+/*
+ * 'CancelJob()' - Cancel the current job...
+ */
+
+void
+CancelJob(int sig) /* I - Signal */
+{
+ (void)sig;
+
+ Canceled = 1;
+}
+
+
+/*
+ * 'CompressData()' - Compress a line of graphics.
+ */
+
+void
+CompressData(ppd_file_t *ppd, /* I - PPD file information */
+ const unsigned char *line, /* I - Data to compress */
+ const int length,/* I - Number of bytes */
+ int plane, /* I - Color plane */
+ int type, /* I - Type of compression */
+ const int rows, /* I - Number of lines to write */
+ const int xstep, /* I - Spacing between columns */
+ const int ystep, /* I - Spacing between lines */
+ const int offset)/* I - Head offset */
+{
+ register const unsigned char *line_ptr,
+ /* Current byte pointer */
+ *line_end, /* End-of-line byte pointer */
+ *start; /* Start of compression sequence */
+ register unsigned char *comp_ptr; /* Pointer into compression buffer */
+ register int count; /* Count of bytes for output */
+ register int bytes; /* Number of bytes per row */
+ static int ctable[7][7] = /* Colors */
+ {
+ { 0, 0, 0, 0, 0, 0, 0 }, /* K */
+ { 0, 16, 0, 0, 0, 0, 0 }, /* Kk */
+ { 2, 1, 4, 0, 0, 0, 0 }, /* CMY */
+ { 2, 1, 4, 0, 0, 0, 0 }, /* CMYK */
+ { 0, 0, 0, 0, 0, 0, 0 },
+ { 2, 18, 1, 17, 4, 0, 0 }, /* CcMmYK */
+ { 2, 18, 1, 17, 4, 0, 16 }, /* CcMmYKk */
+ };
+
+
+ switch (type)
+ {
+ case 0 :
+ /*
+ * Do no compression...
+ */
+
+ line_ptr = (const unsigned char *)line;
+ line_end = (const unsigned char *)line + length;
+ break;
+
+ default :
+ /*
+ * Do TIFF pack-bits encoding...
+ */
+
+ line_ptr = (const unsigned char *)line;
+ line_end = (const unsigned char *)line + length;
+ comp_ptr = CompBuffer;
+
+ while (line_ptr < line_end && (comp_ptr - CompBuffer) < length)
+ {
+ if ((line_ptr + 1) >= line_end)
+ {
+ /*
+ * Single byte on the end...
+ */
+
+ *comp_ptr++ = 0x00;
+ *comp_ptr++ = *line_ptr++;
+ }
+ else if (line_ptr[0] == line_ptr[1])
+ {
+ /*
+ * Repeated sequence...
+ */
+
+ line_ptr ++;
+ count = 2;
+
+ while (line_ptr < (line_end - 1) &&
+ line_ptr[0] == line_ptr[1] &&
+ count < 127)
+ {
+ line_ptr ++;
+ count ++;
+ }
+
+ *comp_ptr++ = 257 - count;
+ *comp_ptr++ = *line_ptr++;
+ }
+ else
+ {
+ /*
+ * Non-repeated sequence...
+ */
+
+ start = line_ptr;
+ line_ptr ++;
+ count = 1;
+
+ while (line_ptr < (line_end - 1) &&
+ line_ptr[0] != line_ptr[1] &&
+ count < 127)
+ {
+ line_ptr ++;
+ count ++;
+ }
+
+ *comp_ptr++ = count - 1;
+
+ memcpy(comp_ptr, start, count);
+ comp_ptr += count;
+ }
+ }
+
+ if ((comp_ptr - CompBuffer) < length)
+ {
+ line_ptr = (const unsigned char *)CompBuffer;
+ line_end = (const unsigned char *)comp_ptr;
+ }
+ else
+ {
+ type = 0;
+ line_ptr = (const unsigned char *)line;
+ line_end = (const unsigned char *)line + length;
+ }
+ break;
+ }
+
+ /*
+ * Position the print head...
+ */
+
+ putchar(0x0d);
+
+ if (offset)
+ {
+ if (BitPlanes == 1)
+ cupsWritePrintData("\033(\\\004\000\240\005", 7);
+ else
+ printf("\033\\");
+
+ putchar(offset);
+ putchar(offset >> 8);
+ }
+
+ /*
+ * Send the graphics...
+ */
+
+ bytes = length / rows;
+
+ if (ppd->model_number & ESCP_RASTER_ESCI)
+ {
+ /*
+ * Send graphics with ESC i command.
+ */
+
+ printf("\033i");
+ putchar(ctable[PrinterPlanes - 1][plane]);
+ putchar(type != 0);
+ putchar(BitPlanes);
+ putchar(bytes & 255);
+ putchar(bytes >> 8);
+ putchar(rows & 255);
+ putchar(rows >> 8);
+ }
+ else
+ {
+ /*
+ * Set the color if necessary...
+ */
+
+ if (PrinterPlanes > 1)
+ {
+ plane = ctable[PrinterPlanes - 1][plane];
+
+ if (plane & 0x10)
+ printf("\033(r%c%c%c%c", 2, 0, 1, plane & 0x0f);
+ else
+ printf("\033r%c", plane);
+ }
+
+ /*
+ * Send graphics with ESC . command.
+ */
+
+ bytes *= 8;
+
+ printf("\033.");
+ putchar(type != 0);
+ putchar(ystep);
+ putchar(xstep);
+ putchar(rows);
+ putchar(bytes & 255);
+ putchar(bytes >> 8);
+ }
+
+ cupsWritePrintData(line_ptr, line_end - line_ptr);
+}
+
+
+/*
+ * 'OutputBand()' - Output a band of graphics.
+ */
+
+void
+OutputBand(ppd_file_t *ppd, /* I - PPD file */
+ cups_page_header2_t *header, /* I - Page header */
+ cups_weave_t *band) /* I - Current band */
+{
+ int xstep, /* Spacing between columns */
+ ystep; /* Spacing between rows */
+
+
+ /*
+ * Interleaved ESC/P2 graphics...
+ */
+
+ OutputFeed = band->y - DotRowCurrent;
+ DotRowCurrent = band->y;
+
+ fprintf(stderr, "DEBUG: Printing band %p, x = %d, y = %d, plane = %d, count = %d, OutputFeed = %d\n",
+ (void*)band, band->x, band->y, band->plane, band->count, OutputFeed);
+
+ /*
+ * Compute step values...
+ */
+
+ xstep = 3600 * DotColStep / header->HWResolution[0];
+ ystep = 3600 * DotRowStep / header->HWResolution[1];
+
+ /*
+ * Output the band...
+ */
+
+ if (OutputFeed > 0)
+ {
+ cupsWritePrintData("\033(v\002\000", 5);
+ putchar(OutputFeed & 255);
+ putchar(OutputFeed >> 8);
+
+ OutputFeed = 0;
+ }
+
+ CompressData(ppd, band->buffer, band->count * DotBufferSize, band->plane,
+ header->cupsCompression, band->count, xstep, ystep, band->x);
+
+ /*
+ * Clear the band...
+ */
+
+ memset(band->buffer, 0, band->count * DotBufferSize);
+ band->dirty = 0;
+
+ /*
+ * Flush the output buffers...
+ */
+
+ fflush(stdout);
+}
+
+
+/*
+ * 'ProcessLine()' - Read graphics from the page stream and output as needed.
+ */
+
+void
+ProcessLine(ppd_file_t *ppd, /* I - PPD file */
+ cups_raster_t *ras, /* I - Raster stream */
+ cups_page_header2_t *header, /* I - Page header */
+ const int y) /* I - Current scanline */
+{
+ int plane, /* Current color plane */
+ width, /* Width of line */
+ subwidth, /* Width of interleaved row */
+ subrow, /* Subrow for interleaved output */
+ offset, /* Offset to current line */
+ pass, /* Pass number */
+ xstep, /* X step value */
+ ystep; /* Y step value */
+ cups_weave_t *band; /* Current band */
+
+
+ /*
+ * Read a row of graphics...
+ */
+
+ if (!cupsRasterReadPixels(ras, PixelBuffer, header->cupsBytesPerLine))
+ return;
+
+ /*
+ * Perform the color separation...
+ */
+
+ width = header->cupsWidth;
+ subwidth = header->cupsWidth / DotColStep;
+ xstep = 3600 / header->HWResolution[0];
+ ystep = 3600 / header->HWResolution[1];
+
+ switch (header->cupsColorSpace)
+ {
+ case CUPS_CSPACE_W :
+ if (RGB)
+ {
+ cupsRGBDoGray(RGB, PixelBuffer, CMYKBuffer, width);
+ cupsCMYKDoCMYK(CMYK, CMYKBuffer, InputBuffer, width);
+ }
+ else
+ cupsCMYKDoGray(CMYK, PixelBuffer, InputBuffer, width);
+ break;
+
+ case CUPS_CSPACE_K :
+ cupsCMYKDoBlack(CMYK, PixelBuffer, InputBuffer, width);
+ break;
+
+ default :
+ case CUPS_CSPACE_RGB :
+ if (RGB)
+ {
+ cupsRGBDoRGB(RGB, PixelBuffer, CMYKBuffer, width);
+ cupsCMYKDoCMYK(CMYK, CMYKBuffer, InputBuffer, width);
+ }
+ else
+ cupsCMYKDoRGB(CMYK, PixelBuffer, InputBuffer, width);
+ break;
+
+ case CUPS_CSPACE_CMYK :
+ cupsCMYKDoCMYK(CMYK, PixelBuffer, InputBuffer, width);
+ break;
+ }
+
+ /*
+ * Dither the pixels...
+ */
+
+ for (plane = 0; plane < PrinterPlanes; plane ++)
+ {
+ cupsDitherLine(DitherStates[plane], DitherLuts[plane], InputBuffer + plane,
+ PrinterPlanes, OutputBuffers[plane]);
+
+ if (DotRowMax == 1)
+ {
+ /*
+ * Handle microweaved output...
+ */
+
+ if (cupsCheckBytes(OutputBuffers[plane], width))
+ continue;
+
+ if (BitPlanes == 1)
+ cupsPackHorizontal(OutputBuffers[plane], DotBuffers[plane],
+ width, 0, 1);
+ else
+ cupsPackHorizontal2(OutputBuffers[plane], DotBuffers[plane],
+ width, 1);
+
+ if (OutputFeed > 0)
+ {
+ cupsWritePrintData("\033(v\002\000", 5);
+ putchar(OutputFeed & 255);
+ putchar(OutputFeed >> 8);
+ OutputFeed = 0;
+ }
+
+ CompressData(ppd, DotBuffers[plane], DotBufferSize, plane, 1, 1,
+ xstep, ystep, 0);
+ fflush(stdout);
+ }
+ else
+ {
+ /*
+ * Handle softweaved output...
+ */
+
+ for (pass = 0, subrow = y % DotRowStep;
+ pass < DotColStep;
+ pass ++, subrow += DotRowStep)
+ {
+ /*
+ * See if we need to output the band...
+ */
+
+ band = DotBands[subrow][plane];
+ offset = band->row * DotBufferSize;
+
+ if (BitPlanes == 1)
+ cupsPackHorizontal(OutputBuffers[plane] + pass,
+ band->buffer + offset, subwidth, 0, DotColStep);
+ else
+ cupsPackHorizontal2(OutputBuffers[plane] + pass,
+ band->buffer + offset, subwidth, DotColStep);
+
+ band->row ++;
+ band->dirty |= !cupsCheckBytes(band->buffer + offset, DotBufferSize);
+ if (band->row >= band->count)
+ {
+ if (band->dirty)
+ {
+ /*
+ * Dirty band needs to be added to the used list...
+ */
+
+ AddBand(band);
+
+ /*
+ * Then find a new band...
+ */
+
+ if (DotAvailList == NULL)
+ {
+ OutputBand(ppd, header, DotUsedList);
+
+ DotBands[subrow][plane] = DotUsedList;
+ DotUsedList->x = band->x;
+ DotUsedList->y = band->y + band->count * DotRowStep;
+ DotUsedList->plane = band->plane;
+ DotUsedList->row = 0;
+ DotUsedList->count = DotRowCount;
+ DotUsedList = DotUsedList->next;
+ }
+ else
+ {
+ DotBands[subrow][plane] = DotAvailList;
+ DotAvailList->x = band->x;
+ DotAvailList->y = band->y + band->count * DotRowStep;
+ DotAvailList->plane = band->plane;
+ DotAvailList->row = 0;
+ DotAvailList->count = DotRowCount;
+ DotAvailList = DotAvailList->next;
+ }
+ }
+ else
+ {
+ /*
+ * This band isn't dirty, so reuse it...
+ */
+
+ fprintf(stderr, "DEBUG: Blank band %p, x = %d, y = %d, plane = %d, count = %d\n",
+ (void*)band, band->x, band->y, band->plane, band->count);
+
+ band->y += band->count * DotRowStep;
+ band->row = 0;
+ band->count = DotRowCount;
+ }
+ }
+ }
+ }
+ }
+
+ if (DotRowMax == 1)
+ OutputFeed ++;
+}
+
+
+/*
+ * 'main()' - Main entry and processing of driver.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int fd; /* File descriptor */
+ cups_raster_t *ras; /* Raster stream for printing */
+ cups_page_header2_t header; /* Page header from file */
+ int page; /* Current page */
+ int y; /* Current line */
+ ppd_file_t *ppd; /* PPD file */
+ int num_options; /* Number of options */
+ cups_option_t *options; /* Options */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc < 6 || argc > 7)
+ {
+ fprintf(stderr, "Usage: %s job-id user title copies options [file]\n",
+ argv[0]);
+ return (1);
+ }
+
+ num_options = cupsParseOptions(argv[5], 0, &options);
+
+ /*
+ * Open the PPD file...
+ */
+
+ ppd = ppdOpenFile(getenv("PPD"));
+
+ if (!ppd)
+ {
+ ppd_status_t status; /* PPD error */
+ int linenum; /* Line number */
+
+ fputs("ERROR: The PPD file could not be opened.\n", stderr);
+
+ status = ppdLastError(&linenum);
+
+ fprintf(stderr, "DEBUG: %s on line %d.\n", ppdErrorString(status), linenum);
+
+ return (1);
+ }
+
+ ppdMarkDefaults(ppd);
+ cupsMarkOptions(ppd, num_options, options);
+
+ /*
+ * Open the page stream...
+ */
+
+ if (argc == 7)
+ {
+ if ((fd = open(argv[6], O_RDONLY)) == -1)
+ {
+ perror("ERROR: Unable to open raster file");
+ return (1);
+ }
+ }
+ else
+ fd = 0;
+
+ ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
+
+ /*
+ * Register a signal handler to eject the current page if the
+ * job is cancelled.
+ */
+
+ Canceled = 0;
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, CancelJob);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = CancelJob;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, CancelJob);
+#endif /* HAVE_SIGSET */
+
+ /*
+ * Initialize the print device...
+ */
+
+ Setup(ppd);
+
+ /*
+ * Process pages as needed...
+ */
+
+ page = 0;
+
+ while (cupsRasterReadHeader2(ras, &header))
+ {
+ /*
+ * Write a status message with the page number and number of copies.
+ */
+
+ if (Canceled)
+ break;
+
+ page ++;
+
+ fprintf(stderr, "PAGE: %d 1\n", page);
+ fprintf(stderr, "INFO: Starting page %d.\n", page);
+
+ StartPage(ppd, &header);
+
+ for (y = 0; y < header.cupsHeight; y ++)
+ {
+ /*
+ * Let the user know how far we have progressed...
+ */
+
+ if (Canceled)
+ break;
+
+ if ((y & 127) == 0)
+ {
+ fprintf(stderr, "INFO: Printing page %d, %d%% complete.\n",
+ page, 100 * y / header.cupsHeight);
+ fprintf(stderr, "ATTR: job-media-progress=%d\n",
+ 100 * y / header.cupsHeight);
+ }
+
+ /*
+ * Read and write a line of graphics or whitespace...
+ */
+
+ ProcessLine(ppd, ras, &header, y);
+ }
+
+ /*
+ * Eject the page...
+ */
+
+ fprintf(stderr, "INFO: Finished page %d.\n", page);
+
+ EndPage(ppd, &header);
+
+ if (Canceled)
+ break;
+ }
+
+ Shutdown(ppd);
+
+ cupsFreeOptions(num_options, options);
+
+ cupsRasterClose(ras);
+
+ if (fd != 0)
+ close(fd);
+
+ return (page == 0);
+}
+
diff --git a/filter/rastertopclm b/filter/rastertopclm
new file mode 100644
index 000000000..5a2f9a51c
--- /dev/null
+++ b/filter/rastertopclm
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# rastertopclm - Raster to PCLm filter for CUPS
+#
+# Note: This is only a wrapper filter, the real work is done by rastertopdf
+#
+# (C) 2017 Sahil Arora <sahilarora.535@gmail.com>
+#
+# Released under GPL 2 or later
+#
+
+echo "DEBUG: rastertopclm argv[$#] = $@" >&2
+echo "DEBUG: PPD: $PPD" >&2
+
+if [ $# -lt 5 -o $# -gt 6 ]; then
+ echo "ERROR: rastertopclm job-id user title copies options [file]" >&2
+ exit 1
+fi
+
+# Read from given file.
+if [ -n "$6" ]; then
+ exec <"$6"
+fi
+
+OUTFORMAT=PCLM $CUPS_SERVERBIN/filter/rastertopdf "$1" "$2" "$3" "$4" "$5"
diff --git a/filter/rastertopclx.c b/filter/rastertopclx.c
new file mode 100644
index 000000000..3f2ecdaae
--- /dev/null
+++ b/filter/rastertopclx.c
@@ -0,0 +1,1963 @@
+/*
+ * Advanced HP Page Control Language and Raster Transfer Language
+ * filter for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1993-2005 by Easy Software Products
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * StartPage() - Start a page of graphics.
+ * EndPage() - Finish a page of graphics.
+ * Shutdown() - Shutdown a printer.
+ * CancelJob() - Cancel the current job...
+ * CompressData() - Compress a line of graphics.
+ * OutputLine() - Output the specified number of lines of graphics.
+ * ReadLine() - Read graphics from the page stream.
+ * main() - Main entry and processing of driver.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <cupsfilters/colormanager.h>
+#include <cupsfilters/driver.h>
+#include "pcl-common.h"
+#include <signal.h>
+
+
+/*
+ * Output modes...
+ */
+
+typedef enum
+{
+ OUTPUT_BITMAP, /* Output bitmap data from RIP */
+ OUTPUT_INVERBIT, /* Output inverted bitmap data */
+ OUTPUT_RGB, /* Output 24-bit RGB data from RIP */
+ OUTPUT_DITHERED /* Output dithered data */
+} pcl_output_t;
+
+
+/*
+ * Globals...
+ */
+
+cups_rgb_t *RGB; /* RGB color separation data */
+cups_cmyk_t *CMYK; /* CMYK color separation data */
+unsigned char *PixelBuffer, /* Pixel buffer */
+ *CMYKBuffer, /* CMYK buffer */
+ *OutputBuffers[6], /* Output buffers */
+ *DotBuffers[6], /* Bit buffers */
+ *CompBuffer, /* Compression buffer */
+ *SeedBuffer, /* Mode 3 seed buffers */
+ BlankValue; /* The blank value */
+short *InputBuffer; /* Color separation buffer */
+cups_lut_t *DitherLuts[6]; /* Lookup tables for dithering */
+cups_dither_t *DitherStates[6]; /* Dither state tables */
+int PrinterPlanes, /* Number of color planes */
+ SeedInvalid, /* Contents of seed buffer invalid? */
+ DotBits[6], /* Number of bits per color */
+ DotBufferSizes[6], /* Size of one row of color dots */
+ DotBufferSize, /* Size of complete line */
+ OutputFeed, /* Number of lines to skip */
+ Page; /* Current page number */
+pcl_output_t OutputMode; /* Output mode - see OUTPUT_ consts */
+const int ColorOrders[7][7] = /* Order of color planes */
+ {
+ { 0, 0, 0, 0, 0, 0, 0 }, /* Black */
+ { 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 1, 2, 0, 0, 0, 0 }, /* CMY */
+ { 3, 0, 1, 2, 0, 0, 0 }, /* KCMY */
+ { 0, 0, 0, 0, 0, 0, 0 },
+ { 5, 0, 1, 2, 3, 4, 0 }, /* KCMYcm */
+ { 5, 0, 1, 2, 3, 4, 6 } /* KCMYcmk */
+ };
+int Canceled; /* Is the job canceled? */
+
+
+/*
+ * Prototypes...
+ */
+
+void StartPage(ppd_file_t *ppd, cups_page_header2_t *header, int job_id,
+ const char *user, const char *title, int num_options,
+ cups_option_t *options);
+void EndPage(ppd_file_t *ppd, cups_page_header2_t *header);
+void Shutdown(ppd_file_t *ppd, int job_id, const char *user,
+ const char *title, int num_options, cups_option_t *options);
+
+void CancelJob(int sig);
+void CompressData(unsigned char *line, int length, int plane, int pend,
+ int type);
+void OutputLine(ppd_file_t *ppd, cups_page_header2_t *header);
+int ReadLine(cups_raster_t *ras, cups_page_header2_t *header);
+
+
+/*
+ * 'StartPage()' - Start a page of graphics.
+ */
+
+void
+StartPage(ppd_file_t *ppd, /* I - PPD file */
+ cups_page_header2_t *header, /* I - Page header */
+ int job_id, /* I - Job ID */
+ const char *user, /* I - User printing job */
+ const char *title, /* I - Title of job */
+ int num_options,
+ /* I - Number of command-line options */
+ cups_option_t *options) /* I - Command-line options */
+{
+ int i; /* Temporary/looping var */
+ int plane; /* Current plane */
+ int cm_disabled; /* Device Color Inhibited */
+ char s[255]; /* Temporary value */
+ const char *colormodel; /* Color model string */
+ char resolution[PPD_MAX_NAME],
+ /* Resolution string */
+ spec[PPD_MAX_NAME]; /* PPD attribute name */
+ ppd_attr_t *attr; /* Attribute from PPD file */
+ ppd_choice_t *choice; /* Selected option */
+ const int *order; /* Order to use */
+ int xorigin, /* X origin of page */
+ yorigin; /* Y origin of page */
+ static const float default_lut[2] = /* Default dithering lookup table */
+ {
+ 0.0,
+ 1.0
+ };
+ cm_calibration_t cm_calibrate; /* Color calibration mode */
+
+ /*
+ * Debug info...
+ */
+
+ fprintf(stderr, "DEBUG: StartPage...\n");
+ fprintf(stderr, "DEBUG: MediaClass = \"%s\"\n", header->MediaClass);
+ fprintf(stderr, "DEBUG: MediaColor = \"%s\"\n", header->MediaColor);
+ fprintf(stderr, "DEBUG: MediaType = \"%s\"\n", header->MediaType);
+ fprintf(stderr, "DEBUG: OutputType = \"%s\"\n", header->OutputType);
+
+ fprintf(stderr, "DEBUG: AdvanceDistance = %d\n", header->AdvanceDistance);
+ fprintf(stderr, "DEBUG: AdvanceMedia = %d\n", header->AdvanceMedia);
+ fprintf(stderr, "DEBUG: Collate = %d\n", header->Collate);
+ fprintf(stderr, "DEBUG: CutMedia = %d\n", header->CutMedia);
+ fprintf(stderr, "DEBUG: Duplex = %d\n", header->Duplex);
+ fprintf(stderr, "DEBUG: HWResolution = [ %d %d ]\n", header->HWResolution[0],
+ header->HWResolution[1]);
+ fprintf(stderr, "DEBUG: ImagingBoundingBox = [ %d %d %d %d ]\n",
+ header->ImagingBoundingBox[0], header->ImagingBoundingBox[1],
+ header->ImagingBoundingBox[2], header->ImagingBoundingBox[3]);
+ fprintf(stderr, "DEBUG: InsertSheet = %d\n", header->InsertSheet);
+ fprintf(stderr, "DEBUG: Jog = %d\n", header->Jog);
+ fprintf(stderr, "DEBUG: LeadingEdge = %d\n", header->LeadingEdge);
+ fprintf(stderr, "DEBUG: Margins = [ %d %d ]\n", header->Margins[0],
+ header->Margins[1]);
+ fprintf(stderr, "DEBUG: ManualFeed = %d\n", header->ManualFeed);
+ fprintf(stderr, "DEBUG: MediaPosition = %d\n", header->MediaPosition);
+ fprintf(stderr, "DEBUG: MediaWeight = %d\n", header->MediaWeight);
+ fprintf(stderr, "DEBUG: MirrorPrint = %d\n", header->MirrorPrint);
+ fprintf(stderr, "DEBUG: NegativePrint = %d\n", header->NegativePrint);
+ fprintf(stderr, "DEBUG: NumCopies = %d\n", header->NumCopies);
+ fprintf(stderr, "DEBUG: Orientation = %d\n", header->Orientation);
+ fprintf(stderr, "DEBUG: OutputFaceUp = %d\n", header->OutputFaceUp);
+ fprintf(stderr, "DEBUG: PageSize = [ %d %d ]\n", header->PageSize[0],
+ header->PageSize[1]);
+ fprintf(stderr, "DEBUG: Separations = %d\n", header->Separations);
+ fprintf(stderr, "DEBUG: TraySwitch = %d\n", header->TraySwitch);
+ fprintf(stderr, "DEBUG: Tumble = %d\n", header->Tumble);
+ fprintf(stderr, "DEBUG: cupsWidth = %d\n", header->cupsWidth);
+ fprintf(stderr, "DEBUG: cupsHeight = %d\n", header->cupsHeight);
+ fprintf(stderr, "DEBUG: cupsMediaType = %d\n", header->cupsMediaType);
+ fprintf(stderr, "DEBUG: cupsBitsPerColor = %d\n", header->cupsBitsPerColor);
+ fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d\n", header->cupsBitsPerPixel);
+ fprintf(stderr, "DEBUG: cupsBytesPerLine = %d\n", header->cupsBytesPerLine);
+ fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", header->cupsColorOrder);
+ fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", header->cupsColorSpace);
+ fprintf(stderr, "DEBUG: cupsCompression = %d\n", header->cupsCompression);
+
+#ifdef __APPLE__
+ /*
+ * MacOS X 10.2.x doesn't set most of the page device attributes, so check
+ * the options and set them accordingly...
+ */
+
+ if (ppd && ppdIsMarked(ppd, "Duplex", "DuplexNoTumble"))
+ {
+ header->Duplex = CUPS_TRUE;
+ header->Tumble = CUPS_FALSE;
+ }
+ else if (ppd && ppdIsMarked(ppd, "Duplex", "DuplexTumble"))
+ {
+ header->Duplex = CUPS_TRUE;
+ header->Tumble = CUPS_TRUE;
+ }
+
+ fprintf(stderr, "DEBUG: num_options=%d\n", num_options);
+
+ for (i = 0; i < num_options; i ++)
+ fprintf(stderr, "DEBUG: options[%d]=[\"%s\" \"%s\"]\n", i,
+ options[i].name, options[i].value);
+#endif /* __APPLE__ */
+
+ /*
+ * Figure out the color model and spec strings...
+ */
+
+ switch (header->cupsColorSpace)
+ {
+ case CUPS_CSPACE_K :
+ colormodel = "Black";
+ break;
+ case CUPS_CSPACE_W :
+ colormodel = "Gray";
+ break;
+ default :
+ case CUPS_CSPACE_RGB :
+ colormodel = "RGB";
+ break;
+ case CUPS_CSPACE_CMY :
+ colormodel = "CMY";
+ break;
+ case CUPS_CSPACE_CMYK :
+ colormodel = "CMYK";
+ break;
+ }
+
+ cm_disabled = 0;
+
+ if (header->HWResolution[0] != header->HWResolution[1])
+ snprintf(resolution, sizeof(resolution), "%dx%ddpi",
+ header->HWResolution[0], header->HWResolution[1]);
+ else
+ snprintf(resolution, sizeof(resolution), "%ddpi",
+ header->HWResolution[0]);
+
+ if (!header->MediaType[0])
+ strcpy(header->MediaType, "PLAIN");
+
+ /*
+ * Get the dithering parameters...
+ */
+
+ BlankValue = 0x00;
+
+ if (header->cupsBitsPerColor == 1)
+ {
+ /*
+ * Use raw bitmap mode...
+ */
+
+ switch (header->cupsColorSpace)
+ {
+ case CUPS_CSPACE_K :
+ OutputMode = OUTPUT_BITMAP;
+ PrinterPlanes = 1;
+ break;
+ case CUPS_CSPACE_W :
+ OutputMode = OUTPUT_INVERBIT;
+ PrinterPlanes = 1;
+ break;
+ default :
+ case CUPS_CSPACE_RGB :
+ OutputMode = OUTPUT_INVERBIT;
+ PrinterPlanes = 3;
+ break;
+ case CUPS_CSPACE_CMY :
+ OutputMode = OUTPUT_BITMAP;
+ PrinterPlanes = 3;
+ break;
+ case CUPS_CSPACE_CMYK :
+ OutputMode = OUTPUT_BITMAP;
+ PrinterPlanes = 4;
+ break;
+ }
+
+ if (OutputMode == OUTPUT_INVERBIT)
+ BlankValue = 0xff;
+
+ DotBufferSize = header->cupsBytesPerLine;
+
+ memset(DitherLuts, 0, sizeof(DitherLuts));
+ memset(DitherStates, 0, sizeof(DitherStates));
+ }
+ else if (header->cupsColorSpace == CUPS_CSPACE_RGB &&
+ (!ppd || (ppd->model_number & PCL_RASTER_RGB24)))
+ {
+ /*
+ * Use 24-bit RGB output mode...
+ */
+
+ OutputMode = OUTPUT_RGB;
+ PrinterPlanes = 3;
+ DotBufferSize = header->cupsBytesPerLine;
+
+ if (header->cupsCompression == 10)
+ BlankValue = 0xff;
+
+ memset(DitherLuts, 0, sizeof(DitherLuts));
+ memset(DitherStates, 0, sizeof(DitherStates));
+ }
+ else if ((header->cupsColorSpace == CUPS_CSPACE_K ||
+ header->cupsColorSpace == CUPS_CSPACE_W) &&
+ (ppd && (ppd->model_number & PCL_RASTER_RGB24)) &&
+ header->cupsCompression == 10)
+ {
+ /*
+ * Use 24-bit RGB output mode for grayscale/black output...
+ */
+
+ OutputMode = OUTPUT_RGB;
+ PrinterPlanes = 1;
+ DotBufferSize = header->cupsBytesPerLine;
+
+ if (header->cupsColorSpace == CUPS_CSPACE_W)
+ BlankValue = 0xff;
+
+ memset(DitherLuts, 0, sizeof(DitherLuts));
+ memset(DitherStates, 0, sizeof(DitherStates));
+ }
+ else
+ {
+ /*
+ * Use dithered output mode...
+ */
+
+ OutputMode = OUTPUT_DITHERED;
+
+ /*
+ * Load the appropriate color profiles...
+ */
+
+ RGB = NULL;
+ CMYK = NULL;
+
+ fputs("DEBUG: Attempting to load color profiles using the following values:\n", stderr);
+ fprintf(stderr, "DEBUG: ColorModel = %s\n", colormodel);
+ fprintf(stderr, "DEBUG: MediaType = %s\n", header->MediaType);
+ fprintf(stderr, "DEBUG: Resolution = %s\n", resolution);
+
+ /* support the "cm-calibration" option */
+ cm_calibrate = cmGetCupsColorCalibrateMode(options, num_options);
+
+ if (cm_calibrate == CM_CALIBRATION_ENABLED)
+ cm_disabled = 1;
+ else
+ cm_disabled = cmIsPrinterCmDisabled(getenv("PRINTER"));
+
+ if (ppd && !cm_disabled)
+ {
+ if (header->cupsColorSpace == CUPS_CSPACE_RGB ||
+ header->cupsColorSpace == CUPS_CSPACE_W)
+ RGB = cupsRGBLoad(ppd, colormodel, header->MediaType, resolution);
+
+ CMYK = cupsCMYKLoad(ppd, colormodel, header->MediaType, resolution);
+ }
+
+ if (RGB)
+ fputs("DEBUG: Loaded RGB separation from PPD.\n", stderr);
+
+ if (CMYK)
+ fputs("DEBUG: Loaded CMYK separation from PPD.\n", stderr);
+ else
+ {
+ if (header->cupsColorSpace == CUPS_CSPACE_KCMY ||
+ header->cupsColorSpace == CUPS_CSPACE_CMYK)
+ PrinterPlanes = 4;
+ else if (header->cupsColorSpace == CUPS_CSPACE_CMY)
+ PrinterPlanes = 3;
+ else
+ PrinterPlanes = 1;
+ /*fputs("DEBUG: Loading default K separation.\n", stderr);*/
+ fprintf(stderr, "DEBUG: Color Space: %d; Color Planes %d\n", header->cupsColorSpace, PrinterPlanes);
+ CMYK = cupsCMYKNew(PrinterPlanes);
+ }
+
+ PrinterPlanes = CMYK->num_channels;
+
+ /*
+ * Use dithered mode...
+ */
+
+ switch (PrinterPlanes)
+ {
+ case 1 : /* K */
+ DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Black");
+ break;
+
+ case 3 : /* CMY */
+ DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Cyan");
+ DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Magenta");
+ DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Yellow");
+ break;
+
+ case 4 : /* CMYK */
+ DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Cyan");
+ DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Magenta");
+ DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Yellow");
+ DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Black");
+ break;
+
+ case 6 : /* CcMmYK */
+ DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Cyan");
+ DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "LightCyan");
+ DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Magenta");
+ DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "LightMagenta");
+ DitherLuts[4] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Yellow");
+ DitherLuts[5] = cupsLutLoad(ppd, colormodel, header->MediaType,
+ resolution, "Black");
+ break;
+ }
+
+ for (plane = 0; plane < PrinterPlanes; plane ++)
+ {
+ if (!DitherLuts[plane])
+ DitherLuts[plane] = cupsLutNew(2, default_lut);
+
+ if (DitherLuts[plane][4095].pixel > 1)
+ DotBits[plane] = 2;
+ else
+ DotBits[plane] = 1;
+
+ DitherStates[plane] = cupsDitherNew(header->cupsWidth);
+
+ if (!DitherLuts[plane])
+ DitherLuts[plane] = cupsLutNew(2, default_lut);
+ }
+ }
+
+ fprintf(stderr, "DEBUG: PrinterPlanes = %d\n", PrinterPlanes);
+
+ /*
+ * Initialize the printer...
+ */
+
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsInitialNulls", NULL)) != NULL))
+ for (i = atoi(attr->value); i > 0; i --)
+ putchar(0);
+
+ if (Page == 1 && (!ppd || ppd->model_number & PCL_PJL))
+ {
+ pjl_escape();
+
+ /*
+ * PJL job setup...
+ */
+
+ pjl_set_job(job_id, user, title);
+
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsPJL", "StartJob")) != NULL))
+ pjl_write(attr->value, NULL, job_id, user, title, num_options,
+ options);
+
+ snprintf(spec, sizeof(spec), "RENDERMODE.%s", colormodel);
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsPJL", spec)) != NULL))
+ printf("@PJL SET RENDERMODE=%s\r\n", attr->value);
+
+ snprintf(spec, sizeof(spec), "COLORSPACE.%s", colormodel);
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsPJL", spec)) != NULL))
+ printf("@PJL SET COLORSPACE=%s\r\n", attr->value);
+ if (!ppd)
+ printf("@PJL SET COLORSPACE=%s\r\n", colormodel);
+
+ snprintf(spec, sizeof(spec), "RENDERINTENT.%s", colormodel);
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsPJL", spec)) != NULL))
+ printf("@PJL SET RENDERINTENT=%s\r\n", attr->value);
+
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsPJL", "Duplex")) != NULL))
+ {
+ sprintf(s, "%d", header->Duplex);
+ pjl_write(attr->value, s, job_id, user, title, num_options, options);
+ }
+
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsPJL", "Tumble")) != NULL))
+ {
+ sprintf(s, "%d", header->Tumble);
+ pjl_write(attr->value, s, job_id, user, title, num_options, options);
+ }
+
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsPJL", "MediaClass")) != NULL))
+ pjl_write(attr->value, header->MediaClass, job_id, user, title,
+ num_options, options);
+
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsPJL", "MediaColor")) != NULL))
+ pjl_write(attr->value, header->MediaColor, job_id, user, title,
+ num_options, options);
+
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsPJL", "MediaType")) != NULL))
+ pjl_write(attr->value, header->MediaType, job_id, user, title,
+ num_options, options);
+
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsPJL", "OutputType")) != NULL))
+ pjl_write(attr->value, header->OutputType, job_id, user, title,
+ num_options, options);
+
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsPJL", "cupsBooklet")) != NULL &&
+ (choice = ppdFindMarkedChoice(ppd, "cupsBooklet")) != NULL))
+ pjl_write(attr->value, choice->choice, job_id, user, title,
+ num_options, options);
+
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsPJL", "Jog")) != NULL))
+ {
+ sprintf(s, "%d", header->Jog);
+ pjl_write(attr->value, s, job_id, user, title, num_options, options);
+ }
+
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsPJL", "cupsPunch")) != NULL &&
+ (choice = ppdFindMarkedChoice(ppd, "cupsPunch")) != NULL))
+ pjl_write(attr->value, choice->choice, job_id, user, title,
+ num_options, options);
+
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsPJL", "cupsStaple")) != NULL &&
+ (choice = ppdFindMarkedChoice(ppd, "cupsStaple")) != NULL))
+ pjl_write(attr->value, choice->choice, job_id, user, title,
+ num_options, options);
+
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsPJL", "cupsRET")) != NULL &&
+ (choice = ppdFindMarkedChoice(ppd, "cupsRET")) != NULL))
+ pjl_write(attr->value, choice->choice, job_id, user, title,
+ num_options, options);
+
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsPJL", "cupsTonerSave")) != NULL &&
+ (choice = ppdFindMarkedChoice(ppd, "cupsTonerSave")) != NULL))
+ pjl_write(attr->value, choice->choice, job_id, user, title,
+ num_options, options);
+
+ if (!ppd || ppd->model_number & PCL_PJL_PAPERWIDTH)
+ {
+ printf("@PJL SET PAPERLENGTH=%d\r\n", header->PageSize[1] * 10);
+ printf("@PJL SET PAPERWIDTH=%d\r\n", header->PageSize[0] * 10);
+ }
+
+ if (!ppd || ppd->model_number & PCL_PJL_RESOLUTION)
+ printf("@PJL SET RESOLUTION=%d\r\n", header->HWResolution[0]);
+
+ if (ppd)
+ ppdEmit(ppd, stdout, PPD_ORDER_JCL);
+ if (ppd && ppd->model_number & PCL_PJL_HPGL2)
+ pjl_enter_language("HPGL2");
+ else if (ppd && ppd->model_number & PCL_PJL_PCL3GUI)
+ pjl_enter_language("PCL3GUI");
+ else
+ pjl_enter_language("PCL");
+ }
+
+ if (Page == 1)
+ {
+ pcl_reset();
+ }
+
+ if (ppd && ppd->model_number & PCL_PJL_HPGL2)
+ {
+ if (Page == 1)
+ {
+ /*
+ * HP-GL/2 initialization...
+ */
+
+ printf("IN;");
+ printf("MG\"%d %s %s\";", job_id, user, title);
+ }
+
+ /*
+ * Set media size, position, type, etc...
+ */
+
+ printf("BP5,0;");
+ printf("PS%.0f,%.0f;",
+ header->cupsHeight * 1016.0 / header->HWResolution[1],
+ header->cupsWidth * 1016.0 / header->HWResolution[0]);
+ printf("PU;");
+ printf("PA0,0");
+
+ printf("MT%d;", header->cupsMediaType);
+
+ if (header->CutMedia == CUPS_CUT_PAGE)
+ printf("EC;");
+ else
+ printf("EC0;");
+
+ /*
+ * Set graphics mode...
+ */
+
+ pcl_set_pcl_mode(0);
+ pcl_set_negative_motion();
+ }
+ else
+ {
+ /*
+ * Set media size, position, type, etc...
+ */
+
+ if (!header->Duplex || (Page & 1))
+ {
+ pcl_set_media_size(ppd, header->PageSize[0], header->PageSize[1]);
+
+ if (header->MediaPosition)
+ pcl_set_media_source(header->MediaPosition);
+
+ pcl_set_media_type(header->cupsMediaType);
+
+ if (!ppd || ppdFindAttr(ppd, "cupsPJL", "Duplex") == NULL)
+ pcl_set_duplex(header->Duplex, header->Tumble);
+
+ /*
+ * Set the number of copies...
+ */
+
+ if (!ppd || !ppd->manual_copies)
+ pcl_set_copies(header->NumCopies);
+
+ /*
+ * Set the output order/bin...
+ */
+
+ if ((!ppd || ppdFindAttr(ppd, "cupsPJL", "Jog") == NULL) && header->Jog)
+ printf("\033&l%dG", header->Jog);
+ }
+ else
+ {
+ /*
+ * Print on the back side...
+ */
+
+ printf("\033&a2G");
+ }
+
+ if (header->Duplex && (ppd && (ppd->model_number & PCL_RASTER_CRD)))
+ {
+ /*
+ * Reload the media...
+ */
+
+ pcl_set_media_source(-2);
+ }
+
+ /*
+ * Set the units for cursor positioning and go to the top of the form.
+ */
+
+ printf("\033&u%dD", header->HWResolution[0]);
+ printf("\033*p0Y\033*p0X");
+ }
+
+ if (ppd && ((attr = cupsFindAttr(ppd, "cupsPCLQuality", colormodel,
+ header->MediaType, resolution, spec,
+ sizeof(spec))) != NULL))
+ {
+ /*
+ * Set the print quality...
+ */
+
+ if (ppd && (ppd->model_number & PCL_PJL_HPGL2))
+ printf("QM%d", atoi(attr->value));
+ else
+ printf("\033*o%dM", atoi(attr->value));
+ }
+
+ /*
+ * Enter graphics mode...
+ */
+
+ if (ppd && (ppd->model_number & PCL_RASTER_CRD))
+ {
+ /*
+ * Use configure raster data command...
+ */
+
+ if (OutputMode == OUTPUT_RGB)
+ {
+ /*
+ * Send 12-byte configure raster data command with horizontal and
+ * vertical resolutions as well as a color count...
+ */
+
+ if (ppd && ((attr = cupsFindAttr(ppd, "cupsPCLCRDMode", colormodel,
+ header->MediaType, resolution, spec,
+ sizeof(spec))) != NULL))
+ i = atoi(attr->value);
+ else
+ i = 31;
+
+ printf("\033*g12W");
+ putchar(6); /* Format 6 */
+ putchar(i); /* Set pen mode */
+ putchar(0x00); /* Number components */
+ putchar(0x01); /* (1 for RGB) */
+
+ putchar(header->HWResolution[0] >> 8);
+ putchar(header->HWResolution[0]);
+ putchar(header->HWResolution[1] >> 8);
+ putchar(header->HWResolution[1]);
+
+ putchar(header->cupsCompression); /* Compression mode 3 or 10 */
+ putchar(0x01); /* Portrait orientation */
+ putchar(0x20); /* Bits per pixel (32 = RGB) */
+ putchar(0x01); /* Planes per pixel (1 = chunky RGB) */
+ }
+ else
+ {
+ /*
+ * Send the configure raster data command with horizontal and
+ * vertical resolutions as well as a color count...
+ */
+
+ printf("\033*g%dW", PrinterPlanes * 6 + 2);
+ putchar(2); /* Format 2 */
+ putchar(PrinterPlanes); /* Output planes */
+
+ order = ColorOrders[PrinterPlanes - 1];
+
+ for (i = 0; i < PrinterPlanes; i ++)
+ {
+ plane = order[i];
+
+ putchar(header->HWResolution[0] >> 8);
+ putchar(header->HWResolution[0]);
+ putchar(header->HWResolution[1] >> 8);
+ putchar(header->HWResolution[1]);
+ putchar(0);
+ putchar(1 << DotBits[plane]);
+ }
+ }
+ }
+ else if ((!ppd || (ppd->model_number & PCL_RASTER_CID)) &&
+ OutputMode == OUTPUT_RGB)
+ {
+ /*
+ * Use configure image data command...
+ */
+
+ pcl_set_simple_resolution(header->HWResolution[0]);
+ /* Set output resolution */
+
+ cupsWritePrintData("\033*v6W\2\3\0\10\10\10", 11);
+ /* 24-bit sRGB */
+ }
+ else
+ {
+ /*
+ * Use simple raster commands...
+ */
+
+ pcl_set_simple_resolution(header->HWResolution[0]);
+ /* Set output resolution */
+
+ if (PrinterPlanes == 3)
+ pcl_set_simple_cmy();
+ else if (PrinterPlanes == 4)
+ pcl_set_simple_kcmy();
+ }
+
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsPCLOrigin", "X")) != NULL))
+ xorigin = atoi(attr->value);
+ else
+ xorigin = 0;
+
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsPCLOrigin", "Y")) != NULL))
+ yorigin = atoi(attr->value);
+ else
+ yorigin = 120;
+
+ printf("\033&a%dH\033&a%dV", xorigin, yorigin);
+ printf("\033*r%dS", header->cupsWidth);
+ printf("\033*r%dT", header->cupsHeight);
+ printf("\033*r1A");
+
+ if (header->cupsCompression && header->cupsCompression != 10)
+ printf("\033*b%dM", header->cupsCompression);
+
+ OutputFeed = 0;
+
+ /*
+ * Allocate memory for the page...
+ */
+
+ PixelBuffer = malloc(header->cupsBytesPerLine);
+
+ if (OutputMode == OUTPUT_DITHERED)
+ {
+ InputBuffer = malloc(header->cupsWidth * PrinterPlanes * 2);
+ OutputBuffers[0] = malloc(PrinterPlanes * header->cupsWidth);
+
+ for (i = 1; i < PrinterPlanes; i ++)
+ OutputBuffers[i] = OutputBuffers[0] + i * header->cupsWidth;
+
+ if (RGB)
+ CMYKBuffer = malloc(header->cupsWidth * PrinterPlanes);
+
+ for (plane = 0, DotBufferSize = 0; plane < PrinterPlanes; plane ++)
+ {
+ DotBufferSizes[plane] = (header->cupsWidth + 7) / 8 * DotBits[plane];
+ DotBufferSize += DotBufferSizes[plane];
+ }
+
+ DotBuffers[0] = malloc(DotBufferSize);
+ for (plane = 1; plane < PrinterPlanes; plane ++)
+ DotBuffers[plane] = DotBuffers[plane - 1] + DotBufferSizes[plane - 1];
+ }
+
+ if (header->cupsCompression)
+ CompBuffer = malloc(DotBufferSize * 4);
+
+ if (header->cupsCompression >= 3)
+ SeedBuffer = malloc(DotBufferSize);
+
+ SeedInvalid = 1;
+
+ fprintf(stderr, "BlankValue=%d\n", BlankValue);
+}
+
+
+/*
+ * 'EndPage()' - Finish a page of graphics.
+ */
+
+void
+EndPage(ppd_file_t *ppd, /* I - PPD file */
+ cups_page_header2_t *header) /* I - Page header */
+{
+ int plane; /* Current plane */
+
+
+ /*
+ * End graphics mode...
+ */
+
+ if (ppd && (ppd->model_number & PCL_RASTER_END_COLOR))
+ printf("\033*rC"); /* End color GFX */
+ else
+ printf("\033*r0B"); /* End B&W GFX */
+
+ /*
+ * Output a page eject sequence...
+ */
+
+ if (ppd && (ppd->model_number & PCL_PJL_HPGL2))
+ {
+ pcl_set_hpgl_mode(0); /* Back to HP-GL/2 mode */
+ printf("PG;"); /* Eject the current page */
+ }
+ else if (!(header->Duplex && (Page & 1)))
+ printf("\014"); /* Eject current page */
+
+ /*
+ * Free memory for the page...
+ */
+
+ free(PixelBuffer);
+
+ if (OutputMode == OUTPUT_DITHERED)
+ {
+ for (plane = 0; plane < PrinterPlanes; plane ++)
+ {
+ cupsDitherDelete(DitherStates[plane]);
+ cupsLutDelete(DitherLuts[plane]);
+ }
+
+ free(DotBuffers[0]);
+ free(InputBuffer);
+ free(OutputBuffers[0]);
+
+ cupsCMYKDelete(CMYK);
+
+ if (RGB)
+ {
+ cupsRGBDelete(RGB);
+ free(CMYKBuffer);
+ }
+ }
+
+ if (header->cupsCompression)
+ free(CompBuffer);
+
+ if (header->cupsCompression >= 3)
+ free(SeedBuffer);
+}
+
+
+/*
+ * 'Shutdown()' - Shutdown a printer.
+ */
+
+void
+Shutdown(ppd_file_t *ppd, /* I - PPD file */
+ int job_id, /* I - Job ID */
+ const char *user, /* I - User printing job */
+ const char *title, /* I - Title of job */
+ int num_options,/* I - Number of command-line options */
+ cups_option_t *options) /* I - Command-line options */
+{
+ ppd_attr_t *attr; /* Attribute from PPD file */
+
+
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsPCL", "EndJob")) != NULL))
+ {
+ /*
+ * Tell the printer how many pages were in the job...
+ */
+
+ putchar(0x1b);
+ printf(attr->value, Page);
+ }
+ else
+ {
+ /*
+ * Return the printer to the default state...
+ */
+
+ pcl_reset();
+ }
+
+ if (!ppd || (ppd->model_number & PCL_PJL))
+ {
+ pjl_escape();
+
+ if (ppd && ((attr = ppdFindAttr(ppd, "cupsPJL", "EndJob")) != NULL))
+ pjl_write(attr->value, NULL, job_id, user, title, num_options,
+ options);
+ else
+ printf("@PJL EOJ\r\n");
+
+ pjl_escape();
+ }
+}
+
+
+/*
+ * 'CancelJob()' - Cancel the current job...
+ */
+
+void
+CancelJob(int sig) /* I - Signal */
+{
+ (void)sig;
+
+ Canceled = 1;
+}
+
+
+/*
+ * 'CompressData()' - Compress a line of graphics.
+ */
+
+void
+CompressData(unsigned char *line, /* I - Data to compress */
+ int length, /* I - Number of bytes */
+ int plane, /* I - Color plane */
+ int pend, /* I - End character for data */
+ int type) /* I - Type of compression */
+{
+ unsigned char *line_ptr, /* Current byte pointer */
+ *line_end, /* End-of-line byte pointer */
+ *comp_ptr, /* Pointer into compression buffer */
+ *start, /* Start of compression sequence */
+ *seed; /* Seed buffer pointer */
+ int count, /* Count of bytes for output */
+ offset, /* Offset of bytes for output */
+ temp; /* Temporary count */
+ int r, g, b; /* RGB deltas for mode 10 compression */
+
+
+ switch (type)
+ {
+ default :
+ /*
+ * Do no compression; with a mode-0 only printer, we can compress blank
+ * lines...
+ */
+
+ line_ptr = line;
+
+ if (cupsCheckBytes(line, length))
+ line_end = line; /* Blank line */
+ else
+ line_end = line + length; /* Non-blank line */
+ break;
+
+ case 1 :
+ /*
+ * Do run-length encoding...
+ */
+
+ line_end = line + length;
+ for (line_ptr = line, comp_ptr = CompBuffer;
+ line_ptr < line_end;
+ comp_ptr += 2, line_ptr += count)
+ {
+ for (count = 1;
+ (line_ptr + count) < line_end &&
+ line_ptr[0] == line_ptr[count] &&
+ count < 256;
+ count ++);
+
+ comp_ptr[0] = count - 1;
+ comp_ptr[1] = line_ptr[0];
+ }
+
+ line_ptr = CompBuffer;
+ line_end = comp_ptr;
+ break;
+
+ case 2 :
+ /*
+ * Do TIFF pack-bits encoding...
+ */
+
+ line_ptr = line;
+ line_end = line + length;
+ comp_ptr = CompBuffer;
+
+ while (line_ptr < line_end)
+ {
+ if ((line_ptr + 1) >= line_end)
+ {
+ /*
+ * Single byte on the end...
+ */
+
+ *comp_ptr++ = 0x00;
+ *comp_ptr++ = *line_ptr++;
+ }
+ else if (line_ptr[0] == line_ptr[1])
+ {
+ /*
+ * Repeated sequence...
+ */
+
+ line_ptr ++;
+ count = 2;
+
+ while (line_ptr < (line_end - 1) &&
+ line_ptr[0] == line_ptr[1] &&
+ count < 127)
+ {
+ line_ptr ++;
+ count ++;
+ }
+
+ *comp_ptr++ = 257 - count;
+ *comp_ptr++ = *line_ptr++;
+ }
+ else
+ {
+ /*
+ * Non-repeated sequence...
+ */
+
+ start = line_ptr;
+ line_ptr ++;
+ count = 1;
+
+ while (line_ptr < (line_end - 1) &&
+ line_ptr[0] != line_ptr[1] &&
+ count < 127)
+ {
+ line_ptr ++;
+ count ++;
+ }
+
+ *comp_ptr++ = count - 1;
+
+ memcpy(comp_ptr, start, count);
+ comp_ptr += count;
+ }
+ }
+
+ line_ptr = CompBuffer;
+ line_end = comp_ptr;
+ break;
+
+ case 3 :
+ /*
+ * Do delta-row compression...
+ */
+
+ line_ptr = line;
+ line_end = line + length;
+
+ comp_ptr = CompBuffer;
+ seed = SeedBuffer + plane * length;
+
+ while (line_ptr < line_end)
+ {
+ /*
+ * Find the next non-matching sequence...
+ */
+
+ start = line_ptr;
+
+ if (SeedInvalid)
+ {
+ /*
+ * The seed buffer is invalid, so do the next 8 bytes, max...
+ */
+
+ offset = 0;
+
+ if ((count = line_end - line_ptr) > 8)
+ count = 8;
+
+ line_ptr += count;
+ }
+ else
+ {
+ /*
+ * The seed buffer is valid, so compare against it...
+ */
+
+ while (*line_ptr == *seed &&
+ line_ptr < line_end)
+ {
+ line_ptr ++;
+ seed ++;
+ }
+
+ if (line_ptr == line_end)
+ break;
+
+ offset = line_ptr - start;
+
+ /*
+ * Find up to 8 non-matching bytes...
+ */
+
+ start = line_ptr;
+ count = 0;
+ while (*line_ptr != *seed &&
+ line_ptr < line_end &&
+ count < 8)
+ {
+ line_ptr ++;
+ seed ++;
+ count ++;
+ }
+ }
+
+ /*
+ * Place mode 3 compression data in the buffer; see HP manuals
+ * for details...
+ */
+
+ if (offset >= 31)
+ {
+ /*
+ * Output multi-byte offset...
+ */
+
+ *comp_ptr++ = ((count - 1) << 5) | 31;
+
+ offset -= 31;
+ while (offset >= 255)
+ {
+ *comp_ptr++ = 255;
+ offset -= 255;
+ }
+
+ *comp_ptr++ = offset;
+ }
+ else
+ {
+ /*
+ * Output single-byte offset...
+ */
+
+ *comp_ptr++ = ((count - 1) << 5) | offset;
+ }
+
+ memcpy(comp_ptr, start, count);
+ comp_ptr += count;
+ }
+
+ line_ptr = CompBuffer;
+ line_end = comp_ptr;
+
+ memcpy(SeedBuffer + plane * length, line, length);
+ break;
+
+ case 10 :
+ /*
+ * Mode 10 "near lossless" RGB compression...
+ */
+
+ line_ptr = line;
+ line_end = line + length;
+
+ comp_ptr = CompBuffer;
+ seed = SeedBuffer;
+
+ if (PrinterPlanes == 1)
+ {
+ /*
+ * Do grayscale compression to RGB...
+ */
+
+ while (line_ptr < line_end)
+ {
+ /*
+ * Find the next non-matching sequence...
+ */
+
+ start = line_ptr;
+ while (line_ptr < line_end &&
+ *line_ptr == *seed)
+ {
+ line_ptr ++;
+ seed ++;
+ }
+
+ if (line_ptr == line_end)
+ break;
+
+ offset = line_ptr - start;
+
+ /*
+ * Find non-matching grayscale pixels...
+ */
+
+ start = line_ptr;
+ while (line_ptr < line_end &&
+ *line_ptr != *seed)
+ {
+ line_ptr ++;
+ seed ++;
+ }
+
+ count = line_ptr - start;
+
+#if 0
+ fprintf(stderr, "DEBUG: offset=%d, count=%d, comp_ptr=%p(%d of %d)...\n",
+ offset, count, comp_ptr, comp_ptr - CompBuffer,
+ BytesPerLine * 5);
+#endif /* 0 */
+
+ /*
+ * Place mode 10 compression data in the buffer; each sequence
+ * starts with a command byte that looks like:
+ *
+ * CMD SRC SRC OFF OFF CNT CNT CNT
+ *
+ * For the purpose of this driver, CMD and SRC are always 0.
+ *
+ * If the offset >= 3 then additional offset bytes follow the
+ * first command byte, each byte == 255 until the last one.
+ *
+ * If the count >= 7, then additional count bytes follow each
+ * group of pixels, each byte == 255 until the last one.
+ *
+ * The offset and count are in RGB tuples (not bytes, as for
+ * Mode 3 and 9)...
+ */
+
+ if (offset >= 3)
+ {
+ /*
+ * Output multi-byte offset...
+ */
+
+ if (count > 7)
+ *comp_ptr++ = 0x1f;
+ else
+ *comp_ptr++ = 0x18 | (count - 1);
+
+ offset -= 3;
+ while (offset >= 255)
+ {
+ *comp_ptr++ = 255;
+ offset -= 255;
+ }
+
+ *comp_ptr++ = offset;
+ }
+ else
+ {
+ /*
+ * Output single-byte offset...
+ */
+
+ if (count > 7)
+ *comp_ptr++ = (offset << 3) | 0x07;
+ else
+ *comp_ptr++ = (offset << 3) | (count - 1);
+ }
+
+ temp = count - 8;
+ seed -= count;
+
+ while (count > 0)
+ {
+ if (count <= temp)
+ {
+ /*
+ * This is exceedingly lame... The replacement counts
+ * are intermingled with the data...
+ */
+
+ if (temp >= 255)
+ *comp_ptr++ = 255;
+ else
+ *comp_ptr++ = temp;
+
+ temp -= 255;
+ }
+
+ /*
+ * Get difference between current and see pixels...
+ */
+
+ r = *start - *seed;
+ g = r;
+ b = ((*start & 0xfe) - (*seed & 0xfe)) / 2;
+
+ if (r < -16 || r > 15 || g < -16 || g > 15 || b < -16 || b > 15)
+ {
+ /*
+ * Pack 24-bit RGB into 23 bits... Lame...
+ */
+
+ g = *start;
+
+ *comp_ptr++ = g >> 1;
+
+ if (g & 1)
+ *comp_ptr++ = 0x80 | (g >> 1);
+ else
+ *comp_ptr++ = g >> 1;
+
+ if (g & 1)
+ *comp_ptr++ = 0x80 | (g >> 1);
+ else
+ *comp_ptr++ = g >> 1;
+ }
+ else
+ {
+ /*
+ * Pack 15-bit RGB difference...
+ */
+
+ *comp_ptr++ = 0x80 | ((r << 2) & 0x7c) | ((g >> 3) & 0x03);
+ *comp_ptr++ = ((g << 5) & 0xe0) | (b & 0x1f);
+ }
+
+ count --;
+ start ++;
+ seed ++;
+ }
+
+ /*
+ * Make sure we have the ending count if the replacement count
+ * was exactly 8 + 255n...
+ */
+
+ if (temp == 0)
+ *comp_ptr++ = 0;
+ }
+ }
+ else
+ {
+ /*
+ * Do RGB compression...
+ */
+
+ while (line_ptr < line_end)
+ {
+ /*
+ * Find the next non-matching sequence...
+ */
+
+ start = line_ptr;
+ while (line_ptr[0] == seed[0] &&
+ line_ptr[1] == seed[1] &&
+ line_ptr[2] == seed[2] &&
+ (line_ptr + 2) < line_end)
+ {
+ line_ptr += 3;
+ seed += 3;
+ }
+
+ if (line_ptr == line_end)
+ break;
+
+ offset = (line_ptr - start) / 3;
+
+ /*
+ * Find non-matching RGB tuples...
+ */
+
+ start = line_ptr;
+ while ((line_ptr[0] != seed[0] ||
+ line_ptr[1] != seed[1] ||
+ line_ptr[2] != seed[2]) &&
+ (line_ptr + 2) < line_end)
+ {
+ line_ptr += 3;
+ seed += 3;
+ }
+
+ count = (line_ptr - start) / 3;
+
+ /*
+ * Place mode 10 compression data in the buffer; each sequence
+ * starts with a command byte that looks like:
+ *
+ * CMD SRC SRC OFF OFF CNT CNT CNT
+ *
+ * For the purpose of this driver, CMD and SRC are always 0.
+ *
+ * If the offset >= 3 then additional offset bytes follow the
+ * first command byte, each byte == 255 until the last one.
+ *
+ * If the count >= 7, then additional count bytes follow each
+ * group of pixels, each byte == 255 until the last one.
+ *
+ * The offset and count are in RGB tuples (not bytes, as for
+ * Mode 3 and 9)...
+ */
+
+ if (offset >= 3)
+ {
+ /*
+ * Output multi-byte offset...
+ */
+
+ if (count > 7)
+ *comp_ptr++ = 0x1f;
+ else
+ *comp_ptr++ = 0x18 | (count - 1);
+
+ offset -= 3;
+ while (offset >= 255)
+ {
+ *comp_ptr++ = 255;
+ offset -= 255;
+ }
+
+ *comp_ptr++ = offset;
+ }
+ else
+ {
+ /*
+ * Output single-byte offset...
+ */
+
+ if (count > 7)
+ *comp_ptr++ = (offset << 3) | 0x07;
+ else
+ *comp_ptr++ = (offset << 3) | (count - 1);
+ }
+
+ temp = count - 8;
+ seed -= count * 3;
+
+ while (count > 0)
+ {
+ if (count <= temp)
+ {
+ /*
+ * This is exceedingly lame... The replacement counts
+ * are intermingled with the data...
+ */
+
+ if (temp >= 255)
+ *comp_ptr++ = 255;
+ else
+ *comp_ptr++ = temp;
+
+ temp -= 255;
+ }
+
+ /*
+ * Get difference between current and see pixels...
+ */
+
+ r = start[0] - seed[0];
+ g = start[1] - seed[1];
+ b = ((start[2] & 0xfe) - (seed[2] & 0xfe)) / 2;
+
+ if (r < -16 || r > 15 || g < -16 || g > 15 || b < -16 || b > 15)
+ {
+ /*
+ * Pack 24-bit RGB into 23 bits... Lame...
+ */
+
+ *comp_ptr++ = start[0] >> 1;
+
+ if (start[0] & 1)
+ *comp_ptr++ = 0x80 | (start[1] >> 1);
+ else
+ *comp_ptr++ = start[1] >> 1;
+
+ if (start[1] & 1)
+ *comp_ptr++ = 0x80 | (start[2] >> 1);
+ else
+ *comp_ptr++ = start[2] >> 1;
+ }
+ else
+ {
+ /*
+ * Pack 15-bit RGB difference...
+ */
+
+ *comp_ptr++ = 0x80 | ((r << 2) & 0x7c) | ((g >> 3) & 0x03);
+ *comp_ptr++ = ((g << 5) & 0xe0) | (b & 0x1f);
+ }
+
+ count --;
+ start += 3;
+ seed += 3;
+ }
+
+ /*
+ * Make sure we have the ending count if the replacement count
+ * was exactly 8 + 255n...
+ */
+
+ if (temp == 0)
+ *comp_ptr++ = 0;
+ }
+ }
+
+ line_ptr = CompBuffer;
+ line_end = comp_ptr;
+
+ memcpy(SeedBuffer, line, length);
+ break;
+ }
+
+ /*
+ * Set the length of the data and write a raster plane...
+ */
+
+ printf("\033*b%d%c", (int)(line_end - line_ptr), pend);
+ cupsWritePrintData(line_ptr, line_end - line_ptr);
+}
+
+
+/*
+ * 'OutputLine()' - Output the specified number of lines of graphics.
+ */
+
+void
+OutputLine(ppd_file_t *ppd, /* I - PPD file */
+ cups_page_header2_t *header) /* I - Page header */
+{
+ int i, j; /* Looping vars */
+ int plane; /* Current plane */
+ unsigned char bit; /* Current bit */
+ int bytes; /* Number of bytes/plane */
+ int width; /* Width of line in pixels */
+ const int *order; /* Order to use */
+ unsigned char *ptr; /* Pointer into buffer */
+
+
+ /*
+ * Output whitespace as needed...
+ */
+
+ if (OutputFeed > 0)
+ {
+ if (header->cupsCompression < 3)
+ {
+ /*
+ * Send blank raster lines...
+ */
+
+ while (OutputFeed > 0)
+ {
+ printf("\033*b0W");
+ OutputFeed --;
+ }
+ }
+ else
+ {
+ /*
+ * Send Y offset command and invalidate the seed buffer...
+ */
+
+ printf("\033*b%dY", OutputFeed);
+ OutputFeed = 0;
+ SeedInvalid = 1;
+ }
+ }
+
+ /*
+ * Write bitmap data as needed...
+ */
+
+ switch (OutputMode)
+ {
+ case OUTPUT_BITMAP : /* Send 1-bit bitmap data... */
+ order = ColorOrders[PrinterPlanes - 1];
+ bytes = header->cupsBytesPerLine / PrinterPlanes;
+
+ for (i = 0; i < PrinterPlanes; i ++)
+ {
+ plane = order[i];
+
+ CompressData(PixelBuffer + i * bytes, bytes, plane,
+ (i < (PrinterPlanes - 1)) ? 'V' : 'W',
+ header->cupsCompression);
+ }
+ break;
+
+ case OUTPUT_INVERBIT : /* Send inverted 1-bit bitmap data... */
+ order = ColorOrders[PrinterPlanes - 1];
+ bytes = header->cupsBytesPerLine / PrinterPlanes;
+
+ for (i = header->cupsBytesPerLine, ptr = PixelBuffer;
+ i > 0;
+ i --, ptr ++)
+ *ptr = ~*ptr;
+
+ for (i = 0; i < PrinterPlanes; i ++)
+ {
+ plane = order[i];
+
+ CompressData(PixelBuffer + i * bytes, bytes, plane,
+ (i < (PrinterPlanes - 1)) ? 'V' : 'W',
+ header->cupsCompression);
+ }
+ break;
+
+ case OUTPUT_RGB : /* Send 24-bit RGB data... */
+ if (PrinterPlanes == 1 && !BlankValue)
+ {
+ /*
+ * Invert black to grayscale...
+ */
+
+ for (i = header->cupsBytesPerLine, ptr = PixelBuffer;
+ i > 0;
+ i --, ptr ++)
+ *ptr = ~*ptr;
+ }
+
+ /*
+ * Compress the output...
+ */
+
+ CompressData(PixelBuffer, header->cupsBytesPerLine, 0, 'W',
+ header->cupsCompression);
+ break;
+
+ default :
+ order = ColorOrders[PrinterPlanes - 1];
+ width = header->cupsWidth;
+
+ for (i = 0, j = 0; i < PrinterPlanes; i ++)
+ {
+ plane = order[i];
+ bytes = DotBufferSizes[plane] / DotBits[plane];
+
+ for (bit = 1, ptr = DotBuffers[plane];
+ bit <= DotBits[plane];
+ bit <<= 1, ptr += bytes, j ++)
+ {
+ cupsPackHorizontalBit(OutputBuffers[plane], DotBuffers[plane],
+ width, 0, bit);
+ CompressData(ptr, bytes, j,
+ i == (PrinterPlanes - 1) &&
+ bit == DotBits[plane] ? 'W' : 'V',
+ header->cupsCompression);
+ }
+ }
+ break;
+ }
+
+ /*
+ * The seed buffer, if any, now should contain valid data...
+ */
+
+ SeedInvalid = 0;
+}
+
+
+/*
+ * 'ReadLine()' - Read graphics from the page stream.
+ */
+
+int /* O - Number of lines (0 if blank) */
+ReadLine(cups_raster_t *ras, /* I - Raster stream */
+ cups_page_header2_t *header) /* I - Page header */
+{
+ int plane, /* Current color plane */
+ width; /* Width of line */
+
+
+ /*
+ * Read raster data...
+ */
+
+ cupsRasterReadPixels(ras, PixelBuffer, header->cupsBytesPerLine);
+
+ /*
+ * See if it is blank; if so, return right away...
+ */
+
+ if (cupsCheckValue(PixelBuffer, header->cupsBytesPerLine, BlankValue))
+ return (0);
+
+ /*
+ * If we aren't dithering, return immediately...
+ */
+
+ if (OutputMode != OUTPUT_DITHERED)
+ return (1);
+
+ /*
+ * Perform the color separation...
+ */
+
+ width = header->cupsWidth;
+
+ switch (header->cupsColorSpace)
+ {
+ case CUPS_CSPACE_W :
+ if (RGB)
+ {
+ cupsRGBDoGray(RGB, PixelBuffer, CMYKBuffer, width);
+
+ if (RGB->num_channels == 1)
+ cupsCMYKDoBlack(CMYK, CMYKBuffer, InputBuffer, width);
+ else
+ cupsCMYKDoCMYK(CMYK, CMYKBuffer, InputBuffer, width);
+ }
+ else
+ cupsCMYKDoGray(CMYK, PixelBuffer, InputBuffer, width);
+ break;
+
+ case CUPS_CSPACE_K :
+ cupsCMYKDoBlack(CMYK, PixelBuffer, InputBuffer, width);
+ break;
+
+ default :
+ case CUPS_CSPACE_RGB :
+ if (RGB)
+ {
+ cupsRGBDoRGB(RGB, PixelBuffer, CMYKBuffer, width);
+
+ if (RGB->num_channels == 1)
+ cupsCMYKDoBlack(CMYK, CMYKBuffer, InputBuffer, width);
+ else
+ cupsCMYKDoCMYK(CMYK, CMYKBuffer, InputBuffer, width);
+ }
+ else
+ cupsCMYKDoRGB(CMYK, PixelBuffer, InputBuffer, width);
+ break;
+
+ case CUPS_CSPACE_CMYK :
+ cupsCMYKDoCMYK(CMYK, PixelBuffer, InputBuffer, width);
+ break;
+ }
+
+ /*
+ * Dither the pixels...
+ */
+
+ for (plane = 0; plane < PrinterPlanes; plane ++)
+ cupsDitherLine(DitherStates[plane], DitherLuts[plane], InputBuffer + plane,
+ PrinterPlanes, OutputBuffers[plane]);
+
+ /*
+ * Return 1 to indicate that we have non-blank output...
+ */
+
+ return (1);
+}
+
+
+/*
+ * 'main()' - Main entry and processing of driver.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int fd; /* File descriptor */
+ cups_raster_t *ras; /* Raster stream for printing */
+ cups_page_header2_t header; /* Page header from file */
+ int y; /* Current line */
+ ppd_file_t *ppd; /* PPD file */
+ int job_id; /* Job ID */
+ int num_options; /* Number of options */
+ cups_option_t *options; /* Options */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc < 6 || argc > 7)
+ {
+ fprintf(stderr, "Usage: %s job-id user title copies options [file]\n",
+ "rastertopclx");
+ return (1);
+ }
+
+ num_options = cupsParseOptions(argv[5], 0, &options);
+
+ /*
+ * Open the PPD file...
+ */
+
+ ppd = ppdOpenFile(getenv("PPD"));
+
+ if (ppd)
+ {
+ ppdMarkDefaults(ppd);
+ cupsMarkOptions(ppd, num_options, options);
+ }
+ else
+ {
+ ppd_status_t status; /* PPD error */
+ int linenum; /* Line number */
+
+ fputs("DEBUG: The PPD file could not be opened.\n", stderr);
+
+ status = ppdLastError(&linenum);
+
+ fprintf(stderr, "DEBUG: %s on line %d.\n", ppdErrorString(status), linenum);
+ }
+
+ /*
+ * Open the page stream...
+ */
+
+ if (argc == 7)
+ {
+ if ((fd = open(argv[6], O_RDONLY)) == -1)
+ {
+ perror("ERROR: Unable to open raster file");
+ return (1);
+ }
+ }
+ else
+ fd = 0;
+
+ ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
+
+ /*
+ * Register a signal handler to eject the current page if the
+ * job is cancelled.
+ */
+
+ Canceled = 0;
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, CancelJob);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = CancelJob;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, CancelJob);
+#endif /* HAVE_SIGSET */
+
+ /*
+ * Process pages as needed...
+ */
+
+ job_id = atoi(argv[1]);
+
+ Page = 0;
+
+ while (cupsRasterReadHeader2(ras, &header))
+ {
+ /*
+ * Write a status message with the page number and number of copies.
+ */
+
+ if (Canceled)
+ break;
+
+ Page ++;
+
+ fprintf(stderr, "PAGE: %d %d\n", Page, header.NumCopies);
+ fprintf(stderr, "INFO: Starting page %d.\n", Page);
+
+ StartPage(ppd, &header, atoi(argv[1]), argv[2], argv[3],
+ num_options, options);
+
+ for (y = 0; y < (int)header.cupsHeight; y ++)
+ {
+ /*
+ * Let the user know how far we have progressed...
+ */
+
+ if (Canceled)
+ break;
+
+ if ((y & 127) == 0)
+ {
+ fprintf(stderr, "INFO: Printing page %d, %d%% complete.\n",
+ Page, 100 * y / header.cupsHeight);
+ fprintf(stderr, "ATTR: job-media-progress=%d\n",
+ 100 * y / header.cupsHeight);
+ }
+
+ /*
+ * Read and write a line of graphics or whitespace...
+ */
+
+ if (ReadLine(ras, &header))
+ OutputLine(ppd, &header);
+ else
+ OutputFeed ++;
+ }
+
+ /*
+ * Eject the page...
+ */
+
+ fprintf(stderr, "INFO: Finished page %d.\n", Page);
+
+ EndPage(ppd, &header);
+
+ if (Canceled)
+ break;
+ }
+
+ Shutdown(ppd, job_id, argv[2], argv[3], num_options, options);
+
+ cupsFreeOptions(num_options, options);
+
+ cupsRasterClose(ras);
+
+ if (fd != 0)
+ close(fd);
+
+ return (Page == 0);
+}
+
diff --git a/filter/rastertopdf.cpp b/filter/rastertopdf.cpp
new file mode 100644
index 000000000..3d3fda1f0
--- /dev/null
+++ b/filter/rastertopdf.cpp
@@ -0,0 +1,1533 @@
+/**
+ * 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/>.
+ *
+ * @brief Convert PWG Raster to a PDF/PCLm file
+ * @file rastertopdf.cpp
+ * @author Neil 'Superna' Armstrong <superna9999@gmail.com> (C) 2010
+ * @author Tobias Hoffmann <smilingthax@gmail.com> (c) 2012
+ * @author Till Kamppeter <till.kamppeter@gmail.com> (c) 2014
+ * @author Sahil Arora <sahilarora.535@gmail.com> (c) 2017
+ */
+
+#include <config.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits>
+#include <signal.h>
+#include <cups/cups.h>
+#include <cups/raster.h>
+#include <cupsfilters/colormanager.h>
+#include <cupsfilters/image.h>
+
+#include <arpa/inet.h> // ntohl
+
+#include <vector>
+#include <qpdf/QPDF.hh>
+#include <qpdf/QPDFWriter.hh>
+#include <qpdf/QUtil.hh>
+
+#include <qpdf/Pl_Flate.hh>
+#include <qpdf/Pl_Buffer.hh>
+#ifdef QPDF_HAVE_PCLM
+#include <qpdf/Pl_RunLength.hh>
+#include <qpdf/Pl_DCT.hh>
+#endif
+
+#ifdef USE_LCMS1
+#include <lcms.h>
+#define cmsColorSpaceSignature icColorSpaceSignature
+#define cmsSetLogErrorHandler cmsSetErrorHandler
+#define cmsSigXYZData icSigXYZData
+#define cmsSigLuvData icSigLuvData
+#define cmsSigLabData icSigLabData
+#define cmsSigYCbCrData icSigYCbCrData
+#define cmsSigYxyData icSigYxyData
+#define cmsSigRgbData icSigRgbData
+#define cmsSigHsvData icSigHsvData
+#define cmsSigHlsData icSigHlsData
+#define cmsSigCmyData icSigCmyData
+#define cmsSig3colorData icSig3colorData
+#define cmsSigGrayData icSigGrayData
+#define cmsSigCmykData icSigCmykData
+#define cmsSig4colorData icSig4colorData
+#define cmsSig2colorData icSig2colorData
+#define cmsSig5colorData icSig5colorData
+#define cmsSig6colorData icSig6colorData
+#define cmsSig7colorData icSig7colorData
+#define cmsSig8colorData icSig8colorData
+#define cmsSig9colorData icSig9colorData
+#define cmsSig10colorData icSig10colorData
+#define cmsSig11colorData icSig11colorData
+#define cmsSig12colorData icSig12colorData
+#define cmsSig13colorData icSig13colorData
+#define cmsSig14colorData icSig14colorData
+#define cmsSig15colorData icSig15colorData
+#define cmsSaveProfileToMem _cmsSaveProfileToMem
+#else
+#include <lcms2.h>
+#endif
+
+#define DEFAULT_PDF_UNIT 72 // 1/72 inch
+
+#define PROGRAM "rastertopdf"
+
+#define dprintf(format, ...) fprintf(stderr, "DEBUG2: (" PROGRAM ") " format, __VA_ARGS__)
+
+#define iprintf(format, ...) fprintf(stderr, "INFO: (" PROGRAM ") " format, __VA_ARGS__)
+
+typedef enum {
+ OUTPUT_FORMAT_PDF,
+ OUTPUT_FORMAT_PCLM
+} OutFormatType;
+
+// Compression method for providing data to PCLm Streams.
+typedef enum {
+ DCT_DECODE = 0,
+ FLATE_DECODE,
+ RLE_DECODE
+} CompressionMethod;
+
+// Color conversion function
+typedef unsigned char *(*convertFunction)(unsigned char *src,
+ unsigned char *dst, unsigned int pixels);
+
+// Bit conversion function
+typedef unsigned char *(*bitFunction)(unsigned char *src,
+ unsigned char *dst, unsigned int pixels);
+
+// PDF color conversion function
+typedef void (*pdfConvertFunction)(struct pdf_info * info);
+
+cmsHPROFILE colorProfile = NULL; // ICC Profile to be applied to PDF
+int cm_disabled = 0; // Flag rasied if color management is disabled
+cm_calibration_t cm_calibrate; // Status of CUPS color management ("on" or "off")
+convertFunction conversion_function; // Raster color conversion function
+bitFunction bit_function; // Raster bit function
+
+
+#ifdef USE_LCMS1
+static int lcmsErrorHandler(int ErrorCode, const char *ErrorText)
+{
+ fprintf(stderr, "ERROR: %s\n",ErrorText);
+ return 1;
+}
+#else
+static void lcmsErrorHandler(cmsContext contextId, cmsUInt32Number ErrorCode,
+ const char *ErrorText)
+{
+ fprintf(stderr, "ERROR: %s\n",ErrorText);
+}
+#endif
+
+
+
+// Bit conversion functions
+
+unsigned char *invertBits(unsigned char *src, unsigned char *dst, unsigned int pixels)
+{
+ unsigned int i;
+
+ // Invert black to grayscale...
+ for (i = pixels, dst = src; i > 0; i --, dst ++)
+ *dst = ~*dst;
+
+ return dst;
+}
+
+unsigned char *noBitConversion(unsigned char *src, unsigned char *dst, unsigned int pixels)
+{
+ return src;
+}
+
+// Color conversion functions
+
+unsigned char *rgbToCmyk(unsigned char *src, unsigned char *dst, unsigned int pixels)
+{
+ cupsImageRGBToCMYK(src,dst,pixels);
+ return dst;
+}
+unsigned char *whiteToCmyk(unsigned char *src, unsigned char *dst, unsigned int pixels)
+{
+ cupsImageWhiteToCMYK(src,dst,pixels);
+ return dst;
+}
+
+unsigned char *cmykToRgb(unsigned char *src, unsigned char *dst, unsigned int pixels)
+{
+ cupsImageCMYKToRGB(src,dst,pixels);
+ return dst;
+}
+
+unsigned char *whiteToRgb(unsigned char *src, unsigned char *dst, unsigned int pixels)
+{
+ cupsImageWhiteToRGB(src,dst,pixels);
+ return dst;
+}
+
+unsigned char *rgbToWhite(unsigned char *src, unsigned char *dst, unsigned int pixels)
+{
+ cupsImageRGBToWhite(src,dst,pixels);
+ return dst;
+}
+
+unsigned char *cmykToWhite(unsigned char *src, unsigned char *dst, unsigned int pixels)
+{
+ cupsImageCMYKToWhite(src,dst,pixels);
+ return dst;
+}
+
+unsigned char *noColorConversion(unsigned char *src,
+ unsigned char *dst, unsigned int pixels)
+{
+ return src;
+}
+
+/**
+ * 'split_strings()' - Split a string to a vector of strings given some delimiters
+ * O - std::vector of std::string after splitting
+ * I - input string to be split
+ * I - string containing delimiters
+ */
+static std::vector<std::string>
+split_strings(std::string const &str, std::string delimiters = ",")
+{
+ std::vector<std::string> vec(0);
+ std::string value = "";
+ bool push_flag = false;
+
+ for (size_t i = 0; i < str.size(); i ++)
+ {
+ if (push_flag && !(value.empty()))
+ {
+ vec.push_back(value);
+ push_flag = false;
+ value.clear();
+ }
+
+ if (delimiters.find(str[i]) != std::string::npos)
+ push_flag = true;
+ else
+ value += str[i];
+ }
+ if (!value.empty())
+ vec.push_back(value);
+ return vec;
+}
+
+/**
+ * 'num_digits()' - Calculates the number of digits in an integer
+ * O - number of digits in the input integer
+ * I - the integer whose digits needs to be calculated
+ */
+int num_digits(int n)
+{
+ if (n == 0) return 1;
+ int digits = 0;
+ while (n)
+ {
+ ++digits;
+ n /= 10;
+ }
+ return digits;
+}
+
+/**
+ * 'int_to_fwstring()' - Convert a number to fixed width string by padding with zeroes
+ * O - converted string
+ * I - the integee which needs to be converted to string
+ * I - width of string required
+ */
+std::string int_to_fwstring(int n, int width)
+{
+ int num_zeroes = width - num_digits(n);
+ if (num_zeroes < 0)
+ num_zeroes = 0;
+ return std::string(num_zeroes, '0') + QUtil::int_to_string(n);
+}
+
+void die(const char * str)
+{
+ fprintf(stderr, "ERROR: (" PROGRAM ") %s\n", str);
+ exit(1);
+}
+
+
+//------------- PDF ---------------
+
+struct pdf_info
+{
+ pdf_info()
+ : pagecount(0),
+ width(0),height(0),
+ line_bytes(0),
+ bpp(0), bpc(0),
+ pclm_num_strips(0),
+ pclm_strip_height_preferred(16), /* default strip height */
+ pclm_strip_height(0),
+ pclm_strip_height_supported(1, 16),
+ pclm_compression_method_preferred(0),
+ pclm_source_resolution_supported(0),
+ pclm_source_resolution_default(""),
+ pclm_raster_back_side(""),
+ pclm_strip_data(0),
+ render_intent(""),
+ color_space(CUPS_CSPACE_K),
+ page_width(0),page_height(0),
+ outformat(OUTPUT_FORMAT_PDF)
+ {
+ }
+
+ QPDF pdf;
+ QPDFObjectHandle page;
+ unsigned pagecount;
+ unsigned width;
+ unsigned height;
+ unsigned line_bytes;
+ unsigned bpp;
+ unsigned bpc;
+ unsigned pclm_num_strips;
+ unsigned pclm_strip_height_preferred;
+ std::vector<unsigned> pclm_strip_height;
+ std::vector<unsigned> pclm_strip_height_supported;
+ std::vector<CompressionMethod> pclm_compression_method_preferred;
+ std::vector<std::string> pclm_source_resolution_supported;
+ std::string pclm_source_resolution_default;
+ std::string pclm_raster_back_side;
+ std::vector< PointerHolder<Buffer> > pclm_strip_data;
+ std::string render_intent;
+ cups_cspace_t color_space;
+ PointerHolder<Buffer> page_data;
+ double page_width,page_height;
+ OutFormatType outformat;
+};
+
+int create_pdf_file(struct pdf_info * info, const OutFormatType & outformat)
+{
+ try {
+ info->pdf.emptyPDF();
+ info->outformat = outformat;
+ } catch (...) {
+ return 1;
+ }
+ return 0;
+}
+
+QPDFObjectHandle makeRealBox(double x1, double y1, double x2, double y2)
+{
+ QPDFObjectHandle ret=QPDFObjectHandle::newArray();
+ ret.appendItem(QPDFObjectHandle::newReal(x1));
+ ret.appendItem(QPDFObjectHandle::newReal(y1));
+ ret.appendItem(QPDFObjectHandle::newReal(x2));
+ ret.appendItem(QPDFObjectHandle::newReal(y2));
+ return ret;
+}
+
+QPDFObjectHandle makeIntegerBox(int x1, int y1, int x2, int y2)
+{
+ QPDFObjectHandle ret = QPDFObjectHandle::newArray();
+ ret.appendItem(QPDFObjectHandle::newInteger(x1));
+ ret.appendItem(QPDFObjectHandle::newInteger(y1));
+ ret.appendItem(QPDFObjectHandle::newInteger(x2));
+ ret.appendItem(QPDFObjectHandle::newInteger(y2));
+ return ret;
+}
+
+
+
+
+// PDF color conversion functons...
+
+void modify_pdf_color(struct pdf_info * info, int bpp, int bpc, convertFunction fn)
+{
+ unsigned old_bpp = info->bpp;
+ unsigned old_bpc = info->bpc;
+ double old_ncolor = old_bpp/old_bpc;
+
+ unsigned old_line_bytes = info->line_bytes;
+
+ double new_ncolor = (bpp/bpc);
+
+ info->line_bytes = (unsigned)old_line_bytes*(new_ncolor/old_ncolor);
+ info->bpp = bpp;
+ info->bpc = bpc;
+ conversion_function = fn;
+
+ return;
+}
+
+void convertPdf_NoConversion(struct pdf_info * info)
+{
+ conversion_function = noColorConversion;
+ bit_function = noBitConversion;
+}
+
+void convertPdf_Cmyk8ToWhite8(struct pdf_info * info)
+{
+ modify_pdf_color(info, 8, 8, cmykToWhite);
+ bit_function = noBitConversion;
+}
+
+void convertPdf_Rgb8ToWhite8(struct pdf_info * info)
+{
+ modify_pdf_color(info, 8, 8, rgbToWhite);
+ bit_function = noBitConversion;
+}
+
+void convertPdf_Cmyk8ToRgb8(struct pdf_info * info)
+{
+ modify_pdf_color(info, 24, 8, cmykToRgb);
+ bit_function = noBitConversion;
+}
+
+void convertPdf_White8ToRgb8(struct pdf_info * info)
+{
+ modify_pdf_color(info, 24, 8, whiteToRgb);
+ bit_function = invertBits;
+}
+
+void convertPdf_Rgb8ToCmyk8(struct pdf_info * info)
+{
+ modify_pdf_color(info, 32, 8, rgbToCmyk);
+ bit_function = noBitConversion;
+}
+
+void convertPdf_White8ToCmyk8(struct pdf_info * info)
+{
+ modify_pdf_color(info, 32, 8, whiteToCmyk);
+ bit_function = invertBits;
+}
+
+void convertPdf_InvertColors(struct pdf_info * info)
+{
+ conversion_function = noColorConversion;
+ bit_function = invertBits;
+}
+
+
+#define PRE_COMPRESS
+
+// Create an '/ICCBased' array and embed a previously
+// set ICC Profile in the PDF
+QPDFObjectHandle embedIccProfile(QPDF &pdf)
+{
+ if (colorProfile == NULL) {
+ return QPDFObjectHandle::newNull();
+ }
+
+ // Return handler
+ QPDFObjectHandle ret;
+ // ICCBased array
+ QPDFObjectHandle array = QPDFObjectHandle::newArray();
+ // Profile stream dictionary
+ QPDFObjectHandle iccstream;
+
+ std::map<std::string,QPDFObjectHandle> dict;
+ std::map<std::string,QPDFObjectHandle> streamdict;
+ std::string n_value = "";
+ std::string alternate_cs = "";
+ PointerHolder<Buffer>ph;
+
+#ifdef USE_LCMS1
+ size_t profile_size;
+#else
+ unsigned int profile_size;
+#endif
+
+ cmsColorSpaceSignature css = cmsGetColorSpace(colorProfile);
+
+ // Write color component # for /ICCBased array in stream dictionary
+ switch(css){
+ case cmsSigGrayData:
+ n_value = "1";
+ alternate_cs = "/DeviceGray";
+ break;
+ case cmsSigRgbData:
+ n_value = "3";
+ alternate_cs = "/DeviceRGB";
+ break;
+ case cmsSigCmykData:
+ n_value = "4";
+ alternate_cs = "/DeviceCMYK";
+ break;
+ default:
+ fputs("DEBUG: Failed to embed ICC Profile.\n", stderr);
+ return QPDFObjectHandle::newNull();
+ }
+
+ streamdict["/Alternate"]=QPDFObjectHandle::newName(alternate_cs);
+ streamdict["/N"]=QPDFObjectHandle::newName(n_value);
+
+ // Read profile into memory
+ cmsSaveProfileToMem(colorProfile, NULL, &profile_size);
+ unsigned char *buff =
+ (unsigned char *)calloc(profile_size, sizeof(unsigned char));
+ cmsSaveProfileToMem(colorProfile, buff, &profile_size);
+
+ // Write ICC profile buffer into PDF
+ ph = new Buffer(buff, profile_size);
+ iccstream = QPDFObjectHandle::newStream(&pdf, ph);
+ iccstream.replaceDict(QPDFObjectHandle::newDictionary(streamdict));
+
+ array.appendItem(QPDFObjectHandle::newName("/ICCBased"));
+ array.appendItem(iccstream);
+
+ // Return a PDF object reference to an '/ICCBased' array
+ ret = pdf.makeIndirectObject(array);
+
+ free(buff);
+ fputs("DEBUG: ICC Profile embedded in PDF.\n", stderr);
+
+ return ret;
+}
+
+QPDFObjectHandle embedSrgbProfile(QPDF &pdf)
+{
+ QPDFObjectHandle iccbased_reference;
+
+ // Create an sRGB profile from lcms
+ colorProfile = cmsCreate_sRGBProfile();
+ // Embed it into the profile
+ iccbased_reference = embedIccProfile(pdf);
+
+ return iccbased_reference;
+}
+
+/*
+Calibration function for non-Lab PDF color spaces
+Requires white point data, and if available, gamma or matrix numbers.
+
+Output:
+ [/'color_space'
+ << /Gamma ['gamma[0]'...'gamma[n]']
+ /WhitePoint ['wp[0]' 'wp[1]' 'wp[2]']
+ /Matrix ['matrix[0]'...'matrix[n*n]']
+ >>
+ ]
+*/
+QPDFObjectHandle getCalibrationArray(const char * color_space, double wp[],
+ double gamma[], double matrix[], double bp[])
+{
+ // Check for invalid input
+ if ((!strcmp("/CalGray", color_space) && matrix != NULL) ||
+ wp == NULL)
+ return QPDFObjectHandle();
+
+ QPDFObjectHandle ret;
+ std::string csString = color_space;
+ std::string colorSpaceArrayString = "";
+
+ char gamma_str[128];
+ char bp_str[256];
+ char wp_str[256];
+ char matrix_str[512];
+
+
+ // Convert numbers into string data for /Gamma, /WhitePoint, and/or /Matrix
+
+
+ // WhitePoint
+ snprintf(wp_str, sizeof(wp_str), "/WhitePoint [%g %g %g]",
+ wp[0], wp[1], wp[2]);
+
+
+ // Gamma
+ if (!strcmp("/CalGray", color_space) && gamma != NULL)
+ snprintf(gamma_str, sizeof(gamma_str), "/Gamma %g",
+ gamma[0]);
+ else if (!strcmp("/CalRGB", color_space) && gamma != NULL)
+ snprintf(gamma_str, sizeof(gamma_str), "/Gamma [%g %g %g]",
+ gamma[0], gamma[1], gamma[2]);
+ else
+ gamma_str[0] = '\0';
+
+
+ // BlackPoint
+ if (bp != NULL)
+ snprintf(bp_str, sizeof(bp_str), "/BlackPoint [%g %g %g]",
+ bp[0], bp[1], bp[2]);
+ else
+ bp_str[0] = '\0';
+
+
+ // Matrix
+ if (!strcmp("/CalRGB", color_space) && matrix != NULL) {
+ snprintf(matrix_str, sizeof(matrix_str), "/Matrix [%g %g %g %g %g %g %g %g %g]",
+ matrix[0], matrix[1], matrix[2],
+ matrix[3], matrix[4], matrix[5],
+ matrix[6], matrix[7], matrix[8]);
+ } else
+ matrix_str[0] = '\0';
+
+
+ // Write array string...
+ colorSpaceArrayString = "[" + csString + " <<"
+ + gamma_str + " " + wp_str + " " + matrix_str + " " + bp_str
+ + " >>]";
+
+ ret = QPDFObjectHandle::parse(colorSpaceArrayString);
+
+ return ret;
+}
+
+QPDFObjectHandle getCalRGBArray(double wp[3], double gamma[3], double matrix[9], double bp[3])
+{
+ QPDFObjectHandle ret = getCalibrationArray("/CalRGB", wp, gamma, matrix, bp);
+ return ret;
+}
+
+QPDFObjectHandle getCalGrayArray(double wp[3], double gamma[1], double bp[3])
+{
+ QPDFObjectHandle ret = getCalibrationArray("/CalGray", wp, gamma, 0, bp);
+ return ret;
+}
+
+#ifdef QPDF_HAVE_PCLM
+/**
+ * 'makePclmStrips()' - return an std::vector of QPDFObjectHandle, each containing the
+ * stream data of the various strips which make up a PCLm page.
+ * O - std::vector of QPDFObjectHandle
+ * I - QPDF object
+ * I - number of strips per page
+ * I - std::vector of PointerHolder<Buffer> containing data for each strip
+ * I - strip width
+ * I - strip height
+ * I - color space
+ * I - bits per component
+ */
+std::vector<QPDFObjectHandle>
+makePclmStrips(QPDF &pdf, unsigned num_strips,
+ std::vector< PointerHolder<Buffer> > &strip_data,
+ std::vector<CompressionMethod> &compression_methods,
+ unsigned width, std::vector<unsigned>& strip_height, cups_cspace_t cs, unsigned bpc)
+{
+ std::vector<QPDFObjectHandle> ret(num_strips);
+ for (size_t i = 0; i < num_strips; i ++)
+ ret[i] = QPDFObjectHandle::newStream(&pdf);
+
+ // Strip stream dictionary
+ std::map<std::string,QPDFObjectHandle> dict;
+
+ dict["/Type"]=QPDFObjectHandle::newName("/XObject");
+ dict["/Subtype"]=QPDFObjectHandle::newName("/Image");
+ dict["/Width"]=QPDFObjectHandle::newInteger(width);
+ dict["/BitsPerComponent"]=QPDFObjectHandle::newInteger(bpc);
+
+ J_COLOR_SPACE color_space;
+ unsigned components;
+ /* Write "/ColorSpace" dictionary based on raster input */
+ switch(cs) {
+ case CUPS_CSPACE_K:
+ case CUPS_CSPACE_SW:
+ dict["/ColorSpace"]=QPDFObjectHandle::newName("/DeviceGray");
+ color_space = JCS_GRAYSCALE;
+ components = 1;
+ break;
+ case CUPS_CSPACE_RGB:
+ case CUPS_CSPACE_SRGB:
+ case CUPS_CSPACE_ADOBERGB:
+ dict["/ColorSpace"]=QPDFObjectHandle::newName("/DeviceRGB");
+ color_space = JCS_RGB;
+ components = 3;
+ break;
+ default:
+ fputs("DEBUG: Color space not supported.\n", stderr);
+ return std::vector<QPDFObjectHandle>(num_strips, QPDFObjectHandle());
+ }
+
+ // We deliver already compressed content (instead of letting QPDFWriter do it)
+ // to avoid using excessive memory. For that we first get preferred compression
+ // method to pre-compress content for strip streams.
+
+ // Use the compression method with highest priority of the available methods
+ // __________________
+ // Priority | Method
+ // ------------------
+ // 0 | DCT
+ // 1 | FLATE
+ // 2 | RLE
+ // ------------------
+ CompressionMethod compression = compression_methods.front();
+ for (std::vector<CompressionMethod>::iterator it = compression_methods.begin();
+ it != compression_methods.end(); ++it)
+ compression = compression > *it ? compression : *it;
+
+ // write compressed stream data
+ for (size_t i = 0; i < num_strips; i ++)
+ {
+ dict["/Height"]=QPDFObjectHandle::newInteger(strip_height[i]);
+ ret[i].replaceDict(QPDFObjectHandle::newDictionary(dict));
+ Pl_Buffer psink("psink");
+ if (compression == FLATE_DECODE)
+ {
+ Pl_Flate pflate("pflate", &psink, Pl_Flate::a_deflate);
+ pflate.write(strip_data[i]->getBuffer(), strip_data[i]->getSize());
+ pflate.finish();
+ ret[i].replaceStreamData(PointerHolder<Buffer>(psink.getBuffer()),
+ QPDFObjectHandle::newName("/FlateDecode"),QPDFObjectHandle::newNull());
+ }
+ else if (compression == RLE_DECODE)
+ {
+ Pl_RunLength prle("prle", &psink, Pl_RunLength::a_encode);
+ prle.write(strip_data[i]->getBuffer(),strip_data[i]->getSize());
+ prle.finish();
+ ret[i].replaceStreamData(PointerHolder<Buffer>(psink.getBuffer()),
+ QPDFObjectHandle::newName("/RunLengthDecode"),QPDFObjectHandle::newNull());
+ }
+ else if (compression == DCT_DECODE)
+ {
+ Pl_DCT pdct("pdct", &psink, width, strip_height[i], components, color_space);
+ pdct.write(strip_data[i]->getBuffer(),strip_data[i]->getSize());
+ pdct.finish();
+ ret[i].replaceStreamData(PointerHolder<Buffer>(psink.getBuffer()),
+ QPDFObjectHandle::newName("/DCTDecode"),QPDFObjectHandle::newNull());
+ }
+ }
+ return ret;
+}
+#endif
+
+QPDFObjectHandle makeImage(QPDF &pdf, PointerHolder<Buffer> page_data, unsigned width,
+ unsigned height, std::string render_intent, cups_cspace_t cs, unsigned bpc)
+{
+ QPDFObjectHandle ret = QPDFObjectHandle::newStream(&pdf);
+
+ QPDFObjectHandle icc_ref;
+
+ int use_blackpoint = 0;
+ std::map<std::string,QPDFObjectHandle> dict;
+
+ dict["/Type"]=QPDFObjectHandle::newName("/XObject");
+ dict["/Subtype"]=QPDFObjectHandle::newName("/Image");
+ dict["/Width"]=QPDFObjectHandle::newInteger(width);
+ dict["/Height"]=QPDFObjectHandle::newInteger(height);
+ dict["/BitsPerComponent"]=QPDFObjectHandle::newInteger(bpc);
+
+ if (!cm_disabled) {
+ // Write rendering intent into the PDF based on raster settings
+ if (render_intent == "Perceptual") {
+ dict["/Intent"]=QPDFObjectHandle::newName("/Perceptual");
+ } else if (render_intent == "Absolute") {
+ dict["/Intent"]=QPDFObjectHandle::newName("/AbsoluteColorimetric");
+ } else if (render_intent == "Relative") {
+ dict["/Intent"]=QPDFObjectHandle::newName("/RelativeColorimetric");
+ } else if (render_intent == "Saturation") {
+ dict["/Intent"]=QPDFObjectHandle::newName("/Saturation");
+ } else if (render_intent == "RelativeBpc") {
+ /* Enable blackpoint compensation */
+ dict["/Intent"]=QPDFObjectHandle::newName("/RelativeColorimetric");
+ use_blackpoint = 1;
+ }
+ }
+
+ /* Write "/ColorSpace" dictionary based on raster input */
+ if (colorProfile != NULL && !cm_disabled) {
+ icc_ref = embedIccProfile(pdf);
+
+ if (!icc_ref.isNull())
+ dict["/ColorSpace"]=icc_ref;
+ } else if (!cm_disabled) {
+ switch (cs) {
+ case CUPS_CSPACE_DEVICE1:
+ case CUPS_CSPACE_DEVICE2:
+ case CUPS_CSPACE_DEVICE3:
+ case CUPS_CSPACE_DEVICE4:
+ case CUPS_CSPACE_DEVICE5:
+ case CUPS_CSPACE_DEVICE6:
+ case CUPS_CSPACE_DEVICE7:
+ case CUPS_CSPACE_DEVICE8:
+ case CUPS_CSPACE_DEVICE9:
+ case CUPS_CSPACE_DEVICEA:
+ case CUPS_CSPACE_DEVICEB:
+ case CUPS_CSPACE_DEVICEC:
+ case CUPS_CSPACE_DEVICED:
+ case CUPS_CSPACE_DEVICEE:
+ case CUPS_CSPACE_DEVICEF:
+ // For right now, DeviceN will use /DeviceCMYK in the PDF
+ dict["/ColorSpace"]=QPDFObjectHandle::newName("/DeviceCMYK");
+ break;
+ case CUPS_CSPACE_K:
+ dict["/ColorSpace"]=QPDFObjectHandle::newName("/DeviceGray");
+ break;
+ case CUPS_CSPACE_SW:
+ if (use_blackpoint)
+ dict["/ColorSpace"]=getCalGrayArray(cmWhitePointSGray(), cmGammaSGray(),
+ cmBlackPointDefault());
+ else
+ dict["/ColorSpace"]=getCalGrayArray(cmWhitePointSGray(), cmGammaSGray(), 0);
+ break;
+ case CUPS_CSPACE_CMYK:
+ dict["/ColorSpace"]=QPDFObjectHandle::newName("/DeviceCMYK");
+ break;
+ case CUPS_CSPACE_RGB:
+ dict["/ColorSpace"]=QPDFObjectHandle::newName("/DeviceRGB");
+ break;
+ case CUPS_CSPACE_SRGB:
+ icc_ref = embedSrgbProfile(pdf);
+ if (!icc_ref.isNull())
+ dict["/ColorSpace"]=icc_ref;
+ else
+ dict["/ColorSpace"]=QPDFObjectHandle::newName("/DeviceRGB");
+ break;
+ case CUPS_CSPACE_ADOBERGB:
+ if (use_blackpoint)
+ dict["/ColorSpace"]=getCalRGBArray(cmWhitePointAdobeRgb(), cmGammaAdobeRgb(),
+ cmMatrixAdobeRgb(), cmBlackPointDefault());
+ else
+ dict["/ColorSpace"]=getCalRGBArray(cmWhitePointAdobeRgb(),
+ cmGammaAdobeRgb(), cmMatrixAdobeRgb(), 0);
+ break;
+ default:
+ fputs("DEBUG: Color space not supported.\n", stderr);
+ return QPDFObjectHandle();
+ }
+ } else if (cm_disabled) {
+ switch(cs) {
+ case CUPS_CSPACE_K:
+ case CUPS_CSPACE_SW:
+ dict["/ColorSpace"]=QPDFObjectHandle::newName("/DeviceGray");
+ break;
+ case CUPS_CSPACE_RGB:
+ case CUPS_CSPACE_SRGB:
+ case CUPS_CSPACE_ADOBERGB:
+ dict["/ColorSpace"]=QPDFObjectHandle::newName("/DeviceRGB");
+ break;
+ case CUPS_CSPACE_DEVICE1:
+ case CUPS_CSPACE_DEVICE2:
+ case CUPS_CSPACE_DEVICE3:
+ case CUPS_CSPACE_DEVICE4:
+ case CUPS_CSPACE_DEVICE5:
+ case CUPS_CSPACE_DEVICE6:
+ case CUPS_CSPACE_DEVICE7:
+ case CUPS_CSPACE_DEVICE8:
+ case CUPS_CSPACE_DEVICE9:
+ case CUPS_CSPACE_DEVICEA:
+ case CUPS_CSPACE_DEVICEB:
+ case CUPS_CSPACE_DEVICEC:
+ case CUPS_CSPACE_DEVICED:
+ case CUPS_CSPACE_DEVICEE:
+ case CUPS_CSPACE_DEVICEF:
+ case CUPS_CSPACE_CMYK:
+ dict["/ColorSpace"]=QPDFObjectHandle::newName("/DeviceCMYK");
+ break;
+ default:
+ fputs("DEBUG: Color space not supported.\n", stderr);
+ return QPDFObjectHandle();
+ }
+ } else
+ return QPDFObjectHandle();
+
+ ret.replaceDict(QPDFObjectHandle::newDictionary(dict));
+
+#ifdef PRE_COMPRESS
+ // we deliver already compressed content (instead of letting QPDFWriter do it), to avoid using excessive memory
+ Pl_Buffer psink("psink");
+ Pl_Flate pflate("pflate",&psink,Pl_Flate::a_deflate);
+
+ pflate.write(page_data->getBuffer(),page_data->getSize());
+ pflate.finish();
+
+ ret.replaceStreamData(PointerHolder<Buffer>(psink.getBuffer()),
+ QPDFObjectHandle::newName("/FlateDecode"),QPDFObjectHandle::newNull());
+#else
+ ret.replaceStreamData(page_data,QPDFObjectHandle::newNull(),QPDFObjectHandle::newNull());
+#endif
+
+ return ret;
+}
+
+void finish_page(struct pdf_info * info)
+{
+ if (info->outformat == OUTPUT_FORMAT_PDF)
+ {
+ // Finish previous PDF Page
+ if(!info->page_data.getPointer())
+ return;
+
+ QPDFObjectHandle image = makeImage(info->pdf, info->page_data, info->width, info->height, info->render_intent, info->color_space, info->bpc);
+ if(!image.isInitialized()) die("Unable to load image data");
+
+ // add it
+ info->page.getKey("/Resources").getKey("/XObject").replaceKey("/I",image);
+ }
+#ifdef QPDF_HAVE_PCLM
+ else if (info->outformat == OUTPUT_FORMAT_PCLM)
+ {
+ // Finish previous PCLm page
+ if (info->pclm_num_strips == 0)
+ return;
+
+ for (size_t i = 0; i < info->pclm_strip_data.size(); i ++)
+ if(!info->pclm_strip_data[i].getPointer())
+ return;
+
+ std::vector<QPDFObjectHandle> strips = makePclmStrips(info->pdf, info->pclm_num_strips, info->pclm_strip_data, info->pclm_compression_method_preferred, info->width, info->pclm_strip_height, info->color_space, info->bpc);
+ for (size_t i = 0; i < info->pclm_num_strips; i ++)
+ if(!strips[i].isInitialized()) die("Unable to load strip data");
+
+ // add it
+ for (size_t i = 0; i < info->pclm_num_strips; i ++)
+ info->page.getKey("/Resources").getKey("/XObject")
+ .replaceKey("/Image" +
+ int_to_fwstring(i,num_digits(info->pclm_num_strips - 1)),
+ strips[i]);
+ }
+#endif
+
+ // draw it
+ std::string content;
+ if (info->outformat == OUTPUT_FORMAT_PDF)
+ {
+ content.append(QUtil::double_to_string(info->page_width) + " 0 0 " +
+ QUtil::double_to_string(info->page_height) + " 0 0 cm\n");
+ content.append("/I Do\n");
+ }
+#ifdef QPDF_HAVE_PCLM
+ else if (info->outformat == OUTPUT_FORMAT_PCLM)
+ {
+ std::string res = info->pclm_source_resolution_default;
+
+ // resolution is in dpi, so remove the last three characters from
+ // resolution string to get resolution integer
+ unsigned resolution_integer = std::stoi(res.substr(0, res.size() - 3));
+ double d = (double)DEFAULT_PDF_UNIT / resolution_integer;
+ content.append(QUtil::double_to_string(d) + " 0 0 " + QUtil::double_to_string(d) + " 0 0 cm\n");
+ unsigned yAnchor = info->height;
+ for (unsigned i = 0; i < info->pclm_num_strips; i ++)
+ {
+ yAnchor -= info->pclm_strip_height[i];
+ content.append("/P <</MCID 0>> BDC q\n");
+ content.append(QUtil::int_to_string(info->width) + " 0 0 " +
+ QUtil::int_to_string(info->pclm_strip_height[i]) +
+ " 0 " + QUtil::int_to_string(yAnchor) + " cm\n");
+ content.append("/Image" +
+ int_to_fwstring(i, num_digits(info->pclm_num_strips - 1)) +
+ " Do Q\n");
+ }
+ }
+#endif
+
+ QPDFObjectHandle page_contents = info->page.getKey("/Contents");
+ if (info->outformat == OUTPUT_FORMAT_PDF)
+ page_contents.replaceStreamData(content, QPDFObjectHandle::newNull(), QPDFObjectHandle::newNull());
+#ifdef QPDF_HAVE_PCLM
+ else if (info->outformat == OUTPUT_FORMAT_PCLM)
+ page_contents.getArrayItem(0).replaceStreamData(content, QPDFObjectHandle::newNull(), QPDFObjectHandle::newNull());
+#endif
+
+ // bookkeeping
+ info->page_data = PointerHolder<Buffer>();
+#ifdef QPDF_HAVE_PCLM
+ info->pclm_strip_data.clear();
+#endif
+}
+
+
+/* Perform modifications to PDF if color space conversions are needed */
+int prepare_pdf_page(struct pdf_info * info, unsigned width, unsigned height, unsigned bpl,
+ unsigned bpp, unsigned bpc, std::string render_intent, cups_cspace_t color_space)
+{
+#define IMAGE_CMYK_8 (bpp == 32 && bpc == 8)
+#define IMAGE_CMYK_16 (bpp == 64 && bpc == 16)
+#define IMAGE_RGB_8 (bpp == 24 && bpc == 8)
+#define IMAGE_RGB_16 (bpp == 48 && bpc == 16)
+#define IMAGE_WHITE_1 (bpp == 1 && bpc == 1)
+#define IMAGE_WHITE_8 (bpp == 8 && bpc == 8)
+#define IMAGE_WHITE_16 (bpp == 16 && bpc == 16)
+
+ int error = 0;
+ pdfConvertFunction fn = convertPdf_NoConversion;
+ cmsColorSpaceSignature css;
+
+ /* Register available raster information into the PDF */
+ info->width = width;
+ info->height = height;
+ info->line_bytes = bpl;
+ info->bpp = bpp;
+ info->bpc = bpc;
+ info->render_intent = render_intent;
+ info->color_space = color_space;
+ if (info->outformat == OUTPUT_FORMAT_PCLM)
+ {
+ info->pclm_num_strips = (height / info->pclm_strip_height_preferred) +
+ (height % info->pclm_strip_height_preferred ? 1 : 0);
+ info->pclm_strip_height.resize(info->pclm_num_strips);
+ info->pclm_strip_data.resize(info->pclm_num_strips);
+ for (size_t i = 0; i < info->pclm_num_strips; i ++)
+ {
+ info->pclm_strip_height[i] = info->pclm_strip_height_preferred < height ?
+ info->pclm_strip_height_preferred : height;
+ height -= info->pclm_strip_height[i];
+ }
+ }
+
+ /* Invert grayscale by default */
+ if (color_space == CUPS_CSPACE_K)
+ fn = convertPdf_InvertColors;
+
+ if (colorProfile != NULL) {
+ css = cmsGetColorSpace(colorProfile);
+
+ // Convert image and PDF color space to an embedded ICC Profile color space
+ switch(css) {
+ // Convert PDF to Grayscale when using a gray profile
+ case cmsSigGrayData:
+ if (color_space == CUPS_CSPACE_CMYK)
+ fn = convertPdf_Cmyk8ToWhite8;
+ else if (color_space == CUPS_CSPACE_RGB)
+ fn = convertPdf_Rgb8ToWhite8;
+ else
+ fn = convertPdf_InvertColors;
+ info->color_space = CUPS_CSPACE_K;
+ break;
+ // Convert PDF to RGB when using an RGB profile
+ case cmsSigRgbData:
+ if (color_space == CUPS_CSPACE_CMYK)
+ fn = convertPdf_Cmyk8ToRgb8;
+ else if (color_space == CUPS_CSPACE_K)
+ fn = convertPdf_White8ToRgb8;
+ info->color_space = CUPS_CSPACE_RGB;
+ break;
+ // Convert PDF to CMYK when using an RGB profile
+ case cmsSigCmykData:
+ if (color_space == CUPS_CSPACE_RGB)
+ fn = convertPdf_Rgb8ToCmyk8;
+ else if (color_space == CUPS_CSPACE_K)
+ fn = convertPdf_White8ToCmyk8;
+ info->color_space = CUPS_CSPACE_CMYK;
+ break;
+ default:
+ fputs("DEBUG: Unable to convert PDF from profile.\n", stderr);
+ colorProfile = NULL;
+ error = 1;
+ }
+ // Perform conversion of an image color space
+ } else if (!cm_disabled) {
+ switch (color_space) {
+ // Convert image to CMYK
+ case CUPS_CSPACE_CMYK:
+ if (IMAGE_RGB_8)
+ fn = convertPdf_Rgb8ToCmyk8;
+ else if (IMAGE_RGB_16)
+ fn = convertPdf_NoConversion;
+ else if (IMAGE_WHITE_8)
+ fn = convertPdf_White8ToCmyk8;
+ else if (IMAGE_WHITE_16)
+ fn = convertPdf_NoConversion;
+ break;
+ // Convert image to RGB
+ case CUPS_CSPACE_ADOBERGB:
+ case CUPS_CSPACE_RGB:
+ case CUPS_CSPACE_SRGB:
+ if (IMAGE_CMYK_8)
+ fn = convertPdf_Cmyk8ToRgb8;
+ else if (IMAGE_CMYK_16)
+ fn = convertPdf_NoConversion;
+ else if (IMAGE_WHITE_8)
+ fn = convertPdf_White8ToRgb8;
+ else if (IMAGE_WHITE_16)
+ fn = convertPdf_NoConversion;
+ break;
+ // Convert image to Grayscale
+ case CUPS_CSPACE_SW:
+ case CUPS_CSPACE_K:
+ if (IMAGE_CMYK_8)
+ fn = convertPdf_Cmyk8ToWhite8;
+ else if (IMAGE_CMYK_16)
+ fn = convertPdf_NoConversion;
+ else if (IMAGE_RGB_8)
+ fn = convertPdf_Rgb8ToWhite8;
+ else if (IMAGE_RGB_16)
+ fn = convertPdf_NoConversion;
+ break;
+ case CUPS_CSPACE_DEVICE1:
+ case CUPS_CSPACE_DEVICE2:
+ case CUPS_CSPACE_DEVICE3:
+ case CUPS_CSPACE_DEVICE4:
+ case CUPS_CSPACE_DEVICE5:
+ case CUPS_CSPACE_DEVICE6:
+ case CUPS_CSPACE_DEVICE7:
+ case CUPS_CSPACE_DEVICE8:
+ case CUPS_CSPACE_DEVICE9:
+ case CUPS_CSPACE_DEVICEA:
+ case CUPS_CSPACE_DEVICEB:
+ case CUPS_CSPACE_DEVICEC:
+ case CUPS_CSPACE_DEVICED:
+ case CUPS_CSPACE_DEVICEE:
+ case CUPS_CSPACE_DEVICEF:
+ // No conversion for right now
+ fn = convertPdf_NoConversion;
+ break;
+ default:
+ fputs("DEBUG: Color space not supported.\n", stderr);
+ error = 1;
+ break;
+ }
+ }
+
+ if (!error)
+ fn(info);
+
+ return error;
+}
+
+int add_pdf_page(struct pdf_info * info, int pagen, unsigned width,
+ unsigned height, int bpp, int bpc, int bpl, std::string render_intent,
+ cups_cspace_t color_space, unsigned xdpi, unsigned ydpi)
+{
+ try {
+ finish_page(info); // any active
+
+ prepare_pdf_page(info, width, height, bpl, bpp,
+ bpc, render_intent, color_space);
+
+ if (info->height > (std::numeric_limits<unsigned>::max() / info->line_bytes)) {
+ die("Page too big");
+ }
+ if (info->outformat == OUTPUT_FORMAT_PDF)
+ info->page_data = PointerHolder<Buffer>(new Buffer(info->line_bytes*info->height));
+ else if (info->outformat == OUTPUT_FORMAT_PCLM)
+ {
+ // reserve space for PCLm strips
+ for (size_t i = 0; i < info->pclm_num_strips; i ++)
+ info->pclm_strip_data[i] = PointerHolder<Buffer>(new Buffer(info->line_bytes*info->pclm_strip_height[i]));
+ }
+
+ QPDFObjectHandle page = QPDFObjectHandle::parse(
+ "<<"
+ " /Type /Page"
+ " /Resources <<"
+ " /XObject << >> "
+ " >>"
+ " /MediaBox null "
+ " /Contents null "
+ ">>");
+
+ // Convert to pdf units
+ info->page_width=((double)info->width/xdpi)*DEFAULT_PDF_UNIT;
+ info->page_height=((double)info->height/ydpi)*DEFAULT_PDF_UNIT;
+ if (info->outformat == OUTPUT_FORMAT_PDF)
+ {
+ page.replaceKey("/Contents",QPDFObjectHandle::newStream(&info->pdf)); // data will be provided later
+ page.replaceKey("/MediaBox",makeRealBox(0,0,info->page_width,info->page_height));
+ }
+ else if (info->outformat == OUTPUT_FORMAT_PCLM)
+ {
+ page.replaceKey("/Contents",
+ QPDFObjectHandle::newArray(std::vector<QPDFObjectHandle>(1, QPDFObjectHandle::newStream(&info->pdf))));
+
+ // box with dimensions rounded off to the nearest integer
+ page.replaceKey("/MediaBox",makeIntegerBox(0,0,info->page_width + 0.5,info->page_height + 0.5));
+ }
+
+ info->page = info->pdf.makeIndirectObject(page); // we want to keep a reference
+ info->pdf.addPage(info->page, false);
+ } catch (std::bad_alloc &ex) {
+ die("Unable to allocate page data");
+ } catch (...) {
+ return 1;
+ }
+
+ return 0;
+}
+
+int close_pdf_file(struct pdf_info * info)
+{
+ try {
+ finish_page(info); // any active
+
+ QPDFWriter output(info->pdf,NULL);
+// output.setMinimumPDFVersion("1.4");
+#ifdef QPDF_HAVE_PCLM
+ if (info->outformat == OUTPUT_FORMAT_PCLM)
+ output.setPCLm(true);
+#endif
+ output.write();
+ } catch (...) {
+ return 1;
+ }
+
+ return 0;
+}
+
+void pdf_set_line(struct pdf_info * info, unsigned line_n, unsigned char *line)
+{
+ //dprintf("pdf_set_line(%d)\n", line_n);
+
+ if(line_n > info->height)
+ {
+ dprintf("Bad line %d\n", line_n);
+ return;
+ }
+
+ switch(info->outformat)
+ {
+ case OUTPUT_FORMAT_PDF:
+ memcpy((info->page_data->getBuffer()+(line_n*info->line_bytes)), line, info->line_bytes);
+ break;
+ case OUTPUT_FORMAT_PCLM:
+ // copy line data into appropriate pclm strip
+ size_t strip_num = line_n / info->pclm_strip_height_preferred;
+ unsigned line_strip = line_n - strip_num*info->pclm_strip_height_preferred;
+ memcpy(((info->pclm_strip_data[strip_num])->getBuffer() + (line_strip*info->line_bytes)),
+ line, info->line_bytes);
+ break;
+ }
+}
+
+int convert_raster(cups_raster_t *ras, unsigned width, unsigned height,
+ int bpp, int bpl, struct pdf_info * info)
+{
+ // We should be at raster start
+ int i;
+ unsigned cur_line = 0;
+ unsigned char *PixelBuffer, *ptr = NULL, *buff;
+
+ PixelBuffer = (unsigned char *)malloc(bpl);
+ buff = (unsigned char *)malloc(info->line_bytes);
+
+ do
+ {
+ // Read raster data...
+ cupsRasterReadPixels(ras, PixelBuffer, bpl);
+
+#if !ARCH_IS_BIG_ENDIAN
+
+ if (info->bpc == 16)
+ {
+ // Swap byte pairs for endianess (cupsRasterReadPixels() switches
+ // from Big Endian back to the system's Endian)
+ for (i = bpl, ptr = PixelBuffer; i > 0; i -= 2, ptr += 2)
+ {
+ unsigned char swap = *ptr;
+ *ptr = *(ptr + 1);
+ *(ptr + 1) = swap;
+ }
+ }
+#endif /* !ARCH_IS_BIG_ENDIAN */
+
+ // perform bit operations if necessary
+ bit_function(PixelBuffer, ptr, bpl);
+
+ // write lines and color convert when necessary
+ pdf_set_line(info, cur_line, conversion_function(PixelBuffer, buff, width));
+ ++cur_line;
+ }
+ while(cur_line < height);
+
+ free(buff);
+ free(PixelBuffer);
+
+ return 0;
+}
+
+int setProfile(const char * path)
+{
+ if (path != NULL)
+ colorProfile = cmsOpenProfileFromFile(path,"r");
+
+ if (colorProfile != NULL) {
+ fputs("DEBUG: Load profile successful.\n", stderr);
+ return 0;
+ }
+ else {
+ fputs("DEBUG: Unable to load profile.\n", stderr);
+ return 1;
+ }
+}
+
+/* Obtain a source profile name using color qualifiers from raster file */
+const char * getIPPColorProfileName(const char * media_type, cups_cspace_t cs, unsigned dpi)
+{
+ std::string mediaType = "";
+ std::string resolution = "";
+ std::string colorModel = "";
+
+ std::string iccProfile = "";
+
+ // ColorModel
+ switch (cs) {
+ case CUPS_CSPACE_RGB:
+ colorModel = "rgb";
+ break;
+ case CUPS_CSPACE_SRGB:
+ colorModel = "srgb";
+ break;
+ case CUPS_CSPACE_ADOBERGB:
+ colorModel = "adobergb";
+ break;
+ case CUPS_CSPACE_K:
+ colorModel = "gray";
+ break;
+ case CUPS_CSPACE_CMYK:
+ colorModel = "cmyk";
+ break;
+ default:
+ colorModel = "";
+ break;
+ }
+
+ if (media_type != NULL)
+ mediaType = media_type;
+ if (dpi > 0)
+ resolution = dpi;
+
+ // Requires color space and media type qualifiers
+ if (resolution != "" || colorModel != "")
+ return 0;
+
+ // profile-uri reference: "http://www.server.com/colorModel-Resolution-mediaType.icc
+ if (mediaType != "")
+ iccProfile = colorModel + "-" + resolution + ".icc";
+ else
+ iccProfile = colorModel + "-" + resolution + "-" + mediaType + ".icc";
+
+ return iccProfile.c_str();
+}
+
+int main(int argc, char **argv)
+{
+ char *outformat_env = NULL;
+ OutFormatType outformat; /* Output format */
+ int fd, Page;
+ struct pdf_info pdf;
+ FILE * input = NULL;
+ cups_raster_t *ras; /* Raster stream for printing */
+ cups_page_header2_t header; /* Page header from file */
+ ppd_file_t *ppd; /* PPD file */
+ ppd_attr_t *attr; /* PPD attribute */
+ int num_options; /* Number of options */
+ const char* profile_name; /* IPP Profile Name */
+ cups_option_t *options; /* Options */
+
+ // Make sure status messages are not buffered...
+ setbuf(stderr, NULL);
+
+ cmsSetLogErrorHandler(lcmsErrorHandler);
+
+ if (argc < 6 || argc > 7)
+ {
+ fprintf(stderr, "Usage: %s <job> <user> <job name> <copies> <option> [file]\n", argv[0]);
+ return 1;
+ }
+
+ /* Determine the output format via an environment variable set by a wrapper
+ script */
+#ifdef QPDF_HAVE_PCLM
+ if ((outformat_env = getenv("OUTFORMAT")) == NULL || strcasestr(outformat_env, "pdf"))
+ outformat = OUTPUT_FORMAT_PDF;
+ else if (strcasestr(outformat_env, "pclm"))
+ outformat = OUTPUT_FORMAT_PCLM;
+ else {
+ fprintf(stderr, "ERROR: OUTFORMAT=\"%s\", cannot determine output format\n",
+ outformat_env);
+ return 1;
+ }
+#else
+ outformat = OUTPUT_FORMAT_PDF;
+#endif
+ fprintf(stderr, "DEBUG: OUTFORMAT=\"%s\", output format will be %s\n",
+ outformat_env, (outformat == OUTPUT_FORMAT_PDF ? "PDF" : "PCLM"));
+
+ num_options = cupsParseOptions(argv[5], 0, &options);
+
+ /* support the CUPS "cm-calibration" option */
+ cm_calibrate = cmGetCupsColorCalibrateMode(options, num_options);
+
+ if (outformat == OUTPUT_FORMAT_PCLM ||
+ cm_calibrate == CM_CALIBRATION_ENABLED)
+ cm_disabled = 1;
+ else
+ cm_disabled = cmIsPrinterCmDisabled(getenv("PRINTER"));
+
+ // Open the PPD file...
+ ppd = ppdOpenFile(getenv("PPD"));
+
+ if (ppd)
+ {
+ ppdMarkDefaults(ppd);
+ cupsMarkOptions(ppd, num_options, options);
+ }
+ else
+ {
+ ppd_status_t status; /* PPD error */
+ int linenum; /* Line number */
+
+ fputs("DEBUG: The PPD file could not be opened.\n", stderr);
+
+ status = ppdLastError(&linenum);
+
+ fprintf(stderr, "DEBUG: %s on line %d.\n", ppdErrorString(status), linenum);
+#ifdef QPDF_HAVE_PCLM
+ if (outformat == OUTPUT_FORMAT_PCLM) {
+ fprintf(stderr, "ERROR: PCLm output only possible with PPD file.\n");
+ return 1;
+ }
+#endif
+ }
+
+ // Open the page stream...
+ if (argc == 7)
+ {
+ input = fopen(argv[6], "rb");
+ if (input == NULL) die("Unable to open PWG Raster file");
+ }
+ else
+ input = stdin;
+
+ // Get fd from file
+ fd = fileno(input);
+
+ // Transform
+ ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
+
+ // Process pages as needed...
+ Page = 0;
+
+ // Create PDF file
+ if (create_pdf_file(&pdf, outformat) != 0)
+ die("Unable to create PDF file");
+
+ /* Get PCLm attributes from PPD */
+ if (ppd && outformat == OUTPUT_FORMAT_PCLM)
+ {
+ char *attr_name = (char *)"cupsPclmStripHeightPreferred";
+ if ((attr = ppdFindAttr(ppd, attr_name, NULL)) != NULL)
+ {
+ fprintf(stderr, "DEBUG: PPD PCLm attribute \"%s\" with value \"%s\"\n",
+ attr_name, attr->value);
+ pdf.pclm_strip_height_preferred = atoi(attr->value);
+ }
+ else
+ pdf.pclm_strip_height_preferred = 16; /* default strip height */
+
+ attr_name = (char *)"cupsPclmStripHeightSupported";
+ if ((attr = ppdFindAttr(ppd, attr_name, NULL)) != NULL)
+ {
+ fprintf(stderr, "DEBUG: PPD PCLm attribute \"%s\" with value \"%s\"\n",
+ attr_name, attr->value);
+ pdf.pclm_strip_height_supported.clear(); // remove default value = 16
+ std::vector<std::string> vec = split_strings(attr->value, ",");
+ for (size_t i = 0; i < vec.size(); i ++)
+ pdf.pclm_strip_height_supported.push_back(atoi(vec[i].c_str()));
+ vec.clear();
+ }
+
+ attr_name = (char *)"cupsPclmRasterBackSide";
+ if ((attr = ppdFindAttr(ppd, attr_name, NULL)) != NULL)
+ {
+ fprintf(stderr, "DEBUG: PPD PCLm attribute \"%s\" with value \"%s\"\n",
+ attr_name, attr->value);
+ pdf.pclm_raster_back_side = attr->value;
+ }
+
+ attr_name = (char *)"cupsPclmSourceResolutionDefault";
+ if ((attr = ppdFindAttr(ppd, attr_name, NULL)) != NULL)
+ {
+ fprintf(stderr, "DEBUG: PPD PCLm attribute \"%s\" with value \"%s\"\n",
+ attr_name, attr->value);
+ pdf.pclm_source_resolution_default = attr->value;
+ }
+
+ attr_name = (char *)"cupsPclmSourceResolutionSupported";
+ if ((attr = ppdFindAttr(ppd, attr_name, NULL)) != NULL)
+ {
+ fprintf(stderr, "DEBUG: PPD PCLm attribute \"%s\" with value \"%s\"\n",
+ attr_name, attr->value);
+ pdf.pclm_source_resolution_supported = split_strings(attr->value, ",");
+ }
+
+ attr_name = (char *)"cupsPclmCompressionMethodPreferred";
+ if ((attr = ppdFindAttr(ppd, attr_name, NULL)) != NULL)
+ {
+ fprintf(stderr, "DEBUG: PPD PCLm attribute \"%s\" with value \"%s\"\n",
+ attr_name, attr->value);
+ std::vector<std::string> vec = split_strings(attr->value, ",");
+
+ // get all compression methods supported by the printer
+ for (std::vector<std::string>::iterator it = vec.begin();
+ it != vec.end(); ++it)
+ {
+ std::string compression_method = *it;
+ for (char& x: compression_method)
+ x = tolower(x);
+ if (compression_method == "flate")
+ pdf.pclm_compression_method_preferred.push_back(FLATE_DECODE);
+ else if (compression_method == "rle")
+ pdf.pclm_compression_method_preferred.push_back(RLE_DECODE);
+ else if (compression_method == "jpeg")
+ pdf.pclm_compression_method_preferred.push_back(DCT_DECODE);
+ }
+
+ }
+ // If the compression methods is none of the above or is erreneous
+ // use FLATE as compression method and show a warning.
+ if (pdf.pclm_compression_method_preferred.empty())
+ {
+ fprintf(stderr, "WARNING: (rastertopclm) Unable parse PPD attribute \"%s\". Using FLATE for encoding image streams.\n", attr_name);
+ pdf.pclm_compression_method_preferred.push_back(FLATE_DECODE);
+ }
+ }
+
+ while (cupsRasterReadHeader2(ras, &header))
+ {
+ // Write a status message with the page number
+ Page ++;
+ fprintf(stderr, "INFO: Starting page %d.\n", Page);
+
+ // Use "profile=profile_name.icc" to embed 'profile_name.icc' into the PDF
+ // for testing. Forces color management to enable.
+ if (outformat == OUTPUT_FORMAT_PDF &&
+ (profile_name = cupsGetOption("profile", num_options, options)) != NULL) {
+ setProfile(profile_name);
+ cm_disabled = 0;
+ }
+ if (colorProfile != NULL)
+ fprintf(stderr, "DEBUG: TEST ICC Profile specified (color management forced ON): \n[%s]\n", profile_name);
+
+ // Add a new page to PDF file
+ if (add_pdf_page(&pdf, Page, header.cupsWidth, header.cupsHeight,
+ header.cupsBitsPerPixel, header.cupsBitsPerColor,
+ header.cupsBytesPerLine, header.cupsRenderingIntent,
+ header.cupsColorSpace, header.HWResolution[0],
+ header.HWResolution[1]) != 0)
+ die("Unable to start new PDF page");
+
+ // Write the bit map into the PDF file
+ if (convert_raster(ras, header.cupsWidth, header.cupsHeight,
+ header.cupsBitsPerPixel, header.cupsBytesPerLine,
+ &pdf) != 0)
+ die("Failed to convert page bitmap");
+ }
+
+ close_pdf_file(&pdf); // will output to stdout
+
+ if (colorProfile != NULL) {
+ cmsCloseProfile(colorProfile);
+ }
+
+ cupsFreeOptions(num_options, options);
+
+ cupsRasterClose(ras);
+
+ if (fd != 0)
+ close(fd);
+
+ return (Page == 0);
+}
diff --git a/filter/rastertops.c b/filter/rastertops.c
new file mode 100644
index 000000000..d5d955b5d
--- /dev/null
+++ b/filter/rastertops.c
@@ -0,0 +1,487 @@
+/*
+ * 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/>.
+ *
+ * @brief Convert PWG Raster to a PostScript file
+ * @file rastertops.c
+ * @author Pranjal Bhor <bhor.pranjal@gmail.com> (C) 2016
+ * @author Neil 'Superna' Armstrong <superna9999@gmail.com> (C) 2010
+ * @author Tobias Hoffmann <smilingthax@gmail.com> (c) 2012
+ * @author Till Kamppeter <till.kamppeter@gmail.com> (c) 2014
+ */
+
+#include <config.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <math.h>
+#include <signal.h>
+#include <cups/cups.h>
+#include <cups/raster.h>
+#include <cupsfilters/colormanager.h>
+#include <cupsfilters/image.h>
+#include <assert.h>
+#include <zlib.h>
+
+/*
+ * 'write_prolog()' - Writing the PostScript prolog for the file
+ */
+
+void
+writeProlog(cups_cspace_t mode, /* I - Color mode (gray or color) */
+ int width, /* I - width of the image in pixels */
+ int height) /* I - height of the image in pixels */
+{
+ /* Document header... */
+ printf("%%!PS-Adobe-3.0\n");
+ printf("%%%%BoundingBox: %d %d %d %d\n", 0, 0, width, height);
+ printf("%%%%Creator: Cups-Filters\n");
+ printf("%%%%LanguageLevel: 2\n");
+ printf("%%%%DocumentData: Clean7Bit\n");
+ printf("%%%%Pages: (atend)\n");
+ printf("%%%%EndComments\n");
+ printf("%%%%BeginProlog\n");
+ printf("%%%%EndProlog\n");
+}
+
+/*
+ * 'writeStartPage()' - Write the basic page setup
+ */
+
+void
+writeStartPage(int page, /* I - Page to write */
+ int width, /* I - Page width in points */
+ int length) /* I - Page length in points */
+{
+ printf("%%%%Page: %d %d\n", page, page);
+ printf("%%%%BeginPageSetup\n");
+ printf("<< /PageSize[%d %d] >> setpagedevice\n", width, length);
+ printf("%%%%EndPageSetup\n");
+}
+
+/*
+ * 'find_bits()' - Finding the number of bits per color
+ */
+
+int /* O - Exit status */
+find_bits(cups_cspace_t mode, /* I - Color space of data */
+ int bpc) /* I - Original bits per color of data */
+{
+ if (bpc == 1 &&
+ (mode == CUPS_CSPACE_RGB ||
+ mode == CUPS_CSPACE_ADOBERGB ||
+ mode == CUPS_CSPACE_SRGB ||
+ mode == CUPS_CSPACE_CMY))
+ return 8;
+
+ if (bpc == 16)
+ return 8;
+
+ return bpc;
+}
+
+/*
+ * 'writeImage()' - Write the information regarding the image
+ */
+
+void /* O - Exit status */
+writeImage(int bpc, /* I - bits per color */
+ int width, /* I - width of image */
+ int height, /* I - height of image */
+ cups_cspace_t mode) /* I - color model of image */
+{
+ printf("gsave\n");
+
+ switch (mode)
+ {
+ case CUPS_CSPACE_RGB:
+ case CUPS_CSPACE_CMY:
+ case CUPS_CSPACE_SRGB:
+ case CUPS_CSPACE_ADOBERGB:
+ printf("/DeviceRGB setcolorspace\n");
+ break;
+
+ case CUPS_CSPACE_CMYK:
+ printf("/DeviceCMYK setcolorspace\n");
+ break;
+
+ default:
+ case CUPS_CSPACE_K:
+ case CUPS_CSPACE_W:
+ case CUPS_CSPACE_SW:
+ printf("/DeviceGray setcolorspace\n");
+ break;
+ }
+
+ if (bpc == 16)
+ printf("/Input currentfile /FlateDecode filter def\n");
+ printf("%d %d scale\n",width, height);
+ printf("<< \n"
+ "/ImageType 1\n"
+ "/Width %d\n"
+ "/Height %d\n"
+ "/BitsPerComponent %d\n", width, height, find_bits(mode, bpc));
+
+ switch (mode)
+ {
+ case CUPS_CSPACE_RGB:
+ case CUPS_CSPACE_CMY:
+ case CUPS_CSPACE_SRGB:
+ case CUPS_CSPACE_ADOBERGB:
+ printf("/Decode [0 1 0 1 0 1]\n");
+ break;
+
+ case CUPS_CSPACE_CMYK:
+ printf("/Decode [0 1 0 1 0 1 0 1]\n");
+ break;
+
+ case CUPS_CSPACE_SW:
+ printf("/Decode [0 1]\n");
+ break;
+
+ default:
+ case CUPS_CSPACE_K:
+ case CUPS_CSPACE_W:
+ printf("/Decode [1 0]\n");
+ break;
+ }
+
+ if(bpc==16)
+ printf("/DataSource {3 string 0 1 2 {1 index exch Input read {pop}"
+ "if Input read pop put } for} bind\n");
+ else
+ printf("/DataSource currentfile /FlateDecode filter\n");
+
+ printf("/ImageMatrix [%d 0 0 %d 0 %d]\n", width, -1*height, height);
+ printf(">> image\n");
+}
+
+/*
+ * 'convert_pixels()'- Convert 1 bpc to 8 bpc
+ */
+
+void
+convert_pixels(unsigned char *pixdata, /* I - Original pixel data */
+ unsigned char *convertedpix, /* I - Buffer for converted data */
+ int width) /* I - Width of data */
+{
+ int j, k = 0; /* Variables for iteration */
+ unsigned int mask; /* Variable for per byte iteration */
+ unsigned char temp; /* temporary character */
+
+ for(j = 0; j < width; ++j)
+ {
+ temp = *(pixdata + j);
+ for (mask = 0x80; mask != 0; mask >>= 1)
+ {
+ if (mask!=0x80 && mask != 0x08)
+ {
+ if (temp & mask)
+ convertedpix[k] = 0xFF;
+ else
+ convertedpix[k] = 0;
+ ++k;
+ }
+ }
+ }
+}
+
+/*
+ * 'write_flate()' - Write the image data in flate encoded format
+ */
+
+int /* O - Error value */
+write_flate(cups_raster_t *ras, /* I - Image data */
+ cups_page_header2_t header) /* I - Bytes Per Line */
+{
+ int ret, /* Return value of this
+ function */
+ flush, /* Check the end of image
+ data */
+ curr_line=1, /* Maitining the working
+ line of pixels */
+ alloc,
+ flag = 0;
+ unsigned have; /* Bytes available in
+ output buffer */
+ z_stream strm; /* Structure required
+ by deflate */
+ unsigned char *pixdata,
+ *convertedpix;
+ unsigned char in[header.cupsBytesPerLine * 6], /* Input data buffer */
+ out[header.cupsBytesPerLine * 6]; /* Output data buffer */
+
+ /* allocate deflate state */
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ ret = deflateInit(&strm, -1);
+ if (ret != Z_OK)
+ return ret;
+
+ if(header.cupsBitsPerColor == 1 &&
+ (header.cupsColorSpace == CUPS_CSPACE_RGB ||
+ header.cupsColorSpace == CUPS_CSPACE_ADOBERGB ||
+ header.cupsColorSpace == CUPS_CSPACE_SRGB))
+ flag = 1;
+
+ /* compress until end of file */
+ do {
+ pixdata = malloc(header.cupsBytesPerLine);
+ cupsRasterReadPixels(ras, pixdata, header.cupsBytesPerLine);
+ if (flag)
+ {
+ convertedpix = malloc(header.cupsBytesPerLine * 6);
+ convert_pixels(pixdata,convertedpix, header.cupsBytesPerLine);
+ alloc = header.cupsBytesPerLine * 6;
+ }
+ else
+ {
+ convertedpix = malloc(header.cupsBytesPerLine);
+ memcpy(convertedpix, pixdata, header.cupsBytesPerLine);
+ alloc = header.cupsBytesPerLine;
+ }
+
+ if(curr_line == header.cupsHeight)
+ flush = Z_FINISH;
+ else
+ flush = Z_NO_FLUSH;
+ curr_line++;
+ memcpy(in, convertedpix, alloc);
+ strm.avail_in = alloc;
+ strm.next_in = in;
+
+ /* run deflate() on input until output buffer not full, finish
+ * compression if all of source has been read in */
+ do {
+ strm.avail_out = alloc;
+ strm.next_out = out;
+
+ /* Run the deflate algorithm on the data */
+ ret = deflate(&strm, flush);
+
+ /* check whether state is not clobbered */
+ assert(ret != Z_STREAM_ERROR);
+ have = alloc - strm.avail_out;
+ if (fwrite(out, 1, have, stdout) != have)
+ {
+ (void)deflateEnd(&strm);
+ return Z_ERRNO;
+ }
+ } while (strm.avail_out == 0);
+
+ /* all input will be used */
+ assert(strm.avail_in == 0);
+
+ /* done when last data in file processed */
+ free(pixdata);
+ free(convertedpix);
+ } while (flush != Z_FINISH);
+
+ /* stream will be complete */
+ assert(ret == Z_STREAM_END);
+
+ /* clean up and return */
+ (void)deflateEnd(&strm);
+ return Z_OK;
+}
+
+/*
+ * Report a zlib or i/o error
+ */
+
+void
+zerr(int ret) /* I - Return status of deflate */
+{
+ fputs("zpipe: ", stderr);
+ switch (ret) {
+ case Z_ERRNO:
+ fputs("error in source data or output file\n", stderr);
+ break;
+ case Z_STREAM_ERROR:
+ fputs("invalid compression level\n", stderr);
+ break;
+ case Z_DATA_ERROR:
+ fputs("invalid or incomplete deflate data\n", stderr);
+ break;
+ case Z_MEM_ERROR:
+ fputs("out of memory\n", stderr);
+ break;
+ case Z_VERSION_ERROR:
+ fputs("zlib version mismatch!\n", stderr);
+ }
+}
+
+/*
+ * 'writeEndPage()' - Show the current page.
+ */
+
+void
+writeEndPage()
+{
+ printf("\ngrestore\n");
+ printf("showpage\n");
+ printf("%%%%PageTrailer\n");
+}
+
+/*
+ * 'writeTrailer()' - Write the PostScript trailer.
+ */
+
+void
+writeTrailer(int pages) /* I - Number of pages */
+{
+ printf("%%%%Trailer\n");
+ printf("%%%%Pages: %d\n", pages);
+ printf("%%%%EOF\n");
+}
+
+/*
+ * 'main()' - Main entry and processing of driver.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ FILE *input = NULL; /* File pointer to raster document */
+ int fd, /* File descriptor for raster document */
+ num_options, /* Number of options */
+ count, /* count for writing the postscript */
+ Canceled = 0, /* variable for job cancellation */
+ Page = 0, /* variable for counting the pages */
+ ret; /* Return value of deflate compression */
+ ppd_file_t *ppd; /* PPD file */
+ cups_raster_t *ras; /* Raster stream for printing */
+ cups_page_header2_t header; /* Page header from file */
+ cups_option_t *options; /* Options */
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+ setbuf(stderr, NULL);
+
+ /*
+ * Check command-line...
+ */
+ if (argc < 6 || argc > 7)
+ {
+ fprintf(stderr, "Usage: %s job-id user title copies options [file]\n",
+ "rastertops");
+ return (1);
+ }
+
+ num_options = cupsParseOptions(argv[5], 0, &options);
+
+ /*
+ * Open the PPD file...
+ */
+ ppd = ppdOpenFile(getenv("PPD"));
+
+ if (ppd)
+ {
+ ppdMarkDefaults(ppd);
+ cupsMarkOptions(ppd, num_options, options);
+ }
+ else
+ {
+ ppd_status_t status; /* PPD error */
+ int linenum; /* Line number */
+
+ fprintf(stderr, "DEBUG: The PPD file could not be opened.\n");
+ status = ppdLastError(&linenum);
+ fprintf(stderr, "DEBUG: %s on line %d.\n", ppdErrorString(status), linenum);
+ }
+
+ /*
+ * Open the page stream...
+ */
+ if (argc == 7)
+ {
+ input = fopen(argv[6], "rb");
+ if (input == NULL) fprintf(stderr, "Unable to open PWG Raster file");
+ }
+ else
+ input = stdin;
+
+ /*
+ * Get fd from file
+ */
+ fd = fileno(input);
+
+ /*
+ * Transform
+ */
+ ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
+
+ /*
+ * Register a signal handler to eject the current page if the
+ * job is cancelled.
+ */
+ Canceled = 0;
+
+
+ /*
+ * Process pages as needed...
+ */
+ Page = 0;
+ count = 0;
+
+ while (cupsRasterReadHeader2(ras, &header))
+ {
+ /*
+ * Write the prolog for PS only once
+ */
+ if (!count)
+ {
+ count++;
+ writeProlog(header.cupsColorSpace, header.cupsWidth, header.cupsHeight);
+ }
+
+ /*
+ * Write a status message with the page number and number of copies.
+ */
+ if (Canceled)
+ break;
+
+ Page ++;
+
+ fprintf(stderr, "INFO: Starting page %d.\n", Page);
+
+ /*
+ * Write the starting of the page
+ */
+ writeStartPage(Page, header.cupsWidth, header.cupsHeight);
+
+ /*
+ * write the information regarding the image
+ */
+ writeImage(header.cupsBitsPerColor, header.cupsWidth, header.cupsHeight,
+ header.cupsColorSpace);
+
+ /* Write the compressed image data*/
+ ret = write_flate(ras, header);
+ if (ret != Z_OK)
+ zerr(ret);
+ writeEndPage();
+ }
+ writeTrailer(Page);
+
+ return 0;
+}
diff --git a/filter/strcasestr.c b/filter/strcasestr.c
new file mode 100644
index 000000000..46bd12fd9
--- /dev/null
+++ b/filter/strcasestr.c
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <ctype.h>
+#include <string.h>
+
+/*
+ * Find the first occurrence of find in s, ignore case.
+ */
+char *
+strcasestr(s, find)
+ const char *s, *find;
+{
+ char c, sc;
+ size_t len;
+
+ if ((c = *find++) != 0) {
+ c = tolower((unsigned char)c);
+ len = strlen(find);
+ do {
+ do {
+ if ((sc = *s++) == 0)
+ return (NULL);
+ } while ((char)tolower((unsigned char)sc) != c);
+ } while (strncasecmp(s, find, len) != 0);
+ s--;
+ }
+ return ((char *)s);
+}
diff --git a/filter/sys5ippprinter.c b/filter/sys5ippprinter.c
new file mode 100644
index 000000000..ad75551d0
--- /dev/null
+++ b/filter/sys5ippprinter.c
@@ -0,0 +1,902 @@
+/*
+ * sys5ippprinter
+ *
+ * System-V-interface-style CUPS filter for PPD-less printing of PDF and
+ * PWG Raster input data on IPP printers which advertise themselves via
+ * Bonjour/DNS-SD.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1997-2006 by Easy Software Products.
+ * Copyright 2011-2013 by Till Kamppeter
+ *
+ * Contents:
+ *
+ * main() - Main entry for filter...
+ * cancel_job() - Flag the job as canceled.
+ * filter_present() - Is the requested filter actually installed?
+ * compare_pids() - Compare process IDs for sorting PID list
+ * exec_filter() - Execute a filter process
+ * exec_filters() - Execute a filter chain
+ * open_pipe() - Create a pipe to transfer data from filter to filter
+ * get_option_in_str() - Get an option value from a string like argv[5]
+ * set_option_in_str() - Set an option value in a string like argv[5]
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <config.h>
+#include <cups/cups.h>
+#include <cups/ppd.h>
+#include <cups/file.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <limits.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <ctype.h>
+#include <cupsfilters/image-private.h>
+
+#define MAX_CHECK_COMMENT_LINES 20
+
+/*
+ * Type definitions
+ */
+
+typedef unsigned output_format_t;
+enum output_format_e {PDF = 0, POSTSCRIPT = 1, PWGRASTER = 2, PCLXL = 3, PCL = 4};
+typedef struct filter_pid_s /* Filter in filter chain */
+{
+ char *name; /* Filter executable name */
+ int pid; /* PID of filter process */
+} filter_pid_t;
+
+/*
+ * Local functions...
+ */
+
+static void cancel_job(int sig);
+static int filter_present(const char *filter);
+static int compare_pids(filter_pid_t *a, filter_pid_t *b);
+static int exec_filter(const char *filter, char **argv,
+ int infd, int outfd);
+static int exec_filters(cups_array_t *filters, char **argv);
+static int open_pipe(int *fds);
+static char* get_option_in_str(char *buf, const char *option,
+ int return_value);
+static void set_option_in_str(char *buf, int buflen,
+ const char *option,
+ const char *value);
+
+/*
+ * Local globals...
+ */
+
+static int job_canceled = 0;
+
+
+/*
+ * 'main()' - Main entry for filter...
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line args */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i; /* Looping var */
+ output_format_t output_format; /* Output format */
+ int fd = 0; /* Copy file descriptor */
+ char *filename, /* PDF file to convert */
+ tempfile[1024]; /* Temporary file */
+ char buffer[8192]; /* Copy buffer */
+ int bytes; /* Bytes copied */
+ int num_options; /* Number of options */
+ cups_option_t *options; /* Options */
+ const char *val; /* Option value */
+ char *argv_nt[8]; /* NULL-terminated array of the command
+ line arguments */
+ int optbuflen;
+ cups_array_t *filter_chain; /* Filter chain to execute */
+ int exit_status = 0; /* Exit status */
+ int color_printing; /* Do we print in color? */
+ char *filter, *p;
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+ static const char * const color_mode_option_names[] =
+ { /* Possible names for a color mode option */
+ "pwg-raster-document-type",
+ "PwgRasterDocumentType",
+ "print-color-mode",
+ "PrintColorMode",
+ "color-space",
+ "ColorSpace",
+ "color-model",
+ "ColorModel",
+ NULL
+ };
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Ignore broken pipe signals...
+ */
+
+ signal(SIGPIPE, SIG_IGN);
+
+ /*
+ * Make sure we have the right number of arguments for CUPS!
+ */
+
+ if (argc < 6 || argc > 7)
+ {
+ fprintf(stderr, "Usage: %s job user title copies options [file]\n",
+ argv[0]);
+ return (1);
+ }
+
+ /*
+ * Register a signal handler to cleanly cancel a job.
+ */
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, cancel_job);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = cancel_job;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, cancel_job);
+#endif /* HAVE_SIGSET */
+
+ /*
+ * Copy stdin if needed...
+ */
+
+ if (argc == 6)
+ {
+ /*
+ * Copy stdin to a temp file...
+ */
+
+ if ((fd = cupsTempFd(tempfile, sizeof(tempfile))) < 0)
+ {
+ perror("DEBUG: Unable to copy PDF file");
+ return (1);
+ }
+
+ fprintf(stderr, "DEBUG: sys5ippprinter - copying to temp print file \"%s\"\n",
+ tempfile);
+
+ while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
+ bytes = write(fd, buffer, bytes);
+
+ close(fd);
+
+ filename = tempfile;
+ }
+ else
+ {
+ /*
+ * Use the filename on the command-line...
+ */
+
+ filename = argv[6];
+ tempfile[0] = '\0';
+ }
+
+ /*
+ * Get the options from the fifth command line argument
+ */
+
+ num_options = cupsParseOptions(argv[5], 0, &options);
+
+ /*
+ * Copy the command line arguments into a NULL-terminated array
+ */
+
+ for (i = 0; i < 5; i++)
+ argv_nt[i] = argv[i];
+ /* We copy the contents of argv[5] into a somewhat larger buffer so that
+ we can manipulate it */
+ optbuflen = strlen(argv[5]) + 256;
+ argv_nt[5] = calloc(optbuflen, sizeof(char));
+ strcpy(argv_nt[5], (const char*)argv[5]);
+ argv_nt[6] = filename;
+ argv_nt[7] = NULL;
+
+ /*
+ * Create filter chain
+ */
+
+ filter_chain = cupsArrayNew(NULL, NULL);
+
+ /*
+ * Add the gziptoany filter if installed
+ */
+
+ if (filter_present("gziptoany"))
+ cupsArrayAdd(filter_chain, "gziptoany");
+
+ /*
+ * If the rastertopdf filter is present and the input is in PWG Raster format
+ * add the rastertopdf filter to the filter chain to support the PWG Raster
+ * input. Same for JPEG input if imagetopdf is present. This way the PPD-less
+ * auto-generated print queue emulates an IPP Everywhere printer, as PPDed
+ * CUPS queues do.
+ */
+
+ if (filter_present("rastertopdf") && (val = getenv("CONTENT_TYPE")) != NULL &&
+ strcasestr(val, "pwg-raster") != NULL) {
+ cupsArrayAdd(filter_chain, "rastertopdf");
+ } else if (filter_present("imagetopdf") &&
+ (val = getenv("CONTENT_TYPE")) != NULL &&
+ strcasestr(val, "jpeg") != NULL) {
+ cupsArrayAdd(filter_chain, "imagetopdf");
+ }
+
+ /*
+ * Check the presence of the pdftopdf filter and add it to the filter
+ * chain if it is there
+ */
+
+ if (filter_present("pdftopdf"))
+ cupsArrayAdd(filter_chain, "pdftopdf");
+
+ /*
+ * Select the output format: PDF, PostScript, PWG Raster, PCL-XL, and
+ * PCL 5c/e
+ * Add the needed filters to the filter chain
+ */
+
+ if ((val = cupsGetOption("output-format", num_options, options)) != NULL)
+ {
+ if (strcasestr(val, "raster"))
+ {
+ output_format = PWGRASTER;
+ /* PWG Raster output */
+ set_option_in_str(argv_nt[5], optbuflen, "MediaClass", NULL);
+ set_option_in_str(argv_nt[5], optbuflen, "media-class", "PwgRaster");
+ /* Page logging into page_log is not done by gstoraster/pdftoraster,
+ so let it be done by pdftopdf */
+ set_option_in_str(argv_nt[5], optbuflen, "page-logging", "on");
+ if (filter_present("gstoraster") && access(CUPS_GHOSTSCRIPT, X_OK) == 0)
+ cupsArrayAdd(filter_chain, "gstoraster");
+ else
+ {
+ fprintf(stderr,
+ "DEBUG: Filter gstoraster or Ghostscript (%s) missing for \"output-format=%s\", using pdftoraster.\n", CUPS_GHOSTSCRIPT, val);
+ if (filter_present("pdftoraster"))
+ cupsArrayAdd(filter_chain, "pdftoraster");
+ else
+ {
+ fprintf(stderr,
+ "ERROR: Filter pdftoraster missing for \"output-format=%s\"\n", val);
+ exit_status = 1;
+ goto error;
+ }
+ }
+ }
+ else if (strcasestr(val, "pdf"))
+ {
+ output_format = PDF;
+ /* Page logging into page_log has to be done by pdftopdf */
+ set_option_in_str(argv_nt[5], optbuflen, "page-logging", "on");
+ }
+ else if (strcasestr(val, "postscript"))
+ {
+ output_format = POSTSCRIPT;
+ /* Page logging into page_log is done by pstops, so no need by
+ pdftopdf */
+ set_option_in_str(argv_nt[5], optbuflen, "page-logging", "off");
+ if (filter_present("pdftops"))
+ {
+ cupsArrayAdd(filter_chain, "pdftops");
+ if (access(CUPS_GHOSTSCRIPT, X_OK) != 0)
+ {
+ fprintf(stderr,
+ "DEBUG: Ghostscript (%s) missing for \"output-format=%s\", using Poppler's pdftops instead.\n", CUPS_GHOSTSCRIPT, val);
+ set_option_in_str(argv_nt[5], optbuflen, "pdftops-renderer",
+ "pdftops");
+ }
+ else if (access(CUPS_POPPLER_PDFTOPS, X_OK) != 0)
+ {
+ fprintf(stderr,
+ "DEBUG: Poppler's pdftops (%s) missing for \"output-format=%s\", using Ghostscript instead.\n", CUPS_POPPLER_PDFTOPS, val);
+ set_option_in_str(argv_nt[5], optbuflen, "pdftops-renderer",
+ "gs");
+ }
+ else
+ set_option_in_str(argv_nt[5], optbuflen, "pdftops-renderer",
+ "hybrid");
+ }
+ else
+ {
+ fprintf(stderr,
+ "ERROR: Filter pdftops missing for \"output-format=%s\"\n", val);
+ exit_status = 1;
+ goto error;
+ }
+ }
+ else if ((p = strcasestr(val, "pcl")) != NULL)
+ {
+ if (!strcasecmp(p, "pclxl"))
+ {
+ output_format = PCLXL;
+ if (filter_present("gstopxl") && access(CUPS_GHOSTSCRIPT, X_OK) == 0)
+ {
+ cupsArrayAdd(filter_chain, "gstopxl");
+ /* Page logging into page_log is not done by gstopxl,
+ so let it be done by pdftopdf */
+ set_option_in_str(argv_nt[5], optbuflen, "page-logging", "on");
+ }
+ else
+ {
+ fprintf(stderr,
+ "DEBUG: Filter gstopxl or Ghostscript (%s) missing for \"output-format=%s\", falling back to PCL 5c/e.\n", CUPS_GHOSTSCRIPT, val);
+ output_format = PCL;
+ }
+ }
+ else
+ {
+ output_format = PCL;
+ }
+ }
+ else
+ {
+ fprintf(stderr,
+ "ERROR: Invalid value for \"output-format\": \"%s\"\n", val);
+ exit_status = 1;
+ goto error;
+ }
+ }
+ else
+ {
+ fprintf(stderr,
+ "ERROR: Missing option \"output-format\".\n");
+ exit_status = 1;
+ goto error;
+ }
+ if (output_format == PCL)
+ {
+ /* We need CUPS Raster as we want to use rastertopclx with unprintable
+ margins */
+ set_option_in_str(argv_nt[5], optbuflen, "MediaClass", NULL);
+ set_option_in_str(argv_nt[5], optbuflen, "media-class", "");
+ /* Page logging into page_log is done by rastertopclx, so no need by
+ pdftopdf */
+ set_option_in_str(argv_nt[5], optbuflen, "page-logging", "off");
+ /* Does the client send info about margins? */
+ if (!get_option_in_str(argv_nt[5], "media-left-margin", 0) &&
+ !get_option_in_str(argv_nt[5], "media-right-margin", 0) &&
+ !get_option_in_str(argv_nt[5], "media-top-margin", 0) &&
+ !get_option_in_str(argv_nt[5], "media-bottom-margin", 0))
+ {
+ /* Set default 12pt margins if there is no info about printer's
+ unprintable margins (100th of mm units, 12.0 * 2540.0 / 72.0 = 423.33)
+ */
+ set_option_in_str(argv_nt[5], optbuflen, "media-left-margin", "423.33");
+ set_option_in_str(argv_nt[5], optbuflen, "media-right-margin", "423.33");
+ set_option_in_str(argv_nt[5], optbuflen, "media-top-margin", "423.33");
+ set_option_in_str(argv_nt[5], optbuflen, "media-bottom-margin", "423.33");
+ }
+ /* Check whether the job is requested to be printed in color and if so,
+ set the color space to RGB as this is the best color printing support
+ in PCL 5c */
+ color_printing = 0;
+ for (i = 0; color_mode_option_names[i]; i ++)
+ {
+ p = get_option_in_str(argv_nt[5], color_mode_option_names[i], 1);
+ if (p && (strcasestr(p, "RGB") || strcasestr(p, "CMY") ||
+ strcasestr(p, "color")))
+ {
+ color_printing = 1;
+ break;
+ }
+ }
+ if (color_printing == 1)
+ {
+ /* Remove unneeded color mode options */
+ for (i = 0; color_mode_option_names[i]; i ++)
+ set_option_in_str(argv_nt[5], optbuflen, color_mode_option_names[i],
+ NULL);
+ /* Set RGB as color mode */
+ set_option_in_str(argv_nt[5], optbuflen, "print-color-mode", "RGB");
+ }
+ if (filter_present("gstoraster") && access(CUPS_GHOSTSCRIPT, X_OK) == 0)
+ cupsArrayAdd(filter_chain, "gstoraster");
+ else
+ {
+ fprintf(stderr,
+ "DEBUG: Filter gstoraster or Ghostscript (%s) missing for \"output-format=%s\", using pdftoraster.\n", CUPS_GHOSTSCRIPT, val);
+ if (filter_present("pdftoraster"))
+ cupsArrayAdd(filter_chain, "pdftoraster");
+ else
+ {
+ fprintf(stderr,
+ "ERROR: Filter pdftoraster missing for \"output-format=%s\"\n", val);
+ exit_status = 1;
+ goto error;
+ }
+ }
+ if (filter_present("rastertopclx"))
+ cupsArrayAdd(filter_chain, "rastertopclx");
+ else
+ {
+ fprintf(stderr,
+ "ERROR: Filter rastertopclx missing for \"output-format=%s\"\n", val);
+ exit_status = 1;
+ goto error;
+ }
+ }
+
+ fprintf(stderr,
+ "DEBUG: Printer supports output formats: %s\nDEBUG: Using following CUPS filter chain to convert input data to the %s format:",
+ val,
+ output_format == PDF ? "PDF" :
+ (output_format == POSTSCRIPT ? "Postscript" :
+ (output_format == PWGRASTER ? "PWG Raster" :
+ (output_format == PCLXL ? "PCL XL" :
+ (output_format == PCL ? "PCL 5c/e" : "unknown")))));
+ for (filter = (char *)cupsArrayFirst(filter_chain);
+ filter;
+ filter = (char *)cupsArrayNext(filter_chain))
+ fprintf(stderr, " %s", filter);
+ fprintf(stderr, "\n");
+
+ /*
+ * Execute the filter chain
+ */
+
+ exit_status = exec_filters(filter_chain, (char **)argv_nt);
+
+ /*
+ * Cleanup and exit...
+ */
+
+ error:
+
+ if (tempfile[0])
+ unlink(tempfile);
+
+ return (exit_status);
+}
+
+
+/*
+ * 'cancel_job()' - Flag the job as canceled.
+ */
+
+static void
+cancel_job(int sig) /* I - Signal number (unused) */
+{
+ (void)sig;
+
+ job_canceled = 1;
+}
+
+
+static int
+filter_present(const char *filter) /* I - Filter name */
+{
+ char filter_path[1024]; /* Path to filter executable */
+ const char *cups_serverbin; /* CUPS_SERVERBIN environment variable */
+
+ if ((cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL)
+ cups_serverbin = CUPS_SERVERBIN;
+
+ snprintf(filter_path, sizeof(filter_path), "%s/filter/%s",
+ cups_serverbin, filter);
+
+ if (access(filter_path, X_OK) == 0)
+ return 1;
+
+ return 0;
+}
+
+
+/*
+ * 'compare_pids()' - Compare two filter PIDs...
+ */
+
+static int /* O - Result of comparison */
+compare_pids(filter_pid_t *a, /* I - First filter */
+ filter_pid_t *b) /* I - Second filter */
+{
+ return (a->pid - b->pid);
+}
+
+
+/*
+ * 'exec_filter()' - Execute a single filter.
+ */
+
+static int /* O - Process ID or -1 on error */
+exec_filter(const char *filter, /* I - Filter to execute */
+ char **argv, /* I - Original command line args */
+ int infd, /* I - Stdin file descriptor */
+ int outfd) /* I - Stdout file descriptor */
+{
+ int pid, /* Process ID */
+ fd; /* Temporary file descriptor */
+
+ if ((pid = fork()) == 0)
+ {
+ /*
+ * Child process goes here...
+ *
+ * Update stdin/stdout/stderr as needed...
+ */
+
+ if (infd != 0)
+ {
+ if (infd < 0)
+ infd = open("/dev/null", O_RDONLY);
+
+ if (infd > 0)
+ {
+ dup2(infd, 0);
+ close(infd);
+ }
+ }
+
+ if (outfd != 1)
+ {
+ if (outfd < 0)
+ outfd = open("/dev/null", O_WRONLY);
+
+ if (outfd > 1)
+ {
+ dup2(outfd, 1);
+ close(outfd);
+ }
+ }
+
+ /* Send stderr to the Nirwana if we are running gziptoany, as
+ gziptoany emits a false "PAGE: 1 1" */
+ if (strcasestr(filter, "gziptoany")) {
+ if ((fd = open("/dev/null", O_RDWR)) > 2)
+ {
+ dup2(fd, 2);
+ close(fd);
+ }
+ fcntl(2, F_SETFL, O_NDELAY);
+ }
+
+ if ((fd = open("/dev/null", O_RDWR)) > 3)
+ {
+ dup2(fd, 3);
+ close(fd);
+ }
+ fcntl(3, F_SETFL, O_NDELAY);
+
+ if ((fd = open("/dev/null", O_RDWR)) > 4)
+ {
+ dup2(fd, 4);
+ close(fd);
+ }
+ fcntl(4, F_SETFL, O_NDELAY);
+
+ /*
+ * Execute command...
+ */
+
+ execvp(filter, argv);
+
+ perror(filter);
+
+ exit(errno);
+ }
+
+ return (pid);
+}
+
+
+/*
+ * 'exec_filters()' - Execute filters for the given file and options.
+ */
+
+static int /* O - 0 on success, 1 on error */
+exec_filters(cups_array_t *filters, /* I - Array of filters to run */
+ char **argv) /* I - Filter options */
+{
+ int i; /* Looping var */
+ char program[1024]; /* Program to run */
+ char *filter, /* Current filter */
+ *next; /* Next filter */
+ int current, /* Current filter */
+ filterfds[2][2], /* Pipes for filters */
+ pid, /* Process ID of filter */
+ status, /* Exit status */
+ retval; /* Return value */
+ cups_array_t *pids; /* Executed filters array */
+ filter_pid_t *pid_entry, /* Entry in executed filters array */
+ key; /* Search key for filters */
+ const char *cups_serverbin; /* CUPS_SERVERBIN environment variable */
+
+ /*
+ * Remove NULL ("-") filters...
+ */
+
+ for (filter = (char *)cupsArrayFirst(filters);
+ filter;
+ filter = (char *)cupsArrayNext(filters))
+ if (!strcmp(filter, "-"))
+ cupsArrayRemove(filters, filter);
+
+ for (i = 0; argv[i]; i ++)
+ fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]);
+
+ /*
+ * Execute all of the filters...
+ */
+
+ pids = cupsArrayNew((cups_array_func_t)compare_pids, NULL);
+ current = 0;
+ filterfds[0][0] = 0;
+ filterfds[0][1] = -1;
+ filterfds[1][0] = -1;
+ filterfds[1][1] = -1;
+
+ for (filter = (char *)cupsArrayFirst(filters);
+ filter;
+ filter = next, current = 1 - current)
+ {
+ next = (char *)cupsArrayNext(filters);
+
+ if (filter[0] == '/')
+ strncpy(program, filter, sizeof(program));
+ else
+ {
+ if ((cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL)
+ cups_serverbin = CUPS_SERVERBIN;
+ snprintf(program, sizeof(program), "%s/filter/%s", cups_serverbin,
+ filter);
+ }
+
+ if (filterfds[!current][1] > 1)
+ {
+ close(filterfds[1 - current][0]);
+ close(filterfds[1 - current][1]);
+
+ filterfds[1 - current][0] = -1;
+ filterfds[1 - current][0] = -1;
+ }
+
+ if (next)
+ open_pipe(filterfds[1 - current]);
+ else
+ filterfds[1 - current][1] = 1;
+
+ pid = exec_filter(program, argv,
+ filterfds[current][0], filterfds[1 - current][1]);
+
+ if (pid > 0)
+ {
+ fprintf(stderr, "INFO: %s (PID %d) started.\n", filter, pid);
+
+ pid_entry = malloc(sizeof(filter_pid_t));
+ pid_entry->pid = pid;
+ pid_entry->name = filter;
+ cupsArrayAdd(pids, pid_entry);
+ }
+ else
+ break;
+
+ argv[6] = NULL;
+ }
+
+ /*
+ * Close remaining pipes...
+ */
+
+ if (filterfds[0][1] > 1)
+ {
+ close(filterfds[0][0]);
+ close(filterfds[0][1]);
+ }
+
+ if (filterfds[1][1] > 1)
+ {
+ close(filterfds[1][0]);
+ close(filterfds[1][1]);
+ }
+
+ /*
+ * Wait for the children to exit...
+ */
+
+ retval = 0;
+
+ while (cupsArrayCount(pids) > 0)
+ {
+ if ((pid = wait(&status)) < 0)
+ {
+ if (errno == EINTR && job_canceled)
+ {
+ fprintf(stderr, "DEBUG: Job canceled, killing filters ...\n");
+ for (pid_entry = (filter_pid_t *)cupsArrayFirst(pids);
+ pid_entry;
+ pid_entry = (filter_pid_t *)cupsArrayNext(pids))
+ kill(pid_entry->pid, SIGTERM);
+ job_canceled = 0;
+ }
+ else
+ continue;
+ }
+
+ key.pid = pid;
+ if ((pid_entry = (filter_pid_t *)cupsArrayFind(pids, &key)) != NULL)
+ {
+ cupsArrayRemove(pids, pid_entry);
+
+ if (status)
+ {
+ if (WIFEXITED(status))
+ fprintf(stderr, "ERROR: %s (PID %d) stopped with status %d\n",
+ pid_entry->name, pid, WEXITSTATUS(status));
+ else
+ fprintf(stderr, "ERROR: %s (PID %d) crashed on signal %d\n",
+ pid_entry->name, pid, WTERMSIG(status));
+
+ retval = 1;
+ }
+ else
+ fprintf(stderr, "INFO: %s (PID %d) exited with no errors.\n",
+ pid_entry->name, pid);
+
+ free(pid_entry);
+ }
+ }
+
+ cupsArrayDelete(pids);
+
+ return (retval);
+}
+
+
+/*
+ * 'open_pipe()' - Create a pipe which is closed on exec.
+ */
+
+static int /* O - 0 on success, -1 on error */
+open_pipe(int *fds) /* O - Pipe file descriptors (2) */
+{
+ /*
+ * Create the pipe...
+ */
+
+ if (pipe(fds))
+ {
+ fds[0] = -1;
+ fds[1] = -1;
+
+ return (-1);
+ }
+
+ /*
+ * Set the "close on exec" flag on each end of the pipe...
+ */
+
+ if (fcntl(fds[0], F_SETFD, fcntl(fds[0], F_GETFD) | FD_CLOEXEC))
+ {
+ close(fds[0]);
+ close(fds[1]);
+
+ fds[0] = -1;
+ fds[1] = -1;
+
+ return (-1);
+ }
+
+ if (fcntl(fds[1], F_SETFD, fcntl(fds[1], F_GETFD) | FD_CLOEXEC))
+ {
+ close(fds[0]);
+ close(fds[1]);
+
+ fds[0] = -1;
+ fds[1] = -1;
+
+ return (-1);
+ }
+
+ /*
+ * Return 0 indicating success...
+ */
+
+ return (0);
+}
+
+
+/*
+ * Get option value in a string of options
+ */
+
+static char* /* O - Value, NULL if option not set */
+get_option_in_str(char *buf, /* I - Buffer with option list string */
+ const char *option, /* I - Option of which to get value */
+ int return_value) /* I - Return value or only check
+ presence of option? */
+{
+ char *p1, *p2;
+ char *result;
+
+ if (!buf || !option)
+ return NULL;
+ if ((p1 = strcasestr(buf, option)) == NULL)
+ return NULL;
+ if (p1 > buf && *(p1 - 1) != ' ' && *(p1 - 1) != '\t')
+ return NULL;
+ p2 = p1 + strlen(option);
+ if (*p2 == ' ' || *p2 == '\t' || *p2 == '\0')
+ return "";
+ if (*p2 != '=')
+ return NULL;
+ if (!return_value)
+ return "";
+ p1 = p2 + 1;
+ for (p2 = p1; *p2 != ' ' && *p2 != '\t' && *p2 != '\0'; p2 ++);
+ if (p2 == p1)
+ return "";
+ result = calloc(p2 - p1 + 1, sizeof(char));
+ memcpy(result, p1, p2 - p1);
+ result[p2 - p1] = '\0';
+ return result;
+}
+
+
+/*
+ * Set an option in a string of options
+ */
+
+void /* O - 0 on success, 1 on error */
+set_option_in_str(char *buf, /* I - Buffer with option list string */
+ int buflen, /* I - Length of buffer */
+ const char *option, /* I - Option to change/add */
+ const char *value) /* I - New value for option, NULL
+ removes option */
+{
+ char *p1, *p2;
+
+ if (!buf || buflen == 0 || !option)
+ return;
+ /* Remove any occurrence of option in the string */
+ p1 = buf;
+ while (*p1 != '\0' && (p2 = strcasestr(p1, option)) != NULL)
+ {
+ if (p2 > buf && *(p2 - 1) != ' ' && *(p2 - 1) != '\t')
+ {
+ p1 = p2 + 1;
+ continue;
+ }
+ p1 = p2 + strlen(option);
+ if (*p1 != '=' && *p1 != ' ' && *p1 != '\t' && *p1 != '\0')
+ continue;
+ while (*p1 != ' ' && *p1 != '\t' && *p1 != '\0') p1 ++;
+ while ((*p1 == ' ' || *p1 == '\t') && *p1 != '\0') p1 ++;
+ memmove(p2, p1, strlen(buf) - (buf - p1) + 1);
+ p1 = p2;
+ }
+ /* Add option=value to the end of the string */
+ if (!value)
+ return;
+ p1 = buf + strlen(buf);
+ *p1 = ' ';
+ p1 ++;
+ snprintf(p1, buflen - (buf - p1), "%s=%s", option, value);
+ buf[buflen - 1] = '\0';
+}
+
+/*
+ * End
+ */
diff --git a/filter/test.sh b/filter/test.sh
new file mode 100755
index 000000000..4a96bfb9b
--- /dev/null
+++ b/filter/test.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+# just for comparison
+/usr/lib/cups/filter/texttops 1 hi_user there_title 1 "" Makefile > test1.ps || :
+
+# for the next to work, you'll have to make a subdirectory fonts/ here, containing the fonts
+# and a subdirectory charsets/ with a file pdf.utf-8
+export CUPS_DATADIR=`pwd`/
+
+./texttopdf 1 hi_user there_title 1 "" Makefile > test1.pdf
+./texttopdf 1 hi_user there_title 1 "PrettyPrint=1" Makefile > test2.pdf
+(export CONTENT_TYPE=application/x-csource; ./texttopdf 1 hi_user there_title 1 "PrettyPrint=1" test_pdf1.c > test3.pdf)
+(export CHARSET=utf-8; ./texttopdf 1 hi_user there_title 1 "PrettyPrint=1" Makefile > test4.pdf)
+(export CHARSET=utf-8; ./texttopdf 1 hi_user there_title 1 "" testin > test5.pdf)
diff --git a/filter/test_pdf1.c b/filter/test_pdf1.c
new file mode 100644
index 000000000..0fadea4a7
--- /dev/null
+++ b/filter/test_pdf1.c
@@ -0,0 +1,52 @@
+#include "pdfutils.h"
+#include <assert.h>
+#include <string.h>
+
+int main()
+{
+ pdfOut *pdf;
+
+ pdf=pdfOut_new();
+ assert(pdf);
+
+ pdfOut_begin_pdf(pdf);
+
+ // bad font
+ int font_obj=pdfOut_add_xref(pdf);
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "<</Type/Font\n"
+ " /Subtype /Type1\n" // /TrueType,/Type3
+ " /BaseFont /%s\n"
+ ">>\n"
+ "endobj\n"
+ ,font_obj,"Courier");
+ // test
+ const int PageWidth=595,PageLength=842;
+ int cobj=pdfOut_add_xref(pdf);
+ const char buf[]="BT /a 10 Tf (abc) Tj ET";
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "<</Length %d\n"
+ ">>\n"
+ "stream\n"
+ "%s\n"
+ "endstream\n"
+ "endobj\n"
+ ,cobj,strlen(buf),buf);
+
+ int obj=pdfOut_add_xref(pdf);
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "<</Type/Page\n"
+ " /Parent 1 0 R\n"
+ " /MediaBox [0 0 %d %d]\n"
+ " /Contents %d 0 R\n"
+ " /Resources << /Font << /a %d 0 R >> >>\n"
+ ">>\n"
+ "endobj\n"
+ ,obj,PageWidth,PageLength,cobj,font_obj); // TODO: into pdf->
+ pdfOut_add_page(pdf,obj);
+ pdfOut_finish_pdf(pdf);
+
+ pdfOut_free(pdf);
+
+ return 0;
+}
diff --git a/filter/test_pdf2.c b/filter/test_pdf2.c
new file mode 100644
index 000000000..a0c1d8b0d
--- /dev/null
+++ b/filter/test_pdf2.c
@@ -0,0 +1,102 @@
+#include "pdfutils.h"
+#include "config.h"
+#include <assert.h>
+#include "fontembed/embed.h"
+#include "fontembed/sfnt.h"
+
+#include <stdio.h>
+
+static inline void write_string(pdfOut *pdf,EMB_PARAMS *emb,const char *str) // {{{
+{
+ assert(pdf);
+ assert(emb);
+ int iA;
+
+ if (emb->plan&EMB_A_MULTIBYTE) {
+ putc('<',stdout);
+ for (iA=0;str[iA];iA++) {
+ const unsigned short gid=emb_get(emb,(unsigned char)str[iA]);
+ fprintf(stdout,"%04x",gid);
+ }
+ putc('>',stdout);
+ pdf->filepos+=4*iA+2;
+ } else {
+ for (iA=0;str[iA];iA++) {
+ emb_get(emb,(unsigned char)str[iA]);
+ // TODO: pdf: otf_from_pdf_default_encoding
+ }
+ pdfOut_putString(pdf,str,-1);
+ }
+}
+// }}}
+
+int main()
+{
+ pdfOut *pdf;
+
+ pdf=pdfOut_new();
+ assert(pdf);
+
+ pdfOut_begin_pdf(pdf);
+
+ // font, pt.1
+ const char *fn=TESTFONT;
+/*
+ if (argc==2) {
+ fn=argv[1];
+ }
+*/
+ OTF_FILE *otf=otf_load(fn);
+ assert(otf);
+ FONTFILE *ff=fontfile_open_sfnt(otf);
+ EMB_PARAMS *emb=emb_new(ff,
+ EMB_DEST_PDF16,
+ EMB_C_FORCE_MULTIBYTE|
+ EMB_C_TAKE_FONTFILE);
+
+ // test
+ const int PageWidth=595,PageLength=842;
+ const int cobj=pdfOut_add_xref(pdf);
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "<</Length %d 0 R\n"
+ ">>\n"
+ "stream\n"
+ ,cobj,cobj+1);
+ long streamlen=-pdf->filepos;
+ pdfOut_printf(pdf,"BT /a 10 Tf ");
+ write_string(pdf,emb,"Test");
+ pdfOut_printf(pdf," Tj ET");
+
+ streamlen+=pdf->filepos;
+ pdfOut_printf(pdf,"\nendstream\n"
+ "endobj\n");
+ const int clobj=pdfOut_add_xref(pdf);
+ assert(clobj==cobj+1);
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "%d\n"
+ "endobj\n"
+ ,clobj,streamlen);
+
+ // font
+ int font_obj=pdfOut_write_font(pdf,emb);
+ assert(font_obj);
+
+ int obj=pdfOut_add_xref(pdf);
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "<</Type/Page\n"
+ " /Parent 1 0 R\n"
+ " /MediaBox [0 0 %d %d]\n"
+ " /Contents %d 0 R\n"
+ " /Resources << /Font << /a %d 0 R >> >>\n"
+ ">>\n"
+ "endobj\n"
+ ,obj,PageWidth,PageLength,cobj,font_obj); // TODO: into pdf->
+ pdfOut_add_page(pdf,obj);
+ pdfOut_finish_pdf(pdf);
+
+ pdfOut_free(pdf);
+
+ emb_close(emb);
+
+ return 0;
+}
diff --git a/filter/textcommon.c b/filter/textcommon.c
new file mode 100644
index 000000000..97a1a7cc5
--- /dev/null
+++ b/filter/textcommon.c
@@ -0,0 +1,1271 @@
+/*
+ * Common text filter routines for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * TextMain() - Standard main entry for text filters.
+ * compare_keywords() - Compare two C/C++ keywords.
+ * getutf8() - Get a UTF-8 encoded wide character...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "textcommon.h"
+#include <limits.h>
+
+
+/*
+ * Globals...
+ */
+
+int WrapLines = 1, /* Wrap text in lines */
+ SizeLines = 60, /* Number of lines on a page */
+ SizeColumns = 80, /* Number of columns on a line */
+ PageColumns = 1, /* Number of columns on a page */
+ ColumnGutter = 0, /* Number of characters between text columns */
+ ColumnWidth = 80, /* Width of each column */
+ PrettyPrint = 0, /* Do pretty code formatting */
+ Copies = 1; /* Number of copies */
+lchar_t **Page = NULL; /* Page characters */
+int NumPages = 0; /* Number of pages in document */
+float CharsPerInch = 10; /* Number of character columns per inch */
+float LinesPerInch = 6; /* Number of lines per inch */
+int NumKeywords = 0; /* Number of known keywords */
+char **Keywords = NULL; /* List of known keywords */
+
+
+/*
+ * Local globals...
+ */
+
+static char *code_keywords[] = /* List of known C/C++ keywords... */
+ {
+ "and",
+ "and_eq",
+ "asm",
+ "auto",
+ "bitand",
+ "bitor",
+ "bool",
+ "break",
+ "case",
+ "catch",
+ "char",
+ "class",
+ "compl",
+ "const",
+ "const_cast",
+ "continue",
+ "default",
+ "delete",
+ "do",
+ "double",
+ "dynamic_cast",
+ "else",
+ "enum",
+ "explicit",
+ "extern",
+ "false",
+ "float",
+ "for",
+ "friend",
+ "goto",
+ "if",
+ "inline",
+ "int",
+ "long",
+ "mutable",
+ "namespace",
+ "new",
+ "not",
+ "not_eq",
+ "operator",
+ "or",
+ "or_eq",
+ "private",
+ "protected",
+ "public",
+ "register",
+ "reinterpret_cast",
+ "return",
+ "short",
+ "signed",
+ "sizeof",
+ "static",
+ "static_cast",
+ "struct",
+ "switch",
+ "template",
+ "this",
+ "throw",
+ "true",
+ "try",
+ "typedef",
+ "typename",
+ "union",
+ "unsigned",
+ "virtual",
+ "void",
+ "volatile",
+ "while",
+ "xor",
+ "xor_eq"
+ },
+ *sh_keywords[] = /* List of known Boure/Korn/zsh/bash keywords... */
+ {
+ "alias",
+ "bg",
+ "break",
+ "case",
+ "cd",
+ "command",
+ "continue",
+ "do",
+ "done",
+ "echo",
+ "elif",
+ "else",
+ "esac",
+ "eval",
+ "exec",
+ "exit",
+ "export",
+ "fc",
+ "fg",
+ "fi",
+ "for",
+ "function",
+ "getopts",
+ "if",
+ "in",
+ "jobs",
+ "kill",
+ "let",
+ "limit",
+ "newgrp",
+ "print",
+ "pwd",
+ "read",
+ "readonly",
+ "return",
+ "select",
+ "set",
+ "shift",
+ "test",
+ "then",
+ "time",
+ "times",
+ "trap",
+ "typeset",
+ "ulimit",
+ "umask",
+ "unalias",
+ "unlimit",
+ "unset",
+ "until",
+ "wait",
+ "whence"
+ "while",
+ },
+ *csh_keywords[] = /* List of known csh/tcsh keywords... */
+ {
+ "alias",
+ "aliases",
+ "bg",
+ "bindkey",
+ "break",
+ "breaksw",
+ "builtins",
+ "case",
+ "cd",
+ "chdir",
+ "complete",
+ "continue",
+ "default",
+ "dirs",
+ "echo",
+ "echotc",
+ "else",
+ "end",
+ "endif",
+ "eval",
+ "exec",
+ "exit",
+ "fg",
+ "foreach",
+ "glob",
+ "goto",
+ "history",
+ "if",
+ "jobs",
+ "kill",
+ "limit",
+ "login",
+ "logout",
+ "ls",
+ "nice",
+ "nohup",
+ "notify",
+ "onintr",
+ "popd",
+ "pushd",
+ "pwd",
+ "rehash",
+ "repeat",
+ "set",
+ "setenv",
+ "settc",
+ "shift",
+ "source",
+ "stop",
+ "suspend",
+ "switch",
+ "telltc",
+ "then",
+ "time",
+ "umask",
+ "unalias",
+ "unbindkey",
+ "unhash",
+ "unlimit",
+ "unset",
+ "unsetenv",
+ "wait",
+ "where",
+ "which",
+ "while"
+ },
+ *perl_keywords[] = /* List of known perl keywords... */
+ {
+ "abs",
+ "accept",
+ "alarm",
+ "and",
+ "atan2",
+ "bind",
+ "binmode",
+ "bless",
+ "caller",
+ "chdir",
+ "chmod",
+ "chomp",
+ "chop",
+ "chown",
+ "chr",
+ "chroot",
+ "closdir",
+ "close",
+ "connect",
+ "continue",
+ "cos",
+ "crypt",
+ "dbmclose",
+ "dbmopen",
+ "defined",
+ "delete",
+ "die",
+ "do",
+ "dump",
+ "each",
+ "else",
+ "elsif",
+ "endgrent",
+ "endhostent",
+ "endnetent",
+ "endprotoent",
+ "endpwent",
+ "endservent",
+ "eof",
+ "eval",
+ "exec",
+ "exists",
+ "exit",
+ "exp",
+ "fcntl",
+ "fileno",
+ "flock",
+ "for",
+ "foreach",
+ "fork",
+ "format",
+ "formline",
+ "getc",
+ "getgrent",
+ "getgrgid",
+ "getgrnam",
+ "gethostbyaddr",
+ "gethostbyname",
+ "gethostent",
+ "getlogin",
+ "getnetbyaddr",
+ "getnetbyname",
+ "getnetent",
+ "getpeername",
+ "getpgrp",
+ "getppid",
+ "getpriority",
+ "getprotobyname",
+ "getprotobynumber",
+ "getprotoent",
+ "getpwent",
+ "getpwnam",
+ "getpwuid",
+ "getservbyname",
+ "getservbyport",
+ "getservent",
+ "getsockname",
+ "getsockopt",
+ "glob",
+ "gmtime",
+ "goto",
+ "grep",
+ "hex",
+ "if",
+ "import",
+ "index",
+ "int",
+ "ioctl",
+ "join",
+ "keys",
+ "kill",
+ "last",
+ "lc",
+ "lcfirst",
+ "length",
+ "link",
+ "listen",
+ "local",
+ "localtime",
+ "log",
+ "lstat",
+ "map",
+ "mkdir",
+ "msgctl",
+ "msgget",
+ "msgrcv",
+ "msgsend",
+ "my",
+ "next",
+ "no",
+ "not",
+ "oct",
+ "open",
+ "opendir",
+ "or",
+ "ord",
+ "pack",
+ "package",
+ "pipe",
+ "pop",
+ "pos",
+ "print",
+ "printf",
+ "push",
+ "quotemeta",
+ "rand",
+ "read",
+ "readdir",
+ "readlink",
+ "recv",
+ "redo",
+ "ref",
+ "rename",
+ "require",
+ "reset",
+ "return",
+ "reverse",
+ "rewinddir",
+ "rindex",
+ "rmdir",
+ "scalar",
+ "seek",
+ "seekdir",
+ "select",
+ "semctl",
+ "semget",
+ "semop",
+ "send",
+ "setgrent",
+ "sethostent",
+ "setnetent",
+ "setpgrp",
+ "setpriority",
+ "setprotoent",
+ "setpwent",
+ "setservent",
+ "setsockopt",
+ "shift",
+ "shmctl",
+ "shmget",
+ "shmread",
+ "shmwrite",
+ "shutdown",
+ "sin",
+ "sleep",
+ "socket",
+ "socketpair",
+ "sort",
+ "splice",
+ "split",
+ "sprintf",
+ "sqrt",
+ "srand",
+ "stat",
+ "study",
+ "sub",
+ "substr",
+ "symlink",
+ "syscall",
+ "sysread",
+ "sysseek",
+ "system",
+ "syswrite",
+ "tell",
+ "telldir",
+ "tie",
+ "tied",
+ "time",
+ "times"
+ "times",
+ "truncate",
+ "uc",
+ "ucfirst",
+ "umask",
+ "undef",
+ "unless",
+ "unlink",
+ "unpack",
+ "unshift",
+ "untie",
+ "until",
+ "use",
+ "utime",
+ "values",
+ "vec",
+ "wait",
+ "waitpid",
+ "wantarray",
+ "warn",
+ "while",
+ "write"
+ };
+
+
+/*
+ * Local functions...
+ */
+
+static int compare_keywords(const void *, const void *);
+static int getutf8(FILE *fp);
+
+
+/*
+ * 'TextMain()' - Standard main entry for text filters.
+ */
+
+int /* O - Exit status */
+TextMain(const char *name, /* I - Name of filter */
+ int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ FILE *fp; /* Print file */
+ ppd_file_t *ppd; /* PPD file */
+ int i, /* Looping var */
+ ch, /* Current char from file */
+ lastch, /* Previous char from file */
+ attr, /* Current attribute */
+ line, /* Current line */
+ column, /* Current column */
+ page_column; /* Current page column */
+ int num_options; /* Number of print options */
+ cups_option_t *options; /* Print options */
+ const char *val; /* Option value */
+ char keyword[64], /* Keyword string */
+ *keyptr; /* Pointer into string */
+ int keycol; /* Column where keyword starts */
+ enum {NLstyl=-1, NoCmnt, SNTXstyl}
+ cmntState; /* Inside a comment */
+ enum {StrBeg=-1, NoStr, StrEnd}
+ strState; /* Inside a dbl-quoted string */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc < 6 || argc > 7)
+ {
+ fprintf(stderr, "Usage: %s job-id user title copies options [file]\n",
+ name);
+ return (1);
+ }
+
+ /*
+ * If we have 7 arguments, print the file named on the command-line.
+ * Otherwise, send stdin instead...
+ */
+
+ if (argc == 6)
+ fp = stdin;
+ else
+ {
+ /*
+ * Try to open the print file...
+ */
+
+ if ((fp = fopen(argv[6], "rb")) == NULL)
+ {
+ perror("DEBUG: unable to open print file - ");
+ return (1);
+ }
+ }
+
+ /*
+ * Process command-line options and write the prolog...
+ */
+
+ options = NULL;
+ num_options = cupsParseOptions(argv[5], 0, &options);
+
+ if ((val = cupsGetOption("prettyprint", num_options, options)) != NULL &&
+ strcasecmp(val, "no") && strcasecmp(val, "off") &&
+ strcasecmp(val, "false"))
+ {
+ PageLeft = 72.0f;
+ PageRight = PageWidth - 36.0f;
+ PageBottom = PageBottom > 36.0f ? PageBottom : 36.0f;
+ PageTop = PageLength - 36.0f;
+ CharsPerInch = 12;
+ LinesPerInch = 8;
+
+ if ((val = getenv("CONTENT_TYPE")) == NULL)
+ {
+ PrettyPrint = PRETTY_PLAIN;
+ NumKeywords = 0;
+ Keywords = NULL;
+ }
+ else if (strcasecmp(val, "application/x-cshell") == 0)
+ {
+ PrettyPrint = PRETTY_SHELL;
+ NumKeywords = sizeof(csh_keywords) / sizeof(csh_keywords[0]);
+ Keywords = csh_keywords;
+ }
+ else if (strcasecmp(val, "application/x-csource") == 0)
+ {
+ PrettyPrint = PRETTY_CODE;
+ NumKeywords = sizeof(code_keywords) / sizeof(code_keywords[0]);
+ Keywords = code_keywords;
+ }
+ else if (strcasecmp(val, "application/x-perl") == 0)
+ {
+ PrettyPrint = PRETTY_PERL;
+ NumKeywords = sizeof(perl_keywords) / sizeof(perl_keywords[0]);
+ Keywords = perl_keywords;
+ }
+ else if (strcasecmp(val, "application/x-shell") == 0)
+ {
+ PrettyPrint = PRETTY_SHELL;
+ NumKeywords = sizeof(sh_keywords) / sizeof(sh_keywords[0]);
+ Keywords = sh_keywords;
+ }
+ else
+ {
+ PrettyPrint = PRETTY_PLAIN;
+ NumKeywords = 0;
+ Keywords = NULL;
+ }
+ }
+
+ ppd = SetCommonOptions(num_options, options, 1);
+
+ if ((val = cupsGetOption("wrap", num_options, options)) == NULL)
+ WrapLines = 1;
+ else
+ WrapLines = !strcasecmp(val, "true") || !strcasecmp(val, "on") ||
+ !strcasecmp(val, "yes");
+
+ if ((val = cupsGetOption("columns", num_options, options)) != NULL)
+ {
+ PageColumns = atoi(val);
+
+ if (PageColumns < 1)
+ {
+ if (fp != stdin)
+ fclose(fp);
+ fprintf(stderr, "ERROR: Bad columns value %d.\n", PageColumns);
+ return (1);
+ }
+ }
+
+ if ((val = cupsGetOption("cpi", num_options, options)) != NULL)
+ {
+ CharsPerInch = atof(val);
+
+ if (CharsPerInch <= 0.0)
+ {
+ if (fp != stdin)
+ fclose(fp);
+ fprintf(stderr, "ERROR: Bad cpi value %f.\n", CharsPerInch);
+ return (1);
+ }
+ }
+
+ if ((val = cupsGetOption("lpi", num_options, options)) != NULL)
+ {
+ LinesPerInch = atof(val);
+
+ if (LinesPerInch <= 0.0)
+ {
+ if (fp != stdin)
+ fclose(fp);
+ fprintf(stderr, "ERROR: Bad lpi value %f.", LinesPerInch);
+ return (1);
+ }
+ }
+
+ if (PrettyPrint)
+ PageTop -= 216.0f / LinesPerInch;
+
+ /*
+ * Allocate memory for the page...
+ */
+
+ SizeColumns = (PageRight - PageLeft) / 72.0 * CharsPerInch;
+ SizeLines = (PageTop - PageBottom) / 72.0 * LinesPerInch;
+
+ /*
+ * Enforce minimum size...
+ */
+ if (SizeColumns < 1)
+ SizeColumns = 1;
+ if (SizeLines < 1)
+ SizeLines = 1;
+
+ if (SizeLines >= INT_MAX / SizeColumns / sizeof(lchar_t))
+ {
+ fprintf(stderr, "ERROR: bad page size\n");
+ exit(1);
+ }
+
+ Page = calloc(sizeof(lchar_t *), SizeLines);
+ if (!Page)
+ {
+ fprintf(stderr, "ERROR: cannot allocate memory for page\n");
+ exit(1);
+ }
+
+ Page[0] = calloc(sizeof(lchar_t), SizeColumns * SizeLines);
+ if (!Page[0])
+ {
+ free(Page);
+ fprintf(stderr, "ERROR: cannot allocate memory for page\n");
+ exit(1);
+ }
+
+ for (i = 1; i < SizeLines; i ++)
+ Page[i] = Page[0] + i * SizeColumns;
+
+ Copies = atoi(argv[4]);
+
+ WriteProlog(argv[3], argv[2], getenv("CLASSIFICATION"),
+ cupsGetOption("page-label", num_options, options), ppd);
+
+ /*
+ * Read text from the specified source and print it...
+ */
+
+ lastch = 0;
+ column = 0;
+ line = 0;
+ page_column = 0;
+ attr = 0;
+ keyptr = keyword;
+ keycol = 0;
+ cmntState = NoCmnt;
+ strState = NoStr;
+
+ while ((ch = getutf8(fp)) >= 0)
+ {
+ /*
+ * Control codes:
+ *
+ * BS Backspace (0x08)
+ * HT Horizontal tab; next 8th column (0x09)
+ * LF Line feed; forward full line (0x0a)
+ * VT Vertical tab; reverse full line (0x0b)
+ * FF Form feed (0x0c)
+ * CR Carriage return (0x0d)
+ * ESC 7 Reverse full line (0x1b 0x37)
+ * ESC 8 Reverse half line (0x1b 0x38)
+ * ESC 9 Forward half line (0x1b 0x39)
+ */
+
+ switch (ch)
+ {
+ case 0x08 : /* BS - backspace for boldface & underline */
+ if (column > 0)
+ column --;
+
+ keyptr = keyword;
+ keycol = column;
+ break;
+
+ case 0x09 : /* HT - tab to next 8th column */
+ if (PrettyPrint && keyptr > keyword)
+ {
+ *keyptr = '\0';
+ keyptr = keyword;
+
+ if (bsearch(&keyptr, Keywords, NumKeywords, sizeof(char *),
+ compare_keywords))
+ {
+ /*
+ * Put keywords in boldface...
+ */
+
+ i = page_column * (ColumnWidth + ColumnGutter);
+
+ while (keycol < column)
+ {
+ Page[line][keycol + i].attr |= ATTR_BOLD;
+ keycol ++;
+ }
+ }
+ }
+
+ column = (column + 8) & ~7;
+
+ if (column >= ColumnWidth && WrapLines)
+ { /* Wrap text to margins */
+ line ++;
+ column = 0;
+
+ if (line >= SizeLines)
+ {
+ page_column ++;
+ line = 0;
+
+ if (page_column >= PageColumns)
+ {
+ WritePage();
+ page_column = 0;
+ }
+ }
+ }
+
+ keycol = column;
+
+ attr &= ~ATTR_BOLD;
+ break;
+
+ case 0x0d : /* CR */
+#ifndef __APPLE__
+ /*
+ * All but MacOS/Darwin treat CR as was intended by ANSI
+ * folks, namely to move to column 0/1. Some programs still
+ * use this to do boldfacing and underlining...
+ */
+
+ column = 0;
+ break;
+#else
+ /*
+ * MacOS/Darwin still need to treat CR as a line ending.
+ */
+
+ {
+ int nextch;
+ if ((nextch = getc(fp)) != 0x0a)
+ ungetc(nextch, fp);
+ else
+ ch = nextch;
+ }
+#endif /* !__APPLE__ */
+
+ case 0x0a : /* LF - output current line */
+ if (PrettyPrint && keyptr > keyword)
+ {
+ *keyptr = '\0';
+ keyptr = keyword;
+
+ if (bsearch(&keyptr, Keywords, NumKeywords, sizeof(char *),
+ compare_keywords))
+ {
+ /*
+ * Put keywords in boldface...
+ */
+
+ i = page_column * (ColumnWidth + ColumnGutter);
+
+ while (keycol < column)
+ {
+ Page[line][keycol + i].attr |= ATTR_BOLD;
+ keycol ++;
+ }
+ }
+ }
+
+ line ++;
+ column = 0;
+ keycol = 0;
+
+ if (cmntState == NLstyl)
+ cmntState = NoCmnt;
+
+ if (!cmntState && !strState)
+ attr &= ~(ATTR_ITALIC | ATTR_BOLD | ATTR_RED | ATTR_GREEN | ATTR_BLUE);
+
+ if (line >= SizeLines)
+ {
+ page_column ++;
+ line = 0;
+
+ if (page_column >= PageColumns)
+ {
+ WritePage();
+ page_column = 0;
+ }
+ }
+ break;
+
+ case 0x0b : /* VT - move up 1 line */
+ if (line > 0)
+ line --;
+
+ keyptr = keyword;
+ keycol = column;
+
+ if (cmntState == NLstyl)
+ cmntState = NoCmnt;
+
+ if (!cmntState && !strState)
+ attr &= ~(ATTR_ITALIC | ATTR_BOLD | ATTR_RED | ATTR_GREEN | ATTR_BLUE);
+ break;
+
+ case 0x0c : /* FF - eject current page... */
+ if (PrettyPrint && keyptr > keyword)
+ {
+ *keyptr = '\0';
+ keyptr = keyword;
+
+ if (bsearch(&keyptr, Keywords, NumKeywords, sizeof(char *),
+ compare_keywords))
+ {
+ /*
+ * Put keywords in boldface...
+ */
+
+ i = page_column * (ColumnWidth + ColumnGutter);
+
+ while (keycol < column)
+ {
+ Page[line][keycol + i].attr |= ATTR_BOLD;
+ keycol ++;
+ }
+ }
+ }
+
+ page_column ++;
+ column = 0;
+ keycol = 0;
+ line = 0;
+
+ if (cmntState == NLstyl)
+ cmntState = NoCmnt;
+
+ if (!cmntState && !strState)
+ attr &= ~(ATTR_ITALIC | ATTR_BOLD | ATTR_RED | ATTR_GREEN | ATTR_BLUE);
+
+ if (page_column >= PageColumns)
+ {
+ WritePage();
+ page_column = 0;
+ }
+ break;
+
+ case 0x1b : /* Escape sequence */
+ ch = getutf8(fp);
+ if (ch == '7')
+ {
+ /*
+ * ESC 7 Reverse full line (0x1b 0x37)
+ */
+
+ if (line > 0)
+ line --;
+ }
+ else if (ch == '8')
+ {
+ /*
+ * ESC 8 Reverse half line (0x1b 0x38)
+ */
+
+ if ((attr & ATTR_RAISED) && line > 0)
+ {
+ attr &= ~ATTR_RAISED;
+ line --;
+ }
+ else if (attr & ATTR_LOWERED)
+ attr &= ~ATTR_LOWERED;
+ else
+ attr |= ATTR_RAISED;
+ }
+ else if (ch == '9')
+ {
+ /*
+ * ESC 9 Forward half line (0x1b 0x39)
+ */
+
+ if ((attr & ATTR_LOWERED) && line < (SizeLines - 1))
+ {
+ attr &= ~ATTR_LOWERED;
+ line ++;
+ }
+ else if (attr & ATTR_RAISED)
+ attr &= ~ATTR_RAISED;
+ else
+ attr |= ATTR_LOWERED;
+ }
+ break;
+
+ default : /* All others... */
+ if (ch < ' ')
+ break; /* Ignore other control chars */
+
+ if (PrettyPrint > PRETTY_PLAIN)
+ {
+ /*
+ * Do highlighting of C/C++ keywords, preprocessor commands,
+ * and comments...
+ */
+
+ if (ch == ' ' && (attr & ATTR_BOLD))
+ {
+ /*
+ * Stop bolding preprocessor command...
+ */
+
+ attr &= ~ATTR_BOLD;
+ }
+ else if (!(isalnum(ch & 255) || ch == '_') && keyptr > keyword)
+ {
+ /*
+ * Look for a keyword...
+ */
+
+ *keyptr = '\0';
+ keyptr = keyword;
+
+ if (bsearch(&keyptr, Keywords, NumKeywords, sizeof(char *),
+ compare_keywords))
+ {
+ /*
+ * Put keywords in boldface...
+ */
+
+ i = page_column * (ColumnWidth + ColumnGutter);
+
+ while (keycol < column)
+ {
+ Page[line][keycol + i].attr |= ATTR_BOLD;
+ keycol ++;
+ }
+ }
+ }
+
+ /*
+ * Look for Syntax-transition Starts...
+ */
+ if (!cmntState && !strState)
+ {
+ if ((isalnum(ch & 255) || ch == '_'))
+ {
+ /*
+ * Add characters to the current keyword (if they'll fit).
+ */
+
+ if (keyptr == keyword)
+ keycol = column;
+
+ if (keyptr < (keyword + sizeof(keyword) - 1))
+ *keyptr++ = ch;
+ }
+ else if (ch == '\"' && lastch != '\\')
+ {
+ /*
+ * Start a dbl-quote string constant...
+ */
+
+ strState = StrBeg;
+ attr = ATTR_BLUE;
+ }
+ else if (ch == '*' && lastch == '/' &&
+ PrettyPrint != PRETTY_SHELL)
+ {
+ /*
+ * Start a C-style comment...
+ */
+
+ cmntState = SNTXstyl;
+ attr = ATTR_ITALIC | ATTR_GREEN;
+ }
+ else if (ch == '/' && lastch == '/' &&
+ PrettyPrint == PRETTY_CODE)
+ {
+ /*
+ * Start a C++-style comment...
+ */
+
+ cmntState = NLstyl;
+ attr = ATTR_ITALIC | ATTR_GREEN;
+ }
+ else if (ch == '#' && PrettyPrint != PRETTY_CODE)
+ {
+ /*
+ * Start a shell-style comment...
+ */
+
+ cmntState = NLstyl;
+ attr = ATTR_ITALIC | ATTR_GREEN;
+ }
+ else if (ch == '#' && column == 0 &&
+ PrettyPrint == PRETTY_CODE)
+ {
+ /*
+ * Start a preprocessor command...
+ */
+
+ attr = ATTR_BOLD | ATTR_RED;
+ }
+ }
+ }
+
+ if (column >= ColumnWidth && WrapLines)
+ { /* Wrap text to margins */
+ column = 0;
+ line ++;
+
+ if (line >= SizeLines)
+ {
+ page_column ++;
+ line = 0;
+
+ if (page_column >= PageColumns)
+ {
+ WritePage();
+ page_column = 0;
+ }
+ }
+ }
+
+ /*
+ * Add text to the current column & line...
+ */
+
+ if (column < ColumnWidth)
+ {
+ i = column + page_column * (ColumnWidth + ColumnGutter);
+
+ if (PrettyPrint)
+ Page[line][i].attr = attr;
+
+ if (ch == ' ' && Page[line][i].ch)
+ ch = Page[line][i].ch;
+ else if (ch == Page[line][i].ch)
+ Page[line][i].attr |= ATTR_BOLD;
+ else if (Page[line][i].ch == '_')
+ Page[line][i].attr |= ATTR_UNDERLINE;
+ else if (ch == '_')
+ {
+ Page[line][i].attr |= ATTR_UNDERLINE;
+
+ if (Page[line][i].ch)
+ ch = Page[line][i].ch;
+ }
+ else
+ Page[line][i].attr = attr;
+
+ Page[line][i].ch = ch;
+ }
+
+ if (PrettyPrint)
+ {
+ if ((ch == '{' || ch == '}') && !cmntState && !strState &&
+ column < ColumnWidth)
+ {
+ /*
+ * Highlight curley braces...
+ */
+
+ Page[line][column].attr |= ATTR_BOLD;
+ }
+ else if ((ch == '/' || ch == '*') && lastch == '/' &&
+ column < ColumnWidth && PrettyPrint != PRETTY_SHELL)
+ {
+ /*
+ * Highlight first comment character...
+ */
+
+ Page[line][column - 1].attr = attr;
+ }
+ else if (ch == '\"' && lastch != '\\' && !cmntState && strState == StrEnd)
+ {
+ /*
+ * End a dbl-quote string constant...
+ */
+
+ strState = NoStr;
+ attr &= ~ATTR_BLUE;
+ }
+ else if (ch == '/' && lastch == '*' && cmntState)
+ {
+ /*
+ * End a C-style comment...
+ */
+
+ cmntState = NoCmnt;
+ attr &= ~(ATTR_ITALIC | ATTR_GREEN);
+ }
+
+ if (strState == StrBeg)
+ strState = StrEnd;
+ }
+
+ column ++;
+ break;
+ }
+
+ /*
+ * Save this character for the next cycle.
+ */
+
+ lastch = ch;
+ }
+
+ /*
+ * Write any remaining page data...
+ */
+
+ if (line > 0 || page_column > 0 || column > 0)
+ WritePage();
+
+ /*
+ * Write the epilog and return...
+ */
+
+ WriteEpilogue();
+
+ if (fp != stdin)
+ fclose(fp);
+
+ if (ppd != NULL)
+ ppdClose(ppd);
+
+ free(Page[0]);
+ free(Page);
+ return (0);
+}
+
+
+/*
+ * 'compare_keywords()' - Compare two C/C++ keywords.
+ */
+
+static int /* O - Result of strcmp */
+compare_keywords(const void *k1, /* I - First keyword */
+ const void *k2) /* I - Second keyword */
+{
+ return (strcmp(*((const char **)k1), *((const char **)k2)));
+}
+
+
+/*
+ * 'getutf8()' - Get a UTF-8 encoded wide character...
+ */
+
+static int /* O - Character or -1 on error */
+getutf8(FILE *fp) /* I - File to read from */
+{
+ int ch; /* Current character value */
+ int next; /* Next character from file */
+
+
+ /*
+ * Read the first character and process things accordingly...
+ *
+ * UTF-8 maps 16-bit characters to:
+ *
+ * 0 to 127 = 0xxxxxxx
+ * 128 to 2047 = 110xxxxx 10yyyyyy (xxxxxyyyyyy)
+ * 2048 to 65535 = 1110xxxx 10yyyyyy 10zzzzzz (xxxxyyyyyyzzzzzz)
+ *
+ * We also accept:
+ *
+ * 128 to 191 = 10xxxxxx
+ *
+ * since this range of values is otherwise undefined unless you are
+ * in the middle of a multi-byte character...
+ *
+ * This code currently does not support anything beyond 16-bit
+ * characters, in part because PostScript doesn't support more than
+ * 16-bit characters...
+ */
+
+ if ((ch = getc(fp)) == EOF)
+ return (EOF);
+
+ if (ch < 0xc0) /* One byte character? */
+ return (ch);
+ else if ((ch & 0xe0) == 0xc0)
+ {
+ /*
+ * Two byte character...
+ */
+
+ if ((next = getc(fp)) == EOF)
+ return (EOF);
+ else
+ return (((ch & 0x1f) << 6) | (next & 0x3f));
+ }
+ else if ((ch & 0xf0) == 0xe0)
+ {
+ /*
+ * Three byte character...
+ */
+
+ if ((next = getc(fp)) == EOF)
+ return (EOF);
+
+ ch = ((ch & 0x0f) << 6) | (next & 0x3f);
+
+ if ((next = getc(fp)) == EOF)
+ return (EOF);
+ else
+ return ((ch << 6) | (next & 0x3f));
+ }
+ else
+ {
+ /*
+ * More than three bytes... We don't support that...
+ */
+
+ return (EOF);
+ }
+}
+
diff --git a/filter/textcommon.h b/filter/textcommon.h
new file mode 100644
index 000000000..36ec180a6
--- /dev/null
+++ b/filter/textcommon.h
@@ -0,0 +1,105 @@
+/*
+ * Common text filter definitions for CUPS.
+ *
+ * Copyright 2007-2010 by Apple Inc.
+ * Copyright 1997-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "common.h"
+
+
+/*
+ * C++ magic...
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/*
+ * Constants...
+ */
+
+#define ATTR_NORMAL 0x00
+#define ATTR_BOLD 0x01
+#define ATTR_ITALIC 0x02
+#define ATTR_BOLDITALIC 0x03
+#define ATTR_FONT 0x03
+
+#define ATTR_UNDERLINE 0x04
+#define ATTR_RAISED 0x08
+#define ATTR_LOWERED 0x10
+#define ATTR_RED 0x20
+#define ATTR_GREEN 0x40
+#define ATTR_BLUE 0x80
+
+#define PRETTY_OFF 0
+#define PRETTY_PLAIN 1
+#define PRETTY_CODE 2
+#define PRETTY_SHELL 3
+#define PRETTY_PERL 4
+#define PRETTY_HTML 5
+
+
+/*
+ * Structures...
+ */
+
+typedef struct /**** Character/attribute structure... ****/
+{
+ unsigned short ch, /* Character */
+ attr; /* Any attributes */
+} lchar_t;
+
+
+/*
+ * Globals...
+ */
+
+extern int WrapLines, /* Wrap text in lines */
+ SizeLines, /* Number of lines on a page */
+ SizeColumns, /* Number of columns on a line */
+ PageColumns, /* Number of columns on a page */
+ ColumnGutter, /* Number of characters between text columns */
+ ColumnWidth, /* Width of each column */
+ PrettyPrint, /* Do pretty code formatting? */
+ Copies; /* Number of copies to produce */
+extern lchar_t **Page; /* Page characters */
+extern int NumPages; /* Number of pages in document */
+extern float CharsPerInch, /* Number of character columns per inch */
+ LinesPerInch; /* Number of lines per inch */
+extern int UTF8, /* Use UTF-8 encoding? */
+ NumKeywords; /* Number of known keywords */
+extern char **Keywords; /* List of known keywords... */
+
+
+/*
+ * Required functions...
+ */
+
+extern int TextMain(const char *name, int argc, char *argv[]);
+extern void WriteEpilogue(void);
+extern void WritePage(void);
+extern void WriteProlog(const char *title, const char *user,
+ const char *classification, const char *label,
+ ppd_file_t *ppd);
+
+
+/*
+ * C++ magic...
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
diff --git a/filter/texttopdf.c b/filter/texttopdf.c
new file mode 100644
index 000000000..55a8309ca
--- /dev/null
+++ b/filter/texttopdf.c
@@ -0,0 +1,1212 @@
+/*
+ * Text to PDF filter for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 2008,2012 by Tobias Hoffmann.
+ * Copyright 2007 by Apple Inc.
+ * Copyright 1993-2007 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * main() - Main entry for text to PDF filter.
+ * WriteEpilogue() - Write the PDF file epilogue.
+ * WritePage() - Write a page of text.
+ * WriteProlog() - Write the PDF file prolog with options.
+ * write_line() - Write a row of text.
+ * write_string() - Write a string of text.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "textcommon.h"
+#include "pdfutils.h"
+#include "fontembed/embed.h"
+#include <assert.h>
+#include "fontembed/sfnt.h"
+#include <fontconfig/fontconfig.h>
+
+/*
+ * Globals...
+ */
+
+#ifdef CUPS_1_4 /* CUPS 1.4.x or newer: only UTF8 is supported */
+int UTF8 = 1; /* Use UTF-8 encoding? */
+#endif /* CUPS_1_4 */
+
+EMB_PARAMS *font_load(const char *font);
+
+EMB_PARAMS *font_load(const char *font)
+{
+ OTF_FILE *otf;
+
+ FcPattern *pattern;
+ FcFontSet *candidates;
+ FcChar8 *fontname = NULL;
+ FcResult result;
+ int i;
+
+ if ( (font[0]=='/')||(font[0]=='.') ) {
+ candidates = NULL;
+ fontname=(FcChar8 *)strdup(font);
+ } else {
+ FcInit ();
+ pattern = FcNameParse ((const FcChar8 *)font);
+ FcPatternAddInteger (pattern, FC_SPACING, FC_MONO); // guide fc, in case substitution becomes necessary
+ FcConfigSubstitute (0, pattern, FcMatchPattern);
+ FcDefaultSubstitute (pattern);
+
+ /* Receive a sorted list of fonts matching our pattern */
+ candidates = FcFontSort (0, pattern, FcFalse, 0, &result);
+ FcPatternDestroy (pattern);
+
+ if (candidates) {
+ /* In the list of fonts returned by FcFontSort()
+ find the first one that is both in TrueType format and monospaced */
+ for (i = 0; i < candidates->nfont; i++) {
+ FcChar8 *fontformat=NULL; // TODO? or just try?
+ int spacing=0; // sane default, as FC_MONO == 100
+ FcPatternGetString (candidates->fonts[i], FC_FONTFORMAT, 0, &fontformat);
+ FcPatternGetInteger (candidates->fonts[i], FC_SPACING, 0, &spacing);
+
+ if ( (fontformat)&&(spacing == FC_MONO) ) {
+ if (strcmp((const char *)fontformat, "TrueType") == 0) {
+ fontname = FcPatternFormat (candidates->fonts[i], (const FcChar8 *)"%{file|cescape}/%{index}");
+ break;
+ } else if (strcmp((const char *)fontformat, "CFF") == 0) {
+ fontname = FcPatternFormat (candidates->fonts[i], (const FcChar8 *)"%{file|cescape}"); // TTC only possible with non-cff glyphs!
+ break;
+ }
+ }
+ }
+ FcFontSetDestroy (candidates);
+ }
+ }
+
+ if (!fontname) {
+ // TODO: try /usr/share/fonts/*/*/%s.ttf
+ fprintf(stderr,"No viable font found\n");
+ return NULL;
+ }
+
+ otf = otf_load((const char *)fontname);
+ free(fontname);
+ if (!otf) {
+ return NULL;
+ }
+
+ FONTFILE *ff=fontfile_open_sfnt(otf);
+ assert(ff);
+ EMB_PARAMS *emb=emb_new(ff,
+ EMB_DEST_PDF16,
+ EMB_C_FORCE_MULTIBYTE|
+ EMB_C_TAKE_FONTFILE);
+ assert(emb);
+ assert(emb->plan&EMB_A_MULTIBYTE);
+ return emb;
+}
+
+EMB_PARAMS *font_std(const char *name)
+{
+ FONTFILE *ff=fontfile_open_std(name);
+ assert(ff);
+ EMB_PARAMS *emb=emb_new(ff,
+ EMB_DEST_PDF16,
+ EMB_C_TAKE_FONTFILE);
+ assert(emb);
+ return emb;
+}
+
+/*
+ * Globals...
+ */
+
+int NumFonts; /* Number of fonts to use */
+EMB_PARAMS *Fonts[256][4]; /* Fonts to use */
+unsigned short Chars[256]; /* Input char to unicode */
+unsigned char Codes[65536]; /* Unicode glyph mapping to font */
+int Widths[256]; /* Widths of each font */
+int Directions[256];/* Text directions for each font */
+pdfOut *pdf;
+int FontResource; /* Object number of font resource dictionary */
+float FontScaleX,FontScaleY; /* The font matrix */
+lchar_t *Title,*Date; /* The title and date strings */
+
+/*
+ * Local functions...
+ */
+
+static void write_line(int row, lchar_t *line);
+static void write_string(int col, int row, int len, lchar_t *s);
+static lchar_t *make_wide(const char *buf);
+static void write_font_str(float x,float y,int fontid, lchar_t *str, int len);
+static void write_pretty_header();
+
+
+/*
+ * 'main()' - Main entry for text to PDF filter.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ return (TextMain("texttopdf", argc, argv));
+}
+
+
+/*
+ * 'WriteEpilogue()' - Write the PDF file epilogue.
+ */
+
+void
+WriteEpilogue(void)
+{
+ static char *names[] = /* Font names */
+ { "FN","FB","FI","FBI" };
+ int i,j;
+
+ // embed fonts
+ for (i = PrettyPrint ? 3 : 1; i >= 0; i --) {
+ for (j = 0; j < NumFonts; j ++)
+ {
+ EMB_PARAMS *emb=Fonts[j][i];
+ if (emb->font->fobj) { // already embedded
+ continue;
+ }
+ if ( (!emb->subset)||(bits_used(emb->subset,emb->font->sfnt->numGlyphs)) ) {
+ emb->font->fobj=pdfOut_write_font(pdf,emb);
+ assert(emb->font->fobj);
+ }
+ }
+ }
+
+ /*
+ * Create the global fontdict
+ */
+
+ // now fix FontResource
+ pdf->xref[FontResource-1]=pdf->filepos;
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "<<\n",
+ FontResource);
+
+ for (i = PrettyPrint ? 3 : 1; i >= 0; i --) {
+ for (j = 0; j < NumFonts; j ++) {
+ EMB_PARAMS *emb=Fonts[j][i];
+ if (emb->font->fobj) { // used
+ pdfOut_printf(pdf," /%s%02x %d 0 R\n",names[i],j,emb->font->fobj);
+ }
+ }
+ }
+
+ pdfOut_printf(pdf,">>\n"
+ "endobj\n");
+
+ pdfOut_finish_pdf(pdf);
+
+ pdfOut_free(pdf);
+}
+
+/*
+ * {{{ 'WritePage()' - Write a page of text.
+ */
+
+void
+WritePage(void)
+{
+ int line; /* Current line */
+
+ int content=pdfOut_add_xref(pdf);
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "<</Length %d 0 R\n"
+ ">>\n"
+ "stream\n"
+ "q\n"
+ ,content,content+1);
+ long size=-(pdf->filepos-2);
+
+ NumPages ++;
+ if (PrettyPrint)
+ write_pretty_header(pdf);
+
+ for (line = 0; line < SizeLines; line ++)
+ write_line(line, Page[line]);
+
+ size+=pdf->filepos+2;
+ pdfOut_printf(pdf,"Q\n"
+ "endstream\n"
+ "endobj\n");
+
+ int len_obj=pdfOut_add_xref(pdf);
+ assert(len_obj==content+1);
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "%ld\n"
+ "endobj\n",
+ len_obj,size);
+
+ int obj=pdfOut_add_xref(pdf);
+ pdfOut_printf(pdf,"%d 0 obj\n"
+ "<</Type/Page\n"
+ " /Parent 1 0 R\n"
+ " /MediaBox [0 0 %.0f %.0f]\n"
+ " /Contents %d 0 R\n"
+ " /Resources << /Font %d 0 R >>\n"
+ ">>\n"
+ "endobj\n",
+ obj,PageWidth,PageLength,content,FontResource);
+ pdfOut_add_page(pdf,obj);
+
+ memset(Page[0], 0, sizeof(lchar_t) * SizeColumns * SizeLines);
+}
+// }}}
+
+/*
+ * {{{'WriteProlog()' - Write the PDF file prolog with options.
+ */
+
+void
+WriteProlog(const char *title, /* I - Title of job */
+ const char *user, /* I - Username */
+ const char *classification, /* I - Classification */
+ const char *label, /* I - Page label */
+ ppd_file_t *ppd) /* I - PPD file info */
+{
+ int i, j, k; /* Looping vars */
+ char *charset; /* Character set string */
+ char filename[1024]; /* Glyph filenames */
+ FILE *fp; /* Glyph files */
+ const char *datadir; /* CUPS_DATADIR environment variable */
+ char line[1024], /* Line from file */
+ *lineptr, /* Pointer into line */
+ *valptr; /* Pointer to value in line */
+#ifndef CUPS_1_4 /* CUPS 1.4.x or newer: support for non-utf8 removed */
+ int ch, unicode; /* Character values */
+#endif
+ int start, end; /* Start and end values for range */
+ time_t curtime; /* Current time */
+ struct tm *curtm; /* Current date */
+ char curdate[255]; /* Current date (text format) */
+ int num_fonts=0; /* Number of unique fonts */
+ EMB_PARAMS *fonts[1024]; /* Unique fonts */
+ char *fontnames[1024]; /* Unique fonts */
+#if 0
+ static char *names[] = /* Font names */
+ {
+ "FN","FB","FI"
+ /*
+ "cupsNormal",
+ "cupsBold",
+ "cupsItalic"
+ */
+ };
+#endif
+
+
+ /*
+ * Get the data directory...
+ */
+
+ if ((datadir = getenv("CUPS_DATADIR")) == NULL)
+ datadir = CUPS_DATADIR;
+
+ /*
+ * Adjust margins as necessary...
+ */
+
+ if (classification || label)
+ {
+ /*
+ * Leave room for labels...
+ */
+
+ PageBottom += 36;
+ PageTop -= 36;
+ }
+
+ if (PageColumns > 1)
+ {
+ ColumnGutter = CharsPerInch / 2;
+ ColumnWidth = (SizeColumns - ColumnGutter * (PageColumns - 1)) /
+ PageColumns;
+ }
+ else
+ ColumnWidth = SizeColumns;
+
+ /*
+ * {{{ Output the PDF header...
+ */
+
+ assert(!pdf);
+ pdf=pdfOut_new();
+ assert(pdf);
+
+ pdfOut_begin_pdf(pdf);
+ pdfOut_printf(pdf,"%%cupsRotation: %d\n", (Orientation & 3) * 90); // TODO?
+
+ pdfOut_add_kv(pdf,"Creator","texttopdf/" PACKAGE_VERSION);
+
+ curtime = time(NULL);
+ curtm = localtime(&curtime);
+ strftime(curdate, sizeof(curdate), "%c", curtm);
+
+ pdfOut_add_kv(pdf,"CreationDate",pdfOut_to_pdfdate(curtm));
+ pdfOut_add_kv(pdf,"Title",title);
+ pdfOut_add_kv(pdf,"Author",user); // was(PostScript): /For
+ // }}}
+
+ /*
+ * {{{ Initialize globals...
+ */
+
+ NumFonts = 0;
+ memset(Fonts, 0, sizeof(Fonts));
+ memset(Chars, 0, sizeof(Chars));
+ memset(Codes, 0, sizeof(Codes));
+ // }}}
+
+ /*
+ * Get the output character set...
+ */
+
+ charset = getenv("CHARSET");
+ if (charset != NULL && strcmp(charset, "us-ascii") != 0) // {{{
+ {
+ snprintf(filename, sizeof(filename), "%s/charsets/pdf.%s", datadir, charset);
+
+ if ((fp = fopen(filename, "r")) == NULL)
+ {
+ /*
+ * Can't open charset file!
+ */
+
+ fprintf(stderr, "ERROR: Unable to open %s: %s\n", filename,
+ strerror(errno));
+ exit(1);
+ }
+
+ /*
+ * Opened charset file; now see if this is really a charset file...
+ */
+
+ if (fgets(line, sizeof(line), fp) == NULL)
+ {
+ /*
+ * Bad/empty charset file!
+ */
+
+ fclose(fp);
+ fprintf(stderr, "ERROR: Bad charset file %s\n", filename);
+ exit(1);
+ }
+
+ if (strncmp(line, "charset", 7) != 0)
+ {
+ /*
+ * Bad format/not a charset file!
+ */
+
+ fclose(fp);
+ fprintf(stderr, "ERROR: Bad charset file %s\n", filename);
+ exit(1);
+ }
+
+ /*
+ * See if this is an 8-bit or UTF-8 character set file...
+ */
+
+ line[strlen(line) - 1] = '\0'; /* Drop \n */
+ for (lineptr = line + 7; isspace(*lineptr & 255); lineptr ++); /* Skip whitespace */
+
+#ifndef CUPS_1_4 /* CUPS 1.4.x or newer: support for non-utf8 removed */
+ if (strcmp(lineptr, "8bit") == 0) // {{{
+ {
+ /*
+ * 8-bit text...
+ */
+
+ UTF8 = 0;
+ NumFonts = 0;
+
+ /*
+ * Read the font description(s)...
+ */
+
+ while (fgets(line, sizeof(line), fp) != NULL)
+ {
+ /*
+ * Skip comment and blank lines...
+ */
+
+ if (line[0] == '#' || line[0] == '\n')
+ continue;
+
+ /*
+ * Read the font descriptions that should look like:
+ *
+ * first last direction width normal [bold italic bold-italic]
+ */
+
+ lineptr = line;
+
+ start = strtol(lineptr, &lineptr, 16);
+ end = strtol(lineptr, &lineptr, 16);
+
+ while (isspace(*lineptr & 255))
+ lineptr ++;
+
+ if (!*lineptr)
+ break; /* Must be a font mapping */
+
+ valptr = lineptr;
+
+ while (!isspace(*lineptr & 255) && *lineptr)
+ lineptr ++;
+
+ if (!*lineptr)
+ {
+ /*
+ * Can't have a font without all required values...
+ */
+
+ fprintf(stderr, "ERROR: Bad font description line: %s\n", valptr);
+ fclose(fp);
+ exit(1);
+ }
+
+ *lineptr++ = '\0';
+
+ if (strcmp(valptr, "ltor") == 0)
+ Directions[NumFonts] = 1;
+ else if (strcmp(valptr, "rtol") == 0)
+ Directions[NumFonts] = -1;
+ else
+ {
+ fprintf(stderr, "ERROR: Bad text direction %s\n", valptr);
+ fclose(fp);
+ exit(1);
+ }
+
+ /*
+ * Got the direction, now get the width...
+ */
+
+ while (isspace(*lineptr & 255))
+ lineptr ++;
+
+ valptr = lineptr;
+
+ while (!isspace(*lineptr & 255) && *lineptr)
+ lineptr ++;
+
+ if (!*lineptr)
+ {
+ /*
+ * Can't have a font without all required values...
+ */
+
+ fprintf(stderr, "ERROR: Bad font description line: %s\n", valptr);
+ fclose(fp);
+ exit(1);
+ }
+
+ *lineptr++ = '\0';
+
+ if (strcmp(valptr, "single") == 0)
+ Widths[NumFonts] = 1;
+ else if (strcmp(valptr, "double") == 0)
+ Widths[NumFonts] = 2;
+ else
+ {
+ fprintf(stderr, "ERROR: Bad text width %s\n", valptr);
+ fclose(fp);
+ exit(1);
+ }
+
+ /*
+ * Get the fonts...
+ */
+
+ for (i = 0; *lineptr && i < 4; i ++)
+ {
+ while (isspace(*lineptr & 255))
+ lineptr ++;
+
+ valptr = lineptr;
+
+ while (!isspace(*lineptr & 255) && *lineptr)
+ lineptr ++;
+
+ if (*lineptr)
+ *lineptr++ = '\0';
+
+ if (lineptr > valptr) {
+ // search for duplicates
+ for (k = 0; k < num_fonts; k ++)
+ if (strcmp(valptr, fontnames[k]) == 0) {
+ Fonts[NumFonts][i] = fonts[k];
+ break;
+ }
+
+ if (k==num_fonts) { // not found
+ fonts[num_fonts] = Fonts[NumFonts][i] = font_load(valptr);
+ if (!fonts[num_fonts]) { // font missing/corrupt, replace by first
+ fprintf(stderr,"WARNING: Ignored bad font \"%s\"\n",valptr);
+ break;
+ }
+ fontnames[num_fonts++] = strdup(valptr);
+ }
+ }
+ }
+
+ /* ignore complete range, when the first font is not available */
+ if (i==0) {
+ continue;
+ }
+
+ /*
+ * Fill in remaining fonts as needed...
+ */
+
+ for (j = i; j < 4; j ++)
+ Fonts[NumFonts][j] = Fonts[NumFonts][0];
+
+ /*
+ * Define the character mappings...
+ */
+
+ for (i = start; i <= end; i ++)
+ Codes[i] = NumFonts;
+
+ NumFonts ++;
+ }
+
+ /*
+ * Read encoding lines...
+ */
+
+ do
+ {
+ /*
+ * Skip comment and blank lines...
+ */
+
+ if (line[0] == '#' || line[0] == '\n')
+ continue;
+
+ /*
+ * Grab the character and unicode glyph number.
+ */
+
+ if (sscanf(line, "%x%x", &ch, &unicode) == 2 && ch < 256)
+ Chars[ch] = unicode;
+ }
+ while (fgets(line, sizeof(line), fp) != NULL);
+
+ fclose(fp);
+ } else // }}}
+#endif
+ if (strcmp(lineptr, "utf8") == 0) { // {{{
+ /*
+ * UTF-8 (Unicode) text...
+ */
+
+ UTF8 = 1;
+
+ /*
+ * Read the font descriptions...
+ */
+
+ NumFonts = 0;
+
+ while (fgets(line, sizeof(line), fp) != NULL)
+ {
+ /*
+ * Skip comment and blank lines...
+ */
+
+ if (line[0] == '#' || line[0] == '\n')
+ continue;
+
+ /*
+ * Read the font descriptions that should look like:
+ *
+ * start end direction width normal [bold italic bold-italic]
+ */
+
+ lineptr = line;
+
+ start = strtol(lineptr, &lineptr, 16);
+ end = strtol(lineptr, &lineptr, 16);
+
+ while (isspace(*lineptr & 255))
+ lineptr ++;
+
+ valptr = lineptr;
+
+ while (!isspace(*lineptr & 255) && *lineptr)
+ lineptr ++;
+
+ if (!*lineptr)
+ {
+ /*
+ * Can't have a font without all required values...
+ */
+
+ fprintf(stderr, "ERROR: Bad font description line: %s\n", valptr);
+ fclose(fp);
+ exit(1);
+ }
+
+ *lineptr++ = '\0';
+
+ if (strcmp(valptr, "ltor") == 0)
+ Directions[NumFonts] = 1;
+ else if (strcmp(valptr, "rtol") == 0)
+ Directions[NumFonts] = -1;
+ else
+ {
+ fprintf(stderr, "ERROR: Bad text direction %s\n", valptr);
+ fclose(fp);
+ exit(1);
+ }
+
+ /*
+ * Got the direction, now get the width...
+ */
+
+ while (isspace(*lineptr & 255))
+ lineptr ++;
+
+ valptr = lineptr;
+
+ while (!isspace(*lineptr & 255) && *lineptr)
+ lineptr ++;
+
+ if (!*lineptr)
+ {
+ /*
+ * Can't have a font without all required values...
+ */
+
+ fprintf(stderr, "ERROR: Bad font description line: %s\n", valptr);
+ fclose(fp);
+ exit(1);
+ }
+
+ *lineptr++ = '\0';
+
+ if (strcmp(valptr, "single") == 0)
+ Widths[NumFonts] = 1;
+ else if (strcmp(valptr, "double") == 0)
+ Widths[NumFonts] = 2;
+ else
+ {
+ fprintf(stderr, "ERROR: Bad text width %s\n", valptr);
+ fclose(fp);
+ exit(1);
+ }
+
+ /*
+ * Get the fonts...
+ */
+
+ for (i = 0; *lineptr && i < 4; i ++)
+ {
+ while (isspace(*lineptr & 255))
+ lineptr ++;
+
+ valptr = lineptr;
+
+ while (!isspace(*lineptr & 255) && *lineptr)
+ lineptr ++;
+
+ if (*lineptr)
+ *lineptr++ = '\0';
+
+ if (lineptr > valptr) {
+ // search for duplicates
+ for (k = 0; k < num_fonts; k ++)
+ if (strcmp(valptr, fontnames[k]) == 0) {
+ Fonts[NumFonts][i] = fonts[k];
+ break;
+ }
+
+ if (k==num_fonts) { // not found
+ fonts[num_fonts] = Fonts[NumFonts][i] = font_load(valptr);
+ if (!fonts[num_fonts]) { // font missing/corrupt, replace by first
+ fprintf(stderr,"WARNING: Ignored bad font \"%s\"\n",valptr);
+ break;
+ }
+ fontnames[num_fonts++] = strdup(valptr);
+ }
+ }
+ }
+
+ /* ignore complete range, when the first font is not available */
+ if (i==0) {
+ continue;
+ }
+
+ /*
+ * Fill in remaining fonts as needed...
+ */
+
+ for (j = i; j < 4; j ++)
+ Fonts[NumFonts][j] = Fonts[NumFonts][0];
+
+ /*
+ * Define the character mappings...
+ */
+
+ for (i = start; i <= end; i ++)
+ {
+ Codes[i] = NumFonts;
+ }
+
+ /*
+ * Move to the next font, stopping if needed...
+ */
+
+ NumFonts ++;
+ if (NumFonts >= 256)
+ break;
+ }
+
+ fclose(fp);
+ } // }}}
+ else // {{{
+ {
+ fprintf(stderr, "ERROR: Bad charset type %s\n", lineptr);
+ fclose(fp);
+ exit(1);
+ } // }}}
+ } // }}}
+ else // {{{ Standard ASCII
+ {
+ /*
+ * Standard ASCII output just uses Courier, Courier-Bold, and
+ * possibly Courier-Oblique.
+ */
+
+ NumFonts = 1;
+
+ Fonts[0][ATTR_NORMAL] = font_std("Courier");
+ Fonts[0][ATTR_BOLD] = font_std("Courier-Bold");
+ Fonts[0][ATTR_ITALIC] = font_std("Courier-Oblique");
+ Fonts[0][ATTR_BOLDITALIC] = font_std("Courier-BoldOblique");
+
+ Widths[0] = 1;
+ Directions[0] = 1;
+
+ /*
+ * Define US-ASCII characters...
+ */
+
+ for (i = 32; i < 127; i ++)
+ {
+ Chars[i] = i;
+ Codes[i] = NumFonts-1;
+ }
+ }
+ // }}}
+
+ if (NumFonts==0) {
+ fprintf(stderr, "ERROR: No usable font available\n");
+ exit(1);
+ }
+
+ FontScaleX=120.0 / CharsPerInch;
+ FontScaleY=68.0 / LinesPerInch;
+
+ // allocate now, for pages to use. will be fixed in epilogue
+ FontResource=pdfOut_add_xref(pdf);
+
+ if (PrettyPrint)
+ {
+ Date=make_wide(curdate);
+ Title=make_wide(title);
+ }
+}
+// }}}
+
+/*
+ * {{{ 'write_line()' - Write a row of text.
+ */
+
+static void
+write_line(int row, /* I - Row number (0 to N) */
+ lchar_t *line) /* I - Line to print */
+{
+ int i; /* Looping var */
+ int col,xcol,xwid; /* Current column */
+ int attr; /* Current attribute */
+ int font, /* Font to use */
+ lastfont, /* Last font */
+ mono; /* Monospaced? */
+ lchar_t *start; /* First character in sequence */
+
+
+ xcol=0;
+ for (col = 0, start = line; col < SizeColumns;)
+ {
+ while (col < SizeColumns && (line->ch == ' ' || line->ch == 0))
+ {
+ col ++;
+ xcol ++;
+ line ++;
+ }
+
+ if (col >= SizeColumns)
+ break;
+
+ if (NumFonts == 1)
+ {
+ /*
+ * All characters in a single font - assume monospaced and single width...
+ */
+
+ attr = line->attr;
+ start = line;
+
+ while (col < SizeColumns && line->ch != 0 && attr == line->attr)
+ {
+ col ++;
+ line ++;
+ }
+
+ write_string(col - (line - start), row, line - start, start);
+ }
+ else
+ {
+ /*
+ * Multiple fonts; break up based on the font...
+ */
+
+ attr = line->attr;
+ start = line;
+ xwid = 0;
+ if (UTF8) {
+ lastfont = Codes[line->ch];
+ } else {
+ lastfont = Codes[Chars[line->ch]];
+ }
+// mono = strncmp(Fonts[lastfont][0], "Courier", 7) == 0;
+mono=1; // TODO
+
+ col ++;
+ xwid += Widths[lastfont];
+ line ++;
+
+ if (mono)
+ {
+ while (col < SizeColumns && line->ch != 0 && attr == line->attr)
+ {
+ if (UTF8) {
+ font = Codes[line->ch];
+ } else {
+ font = Codes[Chars[line->ch]];
+ }
+ if (/*strncmp(Fonts[font][0], "Courier", 7) != 0 ||*/ // TODO
+ font != lastfont)
+ break;
+
+ col ++;
+ xwid += Widths[lastfont];
+ line ++;
+ }
+ }
+
+ if (Directions[lastfont] > 0) {
+ write_string(xcol, row, line - start, start);
+ xcol += xwid;
+ }
+ else
+ {
+ /*
+ * Do right-to-left text... ; assume no font change without direction change
+ */
+
+ while (col < SizeColumns && line->ch != 0 && attr == line->attr)
+ {
+ if (UTF8) {
+ font = Codes[line->ch];
+ } else {
+ font = Codes[Chars[line->ch]];
+ }
+ if (Directions[font] > 0 &&
+ !ispunct(line->ch & 255) && !isspace(line->ch & 255))
+ break;
+
+ col ++;
+ xwid += Widths[lastfont];
+ line ++;
+ }
+
+ for (i = 1; start < line; i ++, start ++)
+ if (!isspace(start->ch & 255)) {
+ xwid-=Widths[lastfont];
+ write_string(xcol + xwid, row, 1, start);
+ } else {
+ xwid--;
+ }
+ }
+ }
+ }
+}
+// }}}
+
+static lchar_t *make_wide(const char *buf) // {{{ - convert to lchar_t
+{
+ const unsigned char *utf8; /* UTF8 text */
+ lchar_t *ret,*out;
+
+ // this is enough, utf8 chars will only require less space
+ out=ret=malloc((strlen(buf)+1)*sizeof(lchar_t));
+
+ utf8 = (const unsigned char *)buf;
+ while (*utf8)
+ {
+ out->attr=0;
+
+ if (*utf8 < 0xc0 || !UTF8)
+ out->ch = *utf8 ++;
+ else if ((*utf8 & 0xe0) == 0xc0)
+ {
+ /*
+ * Two byte character...
+ */
+
+ out->ch = ((utf8[0] & 0x1f) << 6) | (utf8[1] & 0x3f);
+ utf8 += 2;
+ }
+ else
+ {
+ /*
+ * Three byte character...
+ */
+
+ out->ch = ((((utf8[0] & 0x1f) << 6) | (utf8[1] & 0x3f)) << 6) |
+ (utf8[2] & 0x3f);
+ utf8 += 3;
+ }
+
+ out++;
+ }
+ out->ch=out->attr=0;
+ return ret;
+}
+// }}}
+
+/*
+ * {{{ 'write_string()' - Write a string of text.
+ */
+
+static void
+write_string(int col, /* I - Start column */
+ int row, /* I - Row */
+ int len, /* I - Number of characters */
+ lchar_t *s) /* I - String to print */
+{
+ float x, y; /* Position of text */
+ unsigned attr; /* Character attributes */
+
+
+ /*
+ * Position the text and set the font...
+ */
+
+ if (Duplex && (NumPages & 1) == 0)
+ {
+ x = PageWidth - PageRight;
+ y = PageTop;
+ }
+ else
+ {
+ x = PageLeft;
+ y = PageTop;
+ }
+
+ x += (float)col * 72.0f / (float)CharsPerInch;
+ y -= (float)(row + 0.843) * 72.0f / (float)LinesPerInch;
+
+ attr = s->attr;
+
+ if (attr & ATTR_RAISED)
+ y += 36.0 / (float)LinesPerInch;
+ else if (attr & ATTR_LOWERED)
+ y -= 36.0 / (float)LinesPerInch;
+
+ if (attr & ATTR_UNDERLINE)
+ pdfOut_printf(pdf,"q 0.5 w 0 g %.3f %.3f m %.3f %.3f l S Q ",
+ x, y - 6.8 / LinesPerInch,
+ x + (float)len * 72.0 / (float)CharsPerInch,
+ y - 6.8 / LinesPerInch);
+
+ if (PrettyPrint)
+ {
+ if (ColorDevice) {
+ if (attr & ATTR_RED)
+ pdfOut_printf(pdf,"0.5 0 0 rg\n");
+ else if (attr & ATTR_GREEN)
+ pdfOut_printf(pdf,"0 0.5 0 rg\n");
+ else if (attr & ATTR_BLUE)
+ pdfOut_printf(pdf,"0 0 0.5 rg\n");
+ else
+ pdfOut_printf(pdf,"0 g\n");
+ } else {
+ if ( (attr & ATTR_RED)||(attr & ATTR_GREEN)||(attr & ATTR_BLUE) )
+ pdfOut_printf(pdf,"0.2 g\n");
+ else
+ pdfOut_printf(pdf,"0 g\n");
+ }
+ }
+ else
+ pdfOut_printf(pdf,"0 g\n");
+
+ write_font_str(x,y,attr & ATTR_FONT,s,len);
+}
+// }}}
+
+// {{{ show >len characters from >str, using the right font(s) at >x,>y
+static void write_font_str(float x,float y,int fontid, lchar_t *str, int len)
+{
+ unsigned short ch; /* Current character */
+ static char *names[] = /* Font names */
+ { "FN","FB","FI","FBI" };
+
+ if (len==-1) {
+ for (len=0;str[len].ch;len++);
+ }
+ pdfOut_printf(pdf,"BT\n");
+
+ if (x == (int)x)
+ pdfOut_printf(pdf," %.0f ", x);
+ else
+ pdfOut_printf(pdf," %.3f ", x);
+
+ if (y == (int)y)
+ pdfOut_printf(pdf,"%.0f Td\n", y);
+ else
+ pdfOut_printf(pdf,"%.3f Td\n", y);
+
+ int lastfont,font;
+
+ // split on font boundary
+ while (len > 0)
+ {
+ /*
+ * Write a hex string...
+ */
+ if (UTF8) {
+ lastfont=Codes[str->ch];
+ } else {
+ lastfont=Codes[Chars[str->ch]];
+ }
+ EMB_PARAMS *emb=Fonts[lastfont][fontid];
+ OTF_FILE *otf=emb->font->sfnt;
+
+ if (otf) { // TODO?
+ pdfOut_printf(pdf," %.3f Tz\n",
+ FontScaleX*600.0/(otf_get_width(otf,4)*1000.0/otf->unitsPerEm)*100.0/FontScaleY); // TODO?
+ // gid==4 is usually '!', the char after space. We just need "the" width for the monospaced font. gid==0 is bad, and space might also be bad.
+ } else {
+ pdfOut_printf(pdf," %.3f Tz\n",
+ FontScaleX*100.0/FontScaleY); // TODO?
+ }
+
+ pdfOut_printf(pdf," /%s%02x %.3f Tf <",
+ names[fontid],lastfont,FontScaleY);
+
+ while (len > 0)
+ {
+ if (UTF8) {
+ ch=str->ch;
+ } else {
+ ch=Chars[str->ch];
+ }
+
+ font = Codes[ch];
+ if (lastfont != font) { // only possible, when not used via write_string (e.g. utf-8filename.txt in prettyprint)
+ break;
+ }
+ if (otf) { // TODO
+ const unsigned short gid=emb_get(emb,ch);
+ pdfOut_printf(pdf,"%04x", gid);
+ } else { // std 14 font with 7-bit us-ascii uses single byte encoding, TODO
+ pdfOut_printf(pdf,"%02x",ch);
+ }
+
+ len --;
+ str ++;
+ }
+
+ pdfOut_printf(pdf,"> Tj\n");
+ }
+ pdfOut_printf(pdf,"ET\n");
+}
+// }}}
+
+static float stringwidth_x(lchar_t *str)
+{
+ int len;
+
+ for (len=0;str[len].ch;len++);
+
+ return (float)len * 72.0 / (float)CharsPerInch;
+}
+
+static void write_pretty_header() // {{{
+{
+ float x,y;
+ pdfOut_printf(pdf,"q\n"
+ "0.9 g\n");
+
+ if (Duplex && (NumPages & 1) == 0) {
+ x = PageWidth - PageRight;
+ y = PageTop + 72.0f / LinesPerInch;
+ } else {
+ x = PageLeft;
+ y = PageTop + 72.0f / LinesPerInch;
+ }
+
+ pdfOut_printf(pdf,"1 0 0 1 %.3f %.3f cm\n",x,y); // translate
+ pdfOut_printf(pdf,"0 0 %.3f %.3f re f\n",
+ PageRight - PageLeft, 144.0f / LinesPerInch);
+ pdfOut_printf(pdf,"0 g 0 G\n");
+
+ if (Duplex && (NumPages & 1) == 0) {
+ x = PageRight - PageLeft - 36.0f / LinesPerInch - stringwidth_x(Title);
+ y = (0.5f + 0.157f) * 72.0f / LinesPerInch;
+ } else {
+ x = 36.0f / LinesPerInch;
+ y = (0.5f + 0.157f) * 72.0f / LinesPerInch;
+ }
+ write_font_str(x,y,ATTR_BOLD,Title,-1);
+
+ x = (-stringwidth_x(Date) + PageRight - PageLeft) * 0.5;
+ write_font_str(x,y,ATTR_BOLD,Date,-1);
+
+ // convert pagenumber to string
+ char tmp[20];
+ tmp[19]=0;
+ snprintf(tmp,19,"%d",NumPages);
+ lchar_t *pagestr=make_wide(tmp);
+
+ if (Duplex && (NumPages & 1) == 0) {
+ x = 36.0f / LinesPerInch;
+ } else {
+ x = PageRight - PageLeft - 36.0f / LinesPerInch - stringwidth_x(pagestr);
+ }
+ write_font_str(x,y,ATTR_BOLD,pagestr,-1);
+ free(pagestr);
+
+ pdfOut_printf(pdf,"Q\n");
+}
+// }}}
+
diff --git a/filter/texttops b/filter/texttops
new file mode 100644
index 000000000..23609b999
--- /dev/null
+++ b/filter/texttops
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+# texttops - This is a Text-to-PostScript filter for CUPS
+#
+# Note: This wrapper filter is only included for backward compatibility with
+# certan custom configurations. It is not mentioned in any of the .convs
+# files included in this package and therefore never used with the default
+# configuration. It makes sure that third-party PPD files referring to
+# texttops explicitly or custom configurations (in /etc/cups/*.convs files)
+# will not break.
+#
+# DO NOT create new PPD or .convs files using this filter! texttops is
+# DEPRECATED!
+
+# (C) 2012 Till Kamppeter <till.kamppeter@gmail.com>
+#
+# Released under GPL 2 or later
+#
+
+PDF2PS=`which pdf2ps`
+
+echo "DEBUG: texttops argv[$#] = $@" >&2
+echo "DEBUG: PPD: $PPD" >&2
+
+if [ $# -lt 5 -o $# -gt 6 ]; then
+ echo "ERROR: $0 job-id user title copies options [file]" >&2
+ exit 1
+fi
+
+# Read from given file.
+if [ -n "$6" ]; then
+ exec <"$6"
+fi
+
+$CUPS_SERVERBIN/filter/texttopdf "$1" "$2" "$3" "$4" "$5" | $PDF2PS - -
diff --git a/filter/texttotext.c b/filter/texttotext.c
new file mode 100644
index 000000000..8684d6cad
--- /dev/null
+++ b/filter/texttotext.c
@@ -0,0 +1,980 @@
+/*
+ * texttotext
+ *
+ * Filter to print text files on text-only printers. The filter has
+ * several configuration options controlled by a PPD file so that it
+ * should work with most printer models.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1997-2006 by Easy Software Products.
+ * Copyright 2011-2016 by Till Kamppeter
+ *
+ * Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <config.h>
+#include <cups/cups.h>
+#include <cups/ppd.h>
+#include <cups/file.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <limits.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <ctype.h>
+#include <iconv.h>
+#include <cupsfilters/image-private.h>
+
+/*
+ * Type definitions
+ */
+
+typedef enum overlong_line_e {
+ TRUNCATE = 0,
+ WORDWRAP = 1,
+ WRAPATWIDTH = 2
+} overlong_line_t;
+
+typedef enum newline_char_e {
+ LF = 0,
+ CR = 1,
+ CRLF = 2
+} newline_char_t;
+
+
+/*
+ * Local functions...
+ */
+
+static int is_true(const char *value);
+static int is_false(const char *value);
+static int check_range(char *page_ranges, int even_pages,
+ int odd_pages, int page);
+static void cancel_job(int sig);
+
+
+/*
+ * Local globals...
+ */
+
+static int job_canceled = 0;
+
+
+/*
+ * 'main()' - Main entry for filter...
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line args */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i, j; /* Looping vars */
+ char *p;
+ int exit_status = 0; /* Exit status */
+ int fd = 0; /* Copy file descriptor */
+ char *filename, /* Text file to convert */
+ tempfile[1024]; /* Temporary file */
+ char buffer[8192]; /* Copy buffer */
+ int bytes; /* Bytes copied */
+ int num_copies; /* Number of copies */
+ ppd_file_t *ppd; /* PPD file */
+ int num_options; /* Number of options */
+ cups_option_t *options; /* Options */
+ const char *val, *val2; /* Option value */
+ ppd_attr_t *ppd_attr; /* Attribute taken from the PPD */
+ int num_lines = 66, /* Lines per page */
+ num_columns = 80; /* Characters per line */
+ int page_left = 0, /* Page margins */
+ page_right = 0,
+ page_top = 0,
+ page_bottom = 0;
+ int text_width, /* Width of the text area on the page */
+ text_height; /* Height of the text area on the
+ page */
+ char encoding[64]; /* The printer'a encoding, to which
+ the incoming UTF-8 is converted,
+ must be 1-byte-per-character */
+ overlong_line_t overlong_lines = WRAPATWIDTH;
+ /* How to treat overlong lines */
+ int tab_width = 8; /* Turn tabs to spaces with given
+ width */
+ int pagination = 1; /* Paginate text to allow margins
+ and page management */
+ int send_ff = 1; /* Send form-feed char at the end of
+ each page */
+ newline_char_t newline_char = CRLF; /* Character to send at end of line */
+ char *newline_char_str;
+ char *page_ranges = NULL; /* Selection of pages to print */
+ int even_pages = 1; /* Print the even pages */
+ int odd_pages = 1; /* Print the odd pages */
+ int reverse_order = 0; /* Ouput pages in reverse order? */
+ int collate = 1; /* Collate multiple copies? */
+ int page_size; /* Number of bytes needed for a page,
+ to allocate the memory for the
+ output page buffer */
+ char *out_page = NULL; /* Output page buffer */
+ cups_array_t *page_array = NULL; /* Array to hold the output pages
+ for collated copies and reverse
+ output order */
+ iconv_t cd; /* Conversion descriptor, describes
+ between which encodings iconv
+ should convert */
+ char outbuf[4096]; /* Output buffer for iconv */
+ char inbuf[2048]; /* Input buffer for iconv */
+ size_t outsize; /* Space left in outbuf */
+ size_t insize = 0; /* Bytes still to be converted in
+ inbuf */
+ char *outptr = outbuf; /* Pointer for next converted
+ character to be dropped */
+ char *inptr = inbuf; /* Pointer to next character to be
+ converted */
+ size_t nread; /* Number of bytes read from file */
+ size_t nconv; /* -1 on conversion error */
+ int incomplete_char = 0; /* Was last character in input buffer
+ incomplete */
+ int result = 0; /* Conversion result (-1 on error) */
+ char *procptr, /* Pointer into conversion output
+ to indicate next byte to process
+ for output page creation */
+ *destptr; /* Pointer into output page buffer
+ where next character will be put */
+ int page, /* Number of current output page */
+ line, column; /* Character coordiantes on output
+ page */
+ int page_empty; /* Is the current output page still
+ empty (no visible characters)? */
+ int previous_is_cr; /* Is the previous character processed
+ a Carriage Return? */
+ int skip_rest_of_line = 0; /* Are we truncating an overlong
+ line? */
+ int skip_spaces = 0; /* Are we skipping spaces at a line
+ break when word-wrapping? */
+ char *wrapped_word = NULL; /* Section of a word wrapped over
+ to the next line */
+ int num_pages = 0; /* Number of pages which get actually
+ printed */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Ignore broken pipe signals...
+ */
+
+ signal(SIGPIPE, SIG_IGN);
+
+ /*
+ * Make sure we have the right number of arguments for CUPS!
+ */
+
+ if (argc < 6 || argc > 7)
+ {
+ fprintf(stderr, "Usage: %s job user title copies options [file]\n",
+ argv[0]);
+ return (1);
+ }
+
+ /*
+ * Register a signal handler to cleanly cancel a job.
+ */
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, cancel_job);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = cancel_job;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, cancel_job);
+#endif /* HAVE_SIGSET */
+
+ /*
+ * Copy stdin if needed...
+ */
+
+ if (argc == 6)
+ {
+ /*
+ * Copy stdin to a temp file...
+ */
+
+ if ((fd = cupsTempFd(tempfile, sizeof(tempfile))) < 0)
+ {
+ fprintf(stderr, "ERROR: Unable to copy input text file");
+ goto error;
+ }
+
+ fprintf(stderr, "DEBUG: sys5ippprinter - copying to temp print file \"%s\"\n",
+ tempfile);
+
+ while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
+ bytes = write(fd, buffer, bytes);
+
+ close(fd);
+
+ filename = tempfile;
+ }
+ else
+ {
+ /*
+ * Use the filename on the command-line...
+ */
+
+ filename = argv[6];
+ tempfile[0] = '\0';
+ }
+
+ /*
+ * Number of copies
+ */
+
+ num_copies = atoi(argv[4]);
+ if (num_copies < 1)
+ num_copies = 1;
+
+ /*
+ * Get the options from the fifth command line argument
+ */
+
+ num_options = cupsParseOptions(argv[5], 0, &options);
+
+ /*
+ * Load the PPD file and mark options...
+ */
+
+ ppd = ppdOpenFile(getenv("PPD"));
+ if (ppd)
+ {
+ ppdMarkDefaults(ppd);
+ cupsMarkOptions(ppd, num_options, options);
+ }
+
+ /*
+ * Parse the options
+ */
+
+ /* With the "PageSize"/"PageRegion" options we only determine the number
+ of lines and columns of a page, we do not use the geometry defined by
+ "PaperDimension" and "ImageableArea" in the PPD */
+ if ((val = cupsGetOption("PageSize", num_options, options)) != NULL ||
+ (val = cupsGetOption("PageRegion", num_options, options)) != NULL ||
+ (ppd_attr = ppdFindAttr(ppd, "DefaultPageSize", NULL)) != NULL ||
+ (ppd_attr = ppdFindAttr(ppd, "DefaultPageRegion", NULL)) != NULL) {
+ if (val == NULL)
+ val = ppd_attr->value;
+ fprintf(stderr, "DEBUG: PageSize: %s\n", val);
+ snprintf(buffer, sizeof(buffer), "Default%sNumLines", val);
+ if ((val2 = cupsGetOption(buffer + 7, num_options, options)) != NULL ||
+ (ppd_attr = ppdFindAttr(ppd, buffer, NULL)) != NULL) {
+ if (val2 == NULL)
+ val2 = ppd_attr->value;
+ if (!strncasecmp(val2, "Custom.", 7))
+ val2 += 7;
+ num_lines = atoi(val2);
+ }
+ snprintf(buffer, sizeof(buffer), "Default%sNumColumns", val);
+ if ((val2 = cupsGetOption(buffer + 7, num_options, options)) != NULL ||
+ (ppd_attr = ppdFindAttr(ppd, buffer, NULL)) != NULL) {
+ if (val2 == NULL)
+ val2 = ppd_attr->value;
+ if (!strncasecmp(val2, "Custom.", 7))
+ val2 += 7;
+ num_columns = atoi(val2);
+ }
+ if (num_lines <= 0) {
+ fprintf(stderr, "DEBUG: Invalid number of lines %d, using default: 66\n",
+ num_lines);
+ num_lines = 66;
+ }
+ if (num_columns <= 0) {
+ fprintf(stderr, "DEBUG: Invalid number of columns %d, using default: 80\n",
+ num_columns);
+ num_columns = 80;
+ }
+ }
+
+ /* Direct specification of number of lines/columns, mainly for debugging
+ and development */
+ if ((val = cupsGetOption("page-height", num_options, options)) != NULL) {
+ i = atoi(val);
+ if (i > 0)
+ num_lines = i;
+ else
+ fprintf(stderr, "DEBUG: Invalid number of lines %d, using default value: %d\n",
+ i, num_lines);
+ }
+ if ((val = cupsGetOption("page-width", num_options, options)) != NULL) {
+ i = atoi(val);
+ if (i > 0)
+ num_columns = i;
+ else
+ fprintf(stderr, "DEBUG: Invalid number of columns %d, using default value: %d\n",
+ i, num_columns);
+ }
+
+ fprintf(stderr, "DEBUG: Lines per page: %d; Characters per line: %d\n",
+ num_lines, num_columns);
+
+ if ((val = cupsGetOption("page-left", num_options, options)) != NULL ||
+ (ppd_attr = ppdFindAttr(ppd, "Defaultpage-left", NULL)) != NULL) {
+ if (val == NULL)
+ val = ppd_attr->value;
+ if (!strncasecmp(val, "Custom.", 7))
+ val += 7;
+ page_left = atoi(val);
+ if (page_left < 0 || page_left > num_columns - 1) {
+ fprintf(stderr, "DEBUG: Invalid left margin %d, setting to 0.\n",
+ page_left);
+ page_left = 0;
+ }
+ }
+ if ((val = cupsGetOption("page-right", num_options, options)) != NULL ||
+ (ppd_attr = ppdFindAttr(ppd, "Defaultpage-right", NULL)) != NULL) {
+ if (val == NULL)
+ val = ppd_attr->value;
+ if (!strncasecmp(val, "Custom.", 7))
+ val += 7;
+ page_right = atoi(val);
+ if (page_right < 0 || page_right > num_columns - page_left - 1) {
+ fprintf(stderr, "DEBUG: Invalid right margin %d, setting to 0.\n",
+ page_right);
+ page_right = 0;
+ }
+ }
+ if ((val = cupsGetOption("page-top", num_options, options)) != NULL ||
+ (ppd_attr = ppdFindAttr(ppd, "Defaultpage-top", NULL)) != NULL) {
+ if (val == NULL)
+ val = ppd_attr->value;
+ if (!strncasecmp(val, "Custom.", 7))
+ val += 7;
+ page_top = atoi(val);
+ if (page_top < 0 || page_top > num_lines - 1) {
+ fprintf(stderr, "DEBUG: Invalid top margin %d, setting to 0.\n",
+ page_top);
+ page_top = 0;
+ }
+ }
+ if ((val = cupsGetOption("page-bottom", num_options, options)) != NULL ||
+ (ppd_attr = ppdFindAttr(ppd, "Defaultpage-bottom", NULL)) != NULL) {
+ if (val == NULL)
+ val = ppd_attr->value;
+ if (!strncasecmp(val, "Custom.", 7))
+ val += 7;
+ page_bottom = atoi(val);
+ if (page_bottom < 0 || page_bottom > num_lines - page_top - 1) {
+ fprintf(stderr, "DEBUG: Invalid bottom margin %d, setting to 0.\n",
+ page_bottom);
+ page_bottom = 0;
+ }
+ }
+ fprintf(stderr, "DEBUG: Margins: Left (Columns): %d; Right (Columns): %d; Top (Lines): %d; Bottom (Lines): %d\n",
+ page_left, page_right, page_top, page_bottom);
+
+ text_width = num_columns - page_left - page_right;
+ text_height = num_lines - page_top - page_bottom;
+ fprintf(stderr, "DEBUG: Text area: Lines per page: %d; Characters per line: %d\n",
+ text_height, text_width);
+
+ strcpy(encoding, "ASCII//IGNORE");
+ if ((val = cupsGetOption("PrinterEncoding", num_options, options)) != NULL ||
+ (ppd_attr = ppdFindAttr(ppd, "DefaultPrinterEncoding", NULL)) != NULL) {
+ if (val == NULL)
+ val = ppd_attr->value;
+ if (!strncasecmp(val, "Custom.", 7))
+ val += 7;
+ if (val[0] != '\0') {
+ snprintf(encoding, sizeof(encoding), "%s//IGNORE", val);
+ for (p = encoding; *p; p ++)
+ *p = toupper(*p);
+ }
+ }
+ fprintf(stderr, "DEBUG: Output encoding: %s\n", encoding);
+
+ if ((val = cupsGetOption("OverlongLines", num_options, options)) != NULL ||
+ (ppd_attr = ppdFindAttr(ppd, "DefaultOverlongLines", NULL)) != NULL) {
+ if (val == NULL)
+ val = ppd_attr->value;
+ if (!strcasecmp(val, "Truncate"))
+ overlong_lines = TRUNCATE;
+ else if (!strcasecmp(val, "WordWrap"))
+ overlong_lines = WORDWRAP;
+ else if (!strcasecmp(val, "WrapAtWidth"))
+ overlong_lines = WRAPATWIDTH;
+ else
+ fprintf(stderr, "DEBUG: Invalid value for OverlongLines: %s, using default value.\n",
+ val);
+ }
+ fprintf(stderr, "DEBUG: Handling of overlong lines: %s\n",
+ (overlong_lines == TRUNCATE ? "Truncate at maximum width" :
+ (overlong_lines == WORDWRAP ? "Word-wrap" :
+ "Wrap exactly at maximum width")));
+
+ if ((val = cupsGetOption("TabWidth", num_options, options)) != NULL ||
+ (ppd_attr = ppdFindAttr(ppd, "DefaultTabWidth", NULL)) != NULL) {
+ if (val == NULL)
+ val = ppd_attr->value;
+ if (!strncasecmp(val, "Custom.", 7))
+ val += 7;
+ i = atoi(val);
+ if (i > 0)
+ tab_width = i;
+ else
+ fprintf(stderr, "DEBUG: Invalid tab width %d, using default value: %d\n",
+ i, tab_width);
+ }
+ fprintf(stderr, "DEBUG: Tab width: %d\n", tab_width);
+
+ if ((val = cupsGetOption("Pagination", num_options, options)) != NULL ||
+ (ppd_attr = ppdFindAttr(ppd, "DefaultPagination", NULL)) != NULL) {
+ if (val == NULL)
+ val = ppd_attr->value;
+ if (is_true(val))
+ pagination = 1;
+ else if (is_false(val))
+ pagination = 0;
+ else
+ fprintf(stderr, "DEBUG: Invalid value for Pagination: %s, using default value.\n",
+ val);
+ }
+ fprintf(stderr, "DEBUG: Pagination (Print in defined pages): %s\n",
+ (pagination ? "Yes" : "No"));
+
+ if ((val = cupsGetOption("SendFF", num_options, options)) != NULL ||
+ (ppd_attr = ppdFindAttr(ppd, "DefaultSendFF", NULL)) != NULL) {
+ if (val == NULL)
+ val = ppd_attr->value;
+ if (is_true(val))
+ send_ff = 1;
+ else if (is_false(val))
+ send_ff = 0;
+ else
+ fprintf(stderr, "DEBUG: Invalid value for SendFF: %s, using default value.\n",
+ val);
+ }
+ fprintf(stderr, "DEBUG: Send Form Feed character at end of page: %s\n",
+ (send_ff ? "Yes" : "No"));
+
+ if ((val = cupsGetOption("NewlineCharacters", num_options, options)) !=
+ NULL ||
+ (ppd_attr = ppdFindAttr(ppd, "DefaultNewlineCharacters", NULL)) != NULL) {
+ if (val == NULL)
+ val = ppd_attr->value;
+ if (!strcasecmp(val, "LF"))
+ newline_char = LF;
+ else if (!strcasecmp(val, "CR"))
+ newline_char = CR;
+ else if (!strcasecmp(val, "CRLF"))
+ newline_char = CRLF;
+ else
+ fprintf(stderr, "DEBUG: Invalid value for NewlineCharacters: %s, using default value.\n",
+ val);
+ }
+ fprintf(stderr, "DEBUG: Characters sent to make printer start a new line: %s\n",
+ (newline_char == LF ? "Line Feed (LF)" :
+ (newline_char == CR ? "Carriage Return (CR)" :
+ "Carriage Return (CR) and Line Feed (LF)")));
+
+ if ((val = cupsGetOption("page-ranges", num_options, options)) !=
+ NULL) {
+ if (val[0] != '\0')
+ page_ranges = strdup(val);
+ }
+ if (page_ranges)
+ fprintf(stderr, "DEBUG: Page selection: %s\n", page_ranges);
+
+ if ((val = cupsGetOption("page-set", num_options, options)) !=
+ NULL) {
+ if (!strcasecmp(val, "even")) {
+ even_pages = 1;
+ odd_pages = 0;
+ } else if (!strcasecmp(val, "odd")) {
+ even_pages = 0;
+ odd_pages = 1;
+ } else if (!strcasecmp(val, "all")) {
+ even_pages = 1;
+ odd_pages = 1;
+ } else
+ fprintf(stderr, "DEBUG: Invalid value for page-set: %s, using default value.\n",
+ val);
+ }
+ if (!even_pages || !odd_pages)
+ fprintf(stderr, "DEBUG: Print %s.\n",
+ (even_pages ? "only the even pages" :
+ (odd_pages ? "only the odd pages" :
+ "no pages")));
+
+ if ((val = cupsGetOption("output-order", num_options, options)) !=
+ NULL) {
+ if (!strcasecmp(val, "reverse"))
+ reverse_order = 1;
+ else
+ fprintf(stderr, "DEBUG: Invalid value for OutputOrder: %s, using default value.\n",
+ val);
+ }
+ fprintf(stderr, "DEBUG: Print pages in reverse order: %s\n",
+ (reverse_order ? "Yes" : "No"));
+
+ if ((val = cupsGetOption("Collate", num_options, options)) != NULL) {
+ if (is_true(val))
+ collate = 1;
+ else if (is_false(val))
+ collate = 0;
+ else
+ fprintf(stderr, "DEBUG: Invalid value for Collate: %s, using default value.\n",
+ val);
+ }
+ fprintf(stderr, "DEBUG: Collate copies: %s\n",
+ (collate ? "Yes" : "No"));
+
+ /* Create a string to insert as the newline mark */
+ if (newline_char == LF)
+ newline_char_str = "\n";
+ else if (newline_char == CR)
+ newline_char_str = "\r";
+ else if (newline_char == CRLF)
+ newline_char_str = "\r\n";
+
+ /* Size of the output page in bytes (only 1-byte-per-character supported)
+ in the worst case, no blank lines at top and bottom, no blank right
+ margin, 2 characters for newline (CR + LF) plus form feed plus closing
+ zero */
+ page_size = (num_columns + 2) * num_lines + 2;
+
+ /* Allocate output page buffer */
+ out_page = calloc(page_size, sizeof(char));
+
+ /* Set conversion mode of iconv */
+ cd = iconv_open(encoding, "UTF-8");
+ if (cd == (iconv_t) -1) {
+ /* Something went wrong. */
+ if (errno == EINVAL)
+ fprintf(stderr, "ERROR: Conversion from UTF-8 to %s not available\n",
+ encoding);
+ else
+ fprintf(stderr, "ERROR: Error setting up conversion from UTF-8 to %s\n",
+ encoding);
+ goto error;
+ }
+
+ /* Open the input file */
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "ERROR: Unable to open input text file %s\n", filename);
+ goto error;
+ }
+
+ /* Create an array to hold the output pages for collated copies or
+ reverse output order (only when printing paginated) */
+ if (pagination &&
+ ((num_copies != 1 && collate) || reverse_order)) {
+ /* Create page array */
+ page_array = cupsArrayNew(NULL, NULL);
+ }
+
+ /* Main loop for readin the input file, converting the encoding, formatting
+ the output, and printing the pages */
+ destptr = out_page;
+ page_empty = 1;
+ page = 1;
+ line = 0;
+ column = 0;
+ previous_is_cr = 0;
+ insize = 0;
+ do {
+ /* Reset input pointer */
+ inptr = inbuf;
+
+ /* Mark the output buffer empty */
+ outsize = sizeof(outbuf);
+ outptr = outbuf;
+
+ /* Read from the input file */
+ nread = read (fd, inbuf + insize, sizeof (inbuf) - insize);
+ if (nread == 0) {
+ /* When we come here the file is completely read.
+ This still could mean there are some unused
+ characters in the inbuf, meaning that the file
+ ends with an incomplete UTF-8 character. Log
+ this fact. */
+ if (insize > 0 && incomplete_char)
+ fprintf(stderr, "DEBUG: Input text file ends with incomplete UTF-8 character sequence, file possibly incomplete, but printing the successfully read part anyway.\n");
+
+ /* Now write out the byte sequence to get into the
+ initial state if this is necessary. */
+ iconv (cd, NULL, NULL, &outptr, &outsize);
+ }
+
+ insize += nread;
+
+ /* Convert the incoming UTF-8-encoded text to the printer's encoding */
+ if (insize > 0) { /* Do we have data to convert? */
+ /* Do the conversion. */
+ nconv = iconv (cd, &inptr, &insize, &outptr, &outsize);
+ if (nconv == (size_t) -1) {
+ /* Not everything went right. It might only be
+ an unfinished byte sequence at the end of the
+ buffer. Or it is a real problem. */
+ if (errno == EINVAL || errno == E2BIG) {
+ /* This is harmless. Simply move the unused
+ bytes to the beginning of the buffer so that
+ they can be used in the next round. */
+ if (errno == EINVAL)
+ incomplete_char = 1;
+ memmove (inbuf, inptr, insize);
+ } else {
+ /* We found an illegal UTF-8 byte sequence here,
+ so error out at this point. */
+ fprintf(stderr, "ERROR: Illegal UTF-8 sequence found. Input file perhaps not UTF-8-encoded\n");
+ result = -1;
+ break;
+ }
+ }
+ }
+
+ /* Process the output to generate the output pages */
+ if (outptr == outbuf) /* End of input file */
+ *(outptr ++) = '\0';
+ for (procptr = outbuf; procptr < outptr; procptr ++) {
+ if ((column >= text_width && /* Current line is full */
+ *procptr != '\n' && *procptr != '\r' && *procptr != '\f') ||
+ /* Next character is not newline or
+ formfeed */
+ (outbuf[0] == '\0' && column > 0)) { /* End of input file */
+ if (overlong_lines == TRUNCATE && outbuf[0] != '\0')
+ skip_rest_of_line = 1;
+ else {
+ if (overlong_lines == WORDWRAP && outbuf[0] != '\0') {
+ if (*procptr > ' ') {
+ *destptr = '\0';
+ for (p = destptr - 1, i = column - 1; *p != ' ' && i >= 0;
+ p --, i--);
+ if (i >= 0 && i < column - 1) {
+ wrapped_word = strdup(p + 1);
+ for (; *p == ' ' && i >= 0; p --, i--);
+ if (*p != ' ' && i >= 0)
+ destptr = p + 1;
+ else {
+ free(wrapped_word);
+ wrapped_word = NULL;
+ }
+ }
+ } else
+ skip_spaces = 1;
+ }
+ /* Remove trailing whitespace */
+ while (destptr > out_page && *(destptr - 1) == ' ')
+ destptr --;
+ /* Put newline character(s) */
+ for (j = 0; newline_char_str[j]; j ++)
+ *(destptr ++) = newline_char_str[j];
+ /* Position cursor in next line */
+ line ++;
+ column = 0;
+ }
+ }
+ if ((line >= text_height && /* Current page is full */
+ *procptr != '\f') || /* Next character is not formfeed */
+ outbuf[0] == '\0' ) { /* End of input file */
+ /* Do we actually print this page? */
+ if (!pagination ||
+ check_range(page_ranges, even_pages, odd_pages, page)) {
+ /* Finalize the page */
+ if (pagination) {
+ if (send_ff) {
+ if (page_empty)
+ destptr = out_page; /* Remove unneeded white space */
+ /* Send Form Feed */
+ *(destptr ++) = '\f';
+ } else if (outbuf[0] != '\0') {
+ /* Fill up page with blank lines */
+ for (i = 0; i < page_bottom; i ++)
+ for (j = 0; newline_char_str[j]; j ++)
+ *(destptr ++) = newline_char_str[j];
+ }
+ }
+ /* Allow to handle the finished page as a C string */
+ *(destptr ++) = '\0';
+ /* Count pages which will actually get printed */
+ num_pages ++;
+ if (!pagination) {
+ /* Send out the output page buffer content */
+ printf("%s", out_page);
+ /* Log the page output (only once, when printing the first buffer
+ load) */
+ if (num_pages == 1)
+ fprintf(stderr, "PAGE: 1 1\n");
+ } else if ((num_copies == 1 || !collate) && !reverse_order) {
+ /* Send out the page */
+ for (i = 0; i < num_copies; i ++)
+ printf("%s", out_page);
+ /* Log the page output */
+ fprintf(stderr, "PAGE: %d %d\n", num_pages, num_copies);
+ } else {
+ /* Save the page in the page array */
+ cupsArrayAdd(page_array, strdup(out_page));
+ }
+ }
+ /* Reset for next page */
+ destptr = out_page;
+ page_empty = 1;
+ line = 0;
+ column = 0;
+ page ++;
+ }
+ if (outbuf[0] == '\0') /* End of input file */
+ break;
+ if (column == 0) { /* Start of new line */
+ if (line == 0 && pagination) /* Start of new page */
+ for (i = 0; i < page_top; i ++)
+ for (j = 0; newline_char_str[j]; j ++)
+ *(destptr ++) = newline_char_str[j];
+ for (i = 0; i < page_left; i ++)
+ *(destptr ++) = ' ';
+ /* Did we wrap a word from the previous line? */
+ if (wrapped_word) {
+ for (p = wrapped_word; *p != '\0'; p ++, column ++)
+ *(destptr ++) = *p;
+ free(wrapped_word);
+ wrapped_word = NULL;
+ page_empty = 0;
+ skip_spaces = 0;
+ }
+ }
+ if (*procptr == '\r' || *procptr == '\n') { /* CR or LF */
+ /* Only write newline if we are not on the LF of a CR+LF */
+ if (*procptr == '\r' || previous_is_cr == 0) {
+ /* Remove trailing whitespace */
+ while (destptr > out_page && *(destptr - 1) == ' ')
+ destptr --;
+ /* Put newline character(s) */
+ for (j = 0; newline_char_str[j]; j ++)
+ *(destptr ++) = newline_char_str[j];
+ /* Position cursor in next line */
+ line ++;
+ column = 0;
+ /* Finished truncating an overlong line */
+ skip_rest_of_line = 0;
+ skip_spaces = 0;
+ }
+ if (*procptr == '\r')
+ previous_is_cr = 1;
+ else
+ previous_is_cr = 0;
+ } else {
+ previous_is_cr = 0;
+ if (*procptr == '\t') { /* Tab character */
+ if (!skip_rest_of_line && !skip_spaces) {
+ *(destptr ++) = ' '; /* Always at least one space */
+ column ++;
+ /* Add spaces to reach next multiple of the tab width */
+ for (; column % tab_width != 0 && column < text_width; column ++)
+ *(destptr ++) = ' ';
+ }
+ } else if (*procptr == '\f') { /* Form feed */
+ /* Skip to end of page */
+ if (send_ff)
+ /* Mark page full */
+ line = text_height;
+ else if (pagination)
+ /* Fill page with newlines */
+ for (; line < text_height; line ++)
+ for (j = 0; newline_char_str[j]; j ++)
+ *(destptr ++) = newline_char_str[j];
+ column = 0;
+ /* Finished truncating an overlong line */
+ skip_rest_of_line = 0;
+ skip_spaces = 0;
+ } else if (*procptr == ' ') { /* Space */
+ if (!skip_rest_of_line && !skip_spaces) {
+ *(destptr ++) = *procptr;
+ column ++;
+ }
+ } else if (*procptr > ' ' || *procptr < '\0') { /* Regular character */
+ if (!skip_rest_of_line) {
+ *(destptr ++) = *procptr;
+ column ++;
+ page_empty = 0;
+ skip_spaces = 0;
+ }
+ }
+ }
+ }
+ } while (outbuf[0] != '\0'); /* End of input file */
+
+ close(fd);
+
+ if (iconv_close (cd) != 0)
+ fprintf (stderr, "DEBUG: Error closing iconv encoding conversion session\n");
+
+ /* Error out on an illegal UTF-8 sequence in the input file */
+ if (result < 0)
+ goto error;
+
+ /* Print out the page array if we created one */
+ if (pagination &&
+ ((num_copies != 1 && collate) || reverse_order)) {
+ /* If we print collated copies, the outer loop (i) goes through the
+ copies, if we do not collate, the inner loop (j) goes through the
+ copies. The other loop only runs for one cycle. */
+ for (i = 0; i < (collate ? num_copies : 1); i ++)
+ for (page = (reverse_order ? num_pages : 1);
+ (reverse_order ? (page >= 1) : (page <= num_pages));
+ page += (reverse_order ? -1 : 1)) {
+ p = (char *)cupsArrayIndex(page_array, page - 1);
+ for (j = 0; j < (collate ? 1 : num_copies); j ++)
+ printf("%s", p);
+ fprintf(stderr, "PAGE: %d %d\n", page, (collate ? 1 : num_copies));
+ }
+ /* Clean up */
+ for (page = 0; page < num_pages; page ++) {
+ p = (char *)cupsArrayIndex(page_array, page);
+ free(p);
+ }
+ cupsArrayDelete(page_array);
+ }
+
+ /*
+ * Cleanup and exit...
+ */
+
+ error:
+
+ free(page_ranges);
+ free(out_page);
+
+ if (tempfile[0])
+ unlink(tempfile);
+
+ return (exit_status);
+}
+
+
+/*
+ * 'is_true()' - Check option value for boolean true
+ */
+
+static int is_true(const char *value)
+{
+ if (!value)
+ return 0;
+ return (strcasecmp(value, "yes") == 0) ||
+ (strcasecmp(value, "on") == 0) ||
+ (strcasecmp(value, "true") == 0) ||
+ (strcasecmp(value, "1") == 0);
+}
+
+
+/*
+ * 'is_false()' - Check option value for boolean false
+ */
+
+static int is_false(const char *value)
+{
+ if (!value)
+ return 0;
+ return (strcasecmp(value, "no") == 0) ||
+ (strcasecmp(value, "off") == 0) ||
+ (strcasecmp(value, "false") == 0) ||
+ (strcasecmp(value, "0") == 0);
+}
+
+
+/*
+ * 'check_range()' - Check to see if the current page is selected for
+ * printing.
+ */
+
+static int /* O - 1 if selected, 0 otherwise */
+check_range(char *page_ranges, /* I - Selection of pages to print */
+ int even_pages, /* I - Print the even pages */
+ int odd_pages, /* I - Print the odd pages */
+ int page) /* I - Page number */
+{
+ const char *range; /* Pointer into range string */
+ int lower, upper; /* Lower and upper page numbers */
+
+ /*
+ * See if we only print even or odd pages...
+ */
+
+ if (!odd_pages && (page & 1))
+ return (0);
+
+ if (!even_pages && !(page & 1))
+ return (0);
+
+ /*
+ * page-ranges option
+ */
+
+ if (!page_ranges || page_ranges[0] == '\0')
+ return (1); /* No range, print all pages... */
+
+ for (range = page_ranges; *range != '\0';)
+ {
+ if (*range == '-')
+ {
+ lower = 1;
+ range ++;
+ upper = (int)strtol(range, (char **)&range, 10);
+ }
+ else
+ {
+ lower = (int)strtol(range, (char **)&range, 10);
+
+ if (*range == '-')
+ {
+ range ++;
+ if (!isdigit(*range & 255))
+ upper = 65535;
+ else
+ upper = (int)strtol(range, (char **)&range, 10);
+ }
+ else
+ upper = lower;
+ }
+
+ if (page >= lower && page <= upper)
+ return (1);
+
+ if (*range == ',')
+ range ++;
+ else
+ break;
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'cancel_job()' - Flag the job as canceled.
+ */
+
+static void
+cancel_job(int sig) /* I - Signal number (unused) */
+{
+ (void)sig;
+
+ job_canceled = 1;
+}
+
+
+/*
+ * End
+ */
diff --git a/filter/unirast.h b/filter/unirast.h
new file mode 100644
index 000000000..c3f963385
--- /dev/null
+++ b/filter/unirast.h
@@ -0,0 +1,62 @@
+/**
+ * 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/>.
+ *
+ * @brief UNIRAST Defines
+ * @file unirast.h
+ * @author Neil 'Superna' Armstrong (c) 2010
+ */
+
+#ifndef _UNIRAST_H_
+#define _UNIRAST_H_
+
+enum unirast_color_space_e
+{
+ // Grayscale
+ UNIRAST_COLOR_SPACE_GRAYSCALE_8BIT = 0,
+ UNIRAST_COLOR_SPACE_GRAYSCALE_32BIT = 4,
+
+ //RGB
+ UNIRAST_COLOR_SPACE_SRGB_24BIT_1 = 1,
+ UNIRAST_COLOR_SPACE_SRGB_24BIT_3 = 3,
+ UNIRAST_COLOR_SPACE_SRGB_24BIT_5 = 5,
+ UNIRAST_COLOR_SPACE_SRGB_32BIT = 2,
+
+ //CMYK
+ UNIRAST_COLOR_SPACE_CMYK_32BIT_64BIT = 6
+};
+
+enum unirast_duplex_mode_e
+{
+ UNIRAST_DUPLEX_MODE_0 = 0,
+ UNIRAST_DUPLEX_MODE_1 = 1,
+ UNIRAST_DUPLEX_MODE_2 = 2,
+ UNIRAST_DUPLEX_MODE_3 = 3
+};
+
+enum unirast_quality_e
+{
+ UNIRAST_QUALITY_3 = 3,
+ UNIRAST_QUALITY_4 = 4,
+ UNIRAST_QUALITY_5 = 5
+};
+
+enum unirast_bpp_e
+{
+ UNIRAST_BPP_8BIT = 8,
+ UNIRAST_BPP_24BIT = 24,
+ UNIRAST_BPP_32BIT = 32,
+ UNIRAST_BPP_64BIT = 64
+};
+
+#endif
diff --git a/filter/urftopdf.cpp b/filter/urftopdf.cpp
new file mode 100644
index 000000000..ec3f8dce3
--- /dev/null
+++ b/filter/urftopdf.cpp
@@ -0,0 +1,498 @@
+/**
+ * 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/>.
+ *
+ * @brief Decode URF to a PDF file
+ * @file urf_decode.cpp
+ * @author Neil 'Superna' Armstrong <superna9999@gmail.com> (C) 2010
+ * @author Tobias Hoffmann <smilingthax@gmail.com> (c) 2012
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits>
+#include <errno.h>
+
+#include <arpa/inet.h> // ntohl
+
+#include <vector>
+#include <qpdf/QPDF.hh>
+#include <qpdf/QPDFWriter.hh>
+#include <qpdf/QUtil.hh>
+
+#include <qpdf/Pl_Flate.hh>
+#include <qpdf/Pl_Buffer.hh>
+
+#include "unirast.h"
+
+#define DEFAULT_PDF_UNIT 72 // 1/72 inch
+
+#define PROGRAM "urftopdf"
+
+#ifdef URF_DEBUG
+#define dprintf(format, ...) fprintf(stderr, "DEBUG: (" PROGRAM ") " format, __VA_ARGS__)
+#else
+#define dprintf(format, ...)
+#endif
+
+#define iprintf(format, ...) fprintf(stderr, "INFO: (" PROGRAM ") " format, __VA_ARGS__)
+
+void die(const char * str)
+{
+ fprintf(stderr, "CRIT: (" PROGRAM ") die(%s) [%s]\n", str, strerror(errno));
+ exit(1);
+}
+
+//------------- PDF ---------------
+
+struct pdf_info
+{
+ pdf_info()
+ : pagecount(0),
+ width(0),height(0),
+ pixel_bytes(0),line_bytes(0),
+ bpp(0),
+ page_width(0),page_height(0)
+ {
+ }
+
+ QPDF pdf;
+ QPDFObjectHandle page;
+ unsigned pagecount;
+ unsigned width;
+ unsigned height;
+ unsigned pixel_bytes;
+ unsigned line_bytes;
+ unsigned bpp;
+ PointerHolder<Buffer> page_data;
+ double page_width,page_height;
+};
+
+int create_pdf_file(struct pdf_info * info, unsigned pagecount)
+{
+ try {
+ info->pdf.emptyPDF();
+ } catch (...) {
+ return 1;
+ }
+
+ info->pagecount = pagecount;
+
+ return 0;
+}
+
+QPDFObjectHandle makeBox(double x1, double y1, double x2, double y2)
+{
+ QPDFObjectHandle ret=QPDFObjectHandle::newArray();
+ ret.appendItem(QPDFObjectHandle::newReal(x1));
+ ret.appendItem(QPDFObjectHandle::newReal(y1));
+ ret.appendItem(QPDFObjectHandle::newReal(x2));
+ ret.appendItem(QPDFObjectHandle::newReal(y2));
+ return ret;
+}
+
+enum ColorSpace {
+ DEVICE_GRAY,
+ DEVICE_RGB,
+ DEVICE_CMYK
+};
+
+#define PRE_COMPRESS
+/* or temporarily store images?
+ if(cupsTempFile2(tempfile_name, 255) == NULL) die("Unable to create a temporary pdf file");
+ iprintf("Created temporary file '%s'\n", tempfile_name);
+*/
+
+QPDFObjectHandle makeImage(QPDF &pdf, PointerHolder<Buffer> page_data, unsigned width, unsigned height, ColorSpace cs, unsigned bpc)
+{
+ QPDFObjectHandle ret = QPDFObjectHandle::newStream(&pdf);
+
+ std::map<std::string,QPDFObjectHandle> dict;
+
+ dict["/Type"]=QPDFObjectHandle::newName("/XObject");
+ dict["/Subtype"]=QPDFObjectHandle::newName("/Image");
+ dict["/Width"]=QPDFObjectHandle::newInteger(width);
+ dict["/Height"]=QPDFObjectHandle::newInteger(height);
+ dict["/BitsPerComponent"]=QPDFObjectHandle::newInteger(bpc);
+
+ if (cs==DEVICE_GRAY) {
+ dict["/ColorSpace"]=QPDFObjectHandle::newName("/DeviceGray");
+ } else if (cs==DEVICE_RGB) {
+ dict["/ColorSpace"]=QPDFObjectHandle::newName("/DeviceRGB");
+ } else if (cs==DEVICE_CMYK) {
+ dict["/ColorSpace"]=QPDFObjectHandle::newName("/DeviceCMYK");
+ } else {
+ return QPDFObjectHandle();
+ }
+
+ ret.replaceDict(QPDFObjectHandle::newDictionary(dict));
+
+#ifdef PRE_COMPRESS
+ // we deliver already compressed content (instead of letting QPDFWriter do it), to avoid using excessive memory
+ Pl_Buffer psink("psink");
+ Pl_Flate pflate("pflate",&psink,Pl_Flate::a_deflate);
+
+ pflate.write(page_data->getBuffer(),page_data->getSize());
+ pflate.finish();
+
+// /Filter /FlateDecode
+// /DecodeParms [<</Predictor 1 /Colors 1[3] /BitsPerComponent $bits /Columns $x>>] ??
+ ret.replaceStreamData(PointerHolder<Buffer>(psink.getBuffer()),
+ QPDFObjectHandle::newName("/FlateDecode"),QPDFObjectHandle::newNull());
+#else
+ ret.replaceStreamData(page_data,QPDFObjectHandle::newNull(),QPDFObjectHandle::newNull());
+#endif
+
+ return ret;
+}
+
+void finish_page(struct pdf_info * info)
+{
+ //Finish previous Page
+ if(!info->page_data.getPointer())
+ return;
+
+ QPDFObjectHandle image = makeImage(info->pdf, info->page_data, info->width, info->height, DEVICE_RGB, 8);
+ if(!image.isInitialized()) die("Unable to load image data");
+
+ // add it
+ info->page.getKey("/Resources").getKey("/XObject").replaceKey("/I",image);
+
+ // draw it
+ std::string content;
+ content.append(QUtil::double_to_string(info->page_width) + " 0 0 " +
+ QUtil::double_to_string(info->page_height) + " 0 0 cm\n");
+ content.append("/I Do\n");
+ info->page.getKey("/Contents").replaceStreamData(content,QPDFObjectHandle::newNull(),QPDFObjectHandle::newNull());
+
+ // bookkeeping
+ info->page_data = PointerHolder<Buffer>();
+}
+
+int add_pdf_page(struct pdf_info * info, int pagen, unsigned width, unsigned height, int bpp, unsigned dpi)
+{
+ try {
+ finish_page(info); // any active
+
+ info->width = width;
+ info->height = height;
+ info->pixel_bytes = bpp/8;
+ info->line_bytes = (width*info->pixel_bytes);
+ info->bpp = bpp;
+
+ if (info->height > (std::numeric_limits<unsigned>::max() / info->line_bytes)) {
+ die("Page too big");
+ }
+ info->page_data = PointerHolder<Buffer>(new Buffer(info->line_bytes*info->height));
+
+ QPDFObjectHandle page = QPDFObjectHandle::parse(
+ "<<"
+ " /Type /Page"
+ " /Resources <<"
+ " /XObject << >> "
+ " >>"
+ " /MediaBox null "
+ " /Contents null "
+ ">>");
+ page.replaceKey("/Contents",QPDFObjectHandle::newStream(&info->pdf)); // data will be provided later
+
+ // Convert to pdf units
+ info->page_width=((double)info->width/dpi)*DEFAULT_PDF_UNIT;
+ info->page_height=((double)info->height/dpi)*DEFAULT_PDF_UNIT;
+ page.replaceKey("/MediaBox",makeBox(0,0,info->page_width,info->page_height));
+
+ info->page = info->pdf.makeIndirectObject(page); // we want to keep a reference
+ info->pdf.addPage(info->page, false);
+ } catch (std::bad_alloc &ex) {
+ die("Unable to allocate page data");
+ } catch (...) {
+ return 1;
+ }
+
+ return 0;
+}
+
+int close_pdf_file(struct pdf_info * info)
+{
+ try {
+ finish_page(info); // any active
+
+ QPDFWriter output(info->pdf,NULL);
+ output.write();
+ } catch (...) {
+ return 1;
+ }
+
+ return 0;
+}
+
+void pdf_set_line(struct pdf_info * info, unsigned line_n, uint8_t line[])
+{
+ dprintf("pdf_set_line(%d)\n", line_n);
+
+ if(line_n > info->height)
+ {
+ dprintf("Bad line %d\n", line_n);
+ return;
+ }
+
+ memcpy((info->page_data->getBuffer()+(line_n*info->line_bytes)), line, info->line_bytes);
+}
+
+// Data are in network endianness
+struct urf_file_header {
+ char unirast[8];
+ uint32_t page_count;
+} __attribute__((__packed__));
+
+struct urf_page_header {
+ uint8_t bpp;
+ uint8_t colorspace;
+ uint8_t duplex;
+ uint8_t quality;
+ uint32_t unknown0;
+ uint32_t unknown1;
+ uint32_t width;
+ uint32_t height;
+ uint32_t dot_per_inch;
+ uint32_t unknown2;
+ uint32_t unknown3;
+} __attribute__((__packed__));
+
+int decode_raster(int fd, unsigned width, unsigned height, int bpp, struct pdf_info * info)
+{
+ // We should be at raster start
+ int i, j;
+ unsigned cur_line = 0;
+ unsigned pos = 0;
+ uint8_t line_repeat_byte = 0;
+ unsigned line_repeat = 0;
+ int8_t packbit_code = 0;
+ int pixel_size = (bpp/8);
+ std::vector<uint8_t> pixel_container;
+ std::vector<uint8_t> line_container;
+
+ if (width > (std::numeric_limits<unsigned>::max() / pixel_size)) {
+ die("Line too big");
+ }
+ try {
+ pixel_container.resize(pixel_size);
+ line_container.resize(pixel_size*width);
+ } catch (...) {
+ die("Unable to allocate temporary storage");
+ }
+
+ do
+ {
+ if(read(fd, &line_repeat_byte, 1) < 1)
+ {
+ dprintf("l%06d : line_repeat EOF at %lu\n", cur_line, lseek(fd, 0, SEEK_CUR));
+ return 1;
+ }
+
+ line_repeat = (unsigned)line_repeat_byte + 1;
+
+ dprintf("l%06d : next actions for %d lines\n", cur_line, line_repeat);
+
+ // Start of line
+ pos = 0;
+
+ do
+ {
+ if(read(fd, &packbit_code, 1) < 1)
+ {
+ dprintf("p%06dl%06d : packbit_code EOF at %lu\n", pos, cur_line, lseek(fd, 0, SEEK_CUR));
+ return 1;
+ }
+
+ dprintf("p%06dl%06d: Raster code %02X='%d'.\n", pos, cur_line, (uint8_t)packbit_code, packbit_code);
+
+ if(packbit_code == -128)
+ {
+ dprintf("\tp%06dl%06d : blank rest of line.\n", pos, cur_line);
+ memset((&line_container[pos*pixel_size]), 0xFF, (pixel_size*(width-pos)));
+ pos = width;
+ break;
+ }
+ else if(packbit_code >= 0 && packbit_code <= 127)
+ {
+ int n = (packbit_code+1);
+
+ //Read pixel
+ if(read(fd, &pixel_container[0], pixel_size) < pixel_size)
+ {
+ dprintf("p%06dl%06d : pixel repeat EOF at %lu\n", pos, cur_line, lseek(fd, 0, SEEK_CUR));
+ return 1;
+ }
+
+ dprintf("\tp%06dl%06d : Repeat pixel '", pos, cur_line);
+ for(j = 0 ; j < pixel_size ; ++j)
+ dprintf("%02X ", pixel_container[j]);
+ dprintf("' for %d times.\n", n);
+
+ for(i = 0 ; i < n ; ++i)
+ {
+ //for(j = pixel_size-1 ; j >= 0 ; --j)
+ for(j = 0 ; j < pixel_size ; ++j)
+ line_container[pixel_size*pos + j] = pixel_container[j];
+ ++pos;
+ if(pos >= width)
+ break;
+ }
+
+ if(i < n && pos >= width)
+ {
+ dprintf("\tp%06dl%06d : Forced end of line for pixel repeat.\n", pos, cur_line);
+ }
+
+ if(pos >= width)
+ break;
+ }
+ else if(packbit_code > -128 && packbit_code < 0)
+ {
+ int n = (-(int)packbit_code)+1;
+
+ dprintf("\tp%06dl%06d : Copy %d verbatim pixels.\n", pos, cur_line, n);
+
+ for(i = 0 ; i < n ; ++i)
+ {
+ if(read(fd, &pixel_container[0], pixel_size) < pixel_size)
+ {
+ dprintf("p%06dl%06d : literal_pixel EOF at %lu\n", pos, cur_line, lseek(fd, 0, SEEK_CUR));
+ return 1;
+ }
+ //Invert pixels, should be programmable
+ for(j = 0 ; j < pixel_size ; ++j)
+ line_container[pixel_size*pos + j] = pixel_container[j];
+ ++pos;
+ if(pos >= width)
+ break;
+ }
+
+ if(i < n && pos >= width)
+ {
+ dprintf("\tp%06dl%06d : Forced end of line for pixel copy.\n", pos, cur_line);
+ }
+
+ if(pos >= width)
+ break;
+ }
+ }
+ while(pos < width);
+
+ dprintf("\tl%06d : End Of line, drawing %d times.\n", cur_line, line_repeat);
+
+ // write lines
+ for(i = 0 ; i < (int)line_repeat ; ++i)
+ {
+ pdf_set_line(info, cur_line, &line_container[0]);
+ ++cur_line;
+ }
+ }
+ while(cur_line < height);
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int fd, page;
+ struct urf_file_header head, head_orig;
+ struct urf_page_header page_header, page_header_orig;
+ struct pdf_info pdf;
+
+ FILE * input = NULL;
+
+ if(argc < 6)
+ {
+ fprintf(stderr, "Usage: %s <job> <user> <job name> <copies> <option> [file]\n", argv[0]);
+ return 1;
+ }
+
+ if(argc > 6)
+ {
+ input = fopen(argv[6], "rb");
+ if(input == NULL) die("Unable to open unirast file");
+ }
+ else
+ input = stdin;
+
+ // Get fd from file
+ fd = fileno(input);
+
+ if(read(fd, &head_orig, sizeof(head)) == -1) die("Unable to read file header");
+
+ //Transform
+ memcpy(head.unirast, head_orig.unirast, sizeof(head.unirast));
+ head.page_count = ntohl(head_orig.page_count);
+
+ if(head.unirast[7])
+ head.unirast[7] = 0;
+
+ if(strncmp(head.unirast, "UNIRAST", 7) != 0) die("Bad File Header");
+
+ iprintf("%s file, with %d page(s).\n", head.unirast, head.page_count);
+
+ if(create_pdf_file(&pdf, head.page_count) != 0) die("Unable to create PDF file");
+
+ for(page = 0 ; page < (int)head.page_count ; ++page)
+ {
+ if(read(fd, &page_header_orig, sizeof(page_header_orig)) == -1) die("Unable to read page header");
+
+ //Transform
+ page_header.bpp = page_header_orig.bpp;
+ page_header.colorspace = page_header_orig.colorspace;
+ page_header.duplex = page_header_orig.duplex;
+ page_header.quality = page_header_orig.quality;
+ page_header.unknown0 = 0;
+ page_header.unknown1 = 0;
+ page_header.width = ntohl(page_header_orig.width);
+ page_header.height = ntohl(page_header_orig.height);
+ page_header.dot_per_inch = ntohl(page_header_orig.dot_per_inch);
+ page_header.unknown2 = 0;
+ page_header.unknown3 = 0;
+
+ iprintf("Page %d :\n", page);
+ iprintf("Bits Per Pixel : %d\n", page_header.bpp);
+ iprintf("Colorspace : %d\n", page_header.colorspace);
+ iprintf("Duplex Mode : %d\n", page_header.duplex);
+ iprintf("Quality : %d\n", page_header.quality);
+ iprintf("Size : %dx%d pixels\n", page_header.width, page_header.height);
+ iprintf("Dots per Inches : %d\n", page_header.dot_per_inch);
+
+ if(page_header.colorspace != UNIRAST_COLOR_SPACE_SRGB_24BIT_1)
+ {
+ die("Invalid ColorSpace, only RGB 24BIT type 1 is supported");
+ }
+
+ if(page_header.bpp != UNIRAST_BPP_24BIT)
+ {
+ die("Invalid Bit Per Pixel value, only 24bit is supported");
+ }
+
+ if(add_pdf_page(&pdf, page, page_header.width, page_header.height, page_header.bpp, page_header.dot_per_inch) != 0) die("Unable to create PDF file");
+
+ if(decode_raster(fd, page_header.width, page_header.height, page_header.bpp, &pdf) != 0)
+ die("Failed to decode Page");
+ }
+
+ close_pdf_file(&pdf); // will output to stdout
+
+ return 0;
+}
diff --git a/fontembed/README b/fontembed/README
new file mode 100644
index 000000000..f84bd617b
--- /dev/null
+++ b/fontembed/README
@@ -0,0 +1,48 @@
+libfontembed - font embedding and subsetting library
+----------------------------------------------------
+
+This library implements all the stuff required to
+embed and subset TrueType fonts, as for example
+required in PDF files. It is completely self-contained,
+although a FreeType binding might come sometime in the future.
+
+Currently glyf-flavored TrueType is fully supported,
+for OTF, i.e. CFF-flavored TrueType/OpenType, subsetting is not
+done; but embedding does work.
+And single-byte mode does needs work/thought wrt. to encodings.
+Also reencoding and conversion of Type1 to CFF is planned.
+PostScript embedding is another goal of the project.
+
+The most important issue that needs fixing is support for
+text extraction in the PDF multibyte case (most common),
+which requires ToUnicode support; some preparation is already done.
+
+Usage
+-----
+(TODO)... see test_pdf.c ...
+
+ * for direct sfnt access: use <sfnt.h>
+ * for embedding: use <embed.h> (which includes <fontfile.h>)
+
+License (MIT)
+-------------
+Copyright (c) 2008,2012 by Tobias Hoffmann.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/fontembed/aglfn13.c b/fontembed/aglfn13.c
new file mode 100644
index 000000000..0fa143c56
--- /dev/null
+++ b/fontembed/aglfn13.c
@@ -0,0 +1,214 @@
+#include <stdlib.h>
+
+const char *aglfn13(unsigned short uni);
+
+#ifdef WITH_AGLFN
+static const char *agl_l207e[]={
+ "space","exclam","quotedbl","numbersign", "dollar","percent","ampersand","quotesingle",
+ "parenleft","parenright","asterisk","plus", "comma","hyphen","period","slash",
+ "zero","one","two","three", "four","five","six","seven", "eight","nine","colon","semicolon", "less","equal","greater","question",
+ "at","A","B","C", "D","E","F","G", "H","I","J","K", "L","M","N","O",
+ "P","Q","R","S", "T","U","V","W", "X","Y","Z","bracketleft", "backslash","bracketright","asciicircum","underscore",
+ "grave","a","b","c", "d","e","f","g", "h","i","j","k", "l","m","n","o",
+ "p","q","r","s", "t","u","v","w", "x","y","z","braceleft", "bar","braceright","asciitilde"};
+
+static const char *agl_la1ff[]={
+ "exclamdown","cent","sterling","currency", "yen","brokenbar","section","dieresis",
+ "copyright","ordfeminine","guillemotleft","logicalnot", "registered","macron","degree","plusminus",
+ 0,0,"acute",0, "paragraph","periodcentered","cedilla",0,
+ "ordmasculine","guillemotright","onequarter","onehalf", "threequarters","questiondown","Agrave","Aacute",
+ "Acircumflex","Atilde","Adieresis","Aring", "AE","Ccedilla","Egrave","Eacute",
+ "Ecircumflex","Edieresis","Igrave","Iacute", "Icircumflex","Idieresis","Eth","Ntilde",
+ "Ograve","Oacute","Ocircumflex","Otilde", "Odieresis","multiply","Oslash","Ugrave",
+ "Uacute","Ucircumflex","Udieresis","Yacute", "Thorn","germandbls","agrave","aacute",
+ "acircumflex","atilde","adieresis","aring", "ae","ccedilla","egrave","eacute",
+ "ecircumflex","edieresis","igrave","iacute", "icircumflex","idieresis","eth","ntilde",
+ "ograve","oacute","ocircumflex","otilde", "odieresis","divide","oslash","ugrave",
+ "uacute","ucircumflex","udieresis","yacute", "thorn","ydieresis"};
+
+static const char *agl_l1007f[]={
+ "Amacron","amacron","Abreve","abreve", "Aogonek","aogonek","Cacute","cacute",
+ "Ccircumflex","ccircumflex","Cdotaccent","cdotaccent", "Ccaron","ccaron","Dcaron","dcaron",
+ "Dcroat","dcroat","Emacron","emacron", "Ebreve","ebreve","Edotaccent","edotaccent",
+ "Eogonek","eogonek","Ecaron","ecaron", "Gcircumflex","gcircumflex","Gbreve","gbreve",
+ "Gdotaccent","gdotaccent","Gcommaaccent","gcommaaccent", "Hcircumflex","hcircumflex","Hbar","hbar",
+ "Itilde","itilde","Imacron","imacron", "Ibreve","ibreve","Iogonek","iogonek",
+ "Idotaccent","dotlessi","IJ","ij", "Jcircumflex","jcircumflex","Kcommaaccent","kcommaaccent",
+ "kgreenlandic","Lacute","lacute","Lcommaaccent", "lcommaaccent","Lcaron","lcaron","Ldot",
+ "ldot","Lslash","lslash","Nacute", "nacute","Ncommaaccent","ncommaaccent","Ncaron",
+ "ncaron","napostrophe","Eng","eng", "Omacron","omacron","Obreve","obreve",
+ "Ohungarumlaut","ohungarumlaut","OE","oe", "Racute","racute","Rcommaaccent","rcommaaccent",
+ "Rcaron","rcaron","Sacute","sacute", "Scircumflex","scircumflex","Scedilla","scedilla",
+ "Scaron","scaron","Tcommaaccent","tcommaaccent", "Tcaron","tcaron","Tbar","tbar",
+ "Utilde","utilde","Umacron","umacron", "Ubreve","ubreve","Uring","uring",
+ "Uhungarumlaut","uhungarumlaut","Uogonek","uogonek", "Wcircumflex","wcircumflex","Ycircumflex","ycircumflex",
+ "Ydieresis","Zacute","zacute","Zdotaccent", "zdotaccent","Zcaron","zcaron","longs"};
+
+struct agl_lt { unsigned short uid; const char *name; } agl_lxx[]={
+ {0x0192,"florin"},{0x01A0,"Ohorn"},{0x01A1,"ohorn"},{0x01AF,"Uhorn"},
+ {0x01B0,"uhorn"},{0x01E6,"Gcaron"},{0x01E7,"gcaron"},{0x01FA,"Aringacute"},
+ {0x01FB,"aringacute"},{0x01FC,"AEacute"},{0x01FD,"aeacute"},{0x01FE,"Oslashacute"},
+ {0x01FF,"oslashacute"},{0x0218,"Scommaaccent"},{0x0219,"scommaaccent"},{0x02BC,"afii57929"},
+ {0x02BD,"afii64937"},{0x02C6,"circumflex"},{0x02C7,"caron"},{0x02D8,"breve"},
+ {0x02D9,"dotaccent"},{0x02DA,"ring"},{0x02DB,"ogonek"},{0x02DC,"tilde"},
+ {0x02DD,"hungarumlaut"},{0x0300,"gravecomb"},{0x0301,"acutecomb"},{0x0303,"tildecomb"},
+ {0x0309,"hookabovecomb"},{0x0323,"dotbelowcomb"},{0x0384,"tonos"},{0x0385,"dieresistonos"},
+ {0x0386,"Alphatonos"},{0x0387,"anoteleia"},{0x0388,"Epsilontonos"},{0x0389,"Etatonos"},
+ {0x038A,"Iotatonos"},{0x038C,"Omicrontonos"},{0x038E,"Upsilontonos"},{0x038F,"Omegatonos"},
+ {0x0390,"iotadieresistonos"},{0x0391,"Alpha"},{0x0392,"Beta"},{0x0393,"Gamma"},
+ {0x0394,"Delta"},{0x0395,"Epsilon"},{0x0396,"Zeta"},{0x0397,"Eta"},
+ {0x0398,"Theta"},{0x0399,"Iota"},{0x039A,"Kappa"},{0x039B,"Lambda"},
+ {0x039C,"Mu"},{0x039D,"Nu"},{0x039E,"Xi"},{0x039F,"Omicron"},
+ {0x03A0,"Pi"},{0x03A1,"Rho"},{0x03A3,"Sigma"},{0x03A4,"Tau"},
+ {0x03A5,"Upsilon"},{0x03A6,"Phi"},{0x03A7,"Chi"},{0x03A8,"Psi"},
+ {0x03A9,"Omega"},{0x03AA,"Iotadieresis"},{0x03AB,"Upsilondieresis"},{0x03AC,"alphatonos"},
+ {0x03AD,"epsilontonos"},{0x03AE,"etatonos"},{0x03AF,"iotatonos"},{0x03B0,"upsilondieresistonos"},
+ {0x03B1,"alpha"},{0x03B2,"beta"},{0x03B3,"gamma"},{0x03B4,"delta"},
+ {0x03B5,"epsilon"},{0x03B6,"zeta"},{0x03B7,"eta"},{0x03B8,"theta"},
+ {0x03B9,"iota"},{0x03BA,"kappa"},{0x03BB,"lambda"},{0x03BC,"mu"},
+ {0x03BD,"nu"},{0x03BE,"xi"},{0x03BF,"omicron"},{0x03C0,"pi"},
+ {0x03C1,"rho"},{0x03C2,"sigma1"},{0x03C3,"sigma"},{0x03C4,"tau"},
+ {0x03C5,"upsilon"},{0x03C6,"phi"},{0x03C7,"chi"},{0x03C8,"psi"},
+ {0x03C9,"omega"},{0x03CA,"iotadieresis"},{0x03CB,"upsilondieresis"},
+ {0x03CC,"omicrontonos"},{0x03CD,"upsilontonos"},{0x03CE,"omegatonos"},
+ {0x03D1,"theta1"},{0x03D2,"Upsilon1"},{0x03D5,"phi1"},{0x03D6,"omega1"},
+ {0x0401,"afii10023"},{0x0402,"afii10051"},{0x0403,"afii10052"},{0x0404,"afii10053"},
+ {0x0405,"afii10054"},{0x0406,"afii10055"},{0x0407,"afii10056"},{0x0408,"afii10057"},
+ {0x0409,"afii10058"},{0x040A,"afii10059"},{0x040B,"afii10060"},{0x040C,"afii10061"},
+ {0x040E,"afii10062"},{0x040F,"afii10145"},{0x0410,"afii10017"},{0x0411,"afii10018"},
+ {0x0412,"afii10019"},{0x0413,"afii10020"},{0x0414,"afii10021"},{0x0415,"afii10022"},
+ {0x0416,"afii10024"},{0x0417,"afii10025"},{0x0418,"afii10026"},{0x0419,"afii10027"},
+ {0x041A,"afii10028"},{0x041B,"afii10029"},{0x041C,"afii10030"},{0x041D,"afii10031"},
+ {0x041E,"afii10032"},{0x041F,"afii10033"},{0x0420,"afii10034"},{0x0421,"afii10035"},
+ {0x0422,"afii10036"},{0x0423,"afii10037"},{0x0424,"afii10038"},{0x0425,"afii10039"},
+ {0x0426,"afii10040"},{0x0427,"afii10041"},{0x0428,"afii10042"},{0x0429,"afii10043"},
+ {0x042A,"afii10044"},{0x042B,"afii10045"},{0x042C,"afii10046"},{0x042D,"afii10047"},
+ {0x042E,"afii10048"},{0x042F,"afii10049"},{0x0430,"afii10065"},{0x0431,"afii10066"},
+ {0x0432,"afii10067"},{0x0433,"afii10068"},{0x0434,"afii10069"},{0x0435,"afii10070"},
+ {0x0436,"afii10072"},{0x0437,"afii10073"},{0x0438,"afii10074"},{0x0439,"afii10075"},
+ {0x043A,"afii10076"},{0x043B,"afii10077"},{0x043C,"afii10078"},{0x043D,"afii10079"},
+ {0x043E,"afii10080"},{0x043F,"afii10081"},{0x0440,"afii10082"},{0x0441,"afii10083"},
+ {0x0442,"afii10084"},{0x0443,"afii10085"},{0x0444,"afii10086"},{0x0445,"afii10087"},
+ {0x0446,"afii10088"},{0x0447,"afii10089"},{0x0448,"afii10090"},{0x0449,"afii10091"},
+ {0x044A,"afii10092"},{0x044B,"afii10093"},{0x044C,"afii10094"},{0x044D,"afii10095"},
+ {0x044E,"afii10096"},{0x044F,"afii10097"},{0x0451,"afii10071"},{0x0452,"afii10099"},
+ {0x0453,"afii10100"},{0x0454,"afii10101"},{0x0455,"afii10102"},{0x0456,"afii10103"},
+ {0x0457,"afii10104"},{0x0458,"afii10105"},{0x0459,"afii10106"},{0x045A,"afii10107"},
+ {0x045B,"afii10108"},{0x045C,"afii10109"},{0x045E,"afii10110"},{0x045F,"afii10193"},
+ {0x0462,"afii10146"},{0x0463,"afii10194"},{0x0472,"afii10147"},{0x0473,"afii10195"},
+ {0x0474,"afii10148"},{0x0475,"afii10196"},{0x0490,"afii10050"},{0x0491,"afii10098"},
+ {0x04D9,"afii10846"},{0x05B0,"afii57799"},{0x05B1,"afii57801"},{0x05B2,"afii57800"},
+ {0x05B3,"afii57802"},{0x05B4,"afii57793"},{0x05B5,"afii57794"},{0x05B6,"afii57795"},
+ {0x05B7,"afii57798"},{0x05B8,"afii57797"},{0x05B9,"afii57806"},{0x05BB,"afii57796"},
+ {0x05BC,"afii57807"},{0x05BD,"afii57839"},{0x05BE,"afii57645"},{0x05BF,"afii57841"},
+ {0x05C0,"afii57842"},{0x05C1,"afii57804"},{0x05C2,"afii57803"},{0x05C3,"afii57658"},
+ {0x05D0,"afii57664"},{0x05D1,"afii57665"},{0x05D2,"afii57666"},{0x05D3,"afii57667"},
+ {0x05D4,"afii57668"},{0x05D5,"afii57669"},{0x05D6,"afii57670"},{0x05D7,"afii57671"},
+ {0x05D8,"afii57672"},{0x05D9,"afii57673"},{0x05DA,"afii57674"},{0x05DB,"afii57675"},
+ {0x05DC,"afii57676"},{0x05DD,"afii57677"},{0x05DE,"afii57678"},{0x05DF,"afii57679"},
+ {0x05E0,"afii57680"},{0x05E1,"afii57681"},{0x05E2,"afii57682"},{0x05E3,"afii57683"},
+ {0x05E4,"afii57684"},{0x05E5,"afii57685"},{0x05E6,"afii57686"},{0x05E7,"afii57687"},
+ {0x05E8,"afii57688"},{0x05E9,"afii57689"},{0x05EA,"afii57690"},{0x05F0,"afii57716"},
+ {0x05F1,"afii57717"},{0x05F2,"afii57718"},{0x060C,"afii57388"},{0x061B,"afii57403"},
+ {0x061F,"afii57407"},{0x0621,"afii57409"},{0x0622,"afii57410"},{0x0623,"afii57411"},
+ {0x0624,"afii57412"},{0x0625,"afii57413"},{0x0626,"afii57414"},{0x0627,"afii57415"},
+ {0x0628,"afii57416"},{0x0629,"afii57417"},{0x062A,"afii57418"},{0x062B,"afii57419"},
+ {0x062C,"afii57420"},{0x062D,"afii57421"},{0x062E,"afii57422"},{0x062F,"afii57423"},
+ {0x0630,"afii57424"},{0x0631,"afii57425"},{0x0632,"afii57426"},{0x0633,"afii57427"},
+ {0x0634,"afii57428"},{0x0635,"afii57429"},{0x0636,"afii57430"},{0x0637,"afii57431"},
+ {0x0638,"afii57432"},{0x0639,"afii57433"},{0x063A,"afii57434"},{0x0640,"afii57440"},
+ {0x0641,"afii57441"},{0x0642,"afii57442"},{0x0643,"afii57443"},{0x0644,"afii57444"},
+ {0x0645,"afii57445"},{0x0646,"afii57446"},{0x0647,"afii57470"},{0x0648,"afii57448"},
+ {0x0649,"afii57449"},{0x064A,"afii57450"},{0x064B,"afii57451"},{0x064C,"afii57452"},
+ {0x064D,"afii57453"},{0x064E,"afii57454"},{0x064F,"afii57455"},{0x0650,"afii57456"},
+ {0x0651,"afii57457"},{0x0652,"afii57458"},{0x0660,"afii57392"},{0x0661,"afii57393"},
+ {0x0662,"afii57394"},{0x0663,"afii57395"},{0x0664,"afii57396"},{0x0665,"afii57397"},
+ {0x0666,"afii57398"},{0x0667,"afii57399"},{0x0668,"afii57400"},{0x0669,"afii57401"},
+ {0x066A,"afii57381"},{0x066D,"afii63167"},{0x0679,"afii57511"},{0x067E,"afii57506"},
+ {0x0686,"afii57507"},{0x0688,"afii57512"},{0x0691,"afii57513"},{0x0698,"afii57508"},
+ {0x06A4,"afii57505"},{0x06AF,"afii57509"},{0x06BA,"afii57514"},{0x06D2,"afii57519"},
+ {0x06D5,"afii57534"},{0x1E80,"Wgrave"},{0x1E81,"wgrave"},{0x1E82,"Wacute"},
+ {0x1E83,"wacute"},{0x1E84,"Wdieresis"},{0x1E85,"wdieresis"},{0x1EF2,"Ygrave"},
+ {0x1EF3,"ygrave"},{0x200C,"afii61664"},{0x200D,"afii301"},{0x200E,"afii299"},
+ {0x200F,"afii300"},{0x2012,"figuredash"},{0x2013,"endash"},{0x2014,"emdash"},
+ {0x2015,"afii00208"},{0x2017,"underscoredbl"},{0x2018,"quoteleft"},{0x2019,"quoteright"},
+ {0x201A,"quotesinglbase"},{0x201B,"quotereversed"},{0x201C,"quotedblleft"},{0x201D,"quotedblright"},
+ {0x201E,"quotedblbase"},{0x2020,"dagger"},{0x2021,"daggerdbl"},{0x2022,"bullet"},
+ {0x2024,"onedotenleader"},{0x2025,"twodotenleader"},{0x2026,"ellipsis"},{0x202C,"afii61573"},
+ {0x202D,"afii61574"},{0x202E,"afii61575"},{0x2030,"perthousand"},{0x2032,"minute"},
+ {0x2033,"second"},{0x2039,"guilsinglleft"},{0x203A,"guilsinglright"},{0x203C,"exclamdbl"},
+ {0x2044,"fraction"},{0x20A1,"colonmonetary"},{0x20A3,"franc"},{0x20A4,"lira"},
+ {0x20A7,"peseta"},{0x20AA,"afii57636"},{0x20AB,"dong"},{0x20AC,"Euro"},
+ {0x2105,"afii61248"},{0x2111,"Ifraktur"},{0x2113,"afii61289"},{0x2116,"afii61352"},
+ {0x2118,"weierstrass"},{0x211C,"Rfraktur"},{0x211E,"prescription"},{0x2122,"trademark"},
+ {0x212E,"estimated"},{0x2135,"aleph"},{0x2153,"onethird"},{0x2154,"twothirds"},
+ {0x215B,"oneeighth"},{0x215C,"threeeighths"},{0x215D,"fiveeighths"},{0x215E,"seveneighths"},
+ {0x2190,"arrowleft"},{0x2191,"arrowup"},{0x2192,"arrowright"},{0x2193,"arrowdown"},
+ {0x2194,"arrowboth"},{0x2195,"arrowupdn"},{0x21A8,"arrowupdnbse"},{0x21B5,"carriagereturn"},
+ {0x21D0,"arrowdblleft"},{0x21D1,"arrowdblup"},{0x21D2,"arrowdblright"},{0x21D3,"arrowdbldown"},
+ {0x21D4,"arrowdblboth"},{0x2200,"universal"},{0x2202,"partialdiff"},{0x2203,"existential"},
+ {0x2205,"emptyset"},{0x2207,"gradient"},{0x2208,"element"},{0x2209,"notelement"},
+ {0x220B,"suchthat"},{0x220F,"product"},{0x2211,"summation"},{0x2212,"minus"},
+ {0x2217,"asteriskmath"},{0x221A,"radical"},{0x221D,"proportional"},{0x221E,"infinity"},
+ {0x221F,"orthogonal"},{0x2220,"angle"},{0x2227,"logicaland"},{0x2228,"logicalor"},
+ {0x2229,"intersection"},{0x222A,"union"},{0x222B,"integral"},{0x2234,"therefore"},
+ {0x223C,"similar"},{0x2245,"congruent"},{0x2248,"approxequal"},{0x2260,"notequal"},
+ {0x2261,"equivalence"},{0x2264,"lessequal"},{0x2265,"greaterequal"},{0x2282,"propersubset"},
+ {0x2283,"propersuperset"},{0x2284,"notsubset"},{0x2286,"reflexsubset"},{0x2287,"reflexsuperset"},
+ {0x2295,"circleplus"},{0x2297,"circlemultiply"},{0x22A5,"perpendicular"},{0x22C5,"dotmath"},
+ {0x2302,"house"},{0x2310,"revlogicalnot"},{0x2320,"integraltp"},{0x2321,"integralbt"},
+ {0x2329,"angleleft"},{0x232A,"angleright"},{0x2500,"SF100000"},{0x2502,"SF110000"},
+ {0x250C,"SF010000"},{0x2510,"SF030000"},{0x2514,"SF020000"},{0x2518,"SF040000"},
+ {0x251C,"SF080000"},{0x2524,"SF090000"},{0x252C,"SF060000"},{0x2534,"SF070000"},
+ {0x253C,"SF050000"},{0x2550,"SF430000"},{0x2551,"SF240000"},{0x2552,"SF510000"},
+ {0x2553,"SF520000"},{0x2554,"SF390000"},{0x2555,"SF220000"},{0x2556,"SF210000"},
+ {0x2557,"SF250000"},{0x2558,"SF500000"},{0x2559,"SF490000"},{0x255A,"SF380000"},
+ {0x255B,"SF280000"},{0x255C,"SF270000"},{0x255D,"SF260000"},{0x255E,"SF360000"},
+ {0x255F,"SF370000"},{0x2560,"SF420000"},{0x2561,"SF190000"},{0x2562,"SF200000"},
+ {0x2563,"SF230000"},{0x2564,"SF470000"},{0x2565,"SF480000"},{0x2566,"SF410000"},
+ {0x2567,"SF450000"},{0x2568,"SF460000"},{0x2569,"SF400000"},{0x256A,"SF540000"},
+ {0x256B,"SF530000"},{0x256C,"SF440000"},{0x2580,"upblock"},{0x2584,"dnblock"},
+ {0x2588,"block"},{0x258C,"lfblock"},{0x2590,"rtblock"},{0x2591,"ltshade"},
+ {0x2592,"shade"},{0x2593,"dkshade"},{0x25A0,"filledbox"},{0x25A1,"H22073"},
+ {0x25AA,"H18543"},{0x25AB,"H18551"},{0x25AC,"filledrect"},{0x25B2,"triagup"},
+ {0x25BA,"triagrt"},{0x25BC,"triagdn"},{0x25C4,"triaglf"},{0x25CA,"lozenge"},
+ {0x25CB,"circle"},{0x25CF,"H18533"},{0x25D8,"invbullet"},{0x25D9,"invcircle"},
+ {0x25E6,"openbullet"},{0x263A,"smileface"},{0x263B,"invsmileface"},{0x263C,"sun"},
+ {0x2640,"female"},{0x2642,"male"},{0x2660,"spade"},{0x2663,"club"},
+ {0x2665,"heart"},{0x2666,"diamond"},{0x266A,"musicalnote"},{0x266B,"musicalnotedbl"}};
+
+static int agl_cmp(const void *a,const void *b)
+{
+ const unsigned short aa=((struct agl_lt *)a)->uid,bb=((struct agl_lt *)b)->uid;
+ if (aa<bb) {
+ return -1;
+ } else if (aa>bb) {
+ return 1;
+ }
+ return 0;
+}
+
+const char *aglfn13(unsigned short uni)
+{
+ if ( (uni>=0x0020)&&(uni<0x007f) ) {
+ return agl_l207e[uni-0x0020];
+ } else if ( (uni>=0x00a1)&&(uni<=0x00ff) ) {
+ return agl_la1ff[uni-0x00a1];
+ } else if ( (uni>=0x0100)&&(uni<=0x017f) ) {
+ return agl_l1007f[uni-0x0100];
+ } else if (uni>=0x0180) {
+ struct agl_lt key,*res;
+ key.uid=uni;
+ res=bsearch(&key,agl_lxx,(sizeof(agl_lxx)/sizeof(struct agl_lt)),sizeof(struct agl_lt),agl_cmp);
+ if (res) {
+ return res->name;
+ }
+ }
+ return NULL;
+}
+#else
+const char *aglfn13(unsigned short uni)
+{
+ return NULL;
+}
+#endif
diff --git a/fontembed/bitset.h b/fontembed/bitset.h
new file mode 100644
index 000000000..71d50abb7
--- /dev/null
+++ b/fontembed/bitset.h
@@ -0,0 +1,38 @@
+#ifndef _BITSET_H
+#define _BITSET_H
+
+#include <stdlib.h>
+
+typedef int * BITSET;
+
+static inline void bit_set(BITSET bs,int num)
+{
+ bs[num/(8*sizeof(int))]|=1<<(num%(8*sizeof(int)));
+}
+
+static inline int bit_check(BITSET bs,int num)
+{
+ return bs[num/(8*sizeof(int))]&1<<(num%(8*sizeof(int)));
+}
+
+// use free() when done. returns NULL on bad_alloc
+static inline BITSET bitset_new(int size)
+{
+ return (BITSET)calloc(1,((size+8*sizeof(int)-1)&~(8*sizeof(int)-1))/8);
+}
+
+static inline int bits_used(BITSET bits,int size) // {{{ returns true if any bit is used
+{
+ size=(size+8*sizeof(int)-1)/(8*sizeof(int));
+ while (size>0) {
+ if (*bits) {
+ return 1;
+ }
+ bits++;
+ size--;
+ }
+ return 0;
+}
+// }}}
+
+#endif
diff --git a/fontembed/dynstring.c b/fontembed/dynstring.c
new file mode 100644
index 000000000..0bdad157d
--- /dev/null
+++ b/fontembed/dynstring.c
@@ -0,0 +1,105 @@
+#include "dynstring.h"
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+int dyn_init(DYN_STRING *ds,int reserve_size) // {{{
+{
+ assert(ds);
+ assert(reserve_size>0);
+
+ ds->len=0;
+ ds->alloc=reserve_size;
+ ds->buf=malloc(ds->alloc+1);
+ if (!ds->buf) {
+ fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
+ assert(0);
+ ds->len=-1;
+ return -1;
+ }
+ return 0;
+}
+// }}}
+
+void dyn_free(DYN_STRING *ds) // {{{
+{
+ assert(ds);
+
+ ds->len=-1;
+ ds->alloc=0;
+ free(ds->buf);
+ ds->buf=NULL;
+}
+// }}}
+
+int dyn_ensure(DYN_STRING *ds,int free_space) // {{{
+{
+ assert(ds);
+ assert(free_space);
+
+ if (ds->len<0) {
+ return -1;
+ }
+ if (ds->alloc - ds->len >= free_space) {
+ return 0; // done
+ }
+ ds->alloc+=free_space;
+ char *tmp=realloc(ds->buf,ds->alloc+1);
+ if (!tmp) {
+ ds->len=-1;
+ fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
+ assert(0);
+ return -1;
+ }
+ ds->buf=tmp;
+ return 0;
+}
+// }}}
+
+int dyn_vprintf(DYN_STRING *ds,const char *fmt,va_list ap) // {{{
+{
+ assert(ds);
+
+ int need,len=strlen(fmt)+100;
+ va_list va;
+
+ if (dyn_ensure(ds,len)==-1) {
+ return -1;
+ }
+
+ while (1) {
+ va_copy(va,ap);
+ need=vsnprintf(ds->buf+ds->len,ds->alloc-ds->len+1,fmt,va);
+ va_end(va);
+ if (need==-1) {
+ len+=100;
+ } else if (need>=len) {
+ len=need;
+ } else {
+ ds->len+=need;
+ break;
+ }
+ if (dyn_ensure(ds,len)==-1) {
+ return -1;
+ }
+ }
+ return 0;
+}
+// }}}
+
+int dyn_printf(DYN_STRING *ds,const char *fmt,...) // {{{
+{
+ va_list va;
+ int ret;
+
+ va_start(va,fmt);
+ ret=dyn_vprintf(ds,fmt,va);
+ va_end(va);
+
+ return ret;
+}
+// }}}
+
diff --git a/fontembed/dynstring.h b/fontembed/dynstring.h
new file mode 100644
index 000000000..a758f2c1c
--- /dev/null
+++ b/fontembed/dynstring.h
@@ -0,0 +1,16 @@
+#ifndef _DYNSTRING_H
+#define _DYNSTRING_H
+
+typedef struct {
+ int len,alloc;
+ char *buf;
+} DYN_STRING;
+
+int dyn_init(DYN_STRING *ds,int reserve_size); // -1 on error
+void dyn_free(DYN_STRING *ds);
+int dyn_ensure(DYN_STRING *ds,int free_space);
+int dyn_printf(DYN_STRING *ds,const char *fmt,...) // appends
+ __attribute__((format(printf, 2, 3)));
+
+#endif
+
diff --git a/fontembed/embed.c b/fontembed/embed.c
new file mode 100644
index 000000000..cdf8054cf
--- /dev/null
+++ b/fontembed/embed.c
@@ -0,0 +1,260 @@
+#include "embed.h"
+#include "embed_sfnt_int.h"
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+static inline int copy_file(FILE *f,OUTPUT_FN output,void *context) // {{{
+{
+ assert(f);
+ assert(output);
+
+ char buf[4096];
+ int iA,ret=0;
+
+ ret=0;
+ rewind(f);
+ do {
+ iA=fread(buf,1,4096,f);
+ (*output)(buf,iA,context);
+ ret+=iA;
+ } while (iA>0);
+ return ret;
+}
+// }}}
+
+/* certain profiles: (=> constraints to be auto-applied in emb_new via >dest)
+ PSold: T1->T1, TTF->T1, OTF->CFF->T1, STD->STD // output limit: T1 (maybe length, binary/text, ... limit)
+ PS1: T1->T1, TTF->T1, OTF->CFF, STD->STD // output limit: T1,CFF [does this really exists?]
+ PS2: T1->T1, TTF->TTF, OTF->T1, STD->STD // output limit: T1,TTF
+ PS3: T1->T1, TTF->TTF, OTF->CFF, STD->STD
+ PDF12/13?: OTF->CFF
+ PDF16: OTF->OTF (,T1->CFF?)
+ --- rename KEEP_T1 to NEED_T1? NO_T42?
+
+ converters:
+ OTF->CFF, CFF->OTF (extract metrics, etc)
+ (T1->CFF, CFF->T1)
+ ((TTF->T1 ['good'; T1->TTF: not good]))
+ [subsetTTF,subsetCFF,subsetT1]
+
+ output modes:
+ subset,CID(multibyte),(PS:)text/binary,(PS:)incremental
+
+ TODO: remove dest from emb_new, replace with EMB_ACTIONS constraints:
+ - bitfield mask which ACTIONS are allowed. (problem: we want to force certain ones, e.g. MULTIBYTE)
+ - e.g. currently EMB_C_PDF_OT has to functions
+ - the only (other) 'difference' to now is the subsetting spec
+ - another issue is, that emb_pdf_ might want some pdf version informatino (->extra flag?)
+ and funtion to determine appropriate mask for certain destination
+ EMB_ACTIONS emb_mask_for_dest(EMB_DESTINATION)
+ TODO? determine viability before trying emb_embed
+ (idea: use emb_embed(,NULL) -> will just return true/false [same codepath!])
+
+ TODO?! "always subset CJK"
+*/
+
+EMB_PARAMS *emb_new(FONTFILE *font,EMB_DESTINATION dest,EMB_CONSTRAINTS mode) // {{{
+{
+ assert(font);
+
+ EMB_PARAMS *ret=calloc(1,sizeof(EMB_PARAMS));
+ if (!ret) {
+ fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
+ if (mode&EMB_C_TAKE_FONTFILE) {
+ fontfile_close(font);
+ }
+ return NULL;
+ }
+ ret->dest=dest;
+ ret->font=font;
+ if (mode&EMB_C_TAKE_FONTFILE) {
+ ret->plan|=EMB_A_CLOSE_FONTFILE;
+ }
+
+ // check parameters
+ if ( (mode&EMB_C_KEEP_T1)&&(mode&EMB_C_FORCE_MULTIBYTE) ) {
+ fprintf(stderr,"Incompatible mode: KEEP_T1 and FORCE_MULTIBYTE\n");
+ emb_close(ret);
+ return NULL;
+ }
+ if ((mode&0x07)>5) {
+ fprintf(stderr,"Bad subset specification\n");
+ emb_close(ret);
+ return NULL;
+ }
+
+ // determine intype
+ int numGlyphs=0;
+ if (font->sfnt) {
+ if (font->sfnt->flags&OTF_F_FMT_CFF) {
+ ret->intype=EMB_FMT_OTF;
+ } else {
+ ret->intype=EMB_FMT_TTF;
+ }
+ ret->rights=emb_otf_get_rights(ret->font->sfnt);
+ numGlyphs=ret->font->sfnt->numGlyphs; // TODO
+ } else if (font->stdname) {
+ ret->intype=EMB_FMT_STDFONT;
+ ret->rights=EMB_RIGHT_NONE;
+ } else {
+ assert(0);
+ }
+/*
+ if ( (ret->intype==EMB_FMT_CFF)&&
+ (ret->cffFont.is_cid()) ) {
+ ?= || ( (ret->intype==EMB_FMT_OTF)&&(ret->sfnt->cffFont.is_cid()) ) // TODO?
+ ret->plan|=EMB_A_MULTIBYTE;
+ }
+*/
+
+ // determine outtype
+ if (ret->intype==EMB_FMT_STDFONT) {
+ ret->outtype=ret->intype;
+ if (mode&EMB_C_FORCE_MULTIBYTE) {
+ fprintf(stderr,"Multibyte stdfonts are not possible\n");
+ emb_close(ret);
+ return NULL;
+ }
+ return ret; // never subset, no multibyte
+ } else if (ret->intype==EMB_FMT_T1) {
+ if (mode&EMB_C_KEEP_T1) {
+ ret->outtype=EMB_FMT_T1;
+ } else {
+ ret->plan|=EMB_A_T1_TO_CFF;
+ ret->outtype=EMB_FMT_CFF;
+ }
+ } else {
+ ret->outtype=ret->intype;
+ }
+ if (ret->outtype==EMB_FMT_CFF) {
+ if (mode&EMB_C_PDF_OT) {
+ ret->outtype=EMB_FMT_OTF;
+ ret->plan|=EMB_A_CFF_TO_OTF;
+ }
+ } else if (ret->outtype==EMB_FMT_OTF) {
+ // TODO: no support yet; but we want to get the FontDescriptor/Name right
+ mode|=EMB_C_NEVER_SUBSET;
+ if (!(mode&EMB_C_PDF_OT)) { // TODO!?!
+ ret->outtype=EMB_FMT_CFF;
+ ret->plan|=EMB_A_OTF_TO_CFF;
+ }
+ }
+
+ if (mode&EMB_C_FORCE_MULTIBYTE) {
+ ret->plan|=EMB_A_MULTIBYTE;
+ }
+
+ // check rights (for subsetting)
+ if ( (ret->rights&EMB_RIGHT_NONE)||
+ (ret->rights&EMB_RIGHT_BITMAPONLY)||
+ ( (ret->rights&EMB_RIGHT_READONLY)&&(mode&EMB_C_EDITABLE_SUBSET) )||
+ ( (ret->rights&EMB_RIGHT_NO_SUBSET)&&(mode&EMB_C_MUST_SUBSET) ) ) {
+ fprintf(stderr,"The font does not permit the requested embedding\n");
+ emb_close(ret);
+ return NULL;
+ } else if ( (!(ret->rights&EMB_RIGHT_NO_SUBSET))&&
+ (!(mode&EMB_C_NEVER_SUBSET)) ) {
+ ret->plan|=EMB_A_SUBSET;
+ }
+
+ // alloc subset
+ if (ret->plan&EMB_A_SUBSET) {
+ ret->subset=bitset_new(numGlyphs);
+ if (!ret->subset) {
+ fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
+ emb_close(ret);
+ return NULL;
+ }
+ }
+
+ return ret;
+}
+// }}}
+
+int emb_embed(EMB_PARAMS *emb,OUTPUT_FN output,void *context) // {{{
+{
+ assert(emb);
+
+ if (emb->dest==EMB_DEST_NATIVE) {
+ } else if (emb->dest<=EMB_DEST_PS) {
+ int ret=-2;
+ const char *fontname=emb_otf_get_fontname(emb->font->sfnt); // TODO!!
+ (*output)("%%BeginFont: ",13,context);
+ (*output)(fontname,strlen(fontname),context);
+ (*output)("\n",1,context);
+ if (emb->outtype==EMB_FMT_T1) {
+ } else if (emb->outtype==EMB_FMT_TTF) { // emb->outtype==EMB_OUTPUT_OTF is stupid (?)
+ // do Type42
+ ret=emb_otf_ps(emb->font->sfnt,NULL,256,NULL,output,context); // TODO?
+ } else if (emb->outtype==EMB_FMT_CFF) {
+ } else if (emb->outtype==EMB_FMT_STDFONT) {
+ }
+ if (ret!=-2) {
+ if (ret!=-1) {
+ (*output)("%%EndFont\n",10,context);
+ } else {
+ fprintf(stderr,"Failed\n");
+ }
+ return ret;
+ }
+ } else if (emb->dest<=EMB_DEST_PDF16) {
+ if (emb->outtype==EMB_FMT_TTF) {
+ assert(emb->font->sfnt);
+ if (emb->plan&EMB_A_SUBSET) {
+ return otf_subset(emb->font->sfnt,emb->subset,output,context);
+ } else if (emb->font->sfnt->numTTC) { //
+ return otf_ttc_extract(emb->font->sfnt,output,context);
+ } else { // copy verbatim
+ return copy_file(emb->font->sfnt->f,output,context);
+ }
+ } else if (emb->outtype==EMB_FMT_OTF) {
+ if (emb->plan&EMB_A_CFF_TO_OTF) {
+ if (emb->plan&EMB_A_T1_TO_CFF) {
+ // TODO
+ } else {
+ // assert(emb->font->cff);
+ // TODO
+ }
+ } else {
+ assert(emb->font->sfnt);
+ if (emb->plan&EMB_A_SUBSET) {
+ return otf_subset_cff(emb->font->sfnt,emb->subset,output,context);
+ } else {
+ return copy_file(emb->font->sfnt->f,output,context);
+ }
+ }
+ } else if (emb->outtype==EMB_FMT_CFF) {
+ if (emb->plan&EMB_A_OTF_TO_CFF) {
+ assert(emb->font->sfnt);
+ if (emb->plan&EMB_A_SUBSET) {
+ // TODO
+ } else {
+ return otf_cff_extract(emb->font->sfnt,output,context);
+ }
+ } else {
+ // TODO
+ }
+ }
+ }
+
+ fprintf(stderr,"NOT IMPLEMENTED\n");
+ assert(0);
+ return -1;
+}
+// }}}
+
+void emb_close(EMB_PARAMS *emb) // {{{
+{
+ if (emb) {
+ free(emb->subset);
+ if (emb->plan&EMB_A_CLOSE_FONTFILE) {
+ fontfile_close(emb->font);
+ }
+ free(emb);
+ }
+}
+// }}}
+
diff --git a/fontembed/embed.h b/fontembed/embed.h
new file mode 100644
index 000000000..682471f45
--- /dev/null
+++ b/fontembed/embed.h
@@ -0,0 +1,92 @@
+#ifndef EMBED_H
+#define EMBED_H
+
+#include "bitset.h"
+#include "fontfile.h"
+#include "iofn.h"
+
+typedef enum { EMB_FMT_T1, // type1, with AFM/PFM,PFA/PFB
+ EMB_FMT_TTF, // sfnt, for TTF(glyf)
+ EMB_FMT_OTF, // sfnt+cff, for OTF(cff)
+ EMB_FMT_CFF, // cff, for raw CFF
+ EMB_FMT_STDFONT // don't embed (already present)
+ } EMB_FORMAT;
+typedef enum { EMB_DEST_NATIVE, // just subsetting/conversion
+ EMB_DEST_PS,
+// EMB_DEST_PS2,
+// EMB_DEST_PDF13,
+ EMB_DEST_PDF16
+ } EMB_DESTINATION;
+
+typedef enum { EMB_RIGHT_FULL=0, EMB_RIGHT_NONE=0x02,
+ EMB_RIGHT_READONLY=0x04,
+ EMB_RIGHT_NO_SUBSET=0x0100,
+ EMB_RIGHT_BITMAPONLY=0x0200 } EMB_RIGHT_TYPE;
+
+typedef enum { EMB_A_MULTIBYTE=0x01, // embedd as multibyte font?
+ EMB_A_SUBSET=0x02, // do subsetting?
+ EMB_A_T1_TO_CFF=0x04, // convert Type1 to CFF?
+ EMB_A_CFF_TO_OTF=0x08, // wrap CFF(from input or T1+CONVERT_CFF) in sfnt? (OTF)
+ EMB_A_OTF_TO_CFF=0x10, // unwrap CFF
+
+ EMB_A_CLOSE_FONTFILE=0x8000
+ } EMB_ACTIONS;
+
+typedef enum { EMB_C_MUST_SUBSET=0x01, // (fail, when not possible)
+ EMB_C_EDITABLE_SUBSET=0x02, // (...)
+ EMB_C_NEVER_SUBSET=0x04, // (...)
+
+ EMB_C_FORCE_MULTIBYTE=0x08, // always use multibyte fonts
+
+ EMB_C_PDF_OT=0x10, // output TTF/OTF (esp. CFF to OTF)
+ EMB_C_KEEP_T1=0x20, // don't convert T1 to CFF
+
+ EMB_C_TAKE_FONTFILE=0x8000 // take ownership of fontfile
+ } EMB_CONSTRAINTS;
+
+typedef struct _EMB_PARAMS {
+ EMB_FORMAT intype;
+ EMB_FORMAT outtype;
+ EMB_DESTINATION dest;
+
+ EMB_ACTIONS plan;
+
+ // font infos
+ FONTFILE *font;
+ EMB_RIGHT_TYPE rights;
+// public:
+ BITSET subset;
+
+} EMB_PARAMS;
+
+EMB_PARAMS *emb_new(FONTFILE *font,EMB_DESTINATION dest,EMB_CONSTRAINTS mode);
+// emb_embedd does only the "binary" part
+int emb_embed(EMB_PARAMS *emb,OUTPUT_FN output,void *context); // returns number of bytes written
+void emb_close(EMB_PARAMS *emb);
+
+// TODO: encoding, TODO: ToUnicode
+static inline void emb_set(EMB_PARAMS *emb,int unicode,unsigned short gid) // {{{
+{
+ if (emb->subset) {
+ if (emb->plan&EMB_A_MULTIBYTE) {
+ bit_set(emb->subset,gid);
+ // ToUnicode.add(gid,unicode);
+ } else {
+ // TODO ... encoding
+ }
+ }
+}
+// }}}
+
+// TODO: encoding?, TODO: non-sfnt
+static inline unsigned short emb_get(EMB_PARAMS *emb,int unicode) // {{{ gid
+{
+ const unsigned short gid=otf_from_unicode(emb->font->sfnt,unicode);
+ emb_set(emb,unicode,gid);
+ return gid;
+}
+// }}}
+
+#include "embed_pdf.h"
+
+#endif
diff --git a/fontembed/embed_pdf.c b/fontembed/embed_pdf.c
new file mode 100644
index 000000000..f3df1afbe
--- /dev/null
+++ b/fontembed/embed_pdf.c
@@ -0,0 +1,597 @@
+#include "embed.h"
+#include "embed_pdf.h" // already included fron embed.h ...
+#include "embed_pdf_int.h"
+#include "embed_sfnt_int.h"
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <time.h>
+#include "frequent.h"
+
+// NOTE: these must be in sync with the EMB_FORMAT enum
+static const char *emb_pdf_font_subtype[][2]={ // {{{ (output_format,multibyte)
+ {"Type1",NULL},
+ {"TrueType","CIDFontType2"},
+ {"Type1","CIDFontType0"},
+ {"Type1","CIDFontType0"},
+ {"Type1",NULL}};
+// }}}
+
+static const char *emb_pdf_fontfile_key[]={ // {{{ (output_format)
+ "FontFile","FontFile2","FontFile3","FontFile3",NULL};
+// }}}
+
+// ... PDF1.6 here
+static const char *emb_pdf_fontfile_subtype[][2]={ // {{{ (output_format,multibyte)
+ {NULL,NULL},
+ {NULL,NULL},
+ {"OpenType","OpenType"},
+ {"Type1C","CIDFontType0C"},
+ {NULL,NULL}};
+// }}}
+
+static inline int emb_multibyte(EMB_PARAMS *emb) // {{{
+{
+ return (emb->plan&EMB_A_MULTIBYTE)?1:0;
+}
+// }}}
+
+static const char *emb_pdf_escape_name(const char *name,int len) // {{{ // - statically allocated buffer
+{
+ assert(name);
+ if (len==-1) {
+ len=strlen(name);
+ }
+ assert(len<=127); // pdf implementation limit
+
+ static char buf[128*3];
+ int iA,iB;
+ const char hex[]="0123456789abcdef";
+
+ for (iA=0,iB=0;iA<len;iA++,iB++) {
+ if ( ((unsigned char)name[iA]<33)||((unsigned char)name[iA]>126)||
+ (strchr("#()<>[]{}/%",name[iA])) ) {
+ buf[iB]='#';
+ buf[++iB]=hex[(name[iA]>>4)&0x0f];
+ buf[++iB]=hex[name[iA]&0xf];
+ } else {
+ buf[iB]=name[iA];
+ }
+ }
+ buf[iB]=0;
+ return buf;
+}
+// }}}
+
+// this is in the font dict
+const char *emb_pdf_get_font_subtype(EMB_PARAMS *emb) // {{{
+{
+ assert(emb);
+ return emb_pdf_font_subtype[emb->outtype][emb_multibyte(emb)];
+}
+// }}}
+
+// in font descriptor
+const char *emb_pdf_get_fontfile_key(EMB_PARAMS *emb) // {{{
+{
+ assert(emb);
+ return emb_pdf_fontfile_key[emb->outtype];
+}
+// }}}
+
+// this is what to put in the font-stream dict
+const char *emb_pdf_get_fontfile_subtype(EMB_PARAMS *emb) // {{{
+{
+ assert(emb);
+ return emb_pdf_fontfile_subtype[emb->outtype][emb_multibyte(emb)];
+}
+// }}}
+
+// {{{ static EMB_PDF_FONTDESCR *emb_pdf_fd_new(fontname,subset_tag,cid_registry,cid_ordering,cid_supplement,panose)
+static EMB_PDF_FONTDESCR *emb_pdf_fd_new(const char *fontname,
+ const char *subset_tag,
+ const char *cid_registry, // or supplement==-1
+ const char *cid_ordering, // or supplement==-1
+ int cid_supplement) // -1 for non-cid
+{
+ assert(fontname);
+ EMB_PDF_FONTDESCR *ret;
+
+ int len=sizeof(EMB_PDF_FONTDESCR);
+ if (subset_tag) {
+ assert(strlen(subset_tag)==6);
+ len+=7;
+ }
+ len+=strlen(fontname)+1;
+ if (cid_supplement>=0) { // cid font
+ len+=12; // space for panose
+ assert(cid_registry);
+ assert(cid_ordering);
+ len+=strlen(cid_registry)+1;
+ len+=strlen(cid_ordering)+1;
+ }
+ ret=calloc(1,len);
+ if (!ret) {
+ fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
+ assert(0);
+ return NULL;
+ }
+
+ // now fill the struct
+ len=0;
+ if (cid_supplement>=0) { // free space for panose is at beginning
+ len+=12;
+ }
+ ret->fontname=ret->data+len;
+ len+=strlen(fontname)+1;
+ if (subset_tag) {
+ strncpy(ret->fontname,subset_tag,6);
+ ret->fontname[6]='+';
+ strcpy(ret->fontname+7,fontname);
+ len+=7;
+ } else {
+ strcpy(ret->fontname,fontname);
+ }
+ ret->italicAngle=90;
+ if (cid_supplement>=0) {
+ ret->registry=ret->data+len;
+ strcpy(ret->registry,cid_registry);
+ len+=strlen(cid_registry)+1;
+
+ ret->ordering=ret->data+len;
+ strcpy(ret->ordering,cid_ordering);
+ len+=strlen(cid_registry)+1;
+ }
+ ret->supplement=cid_supplement;
+
+ return ret;
+}
+// }}}
+
+EMB_PDF_FONTDESCR *emb_pdf_fontdescr(EMB_PARAMS *emb) // {{{ - to be freed by user
+{
+ assert(emb);
+
+ const char *subset_tag=NULL;
+ // {{{ generate pdf subtag
+ static unsigned int rands=0;
+ if (!rands) {
+ rands=time(NULL);
+ }
+
+ char subtag[7];
+ subtag[6]=0;
+ if (emb->plan&EMB_A_SUBSET) {
+ int iA;
+ for (iA=0;iA<6;iA++) {
+ const int x=(int)(26.0*(rand_r(&rands)/(RAND_MAX+1.0)));
+ subtag[iA]='A'+x;
+ }
+ subset_tag=subtag;
+ }
+ // }}}
+
+ const char *fontname=NULL;
+ if ( (emb->intype==EMB_FMT_TTF)||(emb->intype==EMB_FMT_OTF) ) { // TODO? use fontinfo from CFF when outtype==CFT, etc.?
+ assert(emb->font->sfnt);
+ fontname=emb_otf_get_fontname(emb->font->sfnt);
+ } else if (emb->outtype==EMB_FMT_STDFONT) {
+ return NULL;
+ } else {
+ fprintf(stderr,"NOT IMPLEMENTED\n");
+ assert(0);
+ return NULL;
+ }
+
+ EMB_PDF_FONTDESCR *ret;
+ if (emb->plan&EMB_A_MULTIBYTE) { // multibyte
+ ret=emb_pdf_fd_new(fontname,subset_tag,"Adobe","Identity",0); // TODO other /ROS ?
+ } else {
+ ret=emb_pdf_fd_new(fontname,subset_tag,NULL,NULL,-1);
+ }
+ if (!ret) {
+ return NULL;
+ }
+
+ if ( (emb->intype==EMB_FMT_TTF)||(emb->intype==EMB_FMT_OTF) ) {
+ emb_otf_get_pdf_fontdescr(emb->font->sfnt,ret);
+ } else {
+ assert(0);
+ }
+ return ret;
+}
+// }}}
+
+EMB_PDF_FONTWIDTHS *emb_pdf_fw_new(int datasize) // {{{
+{
+ assert(datasize>=0);
+ EMB_PDF_FONTWIDTHS *ret=calloc(1,sizeof(EMB_PDF_FONTWIDTHS)+datasize*sizeof(int));
+ if (!ret) {
+ fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
+ assert(0);
+ return NULL;
+ }
+ return ret;
+}
+// }}}
+
+// if default_width==-1: default_width will be estimated
+EMB_PDF_FONTWIDTHS *emb_pdf_fw_cidwidths(const BITSET glyphs,int len,int default_width,int (*getGlyphWidth)(void *context,int gid),void *context) // {{{ glyphs==NULL -> output all
+{
+ assert(getGlyphWidth);
+
+ FREQUENT *freq=NULL;
+ if (default_width<0) {
+ freq=frequent_new(3);
+ }
+
+ int iA,b,c;
+ int size=0,in_region=0; // current number of elements in after region start
+
+ // first pass: find continuous regions, calculate needed size, estimate dw
+ for (iA=0,b=0,c=1;iA<len;iA++,c<<=1) {
+ if (!c) {
+ b++;
+ c=1;
+ }
+ if ( (!glyphs)||(glyphs[b]&c) ) {
+ if (freq) {
+ const int w=(*getGlyphWidth)(context,iA);
+ frequent_add(freq,w);
+ }
+ if (in_region) {
+ in_region++;
+ } else { // start new region
+ size+=2; // len c
+ in_region=1;
+ }
+ } else { // region end
+ size+=in_region;
+ in_region=0;
+ }
+ }
+ size+=in_region;
+
+ if (freq) {
+ default_width=frequent_get(freq,0);
+ free(freq);
+ }
+ assert(default_width>0);
+
+ // now create the array
+ EMB_PDF_FONTWIDTHS *ret=emb_pdf_fw_new(size+1);
+ if (!ret) {
+ return NULL;
+ }
+ ret->default_width=default_width;
+ ret->warray=ret->data;
+
+ // second pass
+ in_region=0;
+ size=0;
+ int *rlen=0; // position of current len field (only valid if in_region!=0)
+ for (iA=0,b=0,c=1;iA<len;iA++,c<<=1) {
+ if (!c) {
+ b++;
+ c=1;
+ }
+ if ( (!glyphs)||(glyphs[b]&c) ) {
+ const int w=(*getGlyphWidth)(context,iA);
+ if (in_region>0) { // in array region
+ if ( (w==default_width)&&(ret->warray[size-1]==default_width) ) { // omit this and prev entry
+ size--;
+ *rlen=in_region-1; // !=0, as it does not start with >default_width
+ in_region=0; // end region, immediate restart will take just the same amount of space
+ } else if ( (in_region>=4)&&
+ (ret->warray[size-1]==w)&&(ret->warray[size-2]==w)&&
+ (ret->warray[size-3]==w)&&(ret->warray[size-4]==w) ) {
+ // five in a row. c1 c2 w [l c] is equally short and can be extended (-len c1 w) [w/ cost of array-region restart]
+ if (in_region==4) { // completely replace
+ size-=6;
+ } else { // first end previous region
+ size-=4;
+ *rlen=in_region-4;
+ }
+ in_region=-4; // start range region instead
+ rlen=&ret->warray[size++];
+ ret->warray[size++]=iA-4;
+ ret->warray[size++]=w;
+ } else { // just add
+ in_region++;
+ ret->warray[size++]=w;
+ }
+ continue;
+ } else if (in_region<0) { // in range region
+ if (ret->warray[size-1]==w) {
+ in_region--; // just add
+ continue;
+ }
+ *rlen=in_region; // end
+ in_region=0;
+ }
+ if (w!=default_width) { // start new array region
+ in_region=1;
+ rlen=&ret->warray[size++];
+ ret->warray[size++]=iA; // c
+ ret->warray[size++]=w;
+ }
+ } else if (in_region) {
+ // TODO? no need to stop range region? } else if (in_region<0) { inregion--; }
+ *rlen=in_region;
+ in_region=0;
+ }
+ }
+ if (in_region) {
+ *rlen=in_region;
+ }
+ ret->warray[size]=0; // terminator
+ return ret;
+}
+// }}}
+
+// TODO: encoding into EMB_PARAMS (emb_new_enc(...,encoding,len ,to_unicode));
+// -> will then change interpretation of BITSET...(?really?); can we allow dynamic encoding map generation?
+// -> encoding has a "len"; len<256
+EMB_PDF_FONTWIDTHS *emb_pdf_fontwidths(EMB_PARAMS *emb) // {{{
+{
+ assert(emb);
+
+ if ( (emb->intype==EMB_FMT_TTF)||(emb->intype==EMB_FMT_OTF) ) {
+ assert(emb->font->sfnt);
+ if (emb->plan&EMB_A_MULTIBYTE) {
+ return emb_otf_get_pdf_cidwidths(emb->font->sfnt,emb->subset);
+ } else {
+ return emb_otf_get_pdf_widths(emb->font->sfnt,/*encoding*/NULL,emb->font->sfnt->numGlyphs,emb->subset); // TODO: encoding
+ }
+ } else {
+ fprintf(stderr,"NOT IMPLEMENTED\n");
+ assert(0);
+ return NULL;
+ }
+}
+// }}}
+
+/*** PDF out stuff ***/
+#include "dynstring.h"
+
+#define NEXT /* {{{ */ \
+ if ( (len<0)||(len>=size) ) { \
+ assert(0); \
+ free(ret); \
+ return NULL; \
+ } \
+ pos+=len; \
+ size-=len; /* }}} */
+
+// TODO? /CIDSet TODO... /FontFamily /FontStretch /FontWeight (PDF1.5?) would be nice...
+char *emb_pdf_simple_fontdescr(EMB_PARAMS *emb,EMB_PDF_FONTDESCR *fdes,int fontfile_obj_ref) // {{{ - to be freed by user
+{
+ assert(emb);
+ assert(fdes);
+
+ char *ret=NULL,*pos;
+ int len,size;
+
+ size=300;
+ pos=ret=malloc(size);
+ if (!ret) {
+ fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ len=snprintf(pos,size,
+ "<</Type /FontDescriptor\n"
+ " /FontName /%s\n" // TODO? handle quoting in struct?
+ " /Flags %d\n"
+ " /ItalicAngle %d\n",
+ emb_pdf_escape_name(fdes->fontname,-1),
+ fdes->flags,
+ fdes->italicAngle);
+ NEXT;
+
+ if (1) { // TODO type!=EMB_PDF_TYPE3
+ len=snprintf(pos,size,
+ " /FontBBox [%d %d %d %d]\n"
+ " /Ascent %d\n"
+ " /Descent %d\n"
+ " /CapHeight %d\n" // if font has Latin chars
+ " /StemV %d\n",
+ fdes->bbxmin,fdes->bbymin,fdes->bbxmax,fdes->bbymax,
+ fdes->ascent,
+ fdes->descent,
+ fdes->capHeight,
+ fdes->stemV);
+ NEXT;
+ }
+ if (fdes->xHeight) {
+ len=snprintf(pos,size," /XHeight %d\n",fdes->xHeight);
+ NEXT;
+ }
+ if (fdes->avgWidth) {
+ len=snprintf(pos,size," /AvgWidth %d\n",fdes->avgWidth);
+ NEXT;
+ }
+ if (fdes->panose) {
+ int iA;
+ len=snprintf(pos,size," /Style << /Panose <");
+ NEXT;
+ if (size<30) {
+ assert(0);
+ free(ret);
+ return NULL;
+ }
+ for (iA=0;iA<12;iA++) {
+ snprintf(pos+iA*2,size-iA*2,"%02x",fdes->panose[iA]);
+ }
+ size-=24;
+ pos+=24;
+ len=snprintf(pos,size,"> >>\n");
+ NEXT;
+ }
+ // TODO (for Type0)? CIDSet -> simply our glyphs BITSET (ok. endianess?)
+ len=snprintf(pos,size,
+ " /%s %d 0 R\n"
+ ">>\n",
+ emb_pdf_get_fontfile_key(emb),
+ fontfile_obj_ref);
+ NEXT;
+
+ return ret;
+}
+// }}}
+
+char *emb_pdf_simple_font(EMB_PARAMS *emb,EMB_PDF_FONTDESCR *fdes,EMB_PDF_FONTWIDTHS *fwid,int fontdescr_obj_ref) // {{{ - to be freed by user
+{
+ assert(emb);
+ assert(fdes);
+ assert(fwid);
+
+ int iA,iB;
+ DYN_STRING ret;
+
+ if (dyn_init(&ret,500)==-1) {
+ return NULL;
+ }
+
+ dyn_printf(&ret,"<</Type /Font\n"
+ " /Subtype /%s\n"
+ " /BaseFont /%s\n"
+ " /FontDescriptor %d 0 R\n",
+ emb_pdf_get_font_subtype(emb),
+ emb_pdf_escape_name(fdes->fontname,-1),
+ fontdescr_obj_ref);
+
+ if (emb->plan&EMB_A_MULTIBYTE) { // multibyte
+ assert(fwid->warray);
+ dyn_printf(&ret," /CIDSystemInfo <<\n"
+ " /Registry (%s)\n"
+ " /Ordering (%s)\n"
+ " /Supplement %d\n"
+ " >>\n"
+ " /DW %d\n",
+// " /CIDToGIDMap /Id...\n" // TrueType only, default /Identity [optional? which PDF version says what?]
+ fdes->registry,
+ fdes->ordering,
+ fdes->supplement,
+ fwid->default_width);
+
+ if (fwid->warray[0]) {
+ dyn_printf(&ret," /W [");
+ for (iA=0;fwid->warray[iA];) {
+ if (fwid->warray[iA]<0) { // c1 (c1-len) w
+ dyn_printf(&ret," %d %d %d",
+ fwid->warray[iA+1],
+ fwid->warray[iA+1]-fwid->warray[iA],
+ fwid->warray[iA+2]);
+ iA+=3;
+ } else { // c [w ... w]
+ iB=fwid->warray[iA++]; // len
+ dyn_printf(&ret," %d [",fwid->warray[iA++]); // c
+ for (;iB>0;iB--) {
+ dyn_printf(&ret," %d",fwid->warray[iA++]);
+ }
+ dyn_printf(&ret,"]");
+ }
+ }
+ dyn_printf(&ret,"]\n");
+ }
+ } else { // "not std14"
+ assert(fwid->widths);
+ dyn_printf(&ret,
+ " /Encoding /MacRomanEncoding\n" // optional; TODO!!!!!
+// " /ToUnicode ?\n" // optional
+ " /FirstChar %d\n"
+ " /LastChar %d\n"
+ " /Widths [",
+ fwid->first,
+ fwid->last);
+ for (iA=0,iB=fwid->first;iB<=fwid->last;iA++,iB++) {
+ dyn_printf(&ret," %d",fwid->widths[iA]);
+ }
+ dyn_printf(&ret,"]\n");
+ }
+ dyn_printf(&ret,">>\n");
+ if (ret.len==-1) {
+ dyn_free(&ret);
+ assert(0);
+ return NULL;
+ }
+
+ return ret.buf;
+}
+// }}}
+
+// TODO? + encoding as param? TODO + ToUnicode cmap => we need another struct EMB_PDF_FONTMAP
+// (TODO?? fontname here without subset-tag [_some_ pdfs out there seem to be that way])
+// TODO? don't do the CidType0 check here?
+// NOTE: this is _additionally_ to emb_pdf_simple_font()!
+char *emb_pdf_simple_cidfont(EMB_PARAMS *emb,const char *fontname,int descendant_obj_ref) // {{{ - to be freed by user
+{
+ assert(emb);
+ assert(fontname);
+
+ char *ret=NULL,*pos;
+ int len,size;
+
+ size=250;
+ pos=ret=malloc(size);
+ if (!ret) {
+ fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
+ return NULL;
+ }
+ // for CFF: one of:
+ // UniGB-UCS2-H, UniCNS-UCS2-H, UniJIS-UCS2-H, UniKS-UCS2-H
+ const char *encoding="Identity-H",*addenc="-";
+ if (emb->outtype==EMB_FMT_TTF) { // !=CidType0
+ addenc="";
+ }
+
+ len=snprintf(pos,size,
+ "<</Type /Font\n"
+ " /Subtype /Type0\n"
+ " /BaseFont /%s%s%s\n"
+ " /Encoding /%s\n"
+ " /DescendantFonts [%d 0 R]\n",
+// " /ToUnicode ?\n" // TODO
+ emb_pdf_escape_name(fontname,-1),
+ addenc,((addenc[0])?encoding:""),
+ encoding,
+ descendant_obj_ref);
+ NEXT;
+
+ len=snprintf(pos,size,">>\n");
+ NEXT;
+
+ return ret;
+}
+// }}}
+
+char *emb_pdf_simple_stdfont(EMB_PARAMS *emb) // {{{ - to be freed by user
+{
+ assert(emb);
+ assert(emb->font->stdname);
+
+ char *ret=NULL,*pos;
+ int len,size;
+
+ size=300;
+ pos=ret=malloc(size);
+ if (!ret) {
+ fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ len=snprintf(pos,size,
+ "<</Type/Font\n"
+ " /Subtype /Type1\n"
+ " /BaseFont /%s\n"
+ ">>\n",
+// emb_pdf_get_font_subtype(emb),
+ emb->font->stdname);
+ NEXT;
+
+ return ret;
+}
+// }}}
+#undef NEXT
+
diff --git a/fontembed/embed_pdf.h b/fontembed/embed_pdf.h
new file mode 100644
index 000000000..d837e4aeb
--- /dev/null
+++ b/fontembed/embed_pdf.h
@@ -0,0 +1,53 @@
+#ifndef EMBED_PDF_H
+#define EMBED_PDF_H
+
+// all the necessary information for pdf font embedding
+typedef struct {
+ char *fontname;
+ unsigned int flags;
+
+ // for the following: 0=not set/invalid
+ int bbxmin,bbymin,bbxmax,bbymax;
+ int italicAngle; // >=90: not set/invalid
+ int ascent;
+ int descent;
+ int capHeight;
+ int stemV;
+ // optional, default=0:
+ int xHeight;
+ int avgWidth;
+
+ // CID-additions:
+ char *panose; // 12 bytes
+ char *registry,*ordering;
+ int supplement;
+
+ char data[1]; // used for storing e.g. >fontname
+} EMB_PDF_FONTDESCR;
+
+typedef struct {
+ // normal font
+ int first,last;
+ int *widths;
+
+ // multibyte font
+ int default_width;
+ int *warray; // format: (len c w ... w)* if (len<0) { c1 (c2=c1+(-len)) w } else { c w[len] }, terminated by len==0
+
+ int data[1];
+} EMB_PDF_FONTWIDTHS;
+
+const char *emb_pdf_get_font_subtype(EMB_PARAMS *emb);
+const char *emb_pdf_get_fontfile_key(EMB_PARAMS *emb);
+const char *emb_pdf_get_fontfile_subtype(EMB_PARAMS *emb);
+
+EMB_PDF_FONTDESCR *emb_pdf_fontdescr(EMB_PARAMS *emb);
+EMB_PDF_FONTWIDTHS *emb_pdf_fontwidths(EMB_PARAMS *emb);
+
+/** TODO elsewhere **/
+char *emb_pdf_simple_fontdescr(EMB_PARAMS *emb,EMB_PDF_FONTDESCR *fdes,int fontfile_obj_ref);
+char *emb_pdf_simple_font(EMB_PARAMS *emb,EMB_PDF_FONTDESCR *fdes,EMB_PDF_FONTWIDTHS *fwid,int fontdescr_obj_ref);
+char *emb_pdf_simple_cidfont(EMB_PARAMS *emb,const char *fontname,int descendant_obj_ref);
+char *emb_pdf_simple_stdfont(EMB_PARAMS *emb);
+
+#endif
diff --git a/fontembed/embed_pdf_int.h b/fontembed/embed_pdf_int.h
new file mode 100644
index 000000000..81d8facdd
--- /dev/null
+++ b/fontembed/embed_pdf_int.h
@@ -0,0 +1,10 @@
+#ifndef EMBED_PDF_INT_H
+#define EMBED_PDF_INT_H
+
+EMB_PDF_FONTWIDTHS *emb_pdf_fw_new(int datasize);
+
+// if default_width==-1: default_width will be estimated
+// glyphs==NULL -> output all
+EMB_PDF_FONTWIDTHS *emb_pdf_fw_cidwidths(const BITSET glyphs,int len,int default_width,int (*getGlyphWidth)(void *context,int gid),void *context);
+
+#endif
diff --git a/fontembed/embed_sfnt.c b/fontembed/embed_sfnt.c
new file mode 100644
index 000000000..3f1f4dc36
--- /dev/null
+++ b/fontembed/embed_sfnt.c
@@ -0,0 +1,677 @@
+#include "embed.h"
+#include "embed_pdf_int.h"
+#include "embed_sfnt_int.h"
+#include "sfnt.h"
+#include "sfnt_int.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+EMB_RIGHT_TYPE emb_otf_get_rights(OTF_FILE *otf) // {{{
+{
+ EMB_RIGHT_TYPE ret=EMB_RIGHT_FULL;
+
+ int len;
+ char *os2=otf_get_table(otf,OTF_TAG('O','S','/','2'),&len);
+ if (os2) {
+ const unsigned short os2_version=get_USHORT(os2);
+ // check len
+ assert( (os2_version!=0x0000)||(len==78) );
+ assert( (os2_version!=0x0001)||(len==86) );
+ assert( (os2_version<0x0002)||(os2_version>0x0004)||(len==96) );
+ if (os2_version<=0x0004) {
+ // get rights
+ unsigned short fsType=get_USHORT(os2+8);
+ // from Adobe's Fontpolicies_v9.pdf, pg 13:
+ if (fsType==0x0002) {
+ ret=EMB_RIGHT_NONE;
+ } else {
+ ret=fsType&0x0300; // EMB_RIGHT_BITMAPONLY, EMB_RIGHT_NO_SUBSET
+ if ((fsType&0x000c)==0x0004) {
+ ret|=EMB_RIGHT_READONLY;
+ }
+ }
+ }
+ free(os2);
+ }
+ return ret;
+}
+// }}}
+
+// NOTE: statically allocated buffer
+const char *emb_otf_get_fontname(OTF_FILE *otf) // {{{
+{
+ static char fontname[64];
+
+ int len;
+ const char *fname=otf_get_name(otf,3,1,0x409,6,&len); // microsoft
+ if (fname) {
+ int iA,iB=0;
+ for (iA=0;(iA<63)&&(iA*2<len);iA++) {
+ if ( (fname[2*iA]==0)&&
+ (fname[2*iA+1]>=33)&&(fname[2*iA+1]<=126)&&
+ (!strchr("[](){}<>/%",fname[iA*2+1])) ) {
+ fontname[iB++]=fname[iA*2+1];
+ }
+ }
+ fontname[iB]=0;
+ } else if ((fname=otf_get_name(otf,1,0,0,6,&len))) { // mac
+ int iA,iB=0;
+ for (iA=0;(iA<63)&&(iA<len);iA++) {
+ if ( (fname[iA]>=33)&&(fname[iA]<=126)&&
+ (!strchr("[](){}<>/%",fname[iA])) ) {
+ fontname[iB++]=fname[iA];
+ }
+ }
+ fontname[iB]=0;
+ } else {
+ fontname[0]=0;
+ }
+ if (!*fontname) {
+ // TODO construct a fontname, eg from */*/*/4
+ fprintf(stderr,"WARNING: no fontName\n");
+ }
+ return fontname;
+}
+// }}}
+
+// TODO? monospaced by actual glyph width?
+// TODO? use PCLT table? (esp. CFF, as table dircouraged for glyf fonts)
+void emb_otf_get_pdf_fontdescr(OTF_FILE *otf,EMB_PDF_FONTDESCR *ret) // {{{
+{
+ int len;
+
+// TODO
+// ... fill in struct
+ char *head=otf_get_table(otf,OTF_TAG('h','e','a','d'),&len);
+ assert(head); // version is 1.0 from otf_load
+ ret->bbxmin=get_SHORT(head+36)*1000/otf->unitsPerEm;
+ ret->bbymin=get_SHORT(head+38)*1000/otf->unitsPerEm;
+ ret->bbxmax=get_SHORT(head+40)*1000/otf->unitsPerEm;
+ ret->bbymax=get_SHORT(head+42)*1000/otf->unitsPerEm;
+ const int macStyle=get_USHORT(head+44);
+ free(head);
+
+ char *post=otf_get_table(otf,OTF_TAG('p','o','s','t'),&len);
+ assert(post);
+ const unsigned int post_version=get_ULONG(post);
+ // check length
+ assert( (post_version!=0x00010000)||(len==32) );
+ assert( (post_version!=0x00020000)||(len>=34+2*otf->numGlyphs) );
+ assert( (post_version!=0x00025000)||(len==35+otf->numGlyphs) );
+ assert( (post_version!=0x00030000)||(len==32) );
+ assert( (post_version!=0x00020000)||(get_USHORT(post+32)==otf->numGlyphs) ); // v4?
+// assert( (post_version==0x00030000)==(!!(otf->flags&OTF_F_FMT_CFF)) ); // ghostscript embedding does this..
+ // TODO: v4 (apple) : uint16 reencoding[numGlyphs]
+ if ( (post_version==0x00010000)||
+ (post_version==0x00020000)||
+ (post_version==0x00025000)||
+ (post_version==0x00030000)||
+ (post_version==0x00040000) ) {
+ ret->italicAngle=get_LONG(post+4)>>16;
+ if (get_ULONG(post+12)>0) { // monospaced
+ ret->flags|=1;
+ }
+ } else {
+ fprintf(stderr,"WARNING: no italicAngle, no monospaced flag\n");
+ }
+ free(post);
+
+ char *os2=otf_get_table(otf,OTF_TAG('O','S','/','2'),&len);
+ if (os2) {
+ const unsigned short os2_version=get_USHORT(os2);
+ // check len
+ assert( (os2_version!=0x0000)||(len==78) );
+ assert( (os2_version!=0x0001)||(len==86) );
+ assert( (os2_version<0x0002)||(os2_version>0x0004)||(len==96) );
+ if (os2_version<=0x0004) {
+
+ // from PDF14Deltas.pdf, pg 113
+ const int weightClass=get_USHORT(os2+4);
+ ret->stemV=50+weightClass*weightClass/(65*65); // TODO, really bad
+//printf("a %d\n",weightClass);
+
+ if (ret->supplement>=0) { // cid
+ ret->panose=ret->data;
+ memcpy(ret->panose,os2+30,12); // sFamilyClass + panose
+ }
+ const unsigned short fsSelection=get_USHORT(os2+62);
+ if (fsSelection&0x01) { // italic
+ ret->flags|=0x0040;
+ }
+ if ( (fsSelection&0x10)&&(weightClass>600) ) { // force bold
+ ret->flags|=0x0400;
+ }
+ const unsigned char family_class=get_USHORT(os2+30)>>8;
+ if (family_class==10) { // script
+ ret->flags|=0x0008;
+ }
+ if (family_class!=8) { // not sans-serif
+ ret->flags|=0x0002;
+ }
+
+ ret->avgWidth=get_SHORT(os2+2)*1000/otf->unitsPerEm;
+ ret->ascent=get_SHORT(os2+68)*1000/otf->unitsPerEm;
+ ret->descent=get_SHORT(os2+70)*1000/otf->unitsPerEm;
+ if (os2_version>=0x0002) {
+ ret->xHeight=get_SHORT(os2+86)*1000/otf->unitsPerEm;
+ ret->capHeight=get_SHORT(os2+88)*1000/otf->unitsPerEm;
+ } // else capHeight fixed later
+ } else {
+ free(os2);
+ os2=NULL;
+ }
+ } else {
+ fprintf(stderr,"WARNING: no OS/2 table\n");
+ // e.g. subsetted font from ghostscript // e.g. CFF
+ }
+ if (os2) {
+ free(os2);
+ } else { // TODO (if(CFF))
+ fprintf(stderr,"WARNING: no ascent/descent, capHeight, stemV, flags\n");
+ if (macStyle&0x01) { // force bold - just do it on bold
+ ret->flags|=0x0400;
+ }
+ if (macStyle&0x02) { // italic
+ ret->flags|=0x0004;
+ }
+ // ... flags TODO? (Serif, Script, Italic, AllCap,SmallCap, ForceBold)
+ }
+
+// ? maybe get ascent,descent,capHeight,xHeight,stemV directly from cff
+ // Fallbacks
+ if ( (!ret->ascent)||(!ret->descent) ) {
+ char *hhea=otf_get_table(otf,OTF_TAG('h','h','e','a'),&len);
+ if (hhea) {
+ ret->ascent=get_SHORT(hhea+4)*1000/otf->unitsPerEm;
+ ret->descent=get_SHORT(hhea+6)*1000/otf->unitsPerEm;
+ }
+ free(hhea);
+ }
+ if (!ret->stemV) { // TODO? use name
+ const unsigned short d_gid=otf_from_unicode(otf,'.');
+ if (d_gid) { // stemV=bbox['.'].width;
+ len=otf_get_glyph(otf,d_gid);
+ assert(len>=10);
+ ret->stemV=(get_SHORT(otf->gly+6)-get_SHORT(otf->gly+2))*1000/otf->unitsPerEm;
+ } else {
+ if (macStyle&1) { // bold
+ ret->stemV=165;
+ } else {
+ ret->stemV=109; // TODO... unserious values...
+ }
+ }
+ }
+ if (!ret->capHeight) { // TODO? only reqd. for fonts with latin...
+ ret->capHeight=ret->ascent;
+ // TODO: OTF spec says: use metrics of 'H' (0 if not available)
+ }
+ if (0) { // TODO? uses only adobe latin standard? ?? e.g. Type1
+ ret->flags|=0x0020;
+ } else {
+ ret->flags|=0x0004;
+ }
+ // TODO SmallCap by font name(?)
+
+// TODO ; ? cid ?
+}
+// }}}
+
+// TODO: split generic part and otf part
+// TODO: FIXME: gid vs. char ... NOTE: not called in multi_byte mode...
+// Adobe does: char --MacRoman/WinAnsi--> name --AGL--> unicode --cmap(3,1) --> gid only avoidable by setting 'symbol'+custom(1,0)/(3,0)
+// HINT: caller sets len == otf->numGlyphs (only when not using encoding...)
+EMB_PDF_FONTWIDTHS *emb_otf_get_pdf_widths(OTF_FILE *otf,const unsigned short *encoding,int len,const BITSET glyphs) // {{{ glyphs==NULL -> all from 0 to len
+{
+ assert(otf);
+
+ int first=len,last=0;
+ int iA;
+
+ if (glyphs) {
+ for (iA=0;iA<len;iA++) { // iA is a "gid" when in multi_byte mode...
+ const int gid=(encoding)?encoding[iA]:otf_from_unicode(otf,iA); // TODO
+ if (bit_check(glyphs,gid)) {
+ if (first>iA) { // first is a character index
+ first=iA;
+ }
+ if (last<iA) {
+ last=iA;
+ }
+ }
+ }
+ } else {
+ first=0;
+ last=len;
+ }
+ if (last<first) {
+ // empty
+ fprintf(stderr,"WARNING: empty embedding range\n");
+ return NULL;
+ }
+
+ // ensure hmtx is there
+ if (!otf->hmtx) {
+ if (otf_load_more(otf)!=0) {
+ assert(0);
+ return NULL;
+ }
+ }
+
+ // now create the array
+ EMB_PDF_FONTWIDTHS *ret=emb_pdf_fw_new(last-first+1);
+ if (!ret) {
+ return NULL;
+ }
+ ret->first=first;
+ ret->last=last;
+ ret->widths=ret->data;
+ for (iA=0;first<=last;iA++,first++) {
+ const int gid=(encoding)?encoding[first]:otf_from_unicode(otf,first); // TODO
+ if (gid>=otf->numGlyphs) {
+ fprintf(stderr,"Bad glyphid\n");
+ assert(0);
+ free(ret);
+ return NULL;
+ }
+ if ( (!glyphs)||(bit_check(glyphs,gid)) ) {
+ ret->widths[iA]=get_width_fast(otf,gid)*1000/otf->unitsPerEm;
+ } // else 0 from calloc
+ }
+
+ return ret;
+}
+// }}}
+
+// otf->hmtx must be there
+static int emb_otf_pdf_glyphwidth(void *context,int gid) // {{{
+{
+ OTF_FILE *otf=(OTF_FILE *)context;
+ return get_width_fast(otf,gid)*1000/otf->unitsPerEm;
+}
+// }}}
+
+EMB_PDF_FONTWIDTHS *emb_otf_get_pdf_cidwidths(OTF_FILE *otf,const BITSET glyphs) // {{{ // glyphs==NULL -> output all
+{
+ assert(otf);
+
+ // ensure hmtx is there
+ if (!otf->hmtx) {
+ if (otf_load_more(otf)!=0) {
+ assert(0);
+ return NULL;
+ }
+ }
+// int dw=emb_otf_pdf_glyphwidth(otf,0); // e.g.
+ int dw=-1; // let them estimate
+
+ return emb_pdf_fw_cidwidths(glyphs,otf->numGlyphs,dw,emb_otf_pdf_glyphwidth,otf);
+}
+// }}}
+
+/*** PS stuff ***/
+
+#include "dynstring.h"
+
+const char *aglfn13(unsigned short uni); // aglfn13.c
+#include "macroman.h"
+
+// TODO? optimize pascal string skipping? (create index)
+// NOTE: might return a statically allocated string
+static const char *emb_otf_get_post_name(const char *post,unsigned short gid) // {{{
+{
+ if (!post) {
+ return NULL;
+ }
+ const unsigned int post_version=get_ULONG(post);
+ if (post_version==0x00010000) { // font has only 258 chars... font cannot be used on windows
+ if (gid<sizeof(macRoman)/sizeof(macRoman[0])) {
+ return macRoman[gid];
+ }
+ } else if (post_version==0x00020000) {
+ const unsigned short num_glyphs=get_USHORT(post+32);
+ // assert(num_glyphs==otf->numGlyphs);
+ if (gid<num_glyphs) {
+ unsigned short idx=get_USHORT(post+34+2*gid);
+ if (idx<258) {
+ if (idx<sizeof(macRoman)/sizeof(macRoman[0])) {
+ return macRoman[idx];
+ }
+ } else if (idx<32768) {
+ const unsigned char *pos=(unsigned char *)post+34+2*num_glyphs;
+ for (idx-=258;idx>0;idx--) { // this sucks...
+ pos+=*pos+1; // skip this string
+ }
+ // convert pascal string to asciiz
+ static char ret[256];
+ const unsigned char len=*pos;
+ memcpy(ret,(const char *)pos+1,len);
+ ret[len]=0;
+ return ret;
+ }
+ }
+ } else if (post_version==0x00025000) { // similiar to 0x00010000, deprecated
+ const unsigned short num_glyphs=get_USHORT(post+32);
+ if (gid<num_glyphs) {
+ const unsigned short idx=post[34+gid]+gid; // post is signed char *
+ if (idx<sizeof(macRoman)/sizeof(macRoman[0])) {
+ return macRoman[idx];
+ }
+ }
+ } else if (post_version==0x00030000) {
+ // no glyph names, sorry
+// } else if (post_version==0x00040000) { // apple AAT ?!
+ }
+ return NULL;
+}
+// }}}
+
+// TODO!? to_unicode should be able to represent more than one unicode character?
+// NOTE: statically allocated string
+static const char *get_glyphname(const char *post,unsigned short *to_unicode,int charcode,unsigned short gid) // {{{ if charcode==0 -> force gid to be used
+{
+ if (gid==0) {
+ return ".notdef";
+ }
+ const char *postName=emb_otf_get_post_name(post,gid);
+ if (postName) {
+ return postName;
+ }
+ static char ret[255];
+ if (charcode) {
+ if (to_unicode) { // i.e. encoding was there
+ charcode=to_unicode[charcode];
+ // TODO!? to_unicode should be able to represent more than one unicode character?
+ // TODO for additional credit: for ligatures, etc create /f_f /uni12341234 or the like
+ }
+ const char *aglname=aglfn13(charcode); // TODO? special case ZapfDingbats?
+ if (aglname) {
+ return aglname;
+ }
+ snprintf(ret,250,"uni%04X",charcode); // allows extraction
+ } else {
+ snprintf(ret,250,"c%d",gid); // last resort: only by gid
+ }
+ return ret;
+}
+// }}}
+
+struct OUTFILTER_PS {
+ OUTPUT_FN out;
+ void *ctx;
+ int len;
+};
+
+// TODO: for maximum compatiblity (PS<2013 interpreter) split only on table or glyph boundary (needs lookup in loca table!)
+// Note: table boundaries are at each call!
+static void outfilter_ascii_ps(const char *buf,int len,void *context) // {{{
+{
+ struct OUTFILTER_PS *of=context;
+ OUTPUT_FN out=of->out;
+ int iA;
+
+ (*out)("<",1,of->ctx);
+ of->len++;
+
+ const char *last=buf;
+ char tmp[256];
+ while (len>0) {
+ for (iA=0;(iA<76)&&(len>0);iA+=2,len--) {
+ const unsigned char ch=buf[iA>>1];
+ tmp[iA]="0123456789abcdef"[ch>>4];
+ tmp[iA+1]="0123456789abcdef"[ch&0x0f];
+ }
+ buf+=iA>>1;
+ if (buf<last+64000) {
+ if (len>0) {
+ tmp[iA++]='\n';
+ }
+ (*out)(tmp,iA,of->ctx);
+ } else {
+ last=buf;
+ strcpy(tmp+iA,"00>\n<");
+ iA+=5;
+ (*out)(tmp,iA,of->ctx);
+ }
+ of->len+=iA;
+ }
+
+ (*out)("00>\n",4,of->ctx);
+ of->len+=4;
+}
+// }}}
+
+static void outfilter_binary_ps(const char *buf,int len,void *context) // {{{
+{
+ struct OUTFILTER_PS *of=context;
+ OUTPUT_FN out=of->out;
+
+ char tmp[100];
+ while (len>0) {
+ const int maxlen=(len>64000)?64000:len;
+ const int l=sprintf(tmp,"%d RD ",maxlen);
+ (*out)(tmp,l,of->ctx);
+ of->len+=l;
+
+ (*out)(buf,maxlen,of->ctx);
+ (*out)("\n",1,of->ctx);
+ of->len+=maxlen+1;
+ len-=maxlen;
+ buf+=maxlen;
+ }
+}
+// }}}
+
+/*
+ encoding: character-code -> glyph id ["required", NULL: identity, i.e. from_unicode()] // TODO: respect subsetting
+ to_unicode: character-code -> unicode [NULL: no char names] // kind-of "reverse" of encoding (to_unicode does not make sense without >encoding)
+
+Status:
+ - we need a 0..255 encoding to be used in the PS file
+ - we want to allow the use of encoding[]; this should map from your desired PS-stream output character (0..255) directly to the gid
+ - if encoding[] is not used, MacRoman/WinAnsi/latin1 is expected (easiest: latin1, as it is a subset of unicode)
+ i.e. your want to output latin1 to the PS-stream
+ - len is the length of >encoding, or the "last used latin1 character"
+ - oh. in multibyte-mode no >encoding probably should mean identity(gid->gid) not (latin1->gid)
+ - non-multibyte PDF -> only 255 chars ... not recommended (we can't just map to gids, but only to names, which acro will then cmap(3,1) to gids)
+
+ => problem with subsetting BITSET (keyed by gid); we want BITSET keyed by 0..255 (via encoding)
+
+ // TODO: a) multi font encoding
+ // TODO: b) cid/big font encoding (PS>=2015) [/CIDFontType 2] : CMap does Charcode->CID, /CIDMap does CID->GID [e.g. Identity/delta value]
+ // (also needed [or a)] for loca>64000 if split, etc) e.g. /CIDMap 0 [requires PS>=3011?]
+ // [Danger: do not split composites]
+ // TODO? incremental download [/GlyphDirectory array or dict] : /GlyphDirectory does GID-><glyf entry> mapping
+ // need 'fake' gdir table (size,offset=0) in sfnt; loca, glyf can be ommited; hmtx can be omitted for PS>=3011 [/MetricsCount 2]
+ // idea is to fill initial null entries in the array/dict [Beware of save/restore!]
+ // NOTE: even when subsetting the font has to come first in the PS file
+
+
+... special information: when multi-byte PDF encoding is used <gid> is output.
+ therefore /Encoding /Identity-H + /CIDSystemInfo Adobe-Identity-0 will yield 1-1 mapping for font.
+ problem is that text is not selectable. therefore there is the /ToUnicode CMap option
+*/
+int emb_otf_ps(OTF_FILE *otf,unsigned short *encoding,int len,unsigned short *to_unicode,OUTPUT_FN output,void *context) // {{{
+{
+ const int binary=0; // binary format? // TODO
+ if (len>256) {
+ fprintf(stderr,"Encoding too big(%d) for Type42\n",len);
+ return -1;
+ }
+ if (len<1) {
+ fprintf(stderr,"At least .notdef required in Type42\n");
+ return -1;
+ }
+ if (!encoding) {
+ to_unicode=NULL; // does not make sense
+ }
+ int iA,ret=0;
+
+ DYN_STRING ds;
+ if (dyn_init(&ds,1024)==-1) {
+ return -1;
+ }
+
+ int rlen=0;
+ char *head=otf_get_table(otf,OTF_TAG('h','e','a','d'),&rlen);
+ if (!head) {
+ free(ds.buf);
+ return -1;
+ }
+ dyn_printf(&ds,"%%!PS-TrueTypeFont-%d-%d\n",
+ otf->version,get_ULONG(head+4));
+ const int bbxmin=get_SHORT(head+36)*1000/otf->unitsPerEm,
+ bbymin=get_SHORT(head+38)*1000/otf->unitsPerEm,
+ bbxmax=get_SHORT(head+40)*1000/otf->unitsPerEm,
+ bbymax=get_SHORT(head+42)*1000/otf->unitsPerEm;
+ free(head);
+
+ char *post=otf_get_table(otf,OTF_TAG('p','o','s','t'),&rlen);
+ if ( (!post)&&(rlen!=-1) ) { // other error than "not found"
+ free(ds.buf);
+ return -1;
+ }
+ if (post) {
+ const unsigned int minMem=get_ULONG(post+16),maxMem=get_ULONG(post+20);
+ if (minMem) {
+ dyn_printf(&ds,"%%VMusage: %d %d\n",minMem,maxMem);
+ }
+ }
+
+ // don't forget the coordinate scaling...
+ dyn_printf(&ds,"11 dict begin\n"
+ "/FontName /%s def\n"
+ "/FontType 42 def\n"
+ "/FontMatrix [1 0 0 1 0 0] def\n"
+ "/FontBBox [%f %f %f %f] def\n"
+ "/PaintType 0 def\n",
+// "/XUID [42 16#%X 16#%X 16#%X 16#%X] def\n" // TODO?!? (md5 of font data) (16# means base16)
+ emb_otf_get_fontname(otf),
+ bbxmin/1000.0,bbymin/1000.0,bbxmax/1000.0,bbymax/1000.0);
+ if (post) {
+ dyn_printf(&ds,"/FontInfo 4 dict dup begin\n"
+// TODO? [even non-post]: /version|/Notice|/Copyright|/FullName|/FamilyName|/Weight () readonly def\n from name table: 5 7 0 4 1 2
+// using: otf_get_name(otf,3,1,0x409,?,&len) / otf_get_name(otf,1,0,0,?,&len) + encoding
+ " /ItalicAngle %d def\n"
+ " /isFixedPitch %s def\n"
+ " /UnderlinePosition %f def\n"
+ " /UnderlineThickness %f def\n"
+ "end readonly def\n",
+ get_LONG(post+4)>>16,
+ (get_ULONG(post+12)?"true":"false"),
+ (get_SHORT(post+8)-get_SHORT(post+10)/2)/(float)otf->unitsPerEm,
+ get_SHORT(post+10)/(float)otf->unitsPerEm);
+ }
+ dyn_printf(&ds,"/Encoding 256 array\n"
+ "0 1 255 { 1 index exch /.notdef put } for\n");
+ for (iA=0;iA<len;iA++) { // encoding data: 0...255 -> /glyphname
+ const int gid=(encoding)?encoding[iA]:otf_from_unicode(otf,iA);
+ if (gid!=0) {
+ dyn_printf(&ds,"dup %d /%s put\n",
+ iA,get_glyphname(post,to_unicode,iA,gid));
+ }
+ }
+ dyn_printf(&ds,"readonly def\n");
+
+ if (binary) {
+ dyn_printf(&ds,"/RD { string currentfile exch readstring pop } executeonly def\n");
+ }
+ dyn_printf(&ds,"/sfnts[\n");
+
+ if (ds.len<0) {
+ free(post);
+ free(ds.buf);
+ return -1;
+ }
+ (*output)(ds.buf,ds.len,context);
+ ret+=ds.len;
+ ds.len=0;
+
+// TODO: only tables as in otf_subset
+// TODO: somehow communicate table boundaries:
+ // otf_action_copy does exactly one output call (per table)
+ // only otf_action_replace might do two (padding)
+ // {{{ copy tables verbatim (does not affect ds .len)
+ struct _OTF_WRITE *otfree=NULL;
+#if 0
+ struct _OTF_WRITE *otw;
+ otwfree=otw=malloc(sizeof(struct _OTF_WRITE)*otf->numTables);
+ if (!otw) {
+ fprintf(stderr,"Bad alloc: %m\n");
+ free(post);
+ free(ds.buf);
+ return -1;
+ }
+ // just copy everything
+ for (iA=0;iA<otf->numTables;iA++) {
+ otw[iA].tag=otf->tables[iA].tag;
+ otw[iA].action=otf_action_copy;
+ otw[iA].param=otf;
+ otw[iA].length=iA;
+ }
+ int numTables=otf->numTables;
+#else
+ struct _OTF_WRITE otw[]={ // sorted
+ {OTF_TAG('c','m','a','p'),otf_action_copy,otf,},
+ {OTF_TAG('c','v','t',' '),otf_action_copy,otf,},
+ {OTF_TAG('f','p','g','m'),otf_action_copy,otf,},
+ {OTF_TAG('g','l','y','f'),otf_action_copy,otf,},
+ {OTF_TAG('h','e','a','d'),otf_action_copy,otf,},
+ {OTF_TAG('h','h','e','a'),otf_action_copy,otf,},
+ {OTF_TAG('h','m','t','x'),otf_action_copy,otf,},
+ {OTF_TAG('l','o','c','a'),otf_action_copy,otf,},
+ {OTF_TAG('m','a','x','p'),otf_action_copy,otf,},
+ {OTF_TAG('n','a','m','e'),otf_action_copy,otf,},
+ {OTF_TAG('p','r','e','p'),otf_action_copy,otf,},
+ // vhea vmtx (never used in PDF, but possible in PS>=3011)
+ {0,0,0,0}};
+ int numTables=otf_intersect_tables(otf,otw);
+#endif
+
+ struct OUTFILTER_PS of;
+ of.out=output;
+ of.ctx=context;
+ of.len=0;
+ if (binary) {
+ iA=otf_write_sfnt(otw,otf->version,numTables,outfilter_binary_ps,&of);
+ } else {
+ iA=otf_write_sfnt(otw,otf->version,numTables,outfilter_ascii_ps,&of);
+ }
+ free(otfree);
+ if (iA==-1) {
+ free(post);
+ free(ds.buf);
+ return -1;
+ }
+ ret+=of.len;
+ // }}} done copying
+
+ dyn_printf(&ds,"] def\n");
+
+ dyn_printf(&ds,"/CharStrings %d dict dup begin\n"
+ "/.notdef 0 def\n",len);
+ for (iA=0;iA<len;iA++) { // charstrings data: /glyphname -> gid
+ const int gid=(encoding)?encoding[iA]:otf_from_unicode(otf,iA);
+ if (gid) {
+ dyn_printf(&ds,"/%s %d def\n",get_glyphname(post,to_unicode,iA,gid),gid);
+ }
+ // (respecting subsetting...)
+ }
+ dyn_printf(&ds,"end readonly def\n");
+ dyn_printf(&ds,"FontName currentdict end definefont pop\n");
+ free(post);
+
+ if (ds.len<0) {
+ free(ds.buf);
+ return -1;
+ }
+ (*output)(ds.buf,ds.len,context);
+ ret+=ds.len;
+ ds.len=0;
+
+ free(ds.buf);
+ return ret;
+}
+// }}}
+
diff --git a/fontembed/embed_sfnt_int.h b/fontembed/embed_sfnt_int.h
new file mode 100644
index 000000000..9edc3e517
--- /dev/null
+++ b/fontembed/embed_sfnt_int.h
@@ -0,0 +1,18 @@
+#ifndef EMBED_SFNT_INT_H
+#define EMBED_SFNT_INT_H
+
+#include "sfnt.h"
+#include "embed_pdf.h"
+
+EMB_RIGHT_TYPE emb_otf_get_rights(OTF_FILE *otf);
+
+// NOTE: statically allocated buffer
+const char *emb_otf_get_fontname(OTF_FILE *otf);
+
+void emb_otf_get_pdf_fontdescr(OTF_FILE *otf,EMB_PDF_FONTDESCR *ret);
+EMB_PDF_FONTWIDTHS *emb_otf_get_pdf_widths(OTF_FILE *otf,const unsigned short *encoding,int len,const BITSET glyphs);
+EMB_PDF_FONTWIDTHS *emb_otf_get_pdf_cidwidths(OTF_FILE *otf,const BITSET glyph);
+
+int emb_otf_ps(OTF_FILE *otf,unsigned short *encoding,int len,unsigned short *to_unicode,OUTPUT_FN output,void *context);
+
+#endif
diff --git a/fontembed/fontfile.c b/fontembed/fontfile.c
new file mode 100644
index 000000000..703126c5d
--- /dev/null
+++ b/fontembed/fontfile.c
@@ -0,0 +1,50 @@
+#include "fontfile.h"
+#include <assert.h>
+#include <string.h>
+
+//FONTFILE *fontfile_open(const char *filename);
+
+/*
+FONTFILE *fontfile_open(const char *filename)
+{
+ // TODO? check magic
+ if (...) {
+ }
+}
+*/
+
+FONTFILE *fontfile_open_sfnt(OTF_FILE *otf) // {{{
+{
+ if (!otf) {
+ assert(0);
+ return NULL;
+ }
+ FONTFILE *ret=calloc(1,sizeof(FONTFILE));
+
+ ret->sfnt=otf;
+
+ return ret;
+}
+// }}}
+
+FONTFILE *fontfile_open_std(const char *name) // {{{
+{
+ assert(name);
+ FONTFILE *ret=calloc(1,sizeof(FONTFILE));
+
+ ret->stdname=strdup(name);
+
+ return ret;
+}
+// }}}
+
+void fontfile_close(FONTFILE *ff) // {{{
+{
+ if (ff) {
+ otf_close(ff->sfnt);
+ // ??? cff_close(ff->cff);
+ free(ff->stdname);
+ free(ff);
+ }
+}
+// }}}
diff --git a/fontembed/fontfile.h b/fontembed/fontfile.h
new file mode 100644
index 000000000..7e7b1089a
--- /dev/null
+++ b/fontembed/fontfile.h
@@ -0,0 +1,22 @@
+#ifndef _FONTFILE_H
+#define _FONTFILE_H
+
+#include "sfnt.h"
+
+struct _FONTFILE {
+ OTF_FILE *sfnt;
+ // ??? *cff;
+ char *stdname;
+ union {
+ int fobj;
+ void *user;
+ };
+};
+
+typedef struct _FONTFILE FONTFILE;
+
+FONTFILE *fontfile_open_sfnt(OTF_FILE *otf);
+FONTFILE *fontfile_open_std(const char *name);
+void fontfile_close(FONTFILE *ff);
+
+#endif
diff --git a/fontembed/frequent.c b/fontembed/frequent.c
new file mode 100644
index 000000000..eb8edbdf2
--- /dev/null
+++ b/fontembed/frequent.c
@@ -0,0 +1,83 @@
+#include "frequent.h"
+#include <assert.h>
+#include <stdlib.h>
+
+// misra-gries
+// http://www2.research.att.com/~marioh/papers/vldb08-2.pdf
+
+struct _FREQUENT {
+ int size,czero;
+ char sorted;
+ struct { intptr_t key; int count,zero; } pair[];
+};
+
+// size is the precision/return size: in sequence with n _add(), it will find at most >size elements with occurence > n/(size+1) times
+FREQUENT *frequent_new(int size) // {{{ - just free() it
+{
+ assert(size>0);
+ FREQUENT *ret=malloc(sizeof(ret[0])+sizeof(ret->pair[0])*size);
+ if (!ret) {
+ return NULL;
+ }
+ ret->size=size;
+ ret->czero=0;
+ ret->sorted=1;
+ int iA;
+ for (iA=0;iA<size;iA++) {
+ ret->pair[iA].key=INTPTR_MIN;
+ ret->pair[iA].count=0;
+ ret->pair[iA].zero=0;
+ }
+
+ return ret;
+}
+// }}}
+
+void frequent_add(FREQUENT *freq,intptr_t key) // {{{
+{
+ assert(freq);
+ int iA,zero=-1;
+ for (iA=freq->size-1;iA>=0;iA--) {
+ if (freq->pair[iA].key==key) {
+ freq->pair[iA].count++;
+ freq->sorted=0;
+ return;
+ } else if (freq->pair[iA].count==freq->czero) {
+ zero=iA;
+ }
+ }
+ if (zero>=0) { // insert into set
+ freq->pair[zero].key=key;
+ freq->pair[zero].count++; // i.e. czero+1
+ freq->pair[zero].zero=freq->czero;
+ // if it was sorted, the free entries are at the end. zero points to the first free entry, because of the loop direction
+ } else { // out-of-set count
+ freq->czero++;
+ }
+}
+// }}}
+
+static int frequent_cmp(const void *a,const void *b) // {{{
+{
+ const typeof(((FREQUENT *)0)->pair[0]) *aa=a;
+ const typeof(((FREQUENT *)0)->pair[0]) *bb=b;
+ return (bb->count-bb->zero)-(aa->count-aa->zero);
+}
+// }}}
+
+// true frequency is somewhere between (count-zero) and count
+intptr_t frequent_get(FREQUENT *freq,int pos) // {{{
+{
+ assert(freq);
+ if (!freq->sorted) {
+ // sort by (count-zero)
+ qsort(freq->pair,freq->size,sizeof(freq->pair[0]),frequent_cmp);
+ freq->sorted=1;
+ }
+ if ( (pos<0)||(pos>=freq->size) ) {
+ return INTPTR_MIN;
+ }
+ return freq->pair[pos].key;
+}
+// }}}
+
diff --git a/fontembed/frequent.h b/fontembed/frequent.h
new file mode 100644
index 000000000..838adcc27
--- /dev/null
+++ b/fontembed/frequent.h
@@ -0,0 +1,17 @@
+#ifndef _FREQUENT_H
+#define _FREQUENT_H
+
+#include <stdint.h>
+
+typedef struct _FREQUENT FREQUENT;
+
+// size is the precision/return size: it will find at most >size elements (i.e. all, if there) with frequency > 1/(size+1)
+FREQUENT *frequent_new(int size); // - just free() it
+
+void frequent_add(FREQUENT *freq,intptr_t key);
+
+// might return INTPTR_MIN, if not populated
+// this is only an approximation!
+intptr_t frequent_get(FREQUENT *freq,int pos); // 0 is "most frequent"
+
+#endif
diff --git a/fontembed/iofn.h b/fontembed/iofn.h
new file mode 100644
index 000000000..737d2e060
--- /dev/null
+++ b/fontembed/iofn.h
@@ -0,0 +1,6 @@
+#ifndef _IOFN_H
+#define _IOFN_H
+
+typedef void (*OUTPUT_FN)(const char *buf,int len,void *context);
+
+#endif
diff --git a/fontembed/macroman.h b/fontembed/macroman.h
new file mode 100644
index 000000000..9822abdbe
--- /dev/null
+++ b/fontembed/macroman.h
@@ -0,0 +1,32 @@
+// data header only. for inclusion in only one file
+#ifdef WITH_MACROMAN
+static const char *macRoman[]=
+ {".notdef",".null","nonmarkingreturn","space","exclam", "quotedbl","numbersign","dollar","percent","ampersand",
+ "quotesingle","parenleft","parenright","asterisk","plus", "comma","hyphen","period","slash","zero",
+ "one","two","three","four","five", "six","seven","eight","nine","colon",
+ "semicolon","less","equal","greater","question", "at","A","B","C","D",
+ "E","F","G","H","I", "J","K","L","M","N",
+ "O","P","Q","R","S", "T","U","V","W","X",
+ "Y","Z","bracketleft","backslash","bracketright", "asciicircum","underscore","grave","a","b",
+ "c","d","e","f","g", "h","i","j","k","l",
+ "m","n","o","p","q", "r","s","t","u","v",
+ "w","x","y","z","braceleft", "bar","braceright","asciitilde","Adieresis","Aring",
+ "Ccedilla","Eacute","Ntilde","Odieresis","Udieresis", "aacute","agrave","acircumflex","adieresis","atilde",
+ "aring","ccedilla","eacute","egrave","ecircumflex", "edieresis","iacute","igrave","icircumflex","idieresis",
+ "ntilde","oacute","ograve","ocircumflex","odieresis", "otilde","uacute","ugrave","ucircumflex","udieresis",
+ "dagger","degree","cent","sterling","section", "bullet","paragraph","germandbls","registered","copyright",
+ "trademark","acute","dieresis","notequal","AE", "Oslash","infinity","plusminus","lessequal","greaterequal",
+ "yen","mu","partialdiff","summation","product", "pi","integral","ordfeminine","ordmasculine","Omega",
+ "ae","oslash","questiondown","exclamdown","logicalnot", "radical","florin","approxequal","Delta","guillemotleft",
+ "guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde", "Otilde","OE","oe","endash","emdash",
+ "quotedblleft","quotedblright","quoteleft","quoteright","divide", "lozenge","ydieresis","Ydieresis","fraction","currency",
+ "guilsinglleft","guilsinglright","fi","fl","daggerdbl", "periodcentered","quotesinglbase","quotedblbase","perthousand","Acircumflex",
+ "Ecircumflex","Aacute","Edieresis","Egrave","Iacute", "Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex",
+ "apple","Ograve","Uacute","Ucircumflex","Ugrave", "dotlessi","circumflex","tilde","macron","breve",
+ "dotaccent","ring","cedilla","hungarumlaut","ogonek", "caron","Lslash","lslash","Scaron","scaron",
+ "Zcaron","zcaron","brokenbar","Eth","eth", "Yacute","yacute","Thorn","thorn","minus","multiply",
+ "onesuperior","twosuperior","threesuperior","onehalf","onequarter", "threequarters","franc","Gbreve","gbreve","Idotaccent",
+ "Scedilla","scedilla","Cacute","cacute","Ccaron", "ccaron","dcroat"};
+#else
+static const char *macRoman[]={0};
+#endif
diff --git a/fontembed/main.c b/fontembed/main.c
new file mode 100644
index 000000000..af7700417
--- /dev/null
+++ b/fontembed/main.c
@@ -0,0 +1,170 @@
+#include "config.h"
+#include "sfnt.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "embed.h"
+
+#if 0
+enum { TTF_OTF, TYPE1 } inputFile;
+if (TTF_OTF) {
+ assert(!TTC);
+ if (CFF/OTF) {
+ // or EMB_PDF_FONTFILE3_OTF [unstripped]
+ if (CIDfont) {
+ asset(multiBYTE);
+ strip_sfnt() // "CIDFontType0" EMB_PDF_FONTFILE3_CID0C
+ } else {
+ ... strip_sfnt();
+ }
+ } else {
+ ...
+ }
+} else if (TYPE1) {
+ assert(!MMType1);
+ assert(!OCF);
+ assert(!WrappedCID_CFF);
+ ... convert_to_cff()
+}
+// not supported: MMType1 Type3
+#endif
+
+#include <string.h>
+
+static void example_outfn(const char *buf,int len,void *context) // {{{
+{
+ FILE *f=(FILE *)context;
+ if (fwrite(buf,1,len,f)!=len) {
+ perror("Short write");
+ assert(0);
+ return;
+ }
+}
+// }}}
+
+void example_write_fontdescr(OTF_FILE *otf,const char *outfile) // {{{
+{
+ FONTFILE *ff=fontfile_open_sfnt(otf);
+ EMB_PARAMS *emb=emb_new(ff,
+ EMB_DEST_PDF16,
+// EMB_C_KEEP_T1
+ EMB_C_FORCE_MULTIBYTE
+
+ );
+ EMB_PDF_FONTDESCR *fdes=emb_pdf_fontdescr(emb);
+ assert(fdes);
+
+ emb_get(emb,'a');
+ emb_get(emb,0x400);
+
+ EMB_PDF_FONTWIDTHS *fwid=emb_pdf_fontwidths(emb);
+ assert(fwid);
+
+ printf("0 0 obj\n");
+ char *res=emb_pdf_simple_fontdescr(emb,fdes,1);
+ assert(res);
+ fputs(res,stdout);
+ free(res);
+ printf("endobj\n");
+
+ printf("1 0 obj\n"
+ "<<\n");
+ if (emb_pdf_get_fontfile_subtype(emb)) {
+ printf(" /Subtype /%s\n",
+ emb_pdf_get_fontfile_subtype(emb));
+ }
+ if (emb->outtype==EMB_FMT_T1) {
+ printf(" /Length1 ?\n"
+ " /Length2 ?\n"
+ " /Length3 ?\n");
+ } else if (emb->outtype==EMB_FMT_TTF) {
+ printf(" /Length1 2 0 R\n");
+ }
+ printf(" /Length 2 0 R\n" // maybe compress it...
+ ">>\n"
+ "stream\n");
+ int outlen=0; // TODO
+// TODO
+ if (outfile) {
+ FILE *f=fopen(outfile,"w");
+ if (!f) {
+ fprintf(stderr,"Opening \"%s\" for writing failed: %s\n",outfile, strerror(errno));
+ assert(0);
+ emb_close(emb);
+ return;
+ }
+ outlen=emb_embed(emb,example_outfn,f);
+// outlen=otf_ttc_extract(emb->font->sfnt,example_outfn,f);
+ fclose(f);
+ }
+puts("...");
+ printf("endstream\n"
+ "endobj\n");
+ printf("2 0 obj\n"
+ "%d\n"
+ "endobj\n",
+ outlen
+ );
+
+ printf("3 0 obj\n");
+ res=emb_pdf_simple_font(emb,fdes,fwid,0);
+ assert(res);
+ fputs(res,stdout);
+ free(res);
+ printf("endobj\n");
+
+ if (emb->plan&EMB_A_MULTIBYTE) {
+ printf("4 0 obj\n");
+ res=emb_pdf_simple_cidfont(emb,fdes->fontname,3);
+ assert(res);
+ fputs(res,stdout);
+ free(res);
+ printf("endobj\n");
+ }
+
+ free(fdes);
+ free(fwid);
+ emb_close(emb);
+#if 1
+ free(ff); // TODO
+#else
+ ff->sfnt=NULL; // TODO
+ fontfile_close(ff);
+#endif
+}
+// }}}
+
+// TODO? reencode?
+int main(int argc,char **argv)
+{
+ const char *fn=TESTFONT;
+ if (argc==2) {
+ fn=argv[1];
+ }
+ OTF_FILE *otf=otf_load(fn);
+ assert(otf);
+ printf("width(4): %d\n",otf_get_width(otf,4));
+
+
+ if (strcmp(fn,"test.ttf")!=0) {
+ example_write_fontdescr(otf,"test.ttf");
+ } else {
+ example_write_fontdescr(otf,NULL);
+ }
+
+ // show_post(otf);
+
+ // show_name(otf);
+
+ // show_cmap(otf);
+ // printf("%d %d\n",otf_from_unicode(otf,'A'),0);
+
+ // ... name 6 -> FontName /20(cid)
+ // ? StemV Flags(?) from FontName
+
+ otf_close(otf);
+
+ return 0;
+}
diff --git a/fontembed/sfnt.c b/fontembed/sfnt.c
new file mode 100644
index 000000000..6fd1fecff
--- /dev/null
+++ b/fontembed/sfnt.c
@@ -0,0 +1,992 @@
+#include "sfnt.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include "sfnt_int.h"
+
+// TODO?
+// get_SHORT(head+48) // fontDirectionHint
+/* reqd. Tables: cmap, head, hhea, hmtx, maxp, name, OS/2, post
+ OTF: glyf,loca [cvt,fpgm,prep]
+ */
+
+static void otf_bsearch_params(int num, // {{{
+ int recordSize,
+ int *searchRange,
+ int *entrySelector,
+ int *rangeShift)
+{
+ assert(num>0);
+ assert(searchRange);
+ assert(entrySelector);
+ assert(rangeShift);
+
+ int iA,iB;
+ for (iA=1,iB=0;iA<=num;iA<<=1,iB++) {}
+
+ *searchRange=iA*recordSize/2;
+ *entrySelector=iB-1;
+ *rangeShift=num*recordSize-*searchRange;
+}
+// }}}
+
+static char *otf_bsearch(char *table, // {{{
+ const char *target,int len,
+ int searchRange,
+ int entrySelector,
+ int rangeShift,
+ int lower_bound) // return lower_bound, if !=0
+{
+ char *ret=table+rangeShift;
+ if (memcmp(target,ret,len)<0) {
+ ret=table;
+ }
+
+ for (;entrySelector>0;entrySelector--) {
+ searchRange>>=1;
+ ret+=searchRange;
+ if (memcmp(target,ret,len)<0) {
+ ret-=searchRange;
+ }
+ }
+ const int result=memcmp(target,ret,len);
+ if (result==0) {
+ return ret;
+ } else if (lower_bound) {
+ if (result>0) {
+ return ret+searchRange;
+ }
+ return ret;
+ }
+ return NULL; // not found;
+}
+// }}}
+
+static OTF_FILE *otf_new(FILE *f) // {{{
+{
+ assert(f);
+
+ OTF_FILE *ret;
+ ret=calloc(1,sizeof(OTF_FILE));
+ if (ret) {
+ ret->f=f;
+ ret->version=0x00010000;
+ }
+
+ return ret;
+}
+// }}}
+
+// will alloc, if >buf ==NULL, returns >buf, or NULL on error
+// NOTE: you probably want otf_get_table()
+static char *otf_read(OTF_FILE *otf,char *buf,long pos,int length) // {{{
+{
+ char *ours=NULL;
+
+ if (length==0) {
+ return buf;
+ } else if (length<0) {
+ assert(0);
+ return NULL;
+ }
+
+ int res=fseek(otf->f,pos,SEEK_SET);
+ if (res==-1) {
+ fprintf(stderr,"Seek failed: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ // (+3)&~3 for checksum...
+ const int pad_len=(length+3)&~3;
+ if (!buf) {
+ ours=buf=malloc(sizeof(char)*pad_len);
+ if (!buf) {
+ fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
+ return NULL;
+ }
+ }
+
+ res=fread(buf,1,pad_len,otf->f);
+ if (res!=pad_len) {
+ if (res==length) { // file size not multiple of 4, pad with zero
+ memset(buf+res,0,pad_len-length);
+ } else {
+ fprintf(stderr,"Short read\n");
+ free(ours);
+ return NULL;
+ }
+ }
+
+ return buf;
+}
+// }}}
+
+
+static int otf_get_ttc_start(OTF_FILE *otf,int use_ttc) // {{{
+{
+ char buf[4];
+
+ if (!otf->numTTC) { // >0 if TTC...
+ return 0;
+ }
+
+ int pos=0;
+ if ( (use_ttc<0)||(use_ttc>=otf->numTTC)||
+ (!otf_read(otf,buf,pos+12+4*use_ttc,4)) ) {
+ fprintf(stderr,"Bad TTC subfont number\n");
+ return -1;
+ }
+ return get_ULONG(buf);
+}
+// }}}
+
+OTF_FILE *otf_do_load(OTF_FILE *otf,int pos) // {{{
+{
+ int iA;
+ char buf[16];
+
+ // {{{ read offset table
+ if (otf_read(otf,buf,pos,12)) {
+ otf->version=get_ULONG(buf);
+ if (otf->version==0x00010000) { // 1.0 truetype
+ } else if (otf->version==OTF_TAG('O','T','T','O')) { // OTF(CFF)
+ otf->flags|=OTF_F_FMT_CFF;
+ } else if (otf->version==OTF_TAG('t','r','u','e')) { // (old mac)
+ } else if (otf->version==OTF_TAG('t','y','p','1')) { // sfnt wrapped type1
+ // TODO: unsupported
+ } else {
+ otf_close(otf);
+ otf=NULL;
+ }
+ pos+=12;
+ } else {
+ otf_close(otf);
+ otf=NULL;
+ }
+ if (!otf) {
+ fprintf(stderr,"Not a ttf font\n");
+ return NULL;
+ }
+ otf->numTables=get_USHORT(buf+4);
+ // }}}
+
+ // {{{ read directory
+ otf->tables=malloc(sizeof(OTF_DIRENT)*otf->numTables);
+ if (!otf->tables) {
+ fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
+ otf_close(otf);
+ return NULL;
+ }
+ for (iA=0;iA<otf->numTables;iA++) {
+ if (!otf_read(otf,buf,pos,16)) {
+ otf_close(otf);
+ return NULL;
+ }
+ otf->tables[iA].tag=get_ULONG(buf);
+ otf->tables[iA].checkSum=get_ULONG(buf+4);
+ otf->tables[iA].offset=get_ULONG(buf+8);
+ otf->tables[iA].length=get_ULONG(buf+12);
+ if ( (otf->tables[iA].tag==OTF_TAG('C','F','F',' '))&&
+ ((otf->flags&OTF_F_FMT_CFF)==0) ) {
+ fprintf(stderr,"Wrong magic\n");
+ otf_close(otf);
+ return NULL;
+ } else if ( (otf->tables[iA].tag==OTF_TAG('g','l','y','p'))&&
+ (otf->flags&OTF_F_FMT_CFF) ) {
+ fprintf(stderr,"Wrong magic\n");
+ otf_close(otf);
+ return NULL;
+ }
+ pos+=16;
+ }
+ // }}}
+
+// otf->flags|=OTF_F_DO_CHECKSUM;
+ // {{{ check head table
+ int len=0;
+ char *head=otf_get_table(otf,OTF_TAG('h','e','a','d'),&len);
+ if ( (!head)||
+ (get_ULONG(head+0)!=0x00010000)|| // version
+ (len!=54)||
+ (get_ULONG(head+12)!=0x5F0F3CF5)|| // magic
+ (get_SHORT(head+52)!=0x0000) ) { // glyphDataFormat
+ fprintf(stderr,"Unsupported OTF font / head table \n");
+ free(head);
+ otf_close(otf);
+ return NULL;
+ }
+ // }}}
+ otf->unitsPerEm=get_USHORT(head+18);
+ otf->indexToLocFormat=get_SHORT(head+50);
+
+ // {{{ checksum whole file
+ if (otf->flags&OTF_F_DO_CHECKSUM) {
+ unsigned int csum=0;
+ char tmp[1024];
+ rewind(otf->f);
+ while (!feof(otf->f)) {
+ len=fread(tmp,1,1024,otf->f);
+ if (len&3) { // zero padding reqd.
+ memset(tmp+len,0,4-(len&3));
+ }
+ csum+=otf_checksum(tmp,len);
+ }
+ if (csum!=0xb1b0afba) {
+ fprintf(stderr,"Wrong global checksum\n");
+ free(head);
+ otf_close(otf);
+ return NULL;
+ }
+ }
+ // }}}
+ free(head);
+
+ // {{{ read maxp table / numGlyphs
+ char *maxp=otf_get_table(otf,OTF_TAG('m','a','x','p'),&len);
+ if (maxp) {
+ const unsigned int maxp_version=get_ULONG(maxp);
+ if ( (maxp_version==0x00005000)&&(len==6) ) { // version 0.5
+ otf->numGlyphs=get_USHORT(maxp+4);
+ if ( (otf->flags&OTF_F_FMT_CFF)==0) { // only CFF
+ free(maxp);
+ maxp=NULL;
+ }
+ } else if ( (maxp_version==0x00010000)&&(len==32) ) { // version 1.0
+ otf->numGlyphs=get_USHORT(maxp+4);
+ if (otf->flags&OTF_F_FMT_CFF) { // only TTF
+ free(maxp);
+ maxp=NULL;
+ }
+ } else {
+ free(maxp);
+ maxp=NULL;
+ }
+ }
+ if (!maxp) {
+ fprintf(stderr,"Unsupported OTF font / maxp table \n");
+ free(maxp);
+ otf_close(otf);
+ return NULL;
+ }
+ free(maxp);
+ // }}}
+
+ return otf;
+}
+// }}}
+
+OTF_FILE *otf_load(const char *file) // {{{
+{
+ FILE *f;
+ OTF_FILE *otf;
+
+ int use_ttc=-1;
+ if ((f=fopen(file,"rb"))==NULL) {
+ // check for TTC
+ char *tmp=strrchr(file,'/'),*end;
+ if (tmp) {
+ use_ttc=strtoul(tmp+1,&end,10);
+ if (!*end) {
+ end=malloc((tmp-file+1)*sizeof(char));
+ if (!end) {
+ fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
+ return NULL;
+ }
+ strncpy(end,file,tmp-file);
+ end[tmp-file]=0;
+ f=fopen(end,"rb");
+ free(end);
+ }
+ }
+ if (!f) {
+ fprintf(stderr,"Could not open \"%s\": %s\n", file, strerror(errno));
+ return NULL;
+ }
+ }
+ otf=otf_new(f);
+ if (!otf) {
+ fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
+ fclose(f);
+ return NULL;
+ }
+
+ char buf[12];
+ int pos=0;
+ // {{{ check for TTC
+ if (otf_read(otf,buf,pos,12)) {
+ const unsigned int version=get_ULONG(buf);
+ if (version==OTF_TAG('t','t','c','f')) {
+ const unsigned int ttc_version=get_ULONG(buf+4);
+ if ( (ttc_version!=0x00010000)&&(ttc_version!=0x00020000) ) {
+ fprintf(stderr,"Unsupported TTC version\n");
+ otf_close(otf);
+ return NULL;
+ }
+ otf->numTTC=get_ULONG(buf+8);
+ otf->useTTC=use_ttc;
+ pos=otf_get_ttc_start(otf,use_ttc);
+ if (pos==-1) {
+ otf_close(otf);
+ return NULL;
+ }
+ }
+ } else {
+ fprintf(stderr,"Not a ttf font\n");
+ otf_close(otf);
+ return NULL;
+ }
+ // }}}
+
+ return otf_do_load(otf,pos);
+}
+// }}}
+
+void otf_close(OTF_FILE *otf) // {{{
+{
+ assert(otf);
+ if (otf) {
+ free(otf->gly);
+ free(otf->cmap);
+ free(otf->name);
+ free(otf->hmtx);
+ free(otf->glyphOffsets);
+ fclose(otf->f);
+ free(otf->tables);
+ free(otf);
+ }
+}
+// }}}
+
+static int otf_dirent_compare(const void *a,const void *b) // {{{
+{
+ const unsigned int aa=((const OTF_DIRENT *)a)->tag;
+ const unsigned int bb=((const OTF_DIRENT *)b)->tag;
+ if (aa<bb) {
+ return -1;
+ } else if (aa>bb) {
+ return 1;
+ }
+ return 0;
+}
+// }}}
+
+int otf_find_table(OTF_FILE *otf,unsigned int tag) // {{{ - table_index or -1 on error
+{
+#if 0
+ // binary search would require raw table
+ int pos=0;
+ char buf[12];
+ if (!otf_read(otf,buf,pos,12)) {
+ return -1;
+ }
+ pos=12;
+ const unsigned int numTables=get_USHORT(buf+4);
+ char *tables=malloc(16*numTables);
+ if (!tables) {
+ return -1;
+ }
+ if (!otf_read(otf,tables,pos,16*numTables)) {
+ free(tables);
+ return -1;
+ }
+ char target[]={(tag>>24),(tag>>16),(tag>>8),tag};
+ // assert(get_USHORT(buf+6)+get_USHORT(buf+10)==16*numTables);
+ char *result=otf_bsearch(tables,target,4,
+ get_USHORT(buf+6),
+ get_USHORT(buf+8),
+ get_USHORT(buf+10),0);
+ free(tables);
+ if (result) {
+ return (result-tables)/16;
+ }
+#elif 1
+ OTF_DIRENT key={.tag=tag},*res;
+ res=bsearch(&key,otf->tables,otf->numTables,sizeof(otf->tables[0]),otf_dirent_compare);
+ if (res) {
+ return (res-otf->tables);
+ }
+#else
+ int iA;
+ for (iA=0;iA<otf->numTables;iA++) {
+ if (otf->tables[iA].tag==tag) {
+ return iA;
+ }
+ }
+#endif
+ return -1;
+}
+// }}}
+
+char *otf_get_table(OTF_FILE *otf,unsigned int tag,int *ret_len) // {{{
+{
+ assert(otf);
+ assert(ret_len);
+
+ const int idx=otf_find_table(otf,tag);
+ if (idx==-1) {
+ *ret_len=-1;
+ return NULL;
+ }
+ const OTF_DIRENT *table=otf->tables+idx;
+
+ char *ret=otf_read(otf,NULL,table->offset,table->length);
+ if (!ret) {
+ return NULL;
+ }
+ if (otf->flags&OTF_F_DO_CHECKSUM) {
+ unsigned int csum=otf_checksum(ret,table->length);
+ if (tag==OTF_TAG('h','e','a','d')) { // special case
+ csum-=get_ULONG(ret+8);
+ }
+ if (csum!=table->checkSum) {
+ fprintf(stderr,"Wrong checksum for %c%c%c%c\n",OTF_UNTAG(tag));
+ free(ret);
+ return NULL;
+ }
+ }
+ *ret_len=table->length;
+ return ret;
+}
+// }}}
+
+int otf_load_glyf(OTF_FILE *otf) // {{{ - 0 on success
+{
+ assert((otf->flags&OTF_F_FMT_CFF)==0); // not for CFF
+ int iA,len;
+ // {{{ find glyf table
+ iA=otf_find_table(otf,OTF_TAG('g','l','y','f'));
+ if (iA==-1) {
+ fprintf(stderr,"Unsupported OTF font / glyf table \n");
+ return -1;
+ }
+ otf->glyfTable=otf->tables+iA;
+ // }}}
+
+ // {{{ read loca table
+ char *loca=otf_get_table(otf,OTF_TAG('l','o','c','a'),&len);
+ if ( (!loca)||
+ (otf->indexToLocFormat>=2)||
+ (((len+3)&~3)!=((((otf->numGlyphs+1)*(otf->indexToLocFormat+1)*2)+3)&~3)) ) {
+ fprintf(stderr,"Unsupported OTF font / loca table \n");
+ return -1;
+ }
+ if (otf->glyphOffsets) {
+ free(otf->glyphOffsets);
+ assert(0);
+ }
+ otf->glyphOffsets=malloc((otf->numGlyphs+1)*sizeof(unsigned int));
+ if (!otf->glyphOffsets) {
+ fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
+ return -1;
+ }
+ if (otf->indexToLocFormat==0) {
+ for (iA=0;iA<=otf->numGlyphs;iA++) {
+ otf->glyphOffsets[iA]=get_USHORT(loca+iA*2)*2;
+ }
+ } else { // indexToLocFormat==1
+ for (iA=0;iA<=otf->numGlyphs;iA++) {
+ otf->glyphOffsets[iA]=get_ULONG(loca+iA*4);
+ }
+ }
+ free(loca);
+ if (otf->glyphOffsets[otf->numGlyphs]>otf->glyfTable->length) {
+ fprintf(stderr,"Bad loca table \n");
+ return -1;
+ }
+ // }}}
+
+ // {{{ allocate otf->gly slot
+ int maxGlyfLen=0; // no single glyf takes more space
+ for (iA=1;iA<=otf->numGlyphs;iA++) {
+ const int glyfLen=otf->glyphOffsets[iA]-otf->glyphOffsets[iA-1];
+ if (glyfLen<0) {
+ fprintf(stderr,"Bad loca table: glyph len %d\n",glyfLen);
+ return -1;
+ }
+ if (maxGlyfLen<glyfLen) {
+ maxGlyfLen=glyfLen;
+ }
+ }
+ if (otf->gly) {
+ free(otf->gly);
+ assert(0);
+ }
+ otf->gly=malloc(maxGlyfLen*sizeof(char));
+ if (!otf->gly) {
+ fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
+ return -1;
+ }
+ // }}}
+
+ return 0;
+}
+// }}}
+
+int otf_load_more(OTF_FILE *otf) // {{{ - 0 on success => hhea,hmtx,name,[glyf]
+{
+ int iA;
+
+ int len;
+ if ((otf->flags&OTF_F_FMT_CFF)==0) { // not for CFF
+ if (otf_load_glyf(otf)==-1) {
+ return -1;
+ }
+ }
+
+ // {{{ read hhea table
+ char *hhea=otf_get_table(otf,OTF_TAG('h','h','e','a'),&len);
+ if ( (!hhea)||
+ (get_ULONG(hhea)!=0x00010000)|| // version
+ (len!=36)||
+ (get_SHORT(hhea+32)!=0) ) { // metric format
+ fprintf(stderr,"Unsupported OTF font / hhea table \n");
+ return -1;
+ }
+ otf->numberOfHMetrics=get_USHORT(hhea+34);
+ free(hhea);
+ // }}}
+
+ // {{{ read hmtx table
+ char *hmtx=otf_get_table(otf,OTF_TAG('h','m','t','x'),&len);
+ if ( (!hmtx)||
+ (len!=otf->numberOfHMetrics*2+otf->numGlyphs*2) ) {
+ fprintf(stderr,"Unsupported OTF font / hmtx table \n");
+ return -1;
+ }
+ if (otf->hmtx) {
+ free(otf->hmtx);
+ assert(0);
+ }
+ otf->hmtx=hmtx;
+ // }}}
+
+ // {{{ read name table
+ char *name=otf_get_table(otf,OTF_TAG('n','a','m','e'),&len);
+ if ( (!name)||
+ (get_USHORT(name)!=0x0000)|| // version
+ (len<get_USHORT(name+2)*12+6)||
+ (len<=get_USHORT(name+4)) ) {
+ fprintf(stderr,"Unsupported OTF font / name table \n");
+ return -1;
+ }
+ // check bounds
+ int name_count=get_USHORT(name+2);
+ const char *nstore=name+get_USHORT(name+4);
+ for (iA=0;iA<name_count;iA++) {
+ const char *nrec=name+6+12*iA;
+ if (nstore-name+get_USHORT(nrec+10)+get_USHORT(nrec+8)>len) {
+ fprintf(stderr,"Bad name table \n");
+ free(name);
+ return -1;
+ }
+ }
+ if (otf->name) {
+ free(otf->name);
+ assert(0);
+ }
+ otf->name=name;
+ // }}}
+
+ return 0;
+}
+// }}}
+
+int otf_load_cmap(OTF_FILE *otf) // {{{ - 0 on success
+{
+ int iA;
+ int len;
+
+ char *cmap=otf_get_table(otf,OTF_TAG('c','m','a','p'),&len);
+ if ( (!cmap)||
+ (get_USHORT(cmap)!=0x0000)|| // version
+ (len<get_USHORT(cmap+2)*8+4) ) {
+ fprintf(stderr,"Unsupported OTF font / cmap table \n");
+ assert(0);
+ return -1;
+ }
+ // check bounds, find (3,0) or (3,1) [TODO?]
+ const int numTables=get_USHORT(cmap+2);
+ for (iA=0;iA<numTables;iA++) {
+ const char *nrec=cmap+4+8*iA;
+ const unsigned int offset=get_ULONG(nrec+4);
+ const char *ndata=cmap+offset;
+ if ( (ndata<cmap+4+8*numTables)||
+ (offset>=len)||
+ (offset+get_USHORT(ndata+2)>len) ) {
+ fprintf(stderr,"Bad cmap table \n");
+ free(cmap);
+ assert(0);
+ return -1;
+ }
+ if ( (get_USHORT(nrec)==3)&&
+ (get_USHORT(nrec+2)<=1)&&
+ (get_USHORT(ndata)==4)&&
+ (get_USHORT(ndata+4)==0) ) {
+ otf->unimap=ndata;
+ }
+ }
+ if (otf->cmap) {
+ free(otf->cmap);
+ assert(0);
+ }
+ otf->cmap=cmap;
+
+ return 0;
+}
+// }}}
+
+int otf_get_width(OTF_FILE *otf,unsigned short gid) // {{{ -1 on error
+{
+ assert(otf);
+
+ if (gid>=otf->numGlyphs) {
+ return -1;
+ }
+
+ // ensure hmtx is there
+ if (!otf->hmtx) {
+ if (otf_load_more(otf)!=0) {
+ assert(0);
+ return -1;
+ }
+ }
+
+ return get_width_fast(otf,gid);
+#if 0
+ if (gid>=otf->numberOfHMetrics) {
+ return get_USHORT(otf->hmtx+(otf->numberOfHMetrics-1)*2);
+ // TODO? lsb=get_SHORT(otf->hmtx+otf->numberOfHMetrics*2+gid*2); // lsb: left_side_bearing (also in table)
+ }
+ return get_USHORT(otf->hmtx+gid*4);
+ // TODO? lsb=get_SHORT(otf->hmtx+gid*4+2);
+#endif
+}
+// }}}
+
+static int otf_name_compare(const void *a,const void *b) // {{{
+{
+ return memcmp(a,b,8);
+}
+// }}}
+
+const char *otf_get_name(OTF_FILE *otf,int platformID,int encodingID,int languageID,int nameID,int *ret_len) // {{{
+{
+ assert(otf);
+ assert(ret_len);
+
+ // ensure name is there
+ if (!otf->name) {
+ if (otf_load_more(otf)!=0) {
+ *ret_len=-1;
+ assert(0);
+ return NULL;
+ }
+ }
+
+ char key[8];
+ set_USHORT(key,platformID);
+ set_USHORT(key+2,encodingID);
+ set_USHORT(key+4,languageID);
+ set_USHORT(key+6,nameID);
+
+ char *res=bsearch(key,otf->name+6,get_USHORT(otf->name+2),12,otf_name_compare);
+ if (res) {
+ *ret_len=get_USHORT(res+8);
+ int npos=get_USHORT(res+10);
+ const char *nstore=otf->name+get_USHORT(otf->name+4);
+ return nstore+npos;
+ }
+ *ret_len=0;
+ return NULL;
+}
+// }}}
+
+int otf_get_glyph(OTF_FILE *otf,unsigned short gid) // {{{ result in >otf->gly, returns length, -1 on error
+{
+ assert(otf);
+ assert((otf->flags&OTF_F_FMT_CFF)==0); // not for CFF
+
+ if (gid>=otf->numGlyphs) {
+ return -1;
+ }
+
+ // ensure >glyphOffsets and >gly is there
+ if ( (!otf->gly)||(!otf->glyphOffsets) ) {
+ if (otf_load_more(otf)!=0) {
+ assert(0);
+ return -1;
+ }
+ }
+
+ const int len=otf->glyphOffsets[gid+1]-otf->glyphOffsets[gid];
+ if (len==0) {
+ return 0;
+ }
+
+ assert(otf->glyfTable->length>=otf->glyphOffsets[gid+1]);
+ if (!otf_read(otf,otf->gly,
+ otf->glyfTable->offset+otf->glyphOffsets[gid],len)) {
+ return -1;
+ }
+
+ return len;
+}
+// }}}
+
+unsigned short otf_from_unicode(OTF_FILE *otf,int unicode) // {{{ 0 = missing
+{
+ assert(otf);
+ assert( (unicode>=0)&&(unicode<65536) );
+// assert((otf->flags&OTF_F_FMT_CFF)==0); // not for CFF, other method!
+
+ // ensure >cmap and >unimap is there
+ if (!otf->cmap) {
+ if (otf_load_cmap(otf)!=0) {
+ assert(0);
+ return 0; // TODO?
+ }
+ }
+ if (!otf->unimap) {
+ fprintf(stderr,"Unicode (3,1) cmap in format 4 not found\n");
+ return 0;
+ }
+
+#if 0
+ // linear search is cache friendly and should be quite fast
+#else
+ const unsigned short segCountX2=get_USHORT(otf->unimap+6);
+ char target[]={unicode>>8,unicode}; // set_USHORT(target,unicode);
+ char *result=otf_bsearch((char *)otf->unimap+14,target,2,
+ get_USHORT(otf->unimap+8),
+ get_USHORT(otf->unimap+10),
+ get_USHORT(otf->unimap+12),1);
+ if (result>=otf->unimap+14+segCountX2) { // outside of endCode[segCount]
+ assert(0); // bad font, no 0xffff sentinel
+ return 0;
+ }
+
+ result+=2+segCountX2; // jump over padding into startCode[segCount]
+ const unsigned short startCode=get_USHORT(result);
+ if (startCode>unicode) {
+ return 0;
+ }
+ result+=2*segCountX2;
+ const unsigned short rangeOffset=get_USHORT(result);
+ if (rangeOffset) {
+ return get_USHORT(result+rangeOffset+2*(unicode-startCode)); // the so called "obscure indexing trick" into glyphIdArray[]
+ // NOTE: this is according to apple spec; microsoft says we must add delta (probably incorrect; fonts probably have delta==0)
+ } else {
+ const short delta=get_SHORT(result-segCountX2);
+ return (delta+unicode)&0xffff;
+ }
+#endif
+}
+// }}}
+
+/** output stuff **/
+int otf_action_copy(void *param,int table_no,OUTPUT_FN output,void *context) // {{{
+{
+ OTF_FILE *otf=param;
+ const OTF_DIRENT *table=otf->tables+table_no;
+
+ if (!output) { // get checksum and unpadded length
+ *(unsigned int *)context=table->checkSum;
+ return table->length;
+ }
+
+// TODO? copy_block(otf->f,table->offset,(table->length+3)&~3,output,context);
+// problem: PS currently depends on single-output. also checksum not possible
+ char *data=otf_read(otf,NULL,table->offset,table->length);
+ if (!data) {
+ return -1;
+ }
+ int ret=(table->length+3)&~3;
+ (*output)(data,ret,context);
+ free(data);
+ return ret; // padded length
+}
+// }}}
+
+// TODO? >modified time-stamp?
+// Note: don't use this directly. otf_write_sfnt will internally replace otf_action_copy for head with this
+int otf_action_copy_head(void *param,int csum,OUTPUT_FN output,void *context) // {{{
+{
+ OTF_FILE *otf=param;
+ const int table_no=otf_find_table(otf,OTF_TAG('h','e','a','d')); // we can't have csum AND table_no ... never mind!
+ assert(table_no!=-1);
+ const OTF_DIRENT *table=otf->tables+table_no;
+
+ if (!output) { // get checksum and unpadded length
+ *(unsigned int *)context=table->checkSum;
+ return table->length;
+ }
+
+ char *data=otf_read(otf,NULL,table->offset,table->length);
+ if (!data) {
+ return -1;
+ }
+ set_ULONG(data+8,0xb1b0afba-csum); // head. fix global checksum
+ int ret=(table->length+3)&~3;
+ (*output)(data,ret,context);
+ free(data);
+ return ret; // padded length
+}
+// }}}
+
+int otf_action_replace(void *param,int length,OUTPUT_FN output,void *context) // {{{
+{
+ char *data=param;
+ char pad[4]={0,0,0,0};
+
+ int ret=(length+3)&~3;
+ if (!output) { // get checksum and unpadded length
+ if (ret!=length) {
+ unsigned int csum=otf_checksum(data,ret-4);
+ memcpy(pad,data+ret-4,ret-length);
+ csum+=get_ULONG(pad);
+ *(unsigned int *)context=csum;
+ } else {
+ *(unsigned int *)context=otf_checksum(data,length);
+ }
+ return length;
+ }
+
+ (*output)(data,length,context);
+ if (ret!=length) {
+ (*output)(pad,ret-length,context);
+ }
+
+ return ret; // padded length
+}
+// }}}
+
+/* windows "works best" with the following ordering:
+ head, hhea, maxp, OS/2, hmtx, LTSH, VDMX, hdmx, cmap, fpgm, prep, cvt, loca, glyf, kern, name, post, gasp, PCLT, DSIG
+or for CFF:
+ head, hhea, maxp, OS/2, name, cmap, post, CFF, (other tables, as convenient)
+*/
+#define NUM_PRIO 20
+static const struct { int prio; unsigned int tag; } otf_tagorder_win[]={ // {{{
+ {19,OTF_TAG('D','S','I','G')},
+ { 5,OTF_TAG('L','T','S','H')},
+ { 3,OTF_TAG('O','S','/','2')},
+ {18,OTF_TAG('P','C','L','T')},
+ { 6,OTF_TAG('V','D','M','X')},
+ { 8,OTF_TAG('c','m','a','p')},
+ {11,OTF_TAG('c','v','t',' ')},
+ { 9,OTF_TAG('f','p','g','m')},
+ {17,OTF_TAG('g','a','s','p')},
+ {13,OTF_TAG('g','l','y','f')},
+ { 7,OTF_TAG('h','d','m','x')},
+ { 0,OTF_TAG('h','e','a','d')},
+ { 1,OTF_TAG('h','h','e','a')},
+ { 4,OTF_TAG('h','m','t','x')},
+ {14,OTF_TAG('k','e','r','n')},
+ {12,OTF_TAG('l','o','c','a')},
+ { 2,OTF_TAG('m','a','x','p')},
+ {15,OTF_TAG('n','a','m','e')},
+ {16,OTF_TAG('p','o','s','t')},
+ {10,OTF_TAG('p','r','e','p')}};
+// }}}
+
+int otf_write_sfnt(struct _OTF_WRITE *otw,unsigned int version,int numTables,OUTPUT_FN output,void *context) // {{{
+{
+ int iA;
+ int ret;
+
+ int *order=malloc(sizeof(int)*numTables); // temporary
+ char *start=malloc(12+16*numTables);
+ if ( (!order)||(!start) ) {
+ fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
+ free(order);
+ free(start);
+ return -1;
+ }
+
+ if (1) { // sort tables
+ int priolist[NUM_PRIO]={0,};
+
+ // reverse intersection of both sorted arrays
+ int iA=numTables-1,iB=sizeof(otf_tagorder_win)/sizeof(otf_tagorder_win[0])-1;
+ int ret=numTables-1;
+ while ( (iA>=0)&&(iB>=0) ) {
+ if (otw[iA].tag==otf_tagorder_win[iB].tag) {
+ priolist[otf_tagorder_win[iB--].prio]=1+iA--;
+ } else if (otw[iA].tag>otf_tagorder_win[iB].tag) { // no order known: put unchanged at end of result
+ order[ret--]=iA--;
+ } else { // <
+ iB--;
+ }
+ }
+ for (iA=NUM_PRIO-1;iA>=0;iA--) { // pick the matched tables up in sorted order (bucketsort principle)
+ if (priolist[iA]) {
+ order[ret--]=priolist[iA]-1;
+ }
+ }
+ } else {
+ for (iA=0;iA<numTables;iA++) {
+ order[iA]=iA;
+ }
+ }
+
+ // the header
+ set_ULONG(start,version);
+ set_USHORT(start+4,numTables);
+ int a,b,c;
+ otf_bsearch_params(numTables,16,&a,&b,&c);
+ set_USHORT(start+6,a);
+ set_USHORT(start+8,b);
+ set_USHORT(start+10,c);
+
+ // first pass: calculate table directory / offsets and checksums
+ unsigned int globalSum=0,csum;
+ int offset=12+16*numTables;
+ int headAt=-1;
+ for (iA=0;iA<numTables;iA++) {
+ char *entry=start+12+16*order[iA];
+ const int res=(*otw[order[iA]].action)(otw[order[iA]].param,otw[order[iA]].length,NULL,&csum);
+ assert(res>=0);
+ if (otw[order[iA]].tag==OTF_TAG('h','e','a','d')) {
+ headAt=order[iA];
+ }
+ set_ULONG(entry,otw[order[iA]].tag);
+ set_ULONG(entry+4,csum);
+ set_ULONG(entry+8,offset);
+ set_ULONG(entry+12,res);
+ offset+=(res+3)&~3; // padding
+ globalSum+=csum;
+ }
+
+ // second pass: write actual data
+ // write header + directory
+ ret=12+16*numTables;
+ (*output)(start,ret,context);
+ globalSum+=otf_checksum(start,ret);
+
+ // change head
+ if ( (headAt!=-1)&&(otw[headAt].action==otf_action_copy) ) { // more needed?
+ otw[headAt].action=otf_action_copy_head;
+ otw[headAt].length=globalSum;
+ }
+
+ // write tables
+ for (iA=0;iA<numTables;iA++) {
+ const int res=(*otw[order[iA]].action)(otw[order[iA]].param,otw[order[iA]].length,output,context);
+ if (res<0) {
+ free(order);
+ free(start);
+ return -1;
+ }
+ assert(((res+3)&~3)==res); // correctly padded? (i.e. next line is just ret+=res;)
+ ret+=(res+3)&~3;
+ }
+ assert(offset==ret);
+ free(order);
+ free(start);
+
+ return ret;
+}
+// }}}
+
diff --git a/fontembed/sfnt.h b/fontembed/sfnt.h
new file mode 100644
index 000000000..1783098d2
--- /dev/null
+++ b/fontembed/sfnt.h
@@ -0,0 +1,64 @@
+#ifndef _SFNT_H
+#define _SFNT_H
+
+#include <stdio.h>
+
+typedef struct {
+ unsigned int tag;
+ unsigned int checkSum;
+ unsigned int offset;
+ unsigned int length;
+} OTF_DIRENT;
+
+typedef struct {
+ FILE *f;
+ unsigned int numTTC,useTTC;
+ unsigned int version;
+
+ unsigned short numTables;
+ OTF_DIRENT *tables;
+
+ int flags;
+ unsigned short unitsPerEm;
+ unsigned short indexToLocFormat; // 0=short, 1=long
+ unsigned short numGlyphs;
+
+ // optionally loaded data
+ unsigned int *glyphOffsets;
+ unsigned short numberOfHMetrics;
+ char *hmtx,*name,*cmap;
+ const char *unimap; // ptr to (3,1) or (3,0) cmap start
+
+ // single glyf buffer, allocated large enough by otf_load_more()
+ char *gly;
+ OTF_DIRENT *glyfTable;
+
+} OTF_FILE;
+#define OTF_F_FMT_CFF 0x10000
+#define OTF_F_DO_CHECKSUM 0x40000
+
+// to load TTC collections: append e.g. "/3" for the third font in the file.
+OTF_FILE *otf_load(const char *file);
+void otf_close(OTF_FILE *otf);
+
+#define OTF_TAG(a,b,c,d) (unsigned int)( ((a)<<24)|((b)<<16)|((c)<<8)|(d) )
+#define OTF_UNTAG(a) (((unsigned int)(a)>>24)&0xff),(((unsigned int)(a)>>16)&0xff),\
+ (((unsigned int)(a)>>8)&0xff),(((unsigned int)(a))&0xff)
+
+char *otf_get_table(OTF_FILE *otf,unsigned int tag,int *ret_len);
+
+int otf_get_width(OTF_FILE *otf,unsigned short gid);
+const char *otf_get_name(OTF_FILE *otf,int platformID,int encodingID,int languageID,int nameID,int *ret_len);
+int otf_get_glyph(OTF_FILE *otf,unsigned short gid);
+unsigned short otf_from_unicode(OTF_FILE *otf,int unicode);
+
+#include "bitset.h"
+#include "iofn.h"
+
+// TODO?! allow glyphs==NULL for non-subsetting table reduction?
+int otf_subset(OTF_FILE *otf,BITSET glyphs,OUTPUT_FN output,void *context);
+int otf_ttc_extract(OTF_FILE *otf,OUTPUT_FN output,void *context);
+int otf_subset_cff(OTF_FILE *otf,BITSET glyphs,OUTPUT_FN output,void *context);
+int otf_cff_extract(OTF_FILE *otf,OUTPUT_FN output,void *context);
+
+#endif
diff --git a/fontembed/sfnt_int.h b/fontembed/sfnt_int.h
new file mode 100644
index 000000000..777ead669
--- /dev/null
+++ b/fontembed/sfnt_int.h
@@ -0,0 +1,97 @@
+#ifndef _SFNT_INT_H
+#define _SFNT_INT_H
+
+static inline unsigned short get_USHORT(const char *buf) // {{{
+{
+ return ((unsigned char)buf[0]<<8)|((unsigned char)buf[1]);
+}
+// }}}
+static inline short get_SHORT(const char *buf) // {{{
+{
+ return (buf[0]<<8)|((unsigned char)buf[1]);
+}
+// }}}
+static inline unsigned int get_UINT24(const char *buf) // {{{
+{
+ return ((unsigned char)buf[0]<<16)|
+ ((unsigned char)buf[1]<<8)|
+ ((unsigned char)buf[2]);
+}
+// }}}
+static inline unsigned int get_ULONG(const char *buf) // {{{
+{
+ return ((unsigned char)buf[0]<<24)|
+ ((unsigned char)buf[1]<<16)|
+ ((unsigned char)buf[2]<<8)|
+ ((unsigned char)buf[3]);
+}
+// }}}
+static inline int get_LONG(const char *buf) // {{{
+{
+ return (buf[0]<<24)|
+ ((unsigned char)buf[1]<<16)|
+ ((unsigned char)buf[2]<<8)|
+ ((unsigned char)buf[3]);
+}
+// }}}
+
+static inline void set_USHORT(char *buf,unsigned short val) // {{{
+{
+ buf[0]=val>>8;
+ buf[1]=val&0xff;
+}
+// }}}
+static inline void set_ULONG(char *buf,unsigned int val) // {{{
+{
+ buf[0]=val>>24;
+ buf[1]=(val>>16)&0xff;
+ buf[2]=(val>>8)&0xff;
+ buf[3]=val&0xff;
+}
+// }}}
+
+static inline unsigned int otf_checksum(const char *buf, unsigned int len) // {{{
+{
+ unsigned int ret=0;
+ for (len=(len+3)/4;len>0;len--,buf+=4) {
+ ret+=get_ULONG(buf);
+ }
+ return ret;
+}
+// }}}
+static inline int get_width_fast(OTF_FILE *otf,int gid) // {{{
+{
+ if (gid>=otf->numberOfHMetrics) {
+ return get_USHORT(otf->hmtx+(otf->numberOfHMetrics-1)*4);
+ } else {
+ return get_USHORT(otf->hmtx+gid*4);
+ }
+}
+// }}}
+
+int otf_load_glyf(OTF_FILE *otf); // - 0 on success
+int otf_load_more(OTF_FILE *otf); // - 0 on success
+
+int otf_find_table(OTF_FILE *otf,unsigned int tag); // - table_index or -1 on error
+
+int otf_action_copy(void *param,int csum,OUTPUT_FN output,void *context);
+int otf_action_replace(void *param,int csum,OUTPUT_FN output,void *context);
+
+// Note: don't use this directly. otf_write_sfnt will internally replace otf_action_copy for head with this
+int otf_action_copy_head(void *param,int csum,OUTPUT_FN output,void *context);
+
+struct _OTF_WRITE {
+ unsigned long tag;
+ int (*action)(void *param,int length,OUTPUT_FN output,void *context); // -1 on error, num_bytes_written on success; if >output==NULL return checksum in (unsigned int *)context instead.
+ void *param;
+ int length;
+};
+
+int otf_write_sfnt(struct _OTF_WRITE *otw,unsigned int version,int numTables,OUTPUT_FN output,void *context);
+
+/** from sfnt_subset.c: **/
+
+// otw {0,}-terminated, will be modified; returns numTables for otf_write_sfnt
+int otf_intersect_tables(OTF_FILE *otf,struct _OTF_WRITE *otw);
+
+#endif
diff --git a/fontembed/sfnt_subset.c b/fontembed/sfnt_subset.c
new file mode 100644
index 000000000..dee34c5d3
--- /dev/null
+++ b/fontembed/sfnt_subset.c
@@ -0,0 +1,343 @@
+#include "sfnt.h"
+#include "sfnt_int.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include "bitset.h"
+
+int otf_ttc_extract(OTF_FILE *otf,OUTPUT_FN output,void *context) // {{{
+{
+ assert(otf);
+ assert(output);
+ assert(otf->numTTC);
+ int iA;
+
+ struct _OTF_WRITE *otw;
+ otw=malloc(sizeof(struct _OTF_WRITE)*otf->numTables);
+ if (!otw) {
+ fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
+ return -1;
+ }
+
+ // just copy everything
+ for (iA=0;iA<otf->numTables;iA++) {
+ otw[iA].tag=otf->tables[iA].tag;
+ otw[iA].action=otf_action_copy;
+ otw[iA].param=otf;
+ otw[iA].length=iA;
+ }
+ iA=otf_write_sfnt(otw,otf->version,otf->numTables,output,context);
+ free(otw);
+
+ return iA;
+}
+// }}}
+
+// otw {0,}-terminated, will be modified; returns numTables for otf_write_sfnt
+int otf_intersect_tables(OTF_FILE *otf,struct _OTF_WRITE *otw) // {{{
+{
+ int iA,iB,numTables=0;
+ for (iA=0,iB=0;(iA<otf->numTables)&&(otw[iB].tag);) {
+ if (otf->tables[iA].tag==otw[iB].tag) {
+ if (otw[iB].action==otf_action_copy) {
+ otw[iB].length=iA; // original table location found.
+ }
+ if (iB!=numTables) { // >, actually
+ memmove(otw+numTables,otw+iB,sizeof(struct _OTF_WRITE));
+ }
+ iA++;
+ iB++;
+ numTables++;
+ } else if (otf->tables[iA].tag<otw[iB].tag) {
+ iA++;
+ } else { // not in otf->tables
+ if (otw[iB].action!=otf_action_copy) { // keep
+ if (iB!=numTables) { // >, actually
+ memmove(otw+numTables,otw+iB,sizeof(struct _OTF_WRITE));
+ }
+ numTables++;
+ } // else delete
+ iB++;
+ }
+ }
+ return numTables;
+}
+// }}}
+
+
+// include components (set bit in >glyphs) of currently loaded compound glyph (with >curgid)
+// returns additional space requirements (when bits below >donegid are touched)
+static int otf_subset_glyf(OTF_FILE *otf,int curgid,int donegid,BITSET glyphs) // {{{
+{
+ int ret=0;
+ if (get_SHORT(otf->gly)>=0) { // not composite
+ return ret; // done
+ }
+
+ char *cur=otf->gly+10;
+
+ unsigned short flags;
+ do {
+ flags=get_USHORT(cur);
+ const unsigned short sub_gid=get_USHORT(cur+2);
+ assert(sub_gid<otf->numGlyphs);
+ if (!bit_check(glyphs,sub_gid)) {
+ // bad: temporarily load sub glyph
+ const int len=otf_get_glyph(otf,sub_gid);
+ assert(len>0);
+ bit_set(glyphs,sub_gid);
+ if (sub_gid<donegid) {
+ ret+=len;
+ ret+=otf_subset_glyf(otf,sub_gid,donegid,glyphs); // composite of composites?, e.g. in DejaVu
+ }
+ const int res=otf_get_glyph(otf,curgid); // reload current glyph
+ assert(res);
+ }
+
+ // skip parameters
+ cur+=6;
+ if (flags&0x01) {
+ cur+=2;
+ }
+ if (flags&0x08) {
+ cur+=2;
+ } else if (flags&0x40) {
+ cur+=4;
+ } else if (flags&0x80) {
+ cur+=8;
+ }
+ } while (flags&0x20); // more components
+
+ return ret;
+}
+// }}}
+
+// TODO: cmap only required in non-CID context
+int otf_subset(OTF_FILE *otf,BITSET glyphs,OUTPUT_FN output,void *context) // {{{ - returns number of bytes written
+{
+ assert(otf);
+ assert(glyphs);
+ assert(output);
+
+ int iA,b,c;
+
+ // first pass: include all required glyphs
+ bit_set(glyphs,0); // .notdef always required
+ int glyfSize=0;
+ for (iA=0,b=0,c=1;iA<otf->numGlyphs;iA++,c<<=1) {
+ if (!c) {
+ b++;
+ c=1;
+ }
+ if (glyphs[b]&c) {
+ int len=otf_get_glyph(otf,iA);
+ if (len<0) {
+ assert(0);
+ return -1;
+ } else if (len>0) {
+ glyfSize+=len;
+ len=otf_subset_glyf(otf,iA,iA,glyphs);
+ if (len<0) {
+ assert(0);
+ return -1;
+ }
+ glyfSize+=len;
+ }
+ }
+ }
+
+ // second pass: calculate new glyf and loca
+ int locaSize=(otf->numGlyphs+1)*(otf->indexToLocFormat+1)*2;
+
+ char *new_loca=malloc(locaSize);
+ char *new_glyf=malloc(glyfSize);
+ if ( (!new_loca)||(!new_glyf) ) {
+ fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
+ assert(0);
+ free(new_loca);
+ free(new_glyf);
+ return -1;
+ }
+
+ int offset=0;
+ for (iA=0,b=0,c=1;iA<otf->numGlyphs;iA++,c<<=1) {
+ if (!c) {
+ b++;
+ c=1;
+ }
+
+ assert(offset%2==0);
+ // TODO? change format? if glyfSize<0x20000
+ if (otf->indexToLocFormat==0) {
+ set_USHORT(new_loca+iA*2,offset/2);
+ } else { // ==1
+ set_ULONG(new_loca+iA*4,offset);
+ }
+
+ if (glyphs[b]&c) {
+ const int len=otf_get_glyph(otf,iA);
+ assert(len>=0);
+ memcpy(new_glyf+offset,otf->gly,len);
+ offset+=len;
+ }
+ }
+ // last entry
+ if (otf->indexToLocFormat==0) {
+ set_USHORT(new_loca+otf->numGlyphs*2,offset/2);
+ } else { // ==1
+ set_ULONG(new_loca+otf->numGlyphs*4,offset);
+ }
+ assert(offset==glyfSize);
+
+ // determine new tables.
+ struct _OTF_WRITE otw[]={ // sorted
+ // TODO: cmap only required in non-CID context or always in CFF
+ {OTF_TAG('c','m','a','p'),otf_action_copy,otf,},
+ {OTF_TAG('c','v','t',' '),otf_action_copy,otf,},
+ {OTF_TAG('f','p','g','m'),otf_action_copy,otf,},
+ {OTF_TAG('g','l','y','f'),otf_action_replace,new_glyf,glyfSize},
+ {OTF_TAG('h','e','a','d'),otf_action_copy,otf,}, // _copy_head
+ {OTF_TAG('h','h','e','a'),otf_action_copy,otf,},
+ {OTF_TAG('h','m','t','x'),otf_action_copy,otf,},
+ {OTF_TAG('l','o','c','a'),otf_action_replace,new_loca,locaSize},
+ {OTF_TAG('m','a','x','p'),otf_action_copy,otf,},
+ {OTF_TAG('n','a','m','e'),otf_action_copy,otf,},
+ {OTF_TAG('p','r','e','p'),otf_action_copy,otf,},
+ // vhea vmtx (never used in PDF, but possible in PS>=3011)
+ {0,0,0,0}};
+
+ // and write them
+ int numTables=otf_intersect_tables(otf,otw);
+ int ret=otf_write_sfnt(otw,otf->version,numTables,output,context);
+
+ free(new_loca);
+ free(new_glyf);
+ return ret;
+
+ //TODO ? reduce cmap [to (1,0) ;-)]
+ //TODO (cmap for non-cid)
+}
+// }}}
+
+// TODO no subsetting actually done (for now)
+int otf_subset_cff(OTF_FILE *otf,BITSET glyphs,OUTPUT_FN output,void *context) // {{{ - returns number of bytes written
+{
+ assert(otf);
+ assert(output);
+
+// TODO char *new_cff=cff_subset(...);
+
+ // determine new tables.
+ struct _OTF_WRITE otw[]={
+ {OTF_TAG('C','F','F',' '),otf_action_copy,otf,},
+// {OTF_TAG('C','F','F',' '),otf_action_replace,new_glyf,glyfSize},
+ {OTF_TAG('c','m','a','p'),otf_action_copy,otf,},
+#if 0 // not actually needed!
+ {OTF_TAG('c','v','t',' '),otf_action_copy,otf,},
+ {OTF_TAG('f','p','g','m'),otf_action_copy,otf,},
+ {OTF_TAG('h','e','a','d'),otf_action_copy,otf,}, // _copy_head
+ {OTF_TAG('h','h','e','a'),otf_action_copy,otf,},
+ {OTF_TAG('h','m','t','x'),otf_action_copy,otf,},
+ {OTF_TAG('m','a','x','p'),otf_action_copy,otf,},
+ {OTF_TAG('n','a','m','e'),otf_action_copy,otf,},
+ {OTF_TAG('p','r','e','p'),otf_action_copy,otf,},
+#endif
+ {0,0,0,0}};
+
+ // and write them
+ int numTables=otf_intersect_tables(otf,otw);
+ int ret=otf_write_sfnt(otw,otf->version,numTables,output,context);
+
+// free(new_cff);
+ return ret;
+}
+// }}}
+
+//int copy_block(FILE *f,long pos,int length,OUTPUT_FN output,void *context); // copied bytes or -1 (also on premature EOF)
+
+static int copy_block(FILE *f,long pos,int length,OUTPUT_FN output,void *context) // {{{
+{
+ assert(f);
+ assert(output);
+
+ char buf[4096];
+ int iA,ret;
+
+ ret=fseek(f,pos,SEEK_SET);
+ if (ret==-1) {
+ fprintf(stderr,"Seek failed: %s\n", strerror(errno));
+ return -1;
+ }
+ ret=0;
+ while (length>4096) {
+ iA=fread(buf,1,4096,f);
+ if (iA<4096) {
+ return -1;
+ }
+ (*output)(buf,iA,context);
+ ret+=iA;
+ length-=iA;
+ };
+ iA=fread(buf,1,length,f);
+ if (iA<length) {
+ return -1;
+ }
+ (*output)(buf,iA,context);
+ ret+=iA;
+
+ return ret;
+}
+// }}}
+
+int otf_cff_extract(OTF_FILE *otf,OUTPUT_FN output,void *context) // {{{ - returns number of bytes written
+{
+ assert(otf);
+ assert(output);
+
+ int idx=otf_find_table(otf,OTF_TAG('C','F','F',' '));
+ if (idx==-1) {
+ return -1;
+ }
+ const OTF_DIRENT *table=otf->tables+idx;
+
+ return copy_block(otf->f,table->offset,table->length,output,context);
+}
+// }}}
+
+// CFF *otf_get_cff(); // not load, but create by "substream"-in ctor
+#if 0 // TODO elsewhere : char *cff_subset(...);
+ // first pass: include all required glyphs
+ bit_set(glyphs,0); // .notdef always required
+ int glyfSize=0;
+ for (iA=0,b=0,c=1;iA<otf->numGlyphs;iA++,c<<=1) {
+ if (!c) {
+ b++;
+ c=1;
+ }
+ if (glyphs[b]&c) {
+// TODO: cff_glyph
+ }
+ }
+
+ // second pass: calculate new glyf and loca
+ char *new_cff=malloc(cffSize);
+ if (!new_cff) {
+ fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
+ assert(0);
+ return -1;
+ }
+
+ int offset=0;
+ for (iA=0,b=0,c=1;iA<otf->numGlyphs;iA++,c<<=1) {
+ if (!c) {
+ b++;
+ c=1;
+ }
+ if (glyphs[b]&c) {
+//...
+ }
+ }
+ return new_cff;
+#endif
diff --git a/fontembed/test_analyze.c b/fontembed/test_analyze.c
new file mode 100644
index 000000000..3f42573d9
--- /dev/null
+++ b/fontembed/test_analyze.c
@@ -0,0 +1,234 @@
+#include "sfnt.h"
+#include "sfnt_int.h"
+#include "embed.h"
+#include "config.h"
+#include "embed_sfnt_int.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+enum { WEIGHT_THIN=100,
+ WEIGHT_EXTRALIGHT=200, WEIGHT_ULTRALIGHT=200,
+ WEIGHT_LIGHT=300,
+ WEIGHT_NORMAL=400, WEIGHT_REGULAR=400,
+ WEIGHT_MEDIUM=500,
+ WEIGHT_SEMIBOLD=600, // DEMI
+ WEIGHT_BOLD=700,
+ WEIGHT_EXTRABOLD=800, WEIGHT_ULTRABOLD=800,
+ WEIGHT_BLACK=900, WEIGHT_HEAVY=900 };
+
+void show_post(OTF_FILE *otf) // {{{
+{
+ assert(otf);
+ int len=0;
+ char *buf;
+
+ buf=otf_get_table(otf,OTF_TAG('p','o','s','t'),&len);
+ if (!buf) {
+ assert(len==-1);
+ printf("No post table\n");
+ return;
+ }
+ // TODO: check len
+ printf("POST: (%d bytes)\n"
+ " version: %08x\n"
+ " italicAngle: %d.%d\n"
+ " underlinePosition: %d\n"
+ " underlineThickness: %d\n"
+ " isFixedPitch: %d\n"
+ " vmType42: %d %d\n"
+ " vmType1: %d %d\n",len,
+ get_ULONG(buf),
+ get_LONG(buf+4)>>16,get_ULONG(buf+4)&0xffff,
+ get_SHORT(buf+8),
+ get_SHORT(buf+10),
+ get_ULONG(buf+12),
+ get_ULONG(buf+16),get_ULONG(buf+20),
+ get_ULONG(buf+24),get_ULONG(buf+38));
+ free(buf);
+}
+// }}}
+
+void show_name(OTF_FILE *otf) // {{{
+{
+ assert(otf);
+ int iA,len=0;
+ char *buf;
+
+ buf=otf_get_table(otf,OTF_TAG('n','a','m','e'),&len);
+ if (!buf) {
+ assert(len==-1);
+ printf("No name table\n");
+ return;
+ }
+ printf("NAME:\n");
+ int name_count=get_USHORT(buf+2);
+ const char *nstore=buf+get_USHORT(buf+4);
+ for (iA=0;iA<name_count;iA++) {
+ const char *nrec=buf+6+12*iA;
+ printf(" { platformID/encodingID/languageID/nameID: %d/%d/%d/%d\n"
+ " length: %d, offset: %d, data :",
+ get_USHORT(nrec),
+ get_USHORT(nrec+2),
+ get_USHORT(nrec+4),
+ get_USHORT(nrec+6),
+ get_USHORT(nrec+8),
+ get_USHORT(nrec+10));
+ if ( (get_USHORT(nrec)==0)||
+ ( (get_USHORT(nrec)==3) ) ) { // WCHAR
+ int nlen=get_USHORT(nrec+8);
+ int npos=get_USHORT(nrec+10);
+ for (;nlen>0;nlen-=2,npos+=2) {
+ if (nstore[npos]!=0x00) {
+ printf("?");
+ } else {
+ printf("%c",nstore[npos+1]);
+ }
+ }
+ printf(" }\n");
+ } else {
+ printf("%.*s }\n",
+ get_USHORT(nrec+8),nstore+get_USHORT(nrec+10));
+ }
+ }
+ free(buf);
+}
+// }}}
+
+void show_cmap(OTF_FILE *otf) // {{{
+{
+ assert(otf);
+ int iA,len=0;
+
+ char *cmap=otf_get_table(otf,OTF_TAG('c','m','a','p'),&len);
+ if (!cmap) {
+ assert(len==-1);
+ printf("No cmap table\n");
+ return;
+ }
+ printf("cmap:\n");
+ assert(get_USHORT(cmap)==0x0000); // version
+ const int numTables=get_USHORT(cmap+2);
+ printf(" numTables: %d\n",numTables);
+ for (iA=0;iA<numTables;iA++) {
+ const char *nrec=cmap+4+8*iA;
+ const char *ndata=cmap+get_ULONG(nrec+4);
+ assert(ndata>=cmap+4+8*numTables);
+ printf(" platformID/encodingID: %d/%d\n"
+ " offset: %d data (format: %d, length: %d, language: %d);\n",
+ get_USHORT(nrec),get_USHORT(nrec+2),
+ get_ULONG(nrec+4),
+ get_USHORT(ndata),get_USHORT(ndata+2),get_USHORT(ndata+4));
+ }
+ free(cmap);
+}
+// }}}
+
+void show_glyf(OTF_FILE *otf,int full) // {{{
+{
+ assert(otf);
+
+ // ensure >glyphOffsets and >gly is there
+ if ( (!otf->gly)||(!otf->glyphOffsets) ) {
+ if (otf_load_glyf(otf)!=0) {
+ assert(0);
+ return;
+ }
+ }
+
+ int iA;
+ int compGlyf=0,zeroGlyf=0;
+
+ // {{{ glyf
+ assert(otf->gly);
+ for (iA=0;iA<otf->numGlyphs;iA++) {
+ int len=otf_get_glyph(otf,iA);
+ if (len==0) {
+ zeroGlyf++;
+ } else if (get_SHORT(otf->gly)==-1) {
+ compGlyf++;
+ }
+ if (full) {
+ printf("%d(%d) ",get_SHORT(otf->gly),len);
+ }
+ }
+ if (full) {
+ printf("\n");
+ }
+ printf("numGlyf(nonnull): %d(%d), composites: %d\n",otf->numGlyphs,otf->numGlyphs-zeroGlyf,compGlyf);
+ // }}}
+}
+// }}}
+
+void show_hmtx(OTF_FILE *otf) // {{{
+{
+ assert(otf);
+ int iA;
+
+ otf_get_width(otf,0); // load table.
+ if (!otf->hmtx) {
+ printf("NOTE: no hmtx table!\n");
+ return;
+ }
+ printf("hmtx (%d):\n",otf->numberOfHMetrics);
+ for (iA=0;iA<otf->numberOfHMetrics;iA++) {
+ printf("(%d,%d) ",
+ get_USHORT(otf->hmtx+iA*4),
+ get_SHORT(otf->hmtx+iA*4+2));
+ }
+ printf(" (last is repeated for the remaining %d glyphs)\n",otf->numGlyphs-otf->numberOfHMetrics);
+}
+// }}}
+
+int main(int argc,char **argv)
+{
+ const char *fn=TESTFONT;
+ if (argc==2) {
+ fn=argv[1];
+ }
+ OTF_FILE *otf=otf_load(fn);
+ assert(otf);
+ if (otf->numTTC) {
+ printf("TTC has %d fonts, using %d\n",otf->numTTC,otf->useTTC);
+ }
+ if (otf->version==0x00010000) {
+ printf("Got TTF 1.0\n");
+ } else if (otf->version==OTF_TAG('O','T','T','O')) {
+ printf("Got OTF(CFF)\n");
+ } else if (otf->version==OTF_TAG('t','r','u','e')) {
+ printf("Got TTF (true)\n");
+ } else if (otf->version==OTF_TAG('t','y','p','1')) {
+ printf("Got SFNT(Type1)\n");
+ }
+
+ printf("Has %d tables\n",otf->numTables);
+
+ int iA;
+ for (iA=0;iA<otf->numTables;iA++) {
+ printf("%c%c%c%c %d @%d\n",OTF_UNTAG(otf->tables[iA].tag),otf->tables[iA].length,otf->tables[iA].offset);
+ }
+ printf("unitsPerEm: %d, indexToLocFormat: %d\n",
+ otf->unitsPerEm,otf->indexToLocFormat);
+ printf("num glyphs: %d\n",otf->numGlyphs);
+ otf_get_width(otf,0); // load table.
+ printf("numberOfHMetrics: %d\n",otf->numberOfHMetrics);
+
+ printf("Embedding rights: %x\n",emb_otf_get_rights(otf));
+
+ show_post(otf);
+
+ show_name(otf);
+
+ show_cmap(otf);
+ // printf("%d %d\n",otf_from_unicode(otf,'A'),0);
+
+ if (!(otf->flags&OTF_F_FMT_CFF)) {
+ show_glyf(otf,1);
+ }
+
+ show_hmtx(otf);
+
+ otf_close(otf);
+
+ return 0;
+}
diff --git a/fontembed/test_pdf.c b/fontembed/test_pdf.c
new file mode 100644
index 000000000..565fd59f8
--- /dev/null
+++ b/fontembed/test_pdf.c
@@ -0,0 +1,215 @@
+#include "embed.h"
+#include "config.h"
+#include "sfnt.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static void example_outfn(const char *buf,int len,void *context) // {{{
+{
+ FILE *f=(FILE *)context;
+ if (fwrite(buf,1,len,f)!=len) {
+ fprintf(stderr,"Short write: %m\n");
+ assert(0);
+ return;
+ }
+}
+// }}}
+
+#define OBJ \
+ xref[xrefpos++]=ftell(f); \
+ fprintf(f,"%d 0 obj\n",xrefpos);
+
+#define ENDOBJ \
+ fprintf(f,"endobj\n");
+
+#define STREAMDICT \
+ OBJ; \
+ fprintf(f,"<<\n" \
+ " /Length %d 0 R\n",xrefpos+1);
+
+#define STREAMDATA \
+ fprintf(f,">>\n" \
+ "stream\n"); \
+ stream_len=-ftell(f);
+
+#define STREAM \
+ STREAMDICT \
+ STREAMDATA
+
+#define ENDSTREAM \
+ stream_len+=ftell(f); \
+ fprintf(f,"endstream\n" \
+ "endobj\n"); \
+ OBJ; \
+ fprintf(f,"%d\n",stream_len); \
+ ENDOBJ;
+
+static inline void write_string(FILE *f,EMB_PARAMS *emb,const char *str) // {{{
+{
+ assert(f);
+ assert(emb);
+ int iA;
+
+ if (emb->plan&EMB_A_MULTIBYTE) {
+ putc('<',f);
+ for (iA=0;str[iA];iA++) {
+ const unsigned short gid=emb_get(emb,(unsigned char)str[iA]);
+ fprintf(f,"%04x",gid);
+ }
+ putc('>',f);
+ } else {
+ putc('(',f);
+ for (iA=0;str[iA];iA++) {
+ emb_get(emb,(unsigned char)str[iA]);
+ }
+ fprintf(f,"%s",str); // TODO
+ putc(')',f);
+ }
+}
+// }}}
+
+int main(int argc,char **argv)
+{
+ const char *fn=TESTFONT;
+ if (argc==2) {
+ fn=argv[1];
+ }
+ OTF_FILE *otf=otf_load(fn);
+ assert(otf);
+ FONTFILE *ff=fontfile_open_sfnt(otf);
+ EMB_PARAMS *emb=emb_new(ff,
+ EMB_DEST_PDF16,
+ EMB_C_FORCE_MULTIBYTE|
+ EMB_C_TAKE_FONTFILE);
+
+ FILE *f=fopen("test.pdf","w");
+ assert(f);
+ int xref[100],xrefpos=3;
+ int stream_len;
+
+ fprintf(f,"%%PDF-1.3\n");
+ // content
+ STREAM;
+ fprintf(f,"BT\n" // content
+ " 100 100 Td\n"
+ " /F1 10 Tf\n");
+ write_string(f,emb,"Hallo");
+ fprintf(f," Tj\n"
+ "ET\n");
+ ENDSTREAM;
+
+ emb_get(emb,'a');
+
+ // {{{ do font
+ EMB_PDF_FONTDESCR *fdes=emb_pdf_fontdescr(emb);
+ assert(fdes);
+ EMB_PDF_FONTWIDTHS *fwid=emb_pdf_fontwidths(emb);
+ assert(fwid);
+
+ STREAMDICT;
+ int ff_ref=xrefpos;
+ if (emb_pdf_get_fontfile_subtype(emb)) {
+ fprintf(f," /Subtype /%s\n",
+ emb_pdf_get_fontfile_subtype(emb));
+ }
+ if (emb->outtype==EMB_FMT_T1) {
+ fprintf(f," /Length1 ?\n"
+ " /Length2 ?\n"
+ " /Length3 ?\n");
+ } else if (emb->outtype==EMB_FMT_TTF) {
+ fprintf(f," /Length1 %d 0 R\n",xrefpos+2);
+ }
+ STREAMDATA;
+ const int outlen=emb_embed(emb,example_outfn,f);
+ ENDSTREAM;
+ if (emb->outtype==EMB_FMT_TTF) {
+ OBJ;
+ fprintf(f,"%d\n",outlen);
+ ENDOBJ;
+ }
+
+ OBJ;
+ const int fd_ref=xrefpos;
+ char *res=emb_pdf_simple_fontdescr(emb,fdes,ff_ref);
+ assert(res);
+ fputs(res,f);
+ free(res);
+ ENDOBJ;
+
+ OBJ;
+ int f_ref=xrefpos;
+ res=emb_pdf_simple_font(emb,fdes,fwid,fd_ref);
+ assert(res);
+ fputs(res,f);
+ free(res);
+ ENDOBJ;
+
+ if (emb->plan&EMB_A_MULTIBYTE) {
+ OBJ;
+ res=emb_pdf_simple_cidfont(emb,fdes->fontname,f_ref);
+ f_ref=xrefpos;
+ assert(res);
+ fputs(res,f);
+ free(res);
+ ENDOBJ;
+ }
+
+ free(fdes);
+ free(fwid);
+ // }}}
+
+ int iA;
+
+ xref[2]=ftell(f);
+ fprintf(f,"3 0 obj\n"
+ "<</Type/Page\n"
+ " /Parent 2 0 R\n"
+ " /MediaBox [0 0 595 842]\n"
+ " /Contents 4 0 R\n"
+ " /Resources <<\n"
+ " /Font <<\n"
+ " /F1 %d 0 R\n"
+ " >>\n"
+ " >>\n"
+ ">>\n"
+ "endobj\n",
+ f_ref);
+ xref[1]=ftell(f);
+ fprintf(f,"2 0 obj\n"
+ "<</Type/Pages\n"
+ " /Count 1\n"
+ " /Kids [3 0 R]"
+ ">>\n"
+ "endobj\n");
+ xref[0]=ftell(f);
+ fprintf(f,"1 0 obj\n"
+ "<</Type/Catalog\n"
+ " /Pages 2 0 R\n"
+ ">>\n"
+ "endobj\n");
+ // {{{ pdf trailer
+ int xref_start=ftell(f);
+ fprintf(f,"xref\n"
+ "0 %d\n"
+ "%010d 65535 f \n",
+ xrefpos+1,0);
+ for (iA=0;iA<xrefpos;iA++) {
+ fprintf(f,"%010d 00000 n \n",xref[iA]);
+ }
+ fprintf(f,"trailer\n"
+ "<<\n"
+ " /Size %d\n"
+ " /Root 1 0 R\n"
+ ">>\n"
+ "startxref\n"
+ "%d\n"
+ "%%%%EOF\n",
+ xrefpos+1,xref_start);
+ // }}}
+ fclose(f);
+
+ emb_close(emb);
+
+ return 0;
+}
diff --git a/fontembed/test_ps.c b/fontembed/test_ps.c
new file mode 100644
index 000000000..1f8c2bb79
--- /dev/null
+++ b/fontembed/test_ps.c
@@ -0,0 +1,89 @@
+#include "embed.h"
+#include "config.h"
+#include "sfnt.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+const char *emb_otf_get_fontname(OTF_FILE *otf); // TODO
+
+static void example_outfn(const char *buf,int len,void *context) // {{{
+{
+ FILE *f=(FILE *)context;
+ if (fwrite(buf,1,len,f)!=len) {
+ fprintf(stderr,"Short write: %m\n");
+ assert(0);
+ return;
+ }
+}
+// }}}
+
+static inline void write_string(FILE *f,EMB_PARAMS *emb,const char *str) // {{{
+{
+ assert(f);
+ assert(emb);
+ int iA;
+
+ if (emb->plan&EMB_A_MULTIBYTE) {
+ putc('<',f);
+ for (iA=0;str[iA];iA++) {
+ const unsigned short gid=emb_get(emb,(unsigned char)str[iA]);
+ fprintf(f,"%04x",gid);
+ }
+ putc('>',f);
+ } else {
+ putc('(',f);
+ for (iA=0;str[iA];iA++) {
+ emb_get(emb,(unsigned char)str[iA]);
+ }
+ fprintf(f,"%s",str); // TODO
+ putc(')',f);
+ }
+}
+// }}}
+
+int main(int argc,char **argv)
+{
+ const char *fn=TESTFONT;
+ if (argc==2) {
+ fn=argv[1];
+ }
+ OTF_FILE *otf=otf_load(fn);
+ assert(otf);
+ FONTFILE *ff=fontfile_open_sfnt(otf);
+ EMB_PARAMS *emb=emb_new(ff,
+ EMB_DEST_PS,
+// EMB_C_FORCE_MULTIBYTE| // not yet...
+ EMB_C_TAKE_FONTFILE);
+
+ FILE *f=fopen("test.ps","w");
+ assert(f);
+
+ fprintf(f,"%%!PS-Adobe-2.0\n");
+
+ char *str="Hallo";
+
+ emb_get(emb,'a');
+
+ int iA;
+ for (iA=0;str[iA];iA++) {
+ emb_get(emb,(unsigned char)str[iA]);
+ }
+
+ emb_embed(emb,example_outfn,f);
+
+ // content
+ fprintf(f," 100 100 moveto\n" // content
+ " /%s findfont 10 scalefont setfont\n",emb_otf_get_fontname(emb->font->sfnt));
+ write_string(f,emb,"Hallo");
+// Note that write_string sets subset bits, but it's too late
+ fprintf(f," show\n"
+ "showpage\n");
+
+ fprintf(f,"%%%%EOF\n");
+ fclose(f);
+
+ emb_close(emb);
+
+ return 0;
+}
diff --git a/install-sh b/install-sh
new file mode 100755
index 000000000..182258efd
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,220 @@
+#!/bin/sh
+#
+# Install a program, script, or datafile.
+#
+# Copyright 2008-2009 by Apple Inc.
+#
+# This script is not compatible with BSD (or any other) install program, as it
+# allows owner and group changes to fail with a warning and makes sure that the
+# destination directory permissions are as specified - BSD install and the
+# original X11 install script did not change permissions of existing
+# directories. It also does not support the transform options since CUPS does
+# not use them...
+#
+# Original script from X11R5 (mit/util/scripts/install.sh)
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+
+# set DOITPROG to echo to test this script
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+# Force umask to 022...
+umask 022
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c)
+ instcmd="$cpprog"
+ shift
+ continue
+ ;;
+
+ -d)
+ dir_arg=true
+ shift
+ continue
+ ;;
+
+ -m)
+ chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue
+ ;;
+
+ -o)
+ chowncmd="$chownprog $2"
+ shift
+ shift
+ continue
+ ;;
+
+ -g)
+ chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue
+ ;;
+
+ -s)
+ stripcmd="$stripprog"
+ shift
+ continue
+ ;;
+
+ *)
+ if [ x"$src" = x ]; then
+ src="$1"
+ else
+ dst="$1"
+ fi
+ shift
+ continue
+ ;;
+ esac
+done
+
+if [ x"$src" = x ]; then
+ echo "install-sh: No input file specified"
+ exit 1
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst="$src"
+ src=""
+
+ if [ -d "$dst" ]; then
+ instcmd=:
+ else
+ instcmd=$mkdirprog
+ fi
+else
+ # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if [ ! -f "$src" -a ! -d "$src" ]; then
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]; then
+ echo "install: No destination specified"
+ exit 1
+ fi
+
+ # If destination is a directory, append the input filename.
+ if [ -d "$dst" ]; then
+ dst="$dst/`basename $src`"
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir="`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`"
+
+# Make sure that the destination directory exists.
+# This part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+ defaultIFS='
+ '
+ IFS="${IFS-${defaultIFS}}"
+
+ oIFS="${IFS}"
+ # Some sh's can't handle IFS=/ for some reason.
+ IFS='%'
+ set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+ IFS="${oIFS}"
+
+ pathcomp=''
+
+ while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ]; then $doit $mkdirprog "${pathcomp}"; fi
+
+ pathcomp="${pathcomp}/"
+ done
+fi
+
+if [ x"$dir_arg" != x ]; then
+ # Make a directory...
+ $doit $instcmd $dst || exit 1
+
+ # Allow chown/chgrp to fail, but log a warning
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst || echo "warning: Unable to change owner of $dst!"; fi
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst || echo "warning: Unable to change group of $dst!"; fi
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst || exit 1; fi
+else
+ # Install a file...
+ dstfile="`basename $dst`"
+
+ # Check the destination file - for libraries just use the "-x" option
+ # to strip...
+ case "$dstfile" in
+ *.a | *.dylib | *.sl | *.sl.* | *.so | *.so.*)
+ stripopt="-x"
+ ;;
+ *)
+ stripopt=""
+ ;;
+ esac
+
+ # Make a temp file name in the proper directory.
+ dsttmp="$dstdir/#inst.$$#"
+
+ # Move or copy the file name to the temp name
+ $doit $instcmd $src $dsttmp || exit 1
+
+ # Update permissions and strip as needed, then move to the final name.
+ # If the chmod, strip, rm, or mv commands fail, remove the installed
+ # file...
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $stripopt "$dsttmp" || echo "warning: Unable to strip $dst!"; fi
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp" || echo "warning: Unable to change owner of $dst!"; fi
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp" || echo "warning: Unable to change group of $dst!"; fi
+
+ trap "rm -f ${dsttmp}" 0 &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; fi &&
+ $doit $rmcmd -f "$dstdir/$dstfile" &&
+ $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+fi
+
+exit 0
diff --git a/libcupsfilters.pc.in b/libcupsfilters.pc.in
new file mode 100644
index 000000000..8ff99fc24
--- /dev/null
+++ b/libcupsfilters.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libcupsfilters
+Description: Library for reading and writing cups filters
+Version: @VERSION@
+
+Libs: -L${libdir} -lcupsfilters
+Libs.private: @CUPS_LIBS@ @LIBJPEG_LIBS@ @LIBPNG_LIBS@ @LIBTIFF_LIBS@
+Cflags: -I${includedir}/cupsfilters
diff --git a/libfontembed.pc.in b/libfontembed.pc.in
new file mode 100644
index 000000000..2e7362841
--- /dev/null
+++ b/libfontembed.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libfontembed
+Description: Library for de/embedding fonts to pdf
+Version: @VERSION@
+
+Libs: -L${libdir} -lfontembed
+Cflags: -I${includedir}/fontembed
diff --git a/ltmain.sh b/ltmain.sh
new file mode 100644
index 000000000..a736cf994
--- /dev/null
+++ b/ltmain.sh
@@ -0,0 +1,11156 @@
+#! /bin/sh
+## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
+## by inline-source v2014-01-03.01
+
+# libtool (GNU libtool) 2.4.6
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996-2015 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.
+
+# GNU Libtool 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 2 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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/>.
+
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION="2.4.6 Debian-2.4.6-2"
+package_revision=2.4.6
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# Run './libtool --help' for help with using this script from the
+# command line.
+
+
+## ------------------------------- ##
+## User overridable command paths. ##
+## ------------------------------- ##
+
+# After configure completes, it has a better idea of some of the
+# shell tools we need than the defaults used by the functions shared
+# with bootstrap, so set those here where they can still be over-
+# ridden by the user, but otherwise take precedence.
+
+: ${AUTOCONF="autoconf"}
+: ${AUTOMAKE="automake"}
+
+
+## -------------------------- ##
+## Source external libraries. ##
+## -------------------------- ##
+
+# Much of our low-level functionality needs to be sourced from external
+# libraries, which are installed to $pkgauxdir.
+
+# Set a version string for this script.
+scriptversion=2015-01-20.17; # UTC
+
+# General shell script boiler plate, and helper functions.
+# Written by Gary V. Vaughan, 2004
+
+# Copyright (C) 2004-2015 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.
+
+# As a special exception to the GNU General Public License, if you distribute
+# this file as part of a program or library that is built using GNU Libtool,
+# you may include this file under the same distribution terms that you use
+# for the rest of that program.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNES 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/>.
+
+# Please report bugs or propose patches to gary@gnu.org.
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# Evaluate this file near the top of your script to gain access to
+# the functions and variables defined here:
+#
+# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh
+#
+# If you need to override any of the default environment variable
+# settings, do that before evaluating this file.
+
+
+## -------------------- ##
+## Shell normalisation. ##
+## -------------------- ##
+
+# Some shells need a little help to be as Bourne compatible as possible.
+# Before doing anything else, make sure all that help has been provided!
+
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac
+fi
+
+# NLS nuisances: We save the old values in case they are required later.
+_G_user_locale=
+_G_safe_locale=
+for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+ eval "if test set = \"\${$_G_var+set}\"; then
+ save_$_G_var=\$$_G_var
+ $_G_var=C
+ export $_G_var
+ _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\"
+ _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\"
+ fi"
+done
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Make sure IFS has a sensible default
+sp=' '
+nl='
+'
+IFS="$sp $nl"
+
+# There are apparently some retarded systems that use ';' as a PATH separator!
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+
+## ------------------------- ##
+## Locate command utilities. ##
+## ------------------------- ##
+
+
+# func_executable_p FILE
+# ----------------------
+# Check that FILE is an executable regular file.
+func_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+}
+
+
+# func_path_progs PROGS_LIST CHECK_FUNC [PATH]
+# --------------------------------------------
+# Search for either a program that responds to --version with output
+# containing "GNU", or else returned by CHECK_FUNC otherwise, by
+# trying all the directories in PATH with each of the elements of
+# PROGS_LIST.
+#
+# CHECK_FUNC should accept the path to a candidate program, and
+# set $func_check_prog_result if it truncates its output less than
+# $_G_path_prog_max characters.
+func_path_progs ()
+{
+ _G_progs_list=$1
+ _G_check_func=$2
+ _G_PATH=${3-"$PATH"}
+
+ _G_path_prog_max=0
+ _G_path_prog_found=false
+ _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:}
+ for _G_dir in $_G_PATH; do
+ IFS=$_G_save_IFS
+ test -z "$_G_dir" && _G_dir=.
+ for _G_prog_name in $_G_progs_list; do
+ for _exeext in '' .EXE; do
+ _G_path_prog=$_G_dir/$_G_prog_name$_exeext
+ func_executable_p "$_G_path_prog" || continue
+ case `"$_G_path_prog" --version 2>&1` in
+ *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;;
+ *) $_G_check_func $_G_path_prog
+ func_path_progs_result=$func_check_prog_result
+ ;;
+ esac
+ $_G_path_prog_found && break 3
+ done
+ done
+ done
+ IFS=$_G_save_IFS
+ test -z "$func_path_progs_result" && {
+ echo "no acceptable sed could be found in \$PATH" >&2
+ exit 1
+ }
+}
+
+
+# We want to be able to use the functions in this file before configure
+# has figured out where the best binaries are kept, which means we have
+# to search for them ourselves - except when the results are already set
+# where we skip the searches.
+
+# Unless the user overrides by setting SED, search the path for either GNU
+# sed, or the sed that truncates its output the least.
+test -z "$SED" && {
+ _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for _G_i in 1 2 3 4 5 6 7; do
+ _G_sed_script=$_G_sed_script$nl$_G_sed_script
+ done
+ echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed
+ _G_sed_script=
+
+ func_check_prog_sed ()
+ {
+ _G_path_prog=$1
+
+ _G_count=0
+ printf 0123456789 >conftest.in
+ while :
+ do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo '' >> conftest.nl
+ "$_G_path_prog" -f conftest.sed <conftest.nl >conftest.out 2>/dev/null || break
+ diff conftest.out conftest.nl >/dev/null 2>&1 || break
+ _G_count=`expr $_G_count + 1`
+ if test "$_G_count" -gt "$_G_path_prog_max"; then
+ # Best one so far, save it but keep looking for a better one
+ func_check_prog_result=$_G_path_prog
+ _G_path_prog_max=$_G_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test 10 -lt "$_G_count" && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out
+ }
+
+ func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin
+ rm -f conftest.sed
+ SED=$func_path_progs_result
+}
+
+
+# Unless the user overrides by setting GREP, search the path for either GNU
+# grep, or the grep that truncates its output the least.
+test -z "$GREP" && {
+ func_check_prog_grep ()
+ {
+ _G_path_prog=$1
+
+ _G_count=0
+ _G_path_prog_max=0
+ printf 0123456789 >conftest.in
+ while :
+ do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo 'GREP' >> conftest.nl
+ "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' <conftest.nl >conftest.out 2>/dev/null || break
+ diff conftest.out conftest.nl >/dev/null 2>&1 || break
+ _G_count=`expr $_G_count + 1`
+ if test "$_G_count" -gt "$_G_path_prog_max"; then
+ # Best one so far, save it but keep looking for a better one
+ func_check_prog_result=$_G_path_prog
+ _G_path_prog_max=$_G_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test 10 -lt "$_G_count" && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out
+ }
+
+ func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin
+ GREP=$func_path_progs_result
+}
+
+
+## ------------------------------- ##
+## User overridable command paths. ##
+## ------------------------------- ##
+
+# All uppercase variable names are used for environment variables. These
+# variables can be overridden by the user before calling a script that
+# uses them if a suitable command of that name is not already available
+# in the command search PATH.
+
+: ${CP="cp -f"}
+: ${ECHO="printf %s\n"}
+: ${EGREP="$GREP -E"}
+: ${FGREP="$GREP -F"}
+: ${LN_S="ln -s"}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+
+
+## -------------------- ##
+## Useful sed snippets. ##
+## -------------------- ##
+
+sed_dirname='s|/[^/]*$||'
+sed_basename='s|^.*/||'
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s|\([`"$\\]\)|\\\1|g'
+
+# Same as above, but do not quote variable references.
+sed_double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g'
+
+# Sed substitution that converts a w32 file name or path
+# that contains forward slashes, into one that contains
+# (escaped) backslashes. A very naive implementation.
+sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-'\' parameter expansions in output of sed_double_quote_subst that
+# were '\'-ed in input to the same. If an odd number of '\' preceded a
+# '$' in input to sed_double_quote_subst, that '$' was protected from
+# expansion. Since each input '\' is now two '\'s, look for any number
+# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'.
+_G_bs='\\'
+_G_bs2='\\\\'
+_G_bs4='\\\\\\\\'
+_G_dollar='\$'
+sed_double_backslash="\
+ s/$_G_bs4/&\\
+/g
+ s/^$_G_bs2$_G_dollar/$_G_bs&/
+ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g
+ s/\n//g"
+
+
+## ----------------- ##
+## Global variables. ##
+## ----------------- ##
+
+# Except for the global variables explicitly listed below, the following
+# functions in the '^func_' namespace, and the '^require_' namespace
+# variables initialised in the 'Resource management' section, sourcing
+# this file will not pollute your global namespace with anything
+# else. There's no portable way to scope variables in Bourne shell
+# though, so actually running these functions will sometimes place
+# results into a variable named after the function, and often use
+# temporary variables in the '^_G_' namespace. If you are careful to
+# avoid using those namespaces casually in your sourcing script, things
+# should continue to work as you expect. And, of course, you can freely
+# overwrite any of the functions or variables defined here before
+# calling anything to customize them.
+
+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.
+
+# Allow overriding, eg assuming that you follow the convention of
+# putting '$debug_cmd' at the start of all your functions, you can get
+# bash to show function call trace with:
+#
+# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
+debug_cmd=${debug_cmd-":"}
+exit_cmd=:
+
+# By convention, finish your script with:
+#
+# exit $exit_status
+#
+# so that you can set exit_status to non-zero if you want to indicate
+# something went wrong during execution without actually bailing out at
+# the point of failure.
+exit_status=$EXIT_SUCCESS
+
+# 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 "$sed_basename"`
+
+# Make sure we have an absolute progpath for reexecution:
+case $progpath in
+ [\\/]*|[A-Za-z]:\\*) ;;
+ *[\\/]*)
+ progdir=`$ECHO "$progpath" |$SED "$sed_dirname"`
+ progdir=`cd "$progdir" && pwd`
+ progpath=$progdir/$progname
+ ;;
+ *)
+ _G_IFS=$IFS
+ IFS=${PATH_SEPARATOR-:}
+ for progdir in $PATH; do
+ IFS=$_G_IFS
+ test -x "$progdir/$progname" && break
+ done
+ IFS=$_G_IFS
+ test -n "$progdir" || progdir=`pwd`
+ progpath=$progdir/$progname
+ ;;
+esac
+
+
+## ----------------- ##
+## Standard options. ##
+## ----------------- ##
+
+# The following options affect the operation of the functions defined
+# below, and should be set appropriately depending on run-time para-
+# meters passed on the command line.
+
+opt_dry_run=false
+opt_quiet=false
+opt_verbose=false
+
+# Categories 'all' and 'none' are always available. Append any others
+# you will pass as the first argument to func_warning from your own
+# code.
+warning_categories=
+
+# By default, display warnings according to 'opt_warning_types'. Set
+# 'warning_func' to ':' to elide all warnings, or func_fatal_error to
+# treat the next displayed warning as a fatal error.
+warning_func=func_warn_and_continue
+
+# Set to 'all' to display all warnings, 'none' to suppress all
+# warnings, or a space delimited list of some subset of
+# 'warning_categories' to display only the listed warnings.
+opt_warning_types=all
+
+
+## -------------------- ##
+## 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. Call them using their associated
+# 'require_*' variable to ensure that they are executed, at most, once.
+#
+# It's entirely deliberate that calling these functions can set
+# variables that don't obey the namespace limitations obeyed by the rest
+# of this file, in order that that they be as useful as possible to
+# callers.
+
+
+# require_term_colors
+# -------------------
+# Allow display of bold text on terminals that support it.
+require_term_colors=func_require_term_colors
+func_require_term_colors ()
+{
+ $debug_cmd
+
+ test -t 1 && {
+ # COLORTERM and USE_ANSI_COLORS environment variables take
+ # precedence, because most terminfo databases neglect to describe
+ # whether color sequences are supported.
+ test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"}
+
+ if test 1 = "$USE_ANSI_COLORS"; then
+ # Standard ANSI escape sequences
+ tc_reset=''
+ tc_bold=''; tc_standout=''
+ tc_red=''; tc_green=''
+ tc_blue=''; tc_cyan=''
+ else
+ # Otherwise trust the terminfo database after all.
+ test -n "`tput sgr0 2>/dev/null`" && {
+ tc_reset=`tput sgr0`
+ test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold`
+ tc_standout=$tc_bold
+ test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso`
+ test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1`
+ test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2`
+ test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4`
+ test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5`
+ }
+ fi
+ }
+
+ require_term_colors=:
+}
+
+
+## ----------------- ##
+## Function library. ##
+## ----------------- ##
+
+# This section contains a variety of useful functions to call in your
+# scripts. Take note of the portable wrappers for features provided by
+# some modern shells, which will fall back to slower equivalents on
+# less featureful shells.
+
+
+# func_append VAR VALUE
+# ---------------------
+# Append VALUE onto the existing contents of VAR.
+
+ # We should try to minimise forks, especially on Windows where they are
+ # unreasonably slow, so skip the feature probes when bash or zsh are
+ # being used:
+ if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then
+ : ${_G_HAVE_ARITH_OP="yes"}
+ : ${_G_HAVE_XSI_OPS="yes"}
+ # The += operator was introduced in bash 3.1
+ case $BASH_VERSION in
+ [12].* | 3.0 | 3.0*) ;;
+ *)
+ : ${_G_HAVE_PLUSEQ_OP="yes"}
+ ;;
+ esac
+ fi
+
+ # _G_HAVE_PLUSEQ_OP
+ # Can be empty, in which case the shell is probed, "yes" if += is
+ # useable or anything else if it does not work.
+ test -z "$_G_HAVE_PLUSEQ_OP" \
+ && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \
+ && _G_HAVE_PLUSEQ_OP=yes
+
+if test yes = "$_G_HAVE_PLUSEQ_OP"
+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_append_quoted VAR VALUE
+# ----------------------------
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+if test yes = "$_G_HAVE_PLUSEQ_OP"; then
+ eval 'func_append_quoted ()
+ {
+ $debug_cmd
+
+ func_quote_for_eval "$2"
+ eval "$1+=\\ \$func_quote_for_eval_result"
+ }'
+else
+ func_append_quoted ()
+ {
+ $debug_cmd
+
+ func_quote_for_eval "$2"
+ eval "$1=\$$1\\ \$func_quote_for_eval_result"
+ }
+fi
+
+
+# func_append_uniq 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_uniq 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_uniq ()
+{
+ $debug_cmd
+
+ eval _G_current_value='`$ECHO $'$1'`'
+ _G_delim=`expr "$2" : '\(.\)'`
+
+ case $_G_delim$_G_current_value$_G_delim in
+ *"$2$_G_delim"*) ;;
+ *) func_append "$@" ;;
+ esac
+}
+
+
+# func_arith TERM...
+# ------------------
+# Set func_arith_result to the result of evaluating TERMs.
+ test -z "$_G_HAVE_ARITH_OP" \
+ && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \
+ && _G_HAVE_ARITH_OP=yes
+
+if test yes = "$_G_HAVE_ARITH_OP"; then
+ eval 'func_arith ()
+ {
+ $debug_cmd
+
+ func_arith_result=$(( $* ))
+ }'
+else
+ func_arith ()
+ {
+ $debug_cmd
+
+ func_arith_result=`expr "$@"`
+ }
+fi
+
+
+# func_basename FILE
+# ------------------
+# Set func_basename_result to FILE with everything up to and including
+# the last / stripped.
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ # If this shell supports suffix pattern removal, then use it to avoid
+ # forking. Hide the definitions single quotes in case the shell chokes
+ # on unsupported syntax...
+ _b='func_basename_result=${1##*/}'
+ _d='case $1 in
+ */*) func_dirname_result=${1%/*}$2 ;;
+ * ) func_dirname_result=$3 ;;
+ esac'
+
+else
+ # ...otherwise fall back to using sed.
+ _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`'
+ _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"`
+ if test "X$func_dirname_result" = "X$1"; then
+ func_dirname_result=$3
+ else
+ func_append func_dirname_result "$2"
+ fi'
+fi
+
+eval 'func_basename ()
+{
+ $debug_cmd
+
+ '"$_b"'
+}'
+
+
+# func_dirname FILE APPEND NONDIR_REPLACEMENT
+# -------------------------------------------
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+eval 'func_dirname ()
+{
+ $debug_cmd
+
+ '"$_d"'
+}'
+
+
+# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT
+# --------------------------------------------------------
+# Perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# For efficiency, we do not delegate to the functions above but instead
+# duplicate the functionality here.
+eval 'func_dirname_and_basename ()
+{
+ $debug_cmd
+
+ '"$_b"'
+ '"$_d"'
+}'
+
+
+# func_echo ARG...
+# ----------------
+# Echo program name prefixed message.
+func_echo ()
+{
+ $debug_cmd
+
+ _G_message=$*
+
+ func_echo_IFS=$IFS
+ IFS=$nl
+ for _G_line in $_G_message; do
+ IFS=$func_echo_IFS
+ $ECHO "$progname: $_G_line"
+ done
+ IFS=$func_echo_IFS
+}
+
+
+# func_echo_all ARG...
+# --------------------
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+
+# func_echo_infix_1 INFIX ARG...
+# ------------------------------
+# Echo program name, followed by INFIX on the first line, with any
+# additional lines not showing INFIX.
+func_echo_infix_1 ()
+{
+ $debug_cmd
+
+ $require_term_colors
+
+ _G_infix=$1; shift
+ _G_indent=$_G_infix
+ _G_prefix="$progname: $_G_infix: "
+ _G_message=$*
+
+ # Strip color escape sequences before counting printable length
+ for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan"
+ do
+ test -n "$_G_tc" && {
+ _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"`
+ _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"`
+ }
+ done
+ _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes
+
+ func_echo_infix_1_IFS=$IFS
+ IFS=$nl
+ for _G_line in $_G_message; do
+ IFS=$func_echo_infix_1_IFS
+ $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2
+ _G_prefix=$_G_indent
+ done
+ IFS=$func_echo_infix_1_IFS
+}
+
+
+# func_error ARG...
+# -----------------
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+ $debug_cmd
+
+ $require_term_colors
+
+ func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2
+}
+
+
+# func_fatal_error ARG...
+# -----------------------
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+ $debug_cmd
+
+ func_error "$*"
+ exit $EXIT_FAILURE
+}
+
+
+# func_grep EXPRESSION FILENAME
+# -----------------------------
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+ $debug_cmd
+
+ $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_len STRING
+# ---------------
+# Set func_len_result to the length of STRING. STRING may not
+# start with a hyphen.
+ test -z "$_G_HAVE_XSI_OPS" \
+ && (eval 'x=a/b/c;
+ test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
+ && _G_HAVE_XSI_OPS=yes
+
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ eval 'func_len ()
+ {
+ $debug_cmd
+
+ func_len_result=${#1}
+ }'
+else
+ func_len ()
+ {
+ $debug_cmd
+
+ func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+ }
+fi
+
+
+# func_mkdir_p DIRECTORY-PATH
+# ---------------------------
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+ $debug_cmd
+
+ _G_directory_path=$1
+ _G_dir_list=
+
+ if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then
+
+ # Protect directory names starting with '-'
+ case $_G_directory_path in
+ -*) _G_directory_path=./$_G_directory_path ;;
+ esac
+
+ # While some portion of DIR does not yet exist...
+ while test ! -d "$_G_directory_path"; do
+ # ...make a list in topmost first order. Use a colon delimited
+ # list incase some portion of path contains whitespace.
+ _G_dir_list=$_G_directory_path:$_G_dir_list
+
+ # If the last portion added has no slash in it, the list is done
+ case $_G_directory_path in */*) ;; *) break ;; esac
+
+ # ...otherwise throw away the child directory and loop
+ _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"`
+ done
+ _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'`
+
+ func_mkdir_p_IFS=$IFS; IFS=:
+ for _G_dir in $_G_dir_list; do
+ IFS=$func_mkdir_p_IFS
+ # mkdir can fail with a 'File exist' error if two processes
+ # try to create one of the directories concurrently. Don't
+ # stop in that case!
+ $MKDIR "$_G_dir" 2>/dev/null || :
+ done
+ IFS=$func_mkdir_p_IFS
+
+ # Bail out if we (or some other process) failed to create a directory.
+ test -d "$_G_directory_path" || \
+ func_fatal_error "Failed to create '$1'"
+ fi
+}
+
+
+# func_mktempdir [BASENAME]
+# -------------------------
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible. If
+# given, BASENAME is the basename for that directory.
+func_mktempdir ()
+{
+ $debug_cmd
+
+ _G_template=${TMPDIR-/tmp}/${1-$progname}
+
+ if test : = "$opt_dry_run"; then
+ # Return a directory name, but don't create it in dry-run mode
+ _G_tmpdir=$_G_template-$$
+ else
+
+ # If mktemp works, use that first and foremost
+ _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null`
+
+ if test ! -d "$_G_tmpdir"; then
+ # Failing that, at least try and use $RANDOM to avoid a race
+ _G_tmpdir=$_G_template-${RANDOM-0}$$
+
+ func_mktempdir_umask=`umask`
+ umask 0077
+ $MKDIR "$_G_tmpdir"
+ umask $func_mktempdir_umask
+ fi
+
+ # If we're not in dry-run mode, bomb out on failure
+ test -d "$_G_tmpdir" || \
+ func_fatal_error "cannot create temporary directory '$_G_tmpdir'"
+ fi
+
+ $ECHO "$_G_tmpdir"
+}
+
+
+# func_normal_abspath PATH
+# ------------------------
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+func_normal_abspath ()
+{
+ $debug_cmd
+
+ # These SED scripts presuppose an absolute path with a trailing slash.
+ _G_pathcar='s|^/\([^/]*\).*$|\1|'
+ _G_pathcdr='s|^/[^/]*||'
+ _G_removedotparts=':dotsl
+ s|/\./|/|g
+ t dotsl
+ s|/\.$|/|'
+ _G_collapseslashes='s|/\{1,\}|/|g'
+ _G_finalslash='s|/*$|/|'
+
+ # Start from root dir and reassemble the path.
+ func_normal_abspath_result=
+ func_normal_abspath_tpath=$1
+ func_normal_abspath_altnamespace=
+ case $func_normal_abspath_tpath in
+ "")
+ # Empty path, that just means $cwd.
+ func_stripname '' '/' "`pwd`"
+ func_normal_abspath_result=$func_stripname_result
+ return
+ ;;
+ # The next three entries are used to spot a run of precisely
+ # two leading slashes without using negated character classes;
+ # we take advantage of case's first-match behaviour.
+ ///*)
+ # Unusual form of absolute path, do nothing.
+ ;;
+ //*)
+ # Not necessarily an ordinary path; POSIX reserves leading '//'
+ # and for example Cygwin uses it to access remote file shares
+ # over CIFS/SMB, so we conserve a leading double slash if found.
+ func_normal_abspath_altnamespace=/
+ ;;
+ /*)
+ # Absolute path, do nothing.
+ ;;
+ *)
+ # Relative path, prepend $cwd.
+ func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+ ;;
+ esac
+
+ # Cancel out all the simple stuff to save iterations. We also want
+ # the path to end with a slash for ease of parsing, so make sure
+ # there is one (and only one) here.
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"`
+ while :; do
+ # Processed it all yet?
+ if test / = "$func_normal_abspath_tpath"; then
+ # If we ascended to the root using ".." the result may be empty now.
+ if test -z "$func_normal_abspath_result"; then
+ func_normal_abspath_result=/
+ fi
+ break
+ fi
+ func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$_G_pathcar"`
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$_G_pathcdr"`
+ # Figure out what to do with it
+ case $func_normal_abspath_tcomponent in
+ "")
+ # Trailing empty path component, ignore it.
+ ;;
+ ..)
+ # Parent dir; strip last assembled component from result.
+ func_dirname "$func_normal_abspath_result"
+ func_normal_abspath_result=$func_dirname_result
+ ;;
+ *)
+ # Actual path component, append it.
+ func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent"
+ ;;
+ esac
+ done
+ # Restore leading double-slash if one was found on entry.
+ func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+
+# func_notquiet ARG...
+# --------------------
+# Echo program name prefixed message only when not in quiet mode.
+func_notquiet ()
+{
+ $debug_cmd
+
+ $opt_quiet || func_echo ${1+"$@"}
+
+ # A bug in bash halts the script if the last line of a function
+ # fails when set -e is in force, so we need another command to
+ # work around that:
+ :
+}
+
+
+# func_relative_path SRCDIR DSTDIR
+# --------------------------------
+# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR.
+func_relative_path ()
+{
+ $debug_cmd
+
+ func_relative_path_result=
+ func_normal_abspath "$1"
+ func_relative_path_tlibdir=$func_normal_abspath_result
+ func_normal_abspath "$2"
+ func_relative_path_tbindir=$func_normal_abspath_result
+
+ # Ascend the tree starting from libdir
+ while :; do
+ # check if we have found a prefix of bindir
+ case $func_relative_path_tbindir in
+ $func_relative_path_tlibdir)
+ # found an exact match
+ func_relative_path_tcancelled=
+ break
+ ;;
+ $func_relative_path_tlibdir*)
+ # found a matching prefix
+ func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+ func_relative_path_tcancelled=$func_stripname_result
+ if test -z "$func_relative_path_result"; then
+ func_relative_path_result=.
+ fi
+ break
+ ;;
+ *)
+ func_dirname $func_relative_path_tlibdir
+ func_relative_path_tlibdir=$func_dirname_result
+ if test -z "$func_relative_path_tlibdir"; then
+ # Have to descend all the way to the root!
+ func_relative_path_result=../$func_relative_path_result
+ func_relative_path_tcancelled=$func_relative_path_tbindir
+ break
+ fi
+ func_relative_path_result=../$func_relative_path_result
+ ;;
+ esac
+ done
+
+ # Now calculate path; take care to avoid doubling-up slashes.
+ func_stripname '' '/' "$func_relative_path_result"
+ func_relative_path_result=$func_stripname_result
+ func_stripname '/' '/' "$func_relative_path_tcancelled"
+ if test -n "$func_stripname_result"; then
+ func_append func_relative_path_result "/$func_stripname_result"
+ fi
+
+ # Normalisation. If bindir is libdir, return '.' else relative path.
+ if test -n "$func_relative_path_result"; then
+ func_stripname './' '' "$func_relative_path_result"
+ func_relative_path_result=$func_stripname_result
+ fi
+
+ test -n "$func_relative_path_result" || func_relative_path_result=.
+
+ :
+}
+
+
+# func_quote_for_eval ARG...
+# --------------------------
+# Aesthetically quote ARGs to be evaled later.
+# This function returns two values:
+# i) func_quote_for_eval_result
+# double-quoted, suitable for a subsequent eval
+# ii) func_quote_for_eval_unquoted_result
+# has all characters that are still active within double
+# quotes backslashified.
+func_quote_for_eval ()
+{
+ $debug_cmd
+
+ func_quote_for_eval_unquoted_result=
+ func_quote_for_eval_result=
+ while test 0 -lt $#; do
+ case $1 in
+ *[\\\`\"\$]*)
+ _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
+ *)
+ _G_unquoted_arg=$1 ;;
+ esac
+ if test -n "$func_quote_for_eval_unquoted_result"; then
+ func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
+ else
+ func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
+ fi
+
+ case $_G_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.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ _G_quoted_arg=\"$_G_unquoted_arg\"
+ ;;
+ *)
+ _G_quoted_arg=$_G_unquoted_arg
+ ;;
+ esac
+
+ if test -n "$func_quote_for_eval_result"; then
+ func_append func_quote_for_eval_result " $_G_quoted_arg"
+ else
+ func_append func_quote_for_eval_result "$_G_quoted_arg"
+ fi
+ shift
+ done
+}
+
+
+# func_quote_for_expand ARG
+# -------------------------
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+ $debug_cmd
+
+ case $1 in
+ *[\\\`\"]*)
+ _G_arg=`$ECHO "$1" | $SED \
+ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
+ *)
+ _G_arg=$1 ;;
+ esac
+
+ case $_G_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting and command substitution for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ _G_arg=\"$_G_arg\"
+ ;;
+ esac
+
+ func_quote_for_expand_result=$_G_arg
+}
+
+
+# func_stripname PREFIX SUFFIX NAME
+# ---------------------------------
+# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ eval 'func_stripname ()
+ {
+ $debug_cmd
+
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary variable first.
+ func_stripname_result=$3
+ func_stripname_result=${func_stripname_result#"$1"}
+ func_stripname_result=${func_stripname_result%"$2"}
+ }'
+else
+ func_stripname ()
+ {
+ $debug_cmd
+
+ case $2 in
+ .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;;
+ *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;;
+ esac
+ }
+fi
+
+
+# func_show_eval CMD [FAIL_EXP]
+# -----------------------------
+# Unless opt_quiet 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
+
+ _G_cmd=$1
+ _G_fail_exp=${2-':'}
+
+ func_quote_for_expand "$_G_cmd"
+ eval "func_notquiet $func_quote_for_expand_result"
+
+ $opt_dry_run || {
+ eval "$_G_cmd"
+ _G_status=$?
+ if test 0 -ne "$_G_status"; then
+ eval "(exit $_G_status); $_G_fail_exp"
+ fi
+ }
+}
+
+
+# func_show_eval_locale CMD [FAIL_EXP]
+# ------------------------------------
+# Unless opt_quiet 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. Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+ $debug_cmd
+
+ _G_cmd=$1
+ _G_fail_exp=${2-':'}
+
+ $opt_quiet || {
+ func_quote_for_expand "$_G_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ $opt_dry_run || {
+ eval "$_G_user_locale
+ $_G_cmd"
+ _G_status=$?
+ eval "$_G_safe_locale"
+ if test 0 -ne "$_G_status"; then
+ eval "(exit $_G_status); $_G_fail_exp"
+ fi
+ }
+}
+
+
+# func_tr_sh
+# ----------
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result. All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+ $debug_cmd
+
+ case $1 in
+ [0-9]* | *[!a-zA-Z0-9_]*)
+ func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'`
+ ;;
+ * )
+ func_tr_sh_result=$1
+ ;;
+ esac
+}
+
+
+# func_verbose ARG...
+# -------------------
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+ $debug_cmd
+
+ $opt_verbose && func_echo "$*"
+
+ :
+}
+
+
+# func_warn_and_continue ARG...
+# -----------------------------
+# Echo program name prefixed warning message to standard error.
+func_warn_and_continue ()
+{
+ $debug_cmd
+
+ $require_term_colors
+
+ func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2
+}
+
+
+# func_warning CATEGORY ARG...
+# ----------------------------
+# Echo program name prefixed warning message to standard error. Warning
+# messages can be filtered according to CATEGORY, where this function
+# elides messages where CATEGORY is not listed in the global variable
+# 'opt_warning_types'.
+func_warning ()
+{
+ $debug_cmd
+
+ # CATEGORY must be in the warning_categories list!
+ case " $warning_categories " in
+ *" $1 "*) ;;
+ *) func_internal_error "invalid warning category '$1'" ;;
+ esac
+
+ _G_category=$1
+ shift
+
+ case " $opt_warning_types " in
+ *" $_G_category "*) $warning_func ${1+"$@"} ;;
+ esac
+}
+
+
+# func_sort_ver VER1 VER2
+# -----------------------
+# 'sort -V' is not generally available.
+# 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 ()
+{
+ $debug_cmd
+
+ printf '%s\n%s\n' "$1" "$2" \
+ | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n
+}
+
+# func_lt_ver PREV CURR
+# ---------------------
+# Return true if PREV and CURR are in the correct order according to
+# func_sort_ver, otherwise false. Use it like this:
+#
+# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..."
+func_lt_ver ()
+{
+ $debug_cmd
+
+ test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q`
+}
+
+
+# Local variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-time-zone: "UTC"
+# End:
+#! /bin/sh
+
+# Set a version string for this script.
+scriptversion=2014-01-07.03; # UTC
+
+# A portable, pluggable option parser for Bourne shell.
+# Written by Gary V. Vaughan, 2010
+
+# Copyright (C) 2010-2015 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/>.
+
+# Please report bugs or propose patches to gary@gnu.org.
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# This file is a library for parsing options in your shell scripts along
+# with assorted other useful supporting features that you can make use
+# of too.
+#
+# For the simplest scripts you might need only:
+#
+# #!/bin/sh
+# . relative/path/to/funclib.sh
+# . relative/path/to/options-parser
+# scriptversion=1.0
+# func_options ${1+"$@"}
+# eval set dummy "$func_options_result"; shift
+# ...rest of your script...
+#
+# In order for the '--version' option to work, you will need to have a
+# suitably formatted comment like the one at the top of this file
+# starting with '# Written by ' and ending with '# warranty; '.
+#
+# For '-h' and '--help' to work, you will also need a one line
+# description of your script's purpose in a comment directly above the
+# '# Written by ' line, like the one at the top of this file.
+#
+# The default options also support '--debug', which will turn on shell
+# execution tracing (see the comment above debug_cmd below for another
+# use), and '--verbose' and the func_verbose function to allow your script
+# to display verbose messages only when your user has specified
+# '--verbose'.
+#
+# After sourcing this file, you can plug processing for additional
+# options by amending the variables from the 'Configuration' section
+# below, and following the instructions in the 'Option parsing'
+# section further down.
+
+## -------------- ##
+## Configuration. ##
+## -------------- ##
+
+# You should override these variables in your script after sourcing this
+# file so that they reflect the customisations you have added to the
+# option parser.
+
+# The usage line for option parsing errors and the start of '-h' and
+# '--help' output messages. You can embed shell variables for delayed
+# expansion at the time the message is displayed, but you will need to
+# quote other shell meta-characters carefully to prevent them being
+# expanded when the contents are evaled.
+usage='$progpath [OPTION]...'
+
+# Short help message in response to '-h' and '--help'. Add to this or
+# override it after sourcing this library to reflect the full set of
+# options your script accepts.
+usage_message="\
+ --debug enable verbose shell tracing
+ -W, --warnings=CATEGORY
+ report the warnings falling in CATEGORY [all]
+ -v, --verbose verbosely report processing
+ --version print version information and exit
+ -h, --help print short or long help message and exit
+"
+
+# 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"
+
+# Help message printed before fatal option parsing errors.
+fatal_help="Try '\$progname --help' for more information."
+
+
+
+## ------------------------- ##
+## 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_hookable FUNC_NAME
+# -----------------------
+# Declare that FUNC_NAME will run hooks added with
+# 'func_add_hook FUNC_NAME ...'.
+func_hookable ()
+{
+ $debug_cmd
+
+ func_append hookable_fns " $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 call to 'func_hookable'.
+func_add_hook ()
+{
+ $debug_cmd
+
+ case " $hookable_fns " in
+ *" $1 "*) ;;
+ *) func_fatal_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.
+# It is assumed that the list of hook functions contains nothing more
+# than a whitespace-delimited list of legal shell function names, and
+# no effort is wasted trying to catch shell meta-characters or preserve
+# whitespace.
+func_run_hooks ()
+{
+ $debug_cmd
+
+ case " $hookable_fns " in
+ *" $1 "*) ;;
+ *) func_fatal_error "'$1' does not support hook funcions.n" ;;
+ esac
+
+ eval _G_hook_fns=\$$1_hooks; shift
+
+ for _G_hook in $_G_hook_fns; do
+ eval $_G_hook '"$@"'
+
+ # store returned options list back into positional
+ # parameters for next 'cmd' execution.
+ eval _G_hook_result=\$${_G_hook}_result
+ eval set dummy "$_G_hook_result"; shift
+ done
+
+ func_quote_for_eval ${1+"$@"}
+ func_run_hooks_result=$func_quote_for_eval_result
+}
+
+
+
+## --------------- ##
+## Option parsing. ##
+## --------------- ##
+
+# 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 '<hooked_function_name>_result', escaped suitably for
+# 'eval'. Like this:
+#
+# my_options_prep ()
+# {
+# $debug_cmd
+#
+# # Extend the existing usage message.
+# usage_message=$usage_message'
+# -s, --silent don'\''t print informational messages
+# '
+#
+# func_quote_for_eval ${1+"$@"}
+# my_options_prep_result=$func_quote_for_eval_result
+# }
+# func_add_hook func_options_prep my_options_prep
+#
+#
+# my_silent_option ()
+# {
+# $debug_cmd
+#
+# # Note that for efficiency, we parse as many options as we can
+# # recognise in a loop before passing the remainder back to the
+# # caller on the first unrecognised argument we encounter.
+# while test $# -gt 0; do
+# opt=$1; shift
+# case $opt in
+# --silent|-s) opt_silent=: ;;
+# # Separate non-argument short options:
+# -s*) func_split_short_opt "$_G_opt"
+# set dummy "$func_split_short_opt_name" \
+# "-$func_split_short_opt_arg" ${1+"$@"}
+# shift
+# ;;
+# *) set dummy "$_G_opt" "$*"; shift; break ;;
+# esac
+# done
+#
+# func_quote_for_eval ${1+"$@"}
+# my_silent_option_result=$func_quote_for_eval_result
+# }
+# func_add_hook func_parse_options my_silent_option
+#
+#
+# my_option_validation ()
+# {
+# $debug_cmd
+#
+# $opt_silent && $opt_verbose && func_fatal_help "\
+# '--silent' and '--verbose' options are mutually exclusive."
+#
+# func_quote_for_eval ${1+"$@"}
+# my_option_validation_result=$func_quote_for_eval_result
+# }
+# func_add_hook func_validate_options my_option_validation
+#
+# You'll alse need to manually amend $usage_message to reflect the extra
+# options you parse. It's preferable to append if you can, so that
+# multiple option parsing hooks can be added safely.
+
+
+# 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_result+"$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
+
+ # Option defaults:
+ opt_verbose=false
+ opt_warning_types=
+
+ 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.
+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
+
+ # Break out of the loop if we already parsed every option.
+ test $# -gt 0 || break
+
+ _G_opt=$1
+ shift
+ case $_G_opt in
+ --debug|-x) debug_cmd='set -x'
+ func_echo "enabling shell trace mode"
+ $debug_cmd
+ ;;
+
+ --no-warnings|--no-warning|--no-warn)
+ set dummy --warnings none ${1+"$@"}
+ shift
+ ;;
+
+ --warnings|--warning|-W)
+ test $# = 0 && func_missing_arg $_G_opt && break
+ case " $warning_categories $1" in
+ *" $1 "*)
+ # trailing space prevents matching last $1 above
+ func_append_uniq opt_warning_types " $1"
+ ;;
+ *all)
+ opt_warning_types=$warning_categories
+ ;;
+ *none)
+ opt_warning_types=none
+ warning_func=:
+ ;;
+ *error)
+ opt_warning_types=$warning_categories
+ warning_func=func_fatal_error
+ ;;
+ *)
+ func_fatal_error \
+ "unsupported warning category: '$1'"
+ ;;
+ esac
+ shift
+ ;;
+
+ --verbose|-v) opt_verbose=: ;;
+ --version) func_version ;;
+ -\?|-h) func_usage ;;
+ --help) func_help ;;
+
+ # Separate optargs to long options (plugins may need this):
+ --*=*) func_split_equals "$_G_opt"
+ set dummy "$func_split_equals_lhs" \
+ "$func_split_equals_rhs" ${1+"$@"}
+ shift
+ ;;
+
+ # Separate optargs to short options:
+ -W*)
+ func_split_short_opt "$_G_opt"
+ set dummy "$func_split_short_opt_name" \
+ "$func_split_short_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ # Separate non-argument short options:
+ -\?*|-h*|-v*|-x*)
+ func_split_short_opt "$_G_opt"
+ set dummy "$func_split_short_opt_name" \
+ "-$func_split_short_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ --) break ;;
+ -*) func_fatal_help "unrecognised option: '$_G_opt'" ;;
+ *) set dummy "$_G_opt" ${1+"$@"}; 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_types" || opt_warning_types=" $warning_categories"
+
+ func_run_hooks func_validate_options ${1+"$@"}
+
+ # Bail if the options were screwed!
+ $exit_cmd $EXIT_FAILURE
+
+ # save modified positional parameters for caller
+ func_validate_options_result=$func_run_hooks_result
+}
+
+
+
+## ----------------- ##
+## Helper functions. ##
+## ----------------- ##
+
+# This section contains the helper functions used by the rest of the
+# hookable option parser framework in ascii-betical order.
+
+
+# func_fatal_help ARG...
+# ----------------------
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+ $debug_cmd
+
+ eval \$ECHO \""Usage: $usage"\"
+ eval \$ECHO \""$fatal_help"\"
+ func_error ${1+"$@"}
+ exit $EXIT_FAILURE
+}
+
+
+# func_help
+# ---------
+# Echo long help message to standard output and exit.
+func_help ()
+{
+ $debug_cmd
+
+ func_usage_message
+ $ECHO "$long_help_message"
+ exit 0
+}
+
+
+# func_missing_arg ARGNAME
+# ------------------------
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+ $debug_cmd
+
+ func_error "Missing argument for '$1'."
+ exit_cmd=exit
+}
+
+
+# func_split_equals STRING
+# ------------------------
+# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
+# splitting STRING at the '=' sign.
+test -z "$_G_HAVE_XSI_OPS" \
+ && (eval 'x=a/b/c;
+ test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
+ && _G_HAVE_XSI_OPS=yes
+
+if test yes = "$_G_HAVE_XSI_OPS"
+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_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 test yes = "$_G_HAVE_XSI_OPS"
+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_usage
+# ----------
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+ $debug_cmd
+
+ func_usage_message
+ $ECHO "Run '$progname --help |${PAGER-more}' for full usage"
+ exit 0
+}
+
+
+# func_usage_message
+# ------------------
+# Echo short help message to standard output.
+func_usage_message ()
+{
+ $debug_cmd
+
+ eval \$ECHO \""Usage: $usage"\"
+ echo
+ $SED -n 's|^# ||
+ /^Written by/{
+ x;p;x
+ }
+ h
+ /^Written by/q' < "$progpath"
+ echo
+ eval \$ECHO \""$usage_message"\"
+}
+
+
+# func_version
+# ------------
+# Echo version message to standard output and exit.
+func_version ()
+{
+ $debug_cmd
+
+ printf '%s\n' "$progname $scriptversion"
+ $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
+ }
+ /^warranty; /q' < "$progpath"
+
+ exit $?
+}
+
+
+# Local variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-time-zone: "UTC"
+# End:
+
+# Set a version string.
+scriptversion='(GNU libtool) 2.4.6'
+
+
+# func_echo ARG...
+# ----------------
+# Libtool also displays the current mode in messages, so override
+# funclib.sh func_echo with this custom definition.
+func_echo ()
+{
+ $debug_cmd
+
+ _G_message=$*
+
+ func_echo_IFS=$IFS
+ IFS=$nl
+ for _G_line in $_G_message; do
+ IFS=$func_echo_IFS
+ $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line"
+ done
+ IFS=$func_echo_IFS
+}
+
+
+# func_warning ARG...
+# -------------------
+# Libtool warnings are not categorized, so override funclib.sh
+# func_warning with this simpler definition.
+func_warning ()
+{
+ $debug_cmd
+
+ $warning_func ${1+"$@"}
+}
+
+
+## ---------------- ##
+## Options parsing. ##
+## ---------------- ##
+
+# Hook in the functions to make sure our own options are parsed during
+# the option parsing loop.
+
+usage='$progpath [OPTION]... [MODE-ARG]...'
+
+# Short help message in response to '-h'.
+usage_message="Options:
+ --config show all configuration variables
+ --debug enable verbose shell tracing
+ -n, --dry-run display commands without modifying any files
+ --features display basic configuration information and exit
+ --mode=MODE use operation mode MODE
+ --no-warnings equivalent to '-Wnone'
+ --preserve-dup-deps don't remove duplicate dependency libraries
+ --quiet, --silent don't print informational messages
+ --tag=TAG use configuration variables from tag TAG
+ -v, --verbose print more informational messages than default
+ --version print version information
+ -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all]
+ -h, --help, --help-all print short, long, or detailed help message
+"
+
+# Additional text appended to 'usage_message' in response to '--help'.
+func_help ()
+{
+ $debug_cmd
+
+ func_usage_message
+ $ECHO "$long_help_message
+
+MODE must be one of the following:
+
+ clean remove files from the build directory
+ compile compile a source file into a libtool object
+ execute automatically set library path, then run a program
+ finish complete the installation of libtool libraries
+ install install libraries or executables
+ link create a library or an executable
+ uninstall remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE. When passed as first option,
+'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that.
+Try '$progname --help --mode=MODE' for a more detailed description of MODE.
+
+When reporting a bug, please describe a test case to reproduce it and
+include the following information:
+
+ host-triplet: $host
+ shell: $SHELL
+ compiler: $LTCC
+ compiler flags: $LTCFLAGS
+ linker: $LD (gnu? $with_gnu_ld)
+ version: $progname $scriptversion Debian-2.4.6-2
+ automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
+ autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q`
+
+Report bugs to <bug-libtool@gnu.org>.
+GNU libtool home page: <http://www.gnu.org/s/libtool/>.
+General help using GNU software: <http://www.gnu.org/gethelp/>."
+ exit 0
+}
+
+
+# func_lo2o OBJECT-NAME
+# ---------------------
+# Transform OBJECT-NAME from a '.lo' suffix to the platform specific
+# object suffix.
+
+lo2o=s/\\.lo\$/.$objext/
+o2lo=s/\\.$objext\$/.lo/
+
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ eval 'func_lo2o ()
+ {
+ case $1 in
+ *.lo) func_lo2o_result=${1%.lo}.$objext ;;
+ * ) func_lo2o_result=$1 ;;
+ esac
+ }'
+
+ # func_xform LIBOBJ-OR-SOURCE
+ # ---------------------------
+ # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise)
+ # suffix to a '.lo' libtool-object suffix.
+ eval 'func_xform ()
+ {
+ func_xform_result=${1%.*}.lo
+ }'
+else
+ # ...otherwise fall back to using sed.
+ func_lo2o ()
+ {
+ func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"`
+ }
+
+ func_xform ()
+ {
+ func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'`
+ }
+fi
+
+
+# func_fatal_configuration ARG...
+# -------------------------------
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+ func__fatal_error ${1+"$@"} \
+ "See the $PACKAGE documentation for more information." \
+ "Fatal configuration error."
+}
+
+
+# func_config
+# -----------
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+ re_begincf='^# ### BEGIN LIBTOOL'
+ re_endcf='^# ### END LIBTOOL'
+
+ # Default configuration.
+ $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+ # Now print the configurations for the tags.
+ for tagname in $taglist; do
+ $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+ done
+
+ exit $?
+}
+
+
+# func_features
+# -------------
+# Display the features supported by this script.
+func_features ()
+{
+ echo "host: $host"
+ if test yes = "$build_libtool_libs"; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test yes = "$build_old_libs"; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+
+ exit $?
+}
+
+
+# func_enable_tag TAGNAME
+# -----------------------
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag. We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+ # Global variable:
+ tagname=$1
+
+ re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+ re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+ sed_extractcf=/$re_begincf/,/$re_endcf/p
+
+ # Validate tagname.
+ case $tagname in
+ *[!-_A-Za-z0-9,/]*)
+ func_fatal_error "invalid tag name: $tagname"
+ ;;
+ esac
+
+ # Don't test for the "default" C tag, as we know it's
+ # there but not specially marked.
+ case $tagname in
+ CC) ;;
+ *)
+ if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+ taglist="$taglist $tagname"
+
+ # Evaluate the configuration. Be careful to quote the path
+ # and the sed script, to avoid splitting on whitespace, but
+ # also don't use non-portable quotes within backquotes within
+ # quotes we have to do it in 2 steps:
+ extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+ eval "$extractedcf"
+ else
+ func_error "ignoring unknown tag $tagname"
+ fi
+ ;;
+ esac
+}
+
+
+# func_check_version_match
+# ------------------------
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+ if test "$package_revision" != "$macro_revision"; then
+ if test "$VERSION" != "$macro_version"; then
+ if test -z "$macro_version"; then
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ fi
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+ fi
+
+ exit $EXIT_MISMATCH
+ fi
+}
+
+
+# libtool_options_prep [ARG]...
+# -----------------------------
+# Preparation for options parsed by libtool.
+libtool_options_prep ()
+{
+ $debug_mode
+
+ # Option defaults:
+ opt_config=false
+ opt_dlopen=
+ opt_dry_run=false
+ opt_help=false
+ opt_mode=
+ opt_preserve_dup_deps=false
+ opt_quiet=false
+
+ nonopt=
+ preserve_args=
+
+ # Shorthand for --mode=foo, only valid as the first argument
+ case $1 in
+ clean|clea|cle|cl)
+ shift; set dummy --mode clean ${1+"$@"}; shift
+ ;;
+ compile|compil|compi|comp|com|co|c)
+ shift; set dummy --mode compile ${1+"$@"}; shift
+ ;;
+ execute|execut|execu|exec|exe|ex|e)
+ shift; set dummy --mode execute ${1+"$@"}; shift
+ ;;
+ finish|finis|fini|fin|fi|f)
+ shift; set dummy --mode finish ${1+"$@"}; shift
+ ;;
+ install|instal|insta|inst|ins|in|i)
+ shift; set dummy --mode install ${1+"$@"}; shift
+ ;;
+ link|lin|li|l)
+ shift; set dummy --mode link ${1+"$@"}; shift
+ ;;
+ uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+ shift; set dummy --mode uninstall ${1+"$@"}; shift
+ ;;
+ esac
+
+ # Pass back the list of options.
+ func_quote_for_eval ${1+"$@"}
+ libtool_options_prep_result=$func_quote_for_eval_result
+}
+func_add_hook func_options_prep libtool_options_prep
+
+
+# libtool_parse_options [ARG]...
+# ---------------------------------
+# Provide handling for libtool specific options.
+libtool_parse_options ()
+{
+ $debug_cmd
+
+ # Perform our own loop to consume as many options as possible in
+ # each iteration.
+ while test $# -gt 0; do
+ _G_opt=$1
+ shift
+ case $_G_opt in
+ --dry-run|--dryrun|-n)
+ opt_dry_run=:
+ ;;
+
+ --config) func_config ;;
+
+ --dlopen|-dlopen)
+ opt_dlopen="${opt_dlopen+$opt_dlopen
+}$1"
+ shift
+ ;;
+
+ --preserve-dup-deps)
+ opt_preserve_dup_deps=: ;;
+
+ --features) func_features ;;
+
+ --finish) set dummy --mode finish ${1+"$@"}; shift ;;
+
+ --help) opt_help=: ;;
+
+ --help-all) opt_help=': help-all' ;;
+
+ --mode) test $# = 0 && func_missing_arg $_G_opt && break
+ opt_mode=$1
+ case $1 in
+ # Valid mode arguments:
+ clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+ # Catch anything else as an error
+ *) func_error "invalid argument for $_G_opt"
+ exit_cmd=exit
+ break
+ ;;
+ esac
+ shift
+ ;;
+
+ --no-silent|--no-quiet)
+ opt_quiet=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --no-warnings|--no-warning|--no-warn)
+ opt_warning=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --no-verbose)
+ opt_verbose=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --silent|--quiet)
+ opt_quiet=:
+ opt_verbose=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --tag) test $# = 0 && func_missing_arg $_G_opt && break
+ opt_tag=$1
+ func_append preserve_args " $_G_opt $1"
+ func_enable_tag "$1"
+ shift
+ ;;
+
+ --verbose|-v) opt_quiet=false
+ opt_verbose=:
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ # An option not handled by this hook function:
+ *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+ esac
+ done
+
+
+ # save modified positional parameters for caller
+ func_quote_for_eval ${1+"$@"}
+ libtool_parse_options_result=$func_quote_for_eval_result
+}
+func_add_hook func_parse_options libtool_parse_options
+
+
+
+# libtool_validate_options [ARG]...
+# ---------------------------------
+# Perform any sanity checks on option settings and/or unconsumed
+# arguments.
+libtool_validate_options ()
+{
+ # save first non-option argument
+ if test 0 -lt $#; then
+ nonopt=$1
+ shift
+ fi
+
+ # preserve --debug
+ test : = "$debug_cmd" || func_append preserve_args " --debug"
+
+ case $host in
+ # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452
+ # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788
+ *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*)
+ # don't eliminate duplications in $postdeps and $predeps
+ opt_duplicate_compiler_generated_deps=:
+ ;;
+ *)
+ opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+ ;;
+ esac
+
+ $opt_help || {
+ # Sanity checks first:
+ func_check_version_match
+
+ test yes != "$build_libtool_libs" \
+ && test yes != "$build_old_libs" \
+ && func_fatal_configuration "not configured to build any kind of library"
+
+ # Darwin sucks
+ eval std_shrext=\"$shrext_cmds\"
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$opt_dlopen" && test execute != "$opt_mode"; then
+ func_error "unrecognized option '-dlopen'"
+ $ECHO "$help" 1>&2
+ exit $EXIT_FAILURE
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help=$help
+ help="Try '$progname --help --mode=$opt_mode' for more information."
+ }
+
+ # Pass back the unparsed argument list
+ func_quote_for_eval ${1+"$@"}
+ libtool_validate_options_result=$func_quote_for_eval_result
+}
+func_add_hook func_validate_options libtool_validate_options
+
+
+# Process options as early as possible so that --help and --version
+# can return quickly.
+func_options ${1+"$@"}
+eval set dummy "$func_options_result"; shift
+
+
+
+## ----------- ##
+## Main. ##
+## ----------- ##
+
+magic='%%%MAGIC variable%%%'
+magic_exe='%%%MAGIC EXE variable%%%'
+
+# Global variables.
+extracted_archives=
+extracted_serial=0
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end. This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
+# func_generated_by_libtool
+# True iff stdin has been generated by Libtool. This function is only
+# a basic sanity check; it will hardly flush out determined imposters.
+func_generated_by_libtool_p ()
+{
+ $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_p file
+# True iff FILE is a libtool '.la' library or '.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+ test -f "$1" &&
+ $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool '.la' library or '.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs. To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway. Works if 'file' does not exist.
+func_lalib_unsafe_p ()
+{
+ lalib_p=no
+ if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+ for lalib_p_l in 1 2 3 4
+ do
+ read lalib_p_line
+ case $lalib_p_line in
+ \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+ esac
+ done
+ exec 0<&5 5<&-
+ fi
+ test yes = "$lalib_p"
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+ test -f "$1" &&
+ $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+ func_ltwrapper_exec_suffix=
+ case $1 in
+ *.exe) ;;
+ *) func_ltwrapper_exec_suffix=.exe ;;
+ esac
+ $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+ func_dirname_and_basename "$1" "" "."
+ func_stripname '' '.exe' "$func_basename_result"
+ func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+ func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+ $debug_cmd
+
+ save_ifs=$IFS; IFS='~'
+ for cmd in $1; do
+ IFS=$sp$nl
+ eval cmd=\"$cmd\"
+ IFS=$save_ifs
+ func_show_eval "$cmd" "${2-:}"
+ done
+ IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)! Also, sourcing
+# 'FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+ $debug_cmd
+
+ case $1 in
+ */* | *\\*) . "$1" ;;
+ *) . "./$1" ;;
+ esac
+}
+
+
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot. Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+ func_resolve_sysroot_result=$1
+ case $func_resolve_sysroot_result in
+ =*)
+ func_stripname '=' '' "$func_resolve_sysroot_result"
+ func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+ ;;
+ esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+ case $lt_sysroot:$1 in
+ ?*:"$lt_sysroot"*)
+ func_stripname "$lt_sysroot" '' "$1"
+ func_replace_sysroot_result='='$func_stripname_result
+ ;;
+ *)
+ # Including no sysroot.
+ func_replace_sysroot_result=$1
+ ;;
+ esac
+}
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+ $debug_cmd
+
+ if test -n "$available_tags" && test -z "$tagname"; then
+ CC_quoted=
+ for arg in $CC; do
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case $@ in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+ CC_quoted=
+ for arg in $CC; do
+ # Double-quote args containing other shell metacharacters.
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case "$@ " in
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+ # The compiler in the base compile command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ func_echo "unable to infer tagged configuration"
+ func_fatal_error "specify a tag with '--tag'"
+# else
+# func_verbose "using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+ write_libobj=$1
+ if test yes = "$build_libtool_libs"; then
+ write_lobj=\'$2\'
+ else
+ write_lobj=none
+ fi
+
+ if test yes = "$build_old_libs"; then
+ write_oldobj=\'$3\'
+ else
+ write_oldobj=none
+ fi
+
+ $opt_dry_run || {
+ cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+ $MV "${write_libobj}T" "$write_libobj"
+ }
+}
+
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+ $debug_cmd
+
+ func_convert_core_file_wine_to_w32_result=$1
+ if test -n "$1"; then
+ # Unfortunately, winepath does not exit with a non-zero error code, so we
+ # are forced to check the contents of stdout. On the other hand, if the
+ # command is not found, the shell will set an exit code of 127 and print
+ # *an error message* to stdout. So we must check for both error code of
+ # zero AND non-empty stdout, which explains the odd construction:
+ func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+ if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then
+ func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+ $SED -e "$sed_naive_backslashify"`
+ else
+ func_convert_core_file_wine_to_w32_result=
+ fi
+ fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+ $debug_cmd
+
+ # unfortunately, winepath doesn't convert paths, only file names
+ func_convert_core_path_wine_to_w32_result=
+ if test -n "$1"; then
+ oldIFS=$IFS
+ IFS=:
+ for func_convert_core_path_wine_to_w32_f in $1; do
+ IFS=$oldIFS
+ func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+ if test -n "$func_convert_core_file_wine_to_w32_result"; then
+ if test -z "$func_convert_core_path_wine_to_w32_result"; then
+ func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result
+ else
+ func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+ fi
+ fi
+ done
+ IFS=$oldIFS
+ fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+ $debug_cmd
+
+ if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+ func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+ if test "$?" -ne 0; then
+ # on failure, ensure result is empty
+ func_cygpath_result=
+ fi
+ else
+ func_cygpath_result=
+ func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'"
+ fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format. Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+ $debug_cmd
+
+ # awkward: cmd appends spaces to result
+ func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+ $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+ $debug_cmd
+
+ if test -z "$2" && test -n "$1"; then
+ func_error "Could not determine host file name corresponding to"
+ func_error " '$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback:
+ func_to_host_file_result=$1
+ fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+ $debug_cmd
+
+ if test -z "$4" && test -n "$3"; then
+ func_error "Could not determine the host path corresponding to"
+ func_error " '$3'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback. This is a deliberately simplistic "conversion" and
+ # should not be "improved". See libtool.info.
+ if test "x$1" != "x$2"; then
+ lt_replace_pathsep_chars="s|$1|$2|g"
+ func_to_host_path_result=`echo "$3" |
+ $SED -e "$lt_replace_pathsep_chars"`
+ else
+ func_to_host_path_result=$3
+ fi
+ fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+ $debug_cmd
+
+ case $4 in
+ $1 ) func_to_host_path_result=$3$func_to_host_path_result
+ ;;
+ esac
+ case $4 in
+ $2 ) func_append func_to_host_path_result "$3"
+ ;;
+ esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via '$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+ $debug_cmd
+
+ $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result. If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+ $debug_cmd
+
+ case ,$2, in
+ *,"$to_tool_file_cmd",*)
+ func_to_tool_file_result=$1
+ ;;
+ *)
+ $to_tool_file_cmd "$1"
+ func_to_tool_file_result=$func_to_host_file_result
+ ;;
+ esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+ func_to_host_file_result=$1
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_to_host_file_result=$func_convert_core_msys_to_w32_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+ # LT_CYGPATH in this case.
+ func_to_host_file_result=`cygpath -m "$1"`
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format. Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ func_convert_core_file_wine_to_w32 "$1"
+ func_to_host_file_result=$func_convert_core_file_wine_to_w32_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_msys_to_w32_result"
+ func_to_host_file_result=$func_cygpath_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set. Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+ func_convert_core_file_wine_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+ func_to_host_file_result=$func_cygpath_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via '$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format. If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+# file name conversion function : func_convert_file_X_to_Y ()
+# path conversion function : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same. If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+ $debug_cmd
+
+ if test -z "$to_host_path_cmd"; then
+ func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+ to_host_path_cmd=func_convert_path_$func_stripname_result
+ fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+ $debug_cmd
+
+ func_init_to_host_path_cmd
+ $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+ func_to_host_path_result=$1
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from ARG. MSYS
+ # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+ # and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result=$func_convert_core_msys_to_w32_result
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format. Requires a wine environment and
+# a working winepath. Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result=$func_convert_core_path_wine_to_w32_result
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+ func_to_host_path_result=$func_cygpath_result
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set. Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from
+ # ARG. msys behavior is inconsistent here, cygpath turns them
+ # into '.;' and ';.', and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+ func_to_host_path_result=$func_cygpath_result
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
+# func_dll_def_p FILE
+# True iff FILE is a Windows DLL '.def' file.
+# Keep in sync with _LT_DLL_DEF_P in libtool.m4
+func_dll_def_p ()
+{
+ $debug_cmd
+
+ func_dll_def_p_tmp=`$SED -n \
+ -e 's/^[ ]*//' \
+ -e '/^\(;.*\)*$/d' \
+ -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \
+ -e q \
+ "$1"`
+ test DEF = "$func_dll_def_p_tmp"
+}
+
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+ $debug_cmd
+
+ # Get the compilation command and the source file.
+ base_compile=
+ srcfile=$nonopt # always keep a non-empty value in "srcfile"
+ suppress_opt=yes
+ suppress_output=
+ arg_mode=normal
+ libobj=
+ later=
+ pie_flag=
+
+ for arg
+ do
+ case $arg_mode in
+ arg )
+ # do not "continue". Instead, add this to base_compile
+ lastarg=$arg
+ arg_mode=normal
+ ;;
+
+ target )
+ libobj=$arg
+ arg_mode=normal
+ continue
+ ;;
+
+ normal )
+ # Accept any command-line options.
+ case $arg in
+ -o)
+ test -n "$libobj" && \
+ func_fatal_error "you cannot specify '-o' more than once"
+ arg_mode=target
+ continue
+ ;;
+
+ -pie | -fpie | -fPIE)
+ func_append pie_flag " $arg"
+ continue
+ ;;
+
+ -shared | -static | -prefer-pic | -prefer-non-pic)
+ func_append later " $arg"
+ continue
+ ;;
+
+ -no-suppress)
+ suppress_opt=no
+ continue
+ ;;
+
+ -Xcompiler)
+ arg_mode=arg # the next one goes into the "base_compile" arg list
+ continue # The current "srcfile" will either be retained or
+ ;; # replaced later. I would guess that would be a bug.
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ lastarg=
+ save_ifs=$IFS; IFS=,
+ for arg in $args; do
+ IFS=$save_ifs
+ func_append_quoted lastarg "$arg"
+ done
+ IFS=$save_ifs
+ func_stripname ' ' '' "$lastarg"
+ lastarg=$func_stripname_result
+
+ # Add the arguments to base_compile.
+ func_append base_compile " $lastarg"
+ continue
+ ;;
+
+ *)
+ # Accept the current argument as the source file.
+ # The previous "srcfile" becomes the current argument.
+ #
+ lastarg=$srcfile
+ srcfile=$arg
+ ;;
+ esac # case $arg
+ ;;
+ esac # case $arg_mode
+
+ # Aesthetically quote the previous argument.
+ func_append_quoted base_compile "$lastarg"
+ done # for arg
+
+ case $arg_mode in
+ arg)
+ func_fatal_error "you must specify an argument for -Xcompile"
+ ;;
+ target)
+ func_fatal_error "you must specify a target with '-o'"
+ ;;
+ *)
+ # Get the name of the library object.
+ test -z "$libobj" && {
+ func_basename "$srcfile"
+ libobj=$func_basename_result
+ }
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ case $libobj in
+ *.[cCFSifmso] | \
+ *.ada | *.adb | *.ads | *.asm | \
+ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
+ func_xform "$libobj"
+ libobj=$func_xform_result
+ ;;
+ esac
+
+ case $libobj in
+ *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+ *)
+ func_fatal_error "cannot determine name of library object from '$libobj'"
+ ;;
+ esac
+
+ func_infer_tag $base_compile
+
+ for arg in $later; do
+ case $arg in
+ -shared)
+ test yes = "$build_libtool_libs" \
+ || func_fatal_configuration "cannot build a shared library"
+ build_old_libs=no
+ continue
+ ;;
+
+ -static)
+ build_libtool_libs=no
+ build_old_libs=yes
+ continue
+ ;;
+
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
+
+ -prefer-non-pic)
+ pic_mode=no
+ continue
+ ;;
+ esac
+ done
+
+ func_quote_for_eval "$libobj"
+ test "X$libobj" != "X$func_quote_for_eval_result" \
+ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \
+ && func_warning "libobj name '$libobj' may not contain shell special characters."
+ func_dirname_and_basename "$obj" "/" ""
+ objname=$func_basename_result
+ xdir=$func_dirname_result
+ lobj=$xdir$objdir/$objname
+
+ test -z "$base_compile" && \
+ func_fatal_help "you must specify a compilation command"
+
+ # Delete any leftover library objects.
+ if test yes = "$build_old_libs"; then
+ removelist="$obj $lobj $libobj ${libobj}T"
+ else
+ removelist="$lobj $libobj ${libobj}T"
+ fi
+
+ # On Cygwin there's no "real" PIC flag so we must build both object types
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2* | cegcc*)
+ pic_mode=default
+ ;;
+ esac
+ if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then
+ # non-PIC code in shared libraries is not supported
+ pic_mode=default
+ fi
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test no = "$compiler_c_o"; then
+ output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext
+ lockfile=$output_obj.lock
+ else
+ output_obj=
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test yes = "$need_locks"; then
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test warn = "$need_locks"; then
+ if test -f "$lockfile"; then
+ $ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+ func_append removelist " $output_obj"
+ $ECHO "$srcfile" > "$lockfile"
+ fi
+
+ $opt_dry_run || $RM $removelist
+ func_append removelist " $lockfile"
+ trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+ func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+ srcfile=$func_to_tool_file_result
+ func_quote_for_eval "$srcfile"
+ qsrcfile=$func_quote_for_eval_result
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test yes = "$build_libtool_libs"; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ if test no != "$pic_mode"; then
+ command="$base_compile $qsrcfile $pic_flag"
+ else
+ # Don't build PIC code
+ command="$base_compile $qsrcfile"
+ fi
+
+ func_mkdir_p "$xdir$objdir"
+
+ if test -z "$output_obj"; then
+ # Place PIC objects in $objdir
+ func_append command " -o $lobj"
+ fi
+
+ func_show_eval_locale "$command" \
+ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+ if test warn = "$need_locks" &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+ func_show_eval '$MV "$output_obj" "$lobj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+
+ # Allow error messages only from the first compilation.
+ if test yes = "$suppress_opt"; then
+ suppress_output=' >/dev/null 2>&1'
+ fi
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test yes = "$build_old_libs"; then
+ if test yes != "$pic_mode"; then
+ # Don't build PIC code
+ command="$base_compile $qsrcfile$pie_flag"
+ else
+ command="$base_compile $qsrcfile $pic_flag"
+ fi
+ if test yes = "$compiler_c_o"; then
+ func_append command " -o $obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ func_append command "$suppress_output"
+ func_show_eval_locale "$command" \
+ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+ if test warn = "$need_locks" &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed
+ if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+ func_show_eval '$MV "$output_obj" "$obj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+ fi
+
+ $opt_dry_run || {
+ func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+ # Unlock the critical section if it was locked
+ if test no != "$need_locks"; then
+ removelist=$lockfile
+ $RM "$lockfile"
+ fi
+ }
+
+ exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+ test compile = "$opt_mode" && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+ # We need to display help for each of the modes.
+ case $opt_mode in
+ "")
+ # Generic help is extracted from the usage comments
+ # at the start of this file.
+ func_help
+ ;;
+
+ clean)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ compile)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -no-suppress do not suppress compiler output for multiple passes
+ -prefer-pic try to build PIC objects only
+ -prefer-non-pic try to build non-PIC objects only
+ -shared do not build a '.o' file suitable for static linking
+ -static only build a '.o' file suitable for static linking
+ -Wc,FLAG pass FLAG directly to the compiler
+
+COMPILE-COMMAND is a command to be used in creating a 'standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix '.c' with the
+library object suffix, '.lo'."
+ ;;
+
+ execute)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to '-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+ finish)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the '--dry-run' option if you just want to see what would be executed."
+ ;;
+
+ install)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the 'install' or 'cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+ -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+ link)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -bindir BINDIR specify path to binaries directory (for systems where
+ libraries must be found in the PATH setting at runtime)
+ -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-fast-install disable the fast-install mode
+ -no-install link a not-installable executable
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -objectlist FILE use a list of object files found in FILE to specify objects
+ -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes)
+ -precious-files-regex REGEX
+ don't remove output files matching REGEX
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -shared only do dynamic linking of libtool libraries
+ -shrext SUFFIX override the standard shared library file extension
+ -static do not do any dynamic linking of uninstalled libtool libraries
+ -static-libtool-libs
+ do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+ -weak LIBNAME declare that the target provides the LIBNAME interface
+ -Wc,FLAG
+ -Xcompiler FLAG pass linker-specific FLAG directly to the compiler
+ -Wl,FLAG
+ -Xlinker FLAG pass linker-specific FLAG directly to the linker
+ -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with '-') are ignored.
+
+Every other argument is treated as a filename. Files ending in '.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in '.la', then a libtool library is created,
+only library objects ('.lo' files) may be specified, and '-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created
+using 'ar' and 'ranlib', or on Windows using 'lib'.
+
+If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+ uninstall)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ *)
+ func_fatal_help "invalid operation mode '$opt_mode'"
+ ;;
+ esac
+
+ echo
+ $ECHO "Try '$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+ if test : = "$opt_help"; then
+ func_mode_help
+ else
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ func_mode_help
+ done
+ } | $SED -n '1p; 2,$s/^Usage:/ or: /p'
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ echo
+ func_mode_help
+ done
+ } |
+ $SED '1d
+ /^When reporting/,/^Report/{
+ H
+ d
+ }
+ $x
+ /information about other modes/d
+ /more detailed .*MODE/d
+ s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+ fi
+ exit $?
+fi
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+ $debug_cmd
+
+ # The first argument is the command name.
+ cmd=$nonopt
+ test -z "$cmd" && \
+ func_fatal_help "you must specify a COMMAND"
+
+ # Handle -dlopen flags immediately.
+ for file in $opt_dlopen; do
+ test -f "$file" \
+ || func_fatal_help "'$file' is not a file"
+
+ dir=
+ case $file in
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "'$lib' is not a valid libtool archive"
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+ func_source "$file"
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && \
+ func_warning "'$file' was not linked with '-export-dynamic'"
+ continue
+ fi
+
+ func_dirname "$file" "" "."
+ dir=$func_dirname_result
+
+ if test -f "$dir/$objdir/$dlname"; then
+ func_append dir "/$objdir"
+ else
+ if test ! -f "$dir/$dlname"; then
+ func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'"
+ fi
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ func_dirname "$file" "" "."
+ dir=$func_dirname_result
+ ;;
+
+ *)
+ func_warning "'-dlopen' is ignored for non-libtool libraries and objects"
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir=$absdir
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic=$magic
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case $file in
+ -* | *.la | *.lo ) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if func_ltwrapper_script_p "$file"; then
+ func_source "$file"
+ # Transform arg to wrapped name.
+ file=$progdir/$program
+ elif func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ func_source "$func_ltwrapper_scriptname_result"
+ # Transform arg to wrapped name.
+ file=$progdir/$program
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ func_append_quoted args "$file"
+ done
+
+ if $opt_dry_run; then
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+ echo "export $shlibpath_var"
+ fi
+ $ECHO "$cmd$args"
+ exit $EXIT_SUCCESS
+ else
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved environment variables
+ for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+ do
+ eval "if test \"\${save_$lt_var+set}\" = set; then
+ $lt_var=\$save_$lt_var; export $lt_var
+ else
+ $lt_unset $lt_var
+ fi"
+ done
+
+ # Now prepare to actually exec the command.
+ exec_cmd=\$cmd$args
+ fi
+}
+
+test execute = "$opt_mode" && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+ $debug_cmd
+
+ libs=
+ libdirs=
+ admincmds=
+
+ for opt in "$nonopt" ${1+"$@"}
+ do
+ if test -d "$opt"; then
+ func_append libdirs " $opt"
+
+ elif test -f "$opt"; then
+ if func_lalib_unsafe_p "$opt"; then
+ func_append libs " $opt"
+ else
+ func_warning "'$opt' is not a valid libtool archive"
+ fi
+
+ else
+ func_fatal_error "invalid argument '$opt'"
+ fi
+ done
+
+ if test -n "$libs"; then
+ if test -n "$lt_sysroot"; then
+ sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+ sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+ else
+ sysroot_cmd=
+ fi
+
+ # Remove sysroot references
+ if $opt_dry_run; then
+ for lib in $libs; do
+ echo "removing references to $lt_sysroot and '=' prefixes from $lib"
+ done
+ else
+ tmpdir=`func_mktempdir`
+ for lib in $libs; do
+ $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+ > $tmpdir/tmp-la
+ mv -f $tmpdir/tmp-la $lib
+ done
+ ${RM}r "$tmpdir"
+ fi
+ fi
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $opt_dry_run || eval "$cmds" || func_append admincmds "
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ $opt_quiet && exit $EXIT_SUCCESS
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ $ECHO " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use the '-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the '$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the '$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ $ECHO " - use the '$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ $ECHO " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'"
+ fi
+ echo
+
+ echo "See any operating system documentation about shared libraries for"
+ case $host in
+ solaris2.[6789]|solaris2.1[0-9])
+ echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+ echo "pages."
+ ;;
+ *)
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ ;;
+ esac
+ echo "----------------------------------------------------------------------"
+ fi
+ exit $EXIT_SUCCESS
+}
+
+test finish = "$opt_mode" && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+ $debug_cmd
+
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" ||
+ # Allow the use of GNU shtool's install command.
+ case $nonopt in *shtool*) :;; *) false;; esac
+ then
+ # Aesthetically quote it.
+ func_quote_for_eval "$nonopt"
+ install_prog="$func_quote_for_eval_result "
+ arg=$1
+ shift
+ else
+ install_prog=
+ arg=$nonopt
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ func_quote_for_eval "$arg"
+ func_append install_prog "$func_quote_for_eval_result"
+ install_shared_prog=$install_prog
+ case " $install_prog " in
+ *[\\\ /]cp\ *) install_cp=: ;;
+ *) install_cp=false ;;
+ esac
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=false
+ stripme=
+ no_mode=:
+ for arg
+ do
+ arg2=
+ if test -n "$dest"; then
+ func_append files " $dest"
+ dest=$arg
+ continue
+ fi
+
+ case $arg in
+ -d) isdir=: ;;
+ -f)
+ if $install_cp; then :; else
+ prev=$arg
+ fi
+ ;;
+ -g | -m | -o)
+ prev=$arg
+ ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*)
+ ;;
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ if test X-m = "X$prev" && test -n "$install_override_mode"; then
+ arg2=$install_override_mode
+ no_mode=false
+ fi
+ prev=
+ else
+ dest=$arg
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ func_quote_for_eval "$arg"
+ func_append install_prog " $func_quote_for_eval_result"
+ if test -n "$arg2"; then
+ func_quote_for_eval "$arg2"
+ fi
+ func_append install_shared_prog " $func_quote_for_eval_result"
+ done
+
+ test -z "$install_prog" && \
+ func_fatal_help "you must specify an install program"
+
+ test -n "$prev" && \
+ func_fatal_help "the '$prev' option requires an argument"
+
+ if test -n "$install_override_mode" && $no_mode; then
+ if $install_cp; then :; else
+ func_quote_for_eval "$install_override_mode"
+ func_append install_shared_prog " -m $func_quote_for_eval_result"
+ fi
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ func_fatal_help "no file or destination specified"
+ else
+ func_fatal_help "you must specify a destination"
+ fi
+ fi
+
+ # Strip any trailing slash from the destination.
+ func_stripname '' '/' "$dest"
+ dest=$func_stripname_result
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=:
+ if $isdir; then
+ destdir=$dest
+ destname=
+ else
+ func_dirname_and_basename "$dest" "" "."
+ destdir=$func_dirname_result
+ destname=$func_basename_result
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files; shift
+ test "$#" -gt 1 && \
+ func_fatal_help "'$dest' is not a directory"
+ fi
+ case $destdir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case $file in
+ *.lo) ;;
+ *)
+ func_fatal_help "'$destdir' must be an absolute directory name"
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic=$magic
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case $file in
+ *.$libext)
+ # Do the static libraries later.
+ func_append staticlibs " $file"
+ ;;
+
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "'$file' is not a valid libtool archive"
+
+ library_names=
+ old_library=
+ relink_command=
+ func_source "$file"
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append current_libdirs " $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append future_libdirs " $libdir" ;;
+ esac
+ fi
+
+ func_dirname "$file" "/" ""
+ dir=$func_dirname_result
+ func_append dir "$objdir"
+
+ if test -n "$relink_command"; then
+ # Determine the prefix the user has applied to our future dir.
+ inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
+
+ # Don't allow the user to place us outside of our expected
+ # location b/c this prevents finding dependent libraries that
+ # are installed to the same prefix.
+ # At present, this check doesn't affect windows .dll's that
+ # are installed into $libdir/../bin (currently, that works fine)
+ # but it's something to keep an eye on.
+ test "$inst_prefix_dir" = "$destdir" && \
+ func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir"
+
+ if test -n "$inst_prefix_dir"; then
+ # Stick the inst_prefix_dir data into the link command.
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+ else
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+ fi
+
+ func_warning "relinking '$file'"
+ func_show_eval "$relink_command" \
+ 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"'
+ fi
+
+ # See the names of the shared library.
+ set dummy $library_names; shift
+ if test -n "$1"; then
+ realname=$1
+ shift
+
+ srcname=$realname
+ test -n "$relink_command" && srcname=${realname}T
+
+ # Install the shared library and build the symlinks.
+ func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+ 'exit $?'
+ tstripme=$stripme
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $realname in
+ *.dll.a)
+ tstripme=
+ ;;
+ esac
+ ;;
+ os2*)
+ case $realname in
+ *_dll.a)
+ tstripme=
+ ;;
+ esac
+ ;;
+ esac
+ if test -n "$tstripme" && test -n "$striplib"; then
+ func_show_eval "$striplib $destdir/$realname" 'exit $?'
+ fi
+
+ if test "$#" -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ # Try 'ln -sf' first, because the 'ln' binary might depend on
+ # the symlink we replace! Solaris /bin/ln does not understand -f,
+ # so we also need to try rm && ln -s.
+ for linkname
+ do
+ test "$linkname" != "$realname" \
+ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib=$destdir/$realname
+ func_execute_cmds "$postinstall_cmds" 'exit $?'
+ fi
+
+ # Install the pseudo-library for information purposes.
+ func_basename "$file"
+ name=$func_basename_result
+ instname=$dir/${name}i
+ func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile=$destdir/$destname
+ else
+ func_basename "$file"
+ destfile=$func_basename_result
+ destfile=$destdir/$destfile
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case $destfile in
+ *.lo)
+ func_lo2o "$destfile"
+ staticdest=$func_lo2o_result
+ ;;
+ *.$objext)
+ staticdest=$destfile
+ destfile=
+ ;;
+ *)
+ func_fatal_help "cannot copy a libtool object to '$destfile'"
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ test -n "$destfile" && \
+ func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+ # Install the old object if enabled.
+ if test yes = "$build_old_libs"; then
+ # Deduce the name of the old-style object file.
+ func_lo2o "$file"
+ staticobj=$func_lo2o_result
+ func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+ fi
+ exit $EXIT_SUCCESS
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile=$destdir/$destname
+ else
+ func_basename "$file"
+ destfile=$func_basename_result
+ destfile=$destdir/$destfile
+ fi
+
+ # If the file is missing, and there is a .exe on the end, strip it
+ # because it is most likely a libtool script we actually want to
+ # install
+ stripped_ext=
+ case $file in
+ *.exe)
+ if test ! -f "$file"; then
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ stripped_ext=.exe
+ fi
+ ;;
+ esac
+
+ # Do a test to see if this is really a libtool program.
+ case $host in
+ *cygwin* | *mingw*)
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ wrapper=$func_ltwrapper_scriptname_result
+ else
+ func_stripname '' '.exe' "$file"
+ wrapper=$func_stripname_result
+ fi
+ ;;
+ *)
+ wrapper=$file
+ ;;
+ esac
+ if func_ltwrapper_script_p "$wrapper"; then
+ notinst_deplibs=
+ relink_command=
+
+ func_source "$wrapper"
+
+ # Check the variables that should have been set.
+ test -z "$generated_by_libtool_version" && \
+ func_fatal_error "invalid libtool wrapper script '$wrapper'"
+
+ finalize=:
+ for lib in $notinst_deplibs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ func_source "$lib"
+ fi
+ libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'`
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ func_warning "'$lib' has not been installed in '$libdir'"
+ finalize=false
+ fi
+ done
+
+ relink_command=
+ func_source "$wrapper"
+
+ outputname=
+ if test no = "$fast_install" && test -n "$relink_command"; then
+ $opt_dry_run || {
+ if $finalize; then
+ tmpdir=`func_mktempdir`
+ func_basename "$file$stripped_ext"
+ file=$func_basename_result
+ outputname=$tmpdir/$file
+ # Replace the output file specification.
+ relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $opt_quiet || {
+ func_quote_for_expand "$relink_command"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ if eval "$relink_command"; then :
+ else
+ func_error "error: relink '$file' with the above command before installing it"
+ $opt_dry_run || ${RM}r "$tmpdir"
+ continue
+ fi
+ file=$outputname
+ else
+ func_warning "cannot relink '$file'"
+ fi
+ }
+ else
+ # Install the binary that we compiled earlier.
+ file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ # remove .exe since cygwin /usr/bin/install will append another
+ # one anyway
+ case $install_prog,$host in
+ */usr/bin/install*,*cygwin*)
+ case $file:$destfile in
+ *.exe:*.exe)
+ # this is ok
+ ;;
+ *.exe:*)
+ destfile=$destfile.exe
+ ;;
+ *:*.exe)
+ func_stripname '' '.exe' "$destfile"
+ destfile=$func_stripname_result
+ ;;
+ esac
+ ;;
+ esac
+ func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+ $opt_dry_run || if test -n "$outputname"; then
+ ${RM}r "$tmpdir"
+ fi
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ func_basename "$file"
+ name=$func_basename_result
+
+ # Set up the ranlib parameters.
+ oldlib=$destdir/$name
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+
+ func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+ if test -n "$stripme" && test -n "$old_striplib"; then
+ func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
+ fi
+
+ # Do each command in the postinstall commands.
+ func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+ done
+
+ test -n "$future_libdirs" && \
+ func_warning "remember to run '$progname --finish$future_libdirs'"
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ $opt_dry_run && current_libdirs=" -n$current_libdirs"
+ exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs'
+ else
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test install = "$opt_mode" && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+ $debug_cmd
+
+ my_outputname=$1
+ my_originator=$2
+ my_pic_p=${3-false}
+ my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'`
+ my_dlsyms=
+
+ if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ my_dlsyms=${my_outputname}S.c
+ else
+ func_error "not configured to extract global symbols from dlpreopened files"
+ fi
+ fi
+
+ if test -n "$my_dlsyms"; then
+ case $my_dlsyms in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist=$output_objdir/$my_outputname.nm
+
+ func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+ # Parse the name list into a source file.
+ func_verbose "creating $output_objdir/$my_dlsyms"
+
+ $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test yes = "$dlself"; then
+ func_verbose "generating symbol list for '$output'"
+
+ $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ for progfile in $progfiles; do
+ func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+ func_verbose "extracting global C symbols from '$func_to_tool_file_result'"
+ $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $opt_dry_run || {
+ eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $opt_dry_run || {
+ eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols=$output_objdir/$outputname.exp
+ $opt_dry_run || {
+ $RM $export_symbols
+ eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ else
+ $opt_dry_run || {
+ eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+ eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ fi
+ fi
+
+ for dlprefile in $dlprefiles; do
+ func_verbose "extracting global C symbols from '$dlprefile'"
+ func_basename "$dlprefile"
+ name=$func_basename_result
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ # if an import library, we need to obtain dlname
+ if func_win32_import_lib_p "$dlprefile"; then
+ func_tr_sh "$dlprefile"
+ eval "curr_lafile=\$libfile_$func_tr_sh_result"
+ dlprefile_dlbasename=
+ if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+ # Use subshell, to avoid clobbering current variable values
+ dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+ if test -n "$dlprefile_dlname"; then
+ func_basename "$dlprefile_dlname"
+ dlprefile_dlbasename=$func_basename_result
+ else
+ # no lafile. user explicitly requested -dlpreopen <import library>.
+ $sharedlib_from_linklib_cmd "$dlprefile"
+ dlprefile_dlbasename=$sharedlib_from_linklib_result
+ fi
+ fi
+ $opt_dry_run || {
+ if test -n "$dlprefile_dlbasename"; then
+ eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+ else
+ func_warning "Could not compute DLL name from $name"
+ eval '$ECHO ": $name " >> "$nlist"'
+ fi
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+ $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+ }
+ else # not an import lib
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ fi
+ ;;
+ *)
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ ;;
+ esac
+ done
+
+ $opt_dry_run || {
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $MV "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if $GREP -v "^: " < "$nlist" |
+ if sort -k 3 </dev/null >/dev/null 2>&1; then
+ sort -k 3
+ else
+ sort +2
+ fi |
+ uniq > "$nlist"S; then
+ :
+ else
+ $GREP -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+ else
+ echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+ fi
+
+ func_show_eval '$RM "${nlist}I"'
+ if test -n "$global_symbol_to_import"; then
+ eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I'
+ fi
+
+ echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols. */
+typedef struct {
+ const char *name;
+ void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];\
+"
+
+ if test -s "$nlist"I; then
+ echo >> "$output_objdir/$my_dlsyms" "\
+static void lt_syminit(void)
+{
+ LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols;
+ for (; symbol->name; ++symbol)
+ {"
+ $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms"
+ echo >> "$output_objdir/$my_dlsyms" "\
+ }
+}"
+ fi
+ echo >> "$output_objdir/$my_dlsyms" "\
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{ {\"$my_originator\", (void *) 0},"
+
+ if test -s "$nlist"I; then
+ echo >> "$output_objdir/$my_dlsyms" "\
+ {\"@INIT@\", (void *) &lt_syminit},"
+ fi
+
+ case $need_lib_prefix in
+ no)
+ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ *)
+ eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ esac
+ echo >> "$output_objdir/$my_dlsyms" "\
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ } # !$opt_dry_run
+
+ pic_flag_for_symtable=
+ case "$compile_command " in
+ *" -static "*) ;;
+ *)
+ case $host in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+ *-*-hpux*)
+ pic_flag_for_symtable=" $pic_flag" ;;
+ *)
+ $my_pic_p && pic_flag_for_symtable=" $pic_flag"
+ ;;
+ esac
+ ;;
+ esac
+ symtab_cflags=
+ for arg in $LTCFLAGS; do
+ case $arg in
+ -pie | -fpie | -fPIE) ;;
+ *) func_append symtab_cflags " $arg" ;;
+ esac
+ done
+
+ # Now compile the dynamic symbol file.
+ func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+ # Clean up the generated files.
+ func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"'
+
+ # Transform the symbol file into the correct name.
+ symfileobj=$output_objdir/${my_outputname}S.$objext
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ if test -f "$output_objdir/$my_outputname.def"; then
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ else
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ fi
+ ;;
+ *)
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ ;;
+ esac
+ ;;
+ *)
+ func_fatal_error "unknown suffix for '$my_dlsyms'"
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+ fi
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+ $debug_cmd
+
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+ test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+ $debug_cmd
+
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+ test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+ $debug_cmd
+
+ win32_libid_type=unknown
+ win32_fileres=`file -L $1 2>/dev/null`
+ case $win32_fileres in
+ *ar\ archive\ import\ library*) # definitely import
+ win32_libid_type="x86 archive import"
+ ;;
+ *ar\ archive*) # could be an import, or static
+ # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+ if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+ $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+ case $nm_interface in
+ "MS dumpbin")
+ if func_cygming_ms_implib_p "$1" ||
+ func_cygming_gnu_implib_p "$1"
+ then
+ win32_nmres=import
+ else
+ win32_nmres=
+ fi
+ ;;
+ *)
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+ $SED -n -e '
+ 1,100{
+ / I /{
+ s|.*|import|
+ p
+ q
+ }
+ }'`
+ ;;
+ esac
+ case $win32_nmres in
+ import*) win32_libid_type="x86 archive import";;
+ *) win32_libid_type="x86 archive static";;
+ esac
+ fi
+ ;;
+ *DLL*)
+ win32_libid_type="x86 DLL"
+ ;;
+ *executable*) # but shell scripts are "executable" too...
+ case $win32_fileres in
+ *MS\ Windows\ PE\ Intel*)
+ win32_libid_type="x86 DLL"
+ ;;
+ esac
+ ;;
+ esac
+ $ECHO "$win32_libid_type"
+}
+
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+ $debug_cmd
+
+ sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+ $debug_cmd
+
+ match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+ $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+ $SED '/^Contents of section '"$match_literal"':/{
+ # Place marker at beginning of archive member dllname section
+ s/.*/====MARK====/
+ p
+ d
+ }
+ # These lines can sometimes be longer than 43 characters, but
+ # are always uninteresting
+ /:[ ]*file format pe[i]\{,1\}-/d
+ /^In archive [^:]*:/d
+ # Ensure marker is printed
+ /^====MARK====/p
+ # Remove all lines with less than 43 characters
+ /^.\{43\}/!d
+ # From remaining lines, remove first 43 characters
+ s/^.\{43\}//' |
+ $SED -n '
+ # Join marker and all lines until next marker into a single line
+ /^====MARK====/ b para
+ H
+ $ b para
+ b
+ :para
+ x
+ s/\n//g
+ # Remove the marker
+ s/^====MARK====//
+ # Remove trailing dots and whitespace
+ s/[\. \t]*$//
+ # Print
+ /./p' |
+ # we now have a list, one entry per line, of the stringified
+ # contents of the appropriate section of all members of the
+ # archive that possess that section. Heuristic: eliminate
+ # all those that have a first or second character that is
+ # a '.' (that is, objdump's representation of an unprintable
+ # character.) This should work for all archives with less than
+ # 0x302f exports -- but will fail for DLLs whose name actually
+ # begins with a literal '.' or a single character followed by
+ # a '.'.
+ #
+ # Of those that remain, print the first one.
+ $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+ $debug_cmd
+
+ if func_cygming_gnu_implib_p "$1"; then
+ # binutils import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+ elif func_cygming_ms_implib_p "$1"; then
+ # ms-generated import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+ else
+ # unknown
+ sharedlib_from_linklib_result=
+ fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+ $debug_cmd
+
+ f_ex_an_ar_dir=$1; shift
+ f_ex_an_ar_oldlib=$1
+ if test yes = "$lock_old_archive_extraction"; then
+ lockfile=$f_ex_an_ar_oldlib.lock
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ fi
+ func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+ 'stat=$?; rm -f "$lockfile"; exit $stat'
+ if test yes = "$lock_old_archive_extraction"; then
+ $opt_dry_run || rm -f "$lockfile"
+ fi
+ if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+ fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+ $debug_cmd
+
+ my_gentop=$1; shift
+ my_oldlibs=${1+"$@"}
+ my_oldobjs=
+ my_xlib=
+ my_xabs=
+ my_xdir=
+
+ for my_xlib in $my_oldlibs; do
+ # Extract the objects.
+ case $my_xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;;
+ *) my_xabs=`pwd`"/$my_xlib" ;;
+ esac
+ func_basename "$my_xlib"
+ my_xlib=$func_basename_result
+ my_xlib_u=$my_xlib
+ while :; do
+ case " $extracted_archives " in
+ *" $my_xlib_u "*)
+ func_arith $extracted_serial + 1
+ extracted_serial=$func_arith_result
+ my_xlib_u=lt$extracted_serial-$my_xlib ;;
+ *) break ;;
+ esac
+ done
+ extracted_archives="$extracted_archives $my_xlib_u"
+ my_xdir=$my_gentop/$my_xlib_u
+
+ func_mkdir_p "$my_xdir"
+
+ case $host in
+ *-darwin*)
+ func_verbose "Extracting $my_xabs"
+ # Do not bother doing anything if just a dry run
+ $opt_dry_run || {
+ darwin_orig_dir=`pwd`
+ cd $my_xdir || exit $?
+ darwin_archive=$my_xabs
+ darwin_curdir=`pwd`
+ func_basename "$darwin_archive"
+ darwin_base_archive=$func_basename_result
+ darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+ if test -n "$darwin_arches"; then
+ darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+ darwin_arch=
+ func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+ for darwin_arch in $darwin_arches; do
+ func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch"
+ $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive"
+ cd "unfat-$$/$darwin_base_archive-$darwin_arch"
+ func_extract_an_archive "`pwd`" "$darwin_base_archive"
+ cd "$darwin_curdir"
+ $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive"
+ done # $darwin_arches
+ ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+ darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u`
+ darwin_file=
+ darwin_files=
+ for darwin_file in $darwin_filelist; do
+ darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+ $LIPO -create -output "$darwin_file" $darwin_files
+ done # $darwin_filelist
+ $RM -rf unfat-$$
+ cd "$darwin_orig_dir"
+ else
+ cd $darwin_orig_dir
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ fi # $darwin_arches
+ } # !$opt_dry_run
+ ;;
+ *)
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ ;;
+ esac
+ my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+ done
+
+ func_extract_archives_result=$my_oldobjs
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable. Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take. If 'yes', then the emitted script
+# will assume that the directory where it is stored is
+# the $objdir directory. This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+ func_emit_wrapper_arg1=${1-no}
+
+ $ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='$macro_version'
+ notinst_deplibs='$notinst_deplibs'
+else
+ # When we are sourced in execute mode, \$file and \$ECHO are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ file=\"\$0\""
+
+ qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+ $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+ ECHO=\"$qECHO\"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ that is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options that match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=\$0
+ shift
+ for lt_opt
+ do
+ case \"\$lt_opt\" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+ test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+ lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+ cat \"\$lt_dump_D/\$lt_dump_F\"
+ exit 0
+ ;;
+ --lt-*)
+ \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n \"\$lt_option_debug\"; then
+ echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\"
+ lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+ case $host in
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2* | *-cegcc*)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $ECHO "\
+ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ case \" \$* \" in
+ *\\ --lt-*)
+ for lt_wr_arg
+ do
+ case \$lt_wr_arg in
+ --lt-*) ;;
+ *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+ esac
+ shift
+ done ;;
+ esac
+ func_exec_program_core \${1+\"\$@\"}
+}
+
+ # Parse options
+ func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+ done
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+ if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+ # special case for '.'
+ if test \"\$thisdir\" = \".\"; then
+ thisdir=\`pwd\`
+ fi
+ # remove .libs from thisdir
+ case \"\$thisdir\" in
+ *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+ $objdir ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test yes = "$fast_install"; then
+ $ECHO "\
+ program=lt-'$outputname'$exeext
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" ||
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $MKDIR \"\$progdir\"
+ else
+ $RM \"\$progdir/\$file\"
+ fi"
+
+ $ECHO "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+ else
+ \$ECHO \"\$relink_command_output\" >&2
+ $RM \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $RM \"\$progdir/\$program\";
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $RM \"\$progdir/\$file\"
+ fi"
+ else
+ $ECHO "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ $ECHO "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # fixup the dll searchpath if we need to.
+ #
+ # Fix the DLL searchpath if we need to. Do this before prepending
+ # to shlibpath, because on Windows, both are PATH and uninstalled
+ # libraries must come first.
+ if test -n "$dllsearchpath"; then
+ $ECHO "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ # Export our shlibpath_var if we have one.
+ if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $ECHO "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ $ECHO "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+ func_exec_program \${1+\"\$@\"}
+ fi
+ else
+ # The program doesn't exist.
+ \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2
+ \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+ \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+ cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+ Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+
+ The $output program cannot be directly executed until all the libtool
+ libraries that it depends on are installed.
+
+ This wrapper executable should never be moved out of the build directory.
+ If it is, it will not operate correctly.
+*/
+EOF
+ cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+# include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
+
+/* declarations of non-ANSI functions */
+#if defined __MINGW32__
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined __CYGWIN__
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined other_platform || defined ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined _MSC_VER
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+# define S_IXUSR _S_IEXEC
+#elif defined __MINGW32__
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+#elif defined __CYGWIN__
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined other platforms ... */
+#endif
+
+#if defined PATH_MAX
+# define LT_PATHMAX PATH_MAX
+#elif defined MAXPATHLEN
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \
+ defined __OS2__
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+# define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+# define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+ if (stale) { free (stale); stale = 0; } \
+} while (0)
+
+#if defined LT_DEBUGWRAPPER
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+ cat <<EOF
+#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)
+# define externally_visible volatile
+#else
+# define externally_visible __attribute__((externally_visible)) volatile
+#endif
+externally_visible const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+ if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ func_to_host_path "$temp_rpath"
+ cat <<EOF
+const char * LIB_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * LIB_PATH_VALUE = "";
+EOF
+ fi
+
+ if test -n "$dllsearchpath"; then
+ func_to_host_path "$dllsearchpath:"
+ cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE = "";
+EOF
+ fi
+
+ if test yes = "$fast_install"; then
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+ else
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+ fi
+
+
+ cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug";
+
+int
+main (int argc, char *argv[])
+{
+ char **newargz;
+ int newargc;
+ char *tmp_pathspec;
+ char *actual_cwrapper_path;
+ char *actual_cwrapper_name;
+ char *target_name;
+ char *lt_argv_zero;
+ int rval = 127;
+
+ int i;
+
+ program_name = (char *) xstrdup (base_name (argv[0]));
+ newargz = XMALLOC (char *, (size_t) argc + 1);
+
+ /* very simple arg parsing; don't want to rely on getopt
+ * also, copy all non cwrapper options to newargz, except
+ * argz[0], which is handled differently
+ */
+ newargc=0;
+ for (i = 1; i < argc; i++)
+ {
+ if (STREQ (argv[i], dumpscript_opt))
+ {
+EOF
+ case $host in
+ *mingw* | *cygwin* )
+ # make stdout use "unix" line endings
+ echo " setmode(1,_O_BINARY);"
+ ;;
+ esac
+
+ cat <<"EOF"
+ lt_dump_script (stdout);
+ return 0;
+ }
+ if (STREQ (argv[i], debug_opt))
+ {
+ lt_debug = 1;
+ continue;
+ }
+ if (STREQ (argv[i], ltwrapper_option_prefix))
+ {
+ /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+ namespace, but it is not one of the ones we know about and
+ have already dealt with, above (inluding dump-script), then
+ report an error. Otherwise, targets might begin to believe
+ they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+ namespace. The first time any user complains about this, we'll
+ need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+ or a configure.ac-settable value.
+ */
+ lt_fatal (__FILE__, __LINE__,
+ "unrecognized %s option: '%s'",
+ ltwrapper_option_prefix, argv[i]);
+ }
+ /* otherwise ... */
+ newargz[++newargc] = xstrdup (argv[i]);
+ }
+ newargz[++newargc] = NULL;
+
+EOF
+ cat <<EOF
+ /* The GNU banner must be the first non-error debug message */
+ lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE) $VERSION\n");
+EOF
+ cat <<"EOF"
+ lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+ tmp_pathspec = find_executable (argv[0]);
+ if (tmp_pathspec == NULL)
+ lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (before symlink chase) at: %s\n",
+ tmp_pathspec);
+
+ actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (after symlink chase) at: %s\n",
+ actual_cwrapper_path);
+ XFREE (tmp_pathspec);
+
+ actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+ strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+ /* wrapper name transforms */
+ strendzap (actual_cwrapper_name, ".exe");
+ tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+ XFREE (actual_cwrapper_name);
+ actual_cwrapper_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ /* target_name transforms -- use actual target program name; might have lt- prefix */
+ target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+ strendzap (target_name, ".exe");
+ tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+ XFREE (target_name);
+ target_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) libtool target name: %s\n",
+ target_name);
+EOF
+
+ cat <<EOF
+ newargz[0] =
+ XMALLOC (char, (strlen (actual_cwrapper_path) +
+ strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+ strcpy (newargz[0], actual_cwrapper_path);
+ strcat (newargz[0], "$objdir");
+ strcat (newargz[0], "/");
+EOF
+
+ cat <<"EOF"
+ /* stop here, and copy so we don't have to do this twice */
+ tmp_pathspec = xstrdup (newargz[0]);
+
+ /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+ strcat (newargz[0], actual_cwrapper_name);
+
+ /* DO want the lt- prefix here if it exists, so use target_name */
+ lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+ XFREE (tmp_pathspec);
+ tmp_pathspec = NULL;
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ {
+ char* p;
+ while ((p = strchr (newargz[0], '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ }
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+ XFREE (target_name);
+ XFREE (actual_cwrapper_path);
+ XFREE (actual_cwrapper_name);
+
+ lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+ lt_setenv ("DUALCASE", "1"); /* for MSK sh */
+ /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must
+ be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+ because on Windows, both *_VARNAMEs are PATH but uninstalled
+ libraries must come first. */
+ lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+ lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+ lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+ nonnull (lt_argv_zero));
+ for (i = 0; i < newargc; i++)
+ {
+ lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+ i, nonnull (newargz[i]));
+ }
+
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ /* execv doesn't actually work on mingw as expected on unix */
+ newargz = prepare_spawn (newargz);
+ rval = (int) _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+ if (rval == -1)
+ {
+ /* failed to start process */
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) failed to launch target \"%s\": %s\n",
+ lt_argv_zero, nonnull (strerror (errno)));
+ return 127;
+ }
+ return rval;
+EOF
+ ;;
+ *)
+ cat <<"EOF"
+ execv (lt_argv_zero, newargz);
+ return rval; /* =127, but avoids unused variable warning */
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+ void *p = (void *) malloc (num);
+ if (!p)
+ lt_fatal (__FILE__, __LINE__, "memory exhausted");
+
+ return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+ return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+ string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+ const char *base;
+
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+ /* Skip over the disk name in MSDOS pathnames. */
+ if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+ name += 2;
+#endif
+
+ for (base = name; *name; name++)
+ if (IS_DIR_SEPARATOR (*name))
+ base = name + 1;
+ return base;
+}
+
+int
+check_executable (const char *path)
+{
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if ((stat (path, &st) >= 0)
+ && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ return 1;
+ else
+ return 0;
+}
+
+int
+make_executable (const char *path)
+{
+ int rval = 0;
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if (stat (path, &st) >= 0)
+ {
+ rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+ }
+ return rval;
+}
+
+/* Searches for the full path of the wrapper. Returns
+ newly allocated full path name if found, NULL otherwise
+ Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+ int has_slash = 0;
+ const char *p;
+ const char *p_next;
+ /* static buffer for getcwd */
+ char tmp[LT_PATHMAX + 1];
+ size_t tmp_len;
+ char *concat_name;
+
+ lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+ nonempty (wrapper));
+
+ if ((wrapper == NULL) || (*wrapper == '\0'))
+ return NULL;
+
+ /* Absolute path? */
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+ if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ else
+ {
+#endif
+ if (IS_DIR_SEPARATOR (wrapper[0]))
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+ }
+#endif
+
+ for (p = wrapper; *p; p++)
+ if (*p == '/')
+ {
+ has_slash = 1;
+ break;
+ }
+ if (!has_slash)
+ {
+ /* no slashes; search PATH */
+ const char *path = getenv ("PATH");
+ if (path != NULL)
+ {
+ for (p = path; *p; p = p_next)
+ {
+ const char *q;
+ size_t p_len;
+ for (q = p; *q; q++)
+ if (IS_PATH_SEPARATOR (*q))
+ break;
+ p_len = (size_t) (q - p);
+ p_next = (*q == '\0' ? q : q + 1);
+ if (p_len == 0)
+ {
+ /* empty path: current directory */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name =
+ XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+ }
+ else
+ {
+ concat_name =
+ XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, p, p_len);
+ concat_name[p_len] = '/';
+ strcpy (concat_name + p_len + 1, wrapper);
+ }
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ }
+ /* not found in PATH; assume curdir */
+ }
+ /* Relative path | not found in path: prepend cwd */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+ return xstrdup (pathspec);
+#else
+ char buf[LT_PATHMAX];
+ struct stat s;
+ char *tmp_pathspec = xstrdup (pathspec);
+ char *p;
+ int has_symlinks = 0;
+ while (strlen (tmp_pathspec) && !has_symlinks)
+ {
+ lt_debugprintf (__FILE__, __LINE__,
+ "checking path component for symlinks: %s\n",
+ tmp_pathspec);
+ if (lstat (tmp_pathspec, &s) == 0)
+ {
+ if (S_ISLNK (s.st_mode) != 0)
+ {
+ has_symlinks = 1;
+ break;
+ }
+
+ /* search backwards for last DIR_SEPARATOR */
+ p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+ while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ p--;
+ if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ {
+ /* no more DIR_SEPARATORS left */
+ break;
+ }
+ *p = '\0';
+ }
+ else
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "error accessing file \"%s\": %s",
+ tmp_pathspec, nonnull (strerror (errno)));
+ }
+ }
+ XFREE (tmp_pathspec);
+
+ if (!has_symlinks)
+ {
+ return xstrdup (pathspec);
+ }
+
+ tmp_pathspec = realpath (pathspec, buf);
+ if (tmp_pathspec == 0)
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "could not follow symlinks for %s", pathspec);
+ }
+ return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+ size_t len, patlen;
+
+ assert (str != NULL);
+ assert (pat != NULL);
+
+ len = strlen (str);
+ patlen = strlen (pat);
+
+ if (patlen <= len)
+ {
+ str += len - patlen;
+ if (STREQ (str, pat))
+ *str = '\0';
+ }
+ return str;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+ va_list args;
+ if (lt_debug)
+ {
+ (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+ va_start (args, fmt);
+ (void) vfprintf (stderr, fmt, args);
+ va_end (args);
+ }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+ int line, const char *mode,
+ const char *message, va_list ap)
+{
+ fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+ vfprintf (stderr, message, ap);
+ fprintf (stderr, ".\n");
+
+ if (exit_status >= 0)
+ exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+ va_list ap;
+ va_start (ap, message);
+ lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+ va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+ return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+ return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_setenv) setting '%s' to '%s'\n",
+ nonnull (name), nonnull (value));
+ {
+#ifdef HAVE_SETENV
+ /* always make a copy, for consistency with !HAVE_SETENV */
+ char *str = xstrdup (value);
+ setenv (name, str, 1);
+#else
+ size_t len = strlen (name) + 1 + strlen (value) + 1;
+ char *str = XMALLOC (char, len);
+ sprintf (str, "%s=%s", name, value);
+ if (putenv (str) != EXIT_SUCCESS)
+ {
+ XFREE (str);
+ }
+#endif
+ }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+ char *new_value;
+ if (orig_value && *orig_value)
+ {
+ size_t orig_value_len = strlen (orig_value);
+ size_t add_len = strlen (add);
+ new_value = XMALLOC (char, add_len + orig_value_len + 1);
+ if (to_end)
+ {
+ strcpy (new_value, orig_value);
+ strcpy (new_value + orig_value_len, add);
+ }
+ else
+ {
+ strcpy (new_value, add);
+ strcpy (new_value + add_len, orig_value);
+ }
+ }
+ else
+ {
+ new_value = xstrdup (add);
+ }
+ return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ /* some systems can't cope with a ':'-terminated path #' */
+ size_t len = strlen (new_value);
+ while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+ {
+ new_value[--len] = '\0';
+ }
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+EOF
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+ Note that spawn() does not by itself call the command interpreter
+ (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+ ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&v);
+ v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+ }) ? "cmd.exe" : "command.com").
+ Instead it simply concatenates the arguments, separated by ' ', and calls
+ CreateProcess(). We must quote the arguments since Win32 CreateProcess()
+ interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+ special way:
+ - Space and tab are interpreted as delimiters. They are not treated as
+ delimiters if they are surrounded by double quotes: "...".
+ - Unescaped double quotes are removed from the input. Their only effect is
+ that within double quotes, space and tab are treated like normal
+ characters.
+ - Backslashes not followed by double quotes are not special.
+ - But 2*n+1 backslashes followed by a double quote become
+ n backslashes followed by a double quote (n >= 0):
+ \" -> "
+ \\\" -> \"
+ \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+ size_t argc;
+ char **new_argv;
+ size_t i;
+
+ /* Count number of arguments. */
+ for (argc = 0; argv[argc] != NULL; argc++)
+ ;
+
+ /* Allocate new argument vector. */
+ new_argv = XMALLOC (char *, argc + 1);
+
+ /* Put quoted arguments into the new argument vector. */
+ for (i = 0; i < argc; i++)
+ {
+ const char *string = argv[i];
+
+ if (string[0] == '\0')
+ new_argv[i] = xstrdup ("\"\"");
+ else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+ {
+ int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+ size_t length;
+ unsigned int backslashes;
+ const char *s;
+ char *quoted_string;
+ char *p;
+
+ length = 0;
+ backslashes = 0;
+ if (quote_around)
+ length++;
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ length += backslashes + 1;
+ length++;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ length += backslashes + 1;
+
+ quoted_string = XMALLOC (char, length + 1);
+
+ p = quoted_string;
+ backslashes = 0;
+ if (quote_around)
+ *p++ = '"';
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ {
+ unsigned int j;
+ for (j = backslashes + 1; j > 0; j--)
+ *p++ = '\\';
+ }
+ *p++ = c;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ {
+ unsigned int j;
+ for (j = backslashes; j > 0; j--)
+ *p++ = '\\';
+ *p++ = '"';
+ }
+ *p = '\0';
+
+ new_argv[i] = quoted_string;
+ }
+ else
+ new_argv[i] = (char *) string;
+ }
+ new_argv[argc] = NULL;
+
+ return new_argv;
+}
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+ func_emit_wrapper yes |
+ $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/ fputs ("\1", f);/p
+g
+D'
+ cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+ $debug_cmd
+
+ case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+ *import*) : ;;
+ *) false ;;
+ esac
+}
+
+# func_suncc_cstd_abi
+# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!!
+# Several compiler flags select an ABI that is incompatible with the
+# Cstd library. Avoid specifying it if any are in CXXFLAGS.
+func_suncc_cstd_abi ()
+{
+ $debug_cmd
+
+ case " $compile_command " in
+ *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*)
+ suncc_use_cstd_abi=no
+ ;;
+ *)
+ suncc_use_cstd_abi=yes
+ ;;
+ esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+ $debug_cmd
+
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # what system we are compiling for in order to pass an extra
+ # flag for every libtool invocation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll that has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ libtool_args=$nonopt
+ base_compile="$nonopt $@"
+ compile_command=$nonopt
+ finalize_command=$nonopt
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ old_deplibs=
+ compiler_flags=
+ linker_flags=
+ dllsearchpath=
+ lib_search_path=`pwd`
+ inst_prefix_dir=
+ new_inherited_linker_flags=
+
+ avoid_version=no
+ bindir=
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ ltlibs=
+ module=no
+ no_install=no
+ objs=
+ os2dllname=
+ non_pic_objects=
+ precious_files_regex=
+ prefer_static_libs=no
+ preload=false
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+ vinfo_number=no
+ weak_libs=
+ single_module=$wl-single_module
+ func_infer_tag $base_compile
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case $arg in
+ -shared)
+ test yes != "$build_libtool_libs" \
+ && func_fatal_configuration "cannot build a shared library"
+ build_old_libs=no
+ break
+ ;;
+ -all-static | -static | -static-libtool-libs)
+ case $arg in
+ -all-static)
+ if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then
+ func_warning "complete static linking is impossible in this configuration"
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ -static)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=built
+ ;;
+ -static-libtool-libs)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ esac
+ build_libtool_libs=no
+ build_old_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test "$#" -gt 0; do
+ arg=$1
+ shift
+ func_quote_for_eval "$arg"
+ qarg=$func_quote_for_eval_unquoted_result
+ func_append libtool_args " $func_quote_for_eval_result"
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ output)
+ func_append compile_command " @OUTPUT@"
+ func_append finalize_command " @OUTPUT@"
+ ;;
+ esac
+
+ case $prev in
+ bindir)
+ bindir=$arg
+ prev=
+ continue
+ ;;
+ dlfiles|dlprefiles)
+ $preload || {
+ # Add the symbol object into the linking commands.
+ func_append compile_command " @SYMFILE@"
+ func_append finalize_command " @SYMFILE@"
+ preload=:
+ }
+ case $arg in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test no = "$dlself"; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test dlprefiles = "$prev"; then
+ dlself=yes
+ elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test dlfiles = "$prev"; then
+ func_append dlfiles " $arg"
+ else
+ func_append dlprefiles " $arg"
+ fi
+ prev=
+ continue
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols=$arg
+ test -f "$arg" \
+ || func_fatal_error "symbol file '$arg' does not exist"
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex=$arg
+ prev=
+ continue
+ ;;
+ framework)
+ case $host in
+ *-*-darwin*)
+ case "$deplibs " in
+ *" $qarg.ltframework "*) ;;
+ *) func_append deplibs " $qarg.ltframework" # this is fixed later
+ ;;
+ esac
+ ;;
+ esac
+ prev=
+ continue
+ ;;
+ inst_prefix)
+ inst_prefix_dir=$arg
+ prev=
+ continue
+ ;;
+ mllvm)
+ # Clang does not use LLVM to link, so we can simply discard any
+ # '-mllvm $arg' options when doing the link step.
+ prev=
+ continue
+ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+ moreargs=
+ for fil in `cat "$save_arg"`
+ do
+# func_append moreargs " $fil"
+ arg=$fil
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test none = "$pic_object" &&
+ test none = "$non_pic_object"; then
+ func_fatal_error "cannot find name of object for '$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ if test none != "$pic_object"; then
+ # Prepend the subdirectory the object is found in.
+ pic_object=$xdir$pic_object
+
+ if test dlfiles = "$prev"; then
+ if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test dlprefiles = "$prev"; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg=$pic_object
+ fi
+
+ # Non-PIC object.
+ if test none != "$non_pic_object"; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object=$xdir$non_pic_object
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test none = "$pic_object"; then
+ arg=$non_pic_object
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object=$pic_object
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "'$arg' is not a valid libtool object"
+ fi
+ fi
+ done
+ else
+ func_fatal_error "link input file '$arg' does not exist"
+ fi
+ arg=$save_arg
+ prev=
+ continue
+ ;;
+ os2dllname)
+ os2dllname=$arg
+ prev=
+ continue
+ ;;
+ precious_regex)
+ precious_files_regex=$arg
+ prev=
+ continue
+ ;;
+ release)
+ release=-$arg
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case $arg in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ if test rpath = "$prev"; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) func_append rpath " $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) func_append xrpath " $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ shrext)
+ shrext_cmds=$arg
+ prev=
+ continue
+ ;;
+ weak)
+ func_append weak_libs " $arg"
+ prev=
+ continue
+ ;;
+ xcclinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xcompiler)
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xlinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $wl$qarg"
+ prev=
+ func_append compile_command " $wl$qarg"
+ func_append finalize_command " $wl$qarg"
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi # test -n "$prev"
+
+ prevarg=$arg
+
+ case $arg in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ # See comment for -static flag below, for more details.
+ func_append compile_command " $link_static_flag"
+ func_append finalize_command " $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ func_fatal_error "'-allow-undefined' must not be used because it is the default"
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -bindir)
+ prev=bindir
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ func_fatal_error "more than one -exported-symbols argument is not allowed"
+ fi
+ if test X-export-symbols = "X$arg"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -framework)
+ prev=framework
+ continue
+ ;;
+
+ -inst-prefix-dir)
+ prev=inst_prefix
+ continue
+ ;;
+
+ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+ # so, if we see these flags be careful not to treat them like -L
+ -L[A-Z][A-Z]*:*)
+ case $with_gcc/$host in
+ no/*-*-irix* | /*-*-irix*)
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ ;;
+ esac
+ continue
+ ;;
+
+ -L*)
+ func_stripname "-L" '' "$arg"
+ if test -z "$func_stripname_result"; then
+ if test "$#" -gt 0; then
+ func_fatal_error "require no space between '-L' and '$1'"
+ else
+ func_fatal_error "need path for '-L' option"
+ fi
+ fi
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ test -z "$absdir" && \
+ func_fatal_error "cannot determine absolute directory name of '$dir'"
+ dir=$absdir
+ ;;
+ esac
+ case "$deplibs " in
+ *" -L$dir "* | *" $arg "*)
+ # Will only happen for absolute or sysroot arguments
+ ;;
+ *)
+ # Preserve sysroot, but never include relative directories
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+ *) func_append deplibs " -L$dir" ;;
+ esac
+ func_append lib_search_path " $dir"
+ ;;
+ esac
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$dir:"*) ;;
+ ::) dllsearchpath=$dir;;
+ *) func_append dllsearchpath ":$dir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ continue
+ ;;
+
+ -l*)
+ if test X-lc = "X$arg" || test X-lm = "X$arg"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # These systems don't actually have a C or math library (as such)
+ continue
+ ;;
+ *-*-os2*)
+ # These systems don't actually have a C library (as such)
+ test X-lc = "X$arg" && continue
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+ # Do not include libc due to us having libc/libc_r.
+ test X-lc = "X$arg" && continue
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C and math libraries are in the System framework
+ func_append deplibs " System.ltframework"
+ continue
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ test X-lc = "X$arg" && continue
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ test X-lc = "X$arg" && continue
+ ;;
+ esac
+ elif test X-lc_r = "X$arg"; then
+ case $host in
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+ # Do not include libc_r directly, use -pthread flag.
+ continue
+ ;;
+ esac
+ fi
+ func_append deplibs " $arg"
+ continue
+ ;;
+
+ -mllvm)
+ prev=mllvm
+ continue
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ # Tru64 UNIX uses -model [arg] to determine the layout of C++
+ # classes, name mangling, and exception handling.
+ # Darwin uses the -arch flag to determine output architecture.
+ -model|-arch|-isysroot|--sysroot)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ prev=xcompiler
+ continue
+ ;;
+
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case "$new_inherited_linker_flags " in
+ *" $arg "*) ;;
+ * ) func_append new_inherited_linker_flags " $arg" ;;
+ esac
+ continue
+ ;;
+
+ -multi_module)
+ single_module=$wl-multi_module
+ continue
+ ;;
+
+ -no-fast-install)
+ fast_install=no
+ continue
+ ;;
+
+ -no-install)
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+ # The PATH hackery in wrapper scripts is required on Windows
+ # and Darwin in order for the loader to find any dlls it needs.
+ func_warning "'-no-install' is ignored for $host"
+ func_warning "assuming '-no-fast-install' instead"
+ fast_install=no
+ ;;
+ *) no_install=yes ;;
+ esac
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -objectlist)
+ prev=objectlist
+ continue
+ ;;
+
+ -os2dllname)
+ prev=os2dllname
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -precious-files-regex)
+ prev=precious_regex
+ continue
+ ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ func_stripname '-R' '' "$arg"
+ dir=$func_stripname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ =*)
+ func_stripname '=' '' "$dir"
+ dir=$lt_sysroot$func_stripname_result
+ ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ continue
+ ;;
+
+ -shared)
+ # The effects of -shared are defined in a previous loop.
+ continue
+ ;;
+
+ -shrext)
+ prev=shrext
+ continue
+ ;;
+
+ -static | -static-libtool-libs)
+ # The effects of -static are defined in a previous loop.
+ # We used to do the same as -all-static on platforms that
+ # didn't have a PIC flag, but the assumption that the effects
+ # would be equivalent was wrong. It would break on at least
+ # Digital Unix and AIX.
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ -version-number)
+ prev=vinfo
+ vinfo_number=yes
+ continue
+ ;;
+
+ -weak)
+ prev=weak
+ continue
+ ;;
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs=$IFS; IFS=,
+ for flag in $args; do
+ IFS=$save_ifs
+ func_quote_for_eval "$flag"
+ func_append arg " $func_quote_for_eval_result"
+ func_append compiler_flags " $func_quote_for_eval_result"
+ done
+ IFS=$save_ifs
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Wl,*)
+ func_stripname '-Wl,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs=$IFS; IFS=,
+ for flag in $args; do
+ IFS=$save_ifs
+ func_quote_for_eval "$flag"
+ func_append arg " $wl$func_quote_for_eval_result"
+ func_append compiler_flags " $wl$func_quote_for_eval_result"
+ func_append linker_flags " $func_quote_for_eval_result"
+ done
+ IFS=$save_ifs
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Xlinker)
+ prev=xlinker
+ continue
+ ;;
+
+ -XCClinker)
+ prev=xcclinker
+ continue
+ ;;
+
+ # -msg_* for osf cc
+ -msg_*)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ ;;
+
+ # Flags to be passed through unchanged, with rationale:
+ # -64, -mips[0-9] enable 64-bit mode for the SGI compiler
+ # -r[0-9][0-9]* specify processor for the SGI compiler
+ # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+ # +DA*, +DD* enable 64-bit mode for the HP compiler
+ # -q* compiler args for the IBM compiler
+ # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+ # -F/path path to uninstalled frameworks, gcc on darwin
+ # -p, -pg, --coverage, -fprofile-* profiling flags for GCC
+ # -fstack-protector* stack protector flags for GCC
+ # @file GCC response files
+ # -tp=* Portland pgcc target processor selection
+ # --sysroot=* for sysroot support
+ # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+ # -specs=* GCC specs files
+ # -stdlib=* select c++ std lib with clang
+ # -fsanitize=* Clang/GCC memory and address sanitizer
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
+ -specs=*|-fsanitize=*)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ func_append compiler_flags " $arg"
+ continue
+ ;;
+
+ -Z*)
+ if test os2 = "`expr $host : '.*\(os2\)'`"; then
+ # OS/2 uses -Zxxx to specify OS/2-specific options
+ compiler_flags="$compiler_flags $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case $arg in
+ -Zlinker | -Zstack)
+ prev=xcompiler
+ ;;
+ esac
+ continue
+ else
+ # Otherwise treat like 'Some other compiler flag' below
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ fi
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ ;;
+
+ *.$objext)
+ # A standard object.
+ func_append objs " $arg"
+ ;;
+
+ *.lo)
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test none = "$pic_object" &&
+ test none = "$non_pic_object"; then
+ func_fatal_error "cannot find name of object for '$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ test none = "$pic_object" || {
+ # Prepend the subdirectory the object is found in.
+ pic_object=$xdir$pic_object
+
+ if test dlfiles = "$prev"; then
+ if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test dlprefiles = "$prev"; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg=$pic_object
+ }
+
+ # Non-PIC object.
+ if test none != "$non_pic_object"; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object=$xdir$non_pic_object
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test none = "$pic_object"; then
+ arg=$non_pic_object
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object=$pic_object
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "'$arg' is not a valid libtool object"
+ fi
+ fi
+ ;;
+
+ *.$libext)
+ # An archive.
+ func_append deplibs " $arg"
+ func_append old_deplibs " $arg"
+ continue
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ func_resolve_sysroot "$arg"
+ if test dlfiles = "$prev"; then
+ # This library was specified with -dlopen.
+ func_append dlfiles " $func_resolve_sysroot_result"
+ prev=
+ elif test dlprefiles = "$prev"; then
+ # The library was specified with -dlpreopen.
+ func_append dlprefiles " $func_resolve_sysroot_result"
+ prev=
+ else
+ func_append deplibs " $func_resolve_sysroot_result"
+ fi
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ ;;
+ esac # arg
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+ done # argument parsing loop
+
+ test -n "$prev" && \
+ func_fatal_help "the '$prevarg' option requires an argument"
+
+ if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ func_basename "$output"
+ outputname=$func_basename_result
+ libobjs_save=$libobjs
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\`
+ else
+ shlib_search_path=
+ fi
+ eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ # Definition is injected by LT_CONFIG during libtool generation.
+ func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH"
+
+ func_dirname "$output" "/" ""
+ output_objdir=$func_dirname_result$objdir
+ func_to_tool_file "$output_objdir/"
+ tool_output_objdir=$func_to_tool_file_result
+ # Create the object directory.
+ func_mkdir_p "$output_objdir"
+
+ # Determine the type of output
+ case $output in
+ "")
+ func_fatal_help "you must specify an output file"
+ ;;
+ *.$libext) linkmode=oldlib ;;
+ *.lo | *.$objext) linkmode=obj ;;
+ *.la) linkmode=lib ;;
+ *) linkmode=prog ;; # Anything else should be a program.
+ esac
+
+ specialdeplibs=
+
+ libs=
+ # Find all interdependent deplibs by searching for libraries
+ # that are linked more than once (e.g. -la -lb -la)
+ for deplib in $deplibs; do
+ if $opt_preserve_dup_deps; then
+ case "$libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append libs " $deplib"
+ done
+
+ if test lib = "$linkmode"; then
+ libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+ # Compute libraries that are listed more than once in $predeps
+ # $postdeps and mark them as special (i.e., whose duplicates are
+ # not to be eliminated).
+ pre_post_deps=
+ if $opt_duplicate_compiler_generated_deps; then
+ for pre_post_dep in $predeps $postdeps; do
+ case "$pre_post_deps " in
+ *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+ esac
+ func_append pre_post_deps " $pre_post_dep"
+ done
+ fi
+ pre_post_deps=
+ fi
+
+ deplibs=
+ newdependency_libs=
+ newlib_search_path=
+ need_relink=no # whether we're linking any uninstalled libtool libraries
+ notinst_deplibs= # not-installed libtool libraries
+ notinst_path= # paths that contain not-installed libtool libraries
+
+ case $linkmode in
+ lib)
+ passes="conv dlpreopen link"
+ for file in $dlfiles $dlprefiles; do
+ case $file in
+ *.la) ;;
+ *)
+ func_fatal_help "libraries can '-dlopen' only libtool libraries: $file"
+ ;;
+ esac
+ done
+ ;;
+ prog)
+ compile_deplibs=
+ finalize_deplibs=
+ alldeplibs=false
+ newdlfiles=
+ newdlprefiles=
+ passes="conv scan dlopen dlpreopen link"
+ ;;
+ *) passes="conv"
+ ;;
+ esac
+
+ for pass in $passes; do
+ # The preopen pass in lib mode reverses $deplibs; put it back here
+ # so that -L comes before libs that need it for instance...
+ if test lib,link = "$linkmode,$pass"; then
+ ## FIXME: Find the place where the list is rebuilt in the wrong
+ ## order, and fix it there properly
+ tmp_deplibs=
+ for deplib in $deplibs; do
+ tmp_deplibs="$deplib $tmp_deplibs"
+ done
+ deplibs=$tmp_deplibs
+ fi
+
+ if test lib,link = "$linkmode,$pass" ||
+ test prog,scan = "$linkmode,$pass"; then
+ libs=$deplibs
+ deplibs=
+ fi
+ if test prog = "$linkmode"; then
+ case $pass in
+ dlopen) libs=$dlfiles ;;
+ dlpreopen) libs=$dlprefiles ;;
+ link)
+ libs="$deplibs %DEPLIBS%"
+ test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
+ ;;
+ esac
+ fi
+ if test lib,dlpreopen = "$linkmode,$pass"; then
+ # Collect and forward deplibs of preopened libtool libs
+ for lib in $dlprefiles; do
+ # Ignore non-libtool-libs
+ dependency_libs=
+ func_resolve_sysroot "$lib"
+ case $lib in
+ *.la) func_source "$func_resolve_sysroot_result" ;;
+ esac
+
+ # Collect preopened libtool deplibs, except any this library
+ # has declared as weak libs
+ for deplib in $dependency_libs; do
+ func_basename "$deplib"
+ deplib_base=$func_basename_result
+ case " $weak_libs " in
+ *" $deplib_base "*) ;;
+ *) func_append deplibs " $deplib" ;;
+ esac
+ done
+ done
+ libs=$dlprefiles
+ fi
+ if test dlopen = "$pass"; then
+ # Collect dlpreopened libraries
+ save_deplibs=$deplibs
+ deplibs=
+ fi
+
+ for deplib in $libs; do
+ lib=
+ found=false
+ case $deplib in
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append compiler_flags " $deplib"
+ if test lib = "$linkmode"; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -l*)
+ if test lib != "$linkmode" && test prog != "$linkmode"; then
+ func_warning "'-l' is ignored for archives/objects"
+ continue
+ fi
+ func_stripname '-l' '' "$deplib"
+ name=$func_stripname_result
+ if test lib = "$linkmode"; then
+ searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+ else
+ searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+ fi
+ for searchdir in $searchdirs; do
+ for search_ext in .la $std_shrext .so .a; do
+ # Search the libtool library
+ lib=$searchdir/lib$name$search_ext
+ if test -f "$lib"; then
+ if test .la = "$search_ext"; then
+ found=:
+ else
+ found=false
+ fi
+ break 2
+ fi
+ done
+ done
+ if $found; then
+ # deplib is a libtool library
+ # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+ # We need to do some special things here, and not later.
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $deplib "*)
+ if func_lalib_p "$lib"; then
+ library_names=
+ old_library=
+ func_source "$lib"
+ for l in $old_library $library_names; do
+ ll=$l
+ done
+ if test "X$ll" = "X$old_library"; then # only static version available
+ found=false
+ func_dirname "$lib" "" "."
+ ladir=$func_dirname_result
+ lib=$ladir/$old_library
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ fi
+ ;;
+ *) ;;
+ esac
+ fi
+ else
+ # deplib doesn't seem to be a libtool library
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ ;; # -l
+ *.ltframework)
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ if test lib = "$linkmode"; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -L*)
+ case $linkmode in
+ lib)
+ deplibs="$deplib $deplibs"
+ test conv = "$pass" && continue
+ newdependency_libs="$deplib $newdependency_libs"
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ prog)
+ if test conv = "$pass"; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ if test scan = "$pass"; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ *)
+ func_warning "'-L' is ignored for archives/objects"
+ ;;
+ esac # linkmode
+ continue
+ ;; # -L
+ -R*)
+ if test link = "$pass"; then
+ func_stripname '-R' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # Make sure the xrpath contains only unique directories.
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ fi
+ deplibs="$deplib $deplibs"
+ continue
+ ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ lib=$func_resolve_sysroot_result
+ ;;
+ *.$libext)
+ if test conv = "$pass"; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ case $linkmode in
+ lib)
+ # Linking convenience modules into shared libraries is allowed,
+ # but linking other static libraries is non-portable.
+ case " $dlpreconveniencelibs " in
+ *" $deplib "*) ;;
+ *)
+ valid_a_lib=false
+ case $deplibs_check_method in
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
+ | $EGREP "$match_pattern_regex" > /dev/null; then
+ valid_a_lib=:
+ fi
+ ;;
+ pass_all)
+ valid_a_lib=:
+ ;;
+ esac
+ if $valid_a_lib; then
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the"
+ $ECHO "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
+ else
+ echo
+ $ECHO "*** Warning: Trying to link with static lib archive $deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because the file extensions .$libext of this argument makes me believe"
+ echo "*** that it is just a static archive that I should not use here."
+ fi
+ ;;
+ esac
+ continue
+ ;;
+ prog)
+ if test link != "$pass"; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ continue
+ ;;
+ esac # linkmode
+ ;; # *.$libext
+ *.lo | *.$objext)
+ if test conv = "$pass"; then
+ deplibs="$deplib $deplibs"
+ elif test prog = "$linkmode"; then
+ if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then
+ # If there is no dlopen support or we're linking statically,
+ # we need to preload.
+ func_append newdlprefiles " $deplib"
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append newdlfiles " $deplib"
+ fi
+ fi
+ continue
+ ;;
+ %DEPLIBS%)
+ alldeplibs=:
+ continue
+ ;;
+ esac # case $deplib
+
+ $found || test -f "$lib" \
+ || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'"
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$lib" \
+ || func_fatal_error "'$lib' is not a valid libtool archive"
+
+ func_dirname "$lib" "" "."
+ ladir=$func_dirname_result
+
+ dlname=
+ dlopen=
+ dlpreopen=
+ libdir=
+ library_names=
+ old_library=
+ inherited_linker_flags=
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variables installed, or shouldnotlink
+ installed=yes
+ shouldnotlink=no
+ avoidtemprpath=
+
+
+ # Read the .la file
+ func_source "$lib"
+
+ # Convert "-framework foo" to "foo.ltframework"
+ if test -n "$inherited_linker_flags"; then
+ tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+ for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+ case " $new_inherited_linker_flags " in
+ *" $tmp_inherited_linker_flag "*) ;;
+ *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+ esac
+ done
+ fi
+ dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ if test lib,link = "$linkmode,$pass" ||
+ test prog,scan = "$linkmode,$pass" ||
+ { test prog != "$linkmode" && test lib != "$linkmode"; }; then
+ test -n "$dlopen" && func_append dlfiles " $dlopen"
+ test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+ fi
+
+ if test conv = "$pass"; then
+ # Only check for convenience libraries
+ deplibs="$lib $deplibs"
+ if test -z "$libdir"; then
+ if test -z "$old_library"; then
+ func_fatal_error "cannot find name of link library for '$lib'"
+ fi
+ # It is a libtool convenience library, so add in its objects.
+ func_append convenience " $ladir/$objdir/$old_library"
+ func_append old_convenience " $ladir/$objdir/$old_library"
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ if $opt_preserve_dup_deps; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done
+ elif test prog != "$linkmode" && test lib != "$linkmode"; then
+ func_fatal_error "'$lib' is not a convenience library"
+ fi
+ continue
+ fi # $pass = conv
+
+
+ # Get the name of the library we link against.
+ linklib=
+ if test -n "$old_library" &&
+ { test yes = "$prefer_static_libs" ||
+ test built,no = "$prefer_static_libs,$installed"; }; then
+ linklib=$old_library
+ else
+ for l in $old_library $library_names; do
+ linklib=$l
+ done
+ fi
+ if test -z "$linklib"; then
+ func_fatal_error "cannot find name of link library for '$lib'"
+ fi
+
+ # This library was specified with -dlopen.
+ if test dlopen = "$pass"; then
+ test -z "$libdir" \
+ && func_fatal_error "cannot -dlopen a convenience library: '$lib'"
+ if test -z "$dlname" ||
+ test yes != "$dlopen_support" ||
+ test no = "$build_libtool_libs"
+ then
+ # If there is no dlname, no dlopen support or we're linking
+ # statically, we need to preload. We also need to preload any
+ # dependent libraries so libltdl's deplib preloader doesn't
+ # bomb out in the load deplibs phase.
+ func_append dlprefiles " $lib $dependency_libs"
+ else
+ func_append newdlfiles " $lib"
+ fi
+ continue
+ fi # $pass = dlopen
+
+ # We need an absolute path.
+ case $ladir in
+ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;;
+ *)
+ abs_ladir=`cd "$ladir" && pwd`
+ if test -z "$abs_ladir"; then
+ func_warning "cannot determine absolute directory name of '$ladir'"
+ func_warning "passing it literally to the linker, although it might fail"
+ abs_ladir=$ladir
+ fi
+ ;;
+ esac
+ func_basename "$lib"
+ laname=$func_basename_result
+
+ # Find the relevant object directory and library name.
+ if test yes = "$installed"; then
+ if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ func_warning "library '$lib' was moved."
+ dir=$ladir
+ absdir=$abs_ladir
+ libdir=$abs_ladir
+ else
+ dir=$lt_sysroot$libdir
+ absdir=$lt_sysroot$libdir
+ fi
+ test yes = "$hardcode_automatic" && avoidtemprpath=yes
+ else
+ if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ dir=$ladir
+ absdir=$abs_ladir
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ else
+ dir=$ladir/$objdir
+ absdir=$abs_ladir/$objdir
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ fi
+ fi # $installed = yes
+ func_stripname 'lib' '.la' "$laname"
+ name=$func_stripname_result
+
+ # This library was specified with -dlpreopen.
+ if test dlpreopen = "$pass"; then
+ if test -z "$libdir" && test prog = "$linkmode"; then
+ func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'"
+ fi
+ case $host in
+ # special handling for platforms with PE-DLLs.
+ *cygwin* | *mingw* | *cegcc* )
+ # Linker will automatically link against shared library if both
+ # static and shared are present. Therefore, ensure we extract
+ # symbols from the import library if a shared library is present
+ # (otherwise, the dlopen module name will be incorrect). We do
+ # this by putting the import library name into $newdlprefiles.
+ # We recover the dlopen module name by 'saving' the la file
+ # name in a special purpose variable, and (later) extracting the
+ # dlname from the la file.
+ if test -n "$dlname"; then
+ func_tr_sh "$dir/$linklib"
+ eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+ func_append newdlprefiles " $dir/$linklib"
+ else
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ fi
+ ;;
+ * )
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ # Otherwise, use the dlname, so that lt_dlopen finds it.
+ elif test -n "$dlname"; then
+ func_append newdlprefiles " $dir/$dlname"
+ else
+ func_append newdlprefiles " $dir/$linklib"
+ fi
+ ;;
+ esac
+ fi # $pass = dlpreopen
+
+ if test -z "$libdir"; then
+ # Link the convenience library
+ if test lib = "$linkmode"; then
+ deplibs="$dir/$old_library $deplibs"
+ elif test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$dir/$old_library $compile_deplibs"
+ finalize_deplibs="$dir/$old_library $finalize_deplibs"
+ else
+ deplibs="$lib $deplibs" # used for prog,scan pass
+ fi
+ continue
+ fi
+
+
+ if test prog = "$linkmode" && test link != "$pass"; then
+ func_append newlib_search_path " $ladir"
+ deplibs="$lib $deplibs"
+
+ linkalldeplibs=false
+ if test no != "$link_all_deplibs" || test -z "$library_names" ||
+ test no = "$build_libtool_libs"; then
+ linkalldeplibs=:
+ fi
+
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ esac
+ # Need to link against all dependency_libs?
+ if $linkalldeplibs; then
+ deplibs="$deplib $deplibs"
+ else
+ # Need to hardcode shared library paths
+ # or/and link against static libraries
+ newdependency_libs="$deplib $newdependency_libs"
+ fi
+ if $opt_preserve_dup_deps; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done # for deplib
+ continue
+ fi # $linkmode = prog...
+
+ if test prog,link = "$linkmode,$pass"; then
+ if test -n "$library_names" &&
+ { { test no = "$prefer_static_libs" ||
+ test built,yes = "$prefer_static_libs,$installed"; } ||
+ test -z "$old_library"; }; then
+ # We need to hardcode the library path
+ if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then
+ # Make sure the rpath contains only unique directories.
+ case $temp_rpath: in
+ *"$absdir:"*) ;;
+ *) func_append temp_rpath "$absdir:" ;;
+ esac
+ fi
+
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi # $linkmode,$pass = prog,link...
+
+ if $alldeplibs &&
+ { test pass_all = "$deplibs_check_method" ||
+ { test yes = "$build_libtool_libs" &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+ fi
+
+ link_static=no # Whether the deplib will be linked statically
+ use_static_libs=$prefer_static_libs
+ if test built = "$use_static_libs" && test yes = "$installed"; then
+ use_static_libs=no
+ fi
+ if test -n "$library_names" &&
+ { test no = "$use_static_libs" || test -z "$old_library"; }; then
+ case $host in
+ *cygwin* | *mingw* | *cegcc* | *os2*)
+ # No point in relinking DLLs because paths are not encoded
+ func_append notinst_deplibs " $lib"
+ need_relink=no
+ ;;
+ *)
+ if test no = "$installed"; then
+ func_append notinst_deplibs " $lib"
+ need_relink=yes
+ fi
+ ;;
+ esac
+ # This is a shared library
+
+ # Warn about portability, can't link against -module's on some
+ # systems (darwin). Don't bleat about dlopened modules though!
+ dlopenmodule=
+ for dlpremoduletest in $dlprefiles; do
+ if test "X$dlpremoduletest" = "X$lib"; then
+ dlopenmodule=$dlpremoduletest
+ break
+ fi
+ done
+ if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then
+ echo
+ if test prog = "$linkmode"; then
+ $ECHO "*** Warning: Linking the executable $output against the loadable module"
+ else
+ $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+ fi
+ $ECHO "*** $linklib is not portable!"
+ fi
+ if test lib = "$linkmode" &&
+ test yes = "$hardcode_into_libs"; then
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi
+
+ if test -n "$old_archive_from_expsyms_cmds"; then
+ # figure out the soname
+ set dummy $library_names
+ shift
+ realname=$1
+ shift
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ # use dlname if we got it. it's perfectly good, no?
+ if test -n "$dlname"; then
+ soname=$dlname
+ elif test -n "$soname_spec"; then
+ # bleh windows
+ case $host in
+ *cygwin* | mingw* | *cegcc* | *os2*)
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix=-$major
+ ;;
+ esac
+ eval soname=\"$soname_spec\"
+ else
+ soname=$realname
+ fi
+
+ # Make a new name for the extract_expsyms_cmds to use
+ soroot=$soname
+ func_basename "$soroot"
+ soname=$func_basename_result
+ func_stripname 'lib' '.dll' "$soname"
+ newlib=libimp-$func_stripname_result.a
+
+ # If the library has no export list, then create one now
+ if test -f "$output_objdir/$soname-def"; then :
+ else
+ func_verbose "extracting exported symbol list from '$soname'"
+ func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+ fi
+
+ # Create $newlib
+ if test -f "$output_objdir/$newlib"; then :; else
+ func_verbose "generating import library for '$soname'"
+ func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+ fi
+ # make sure the library variables are pointing to the new library
+ dir=$output_objdir
+ linklib=$newlib
+ fi # test -n "$old_archive_from_expsyms_cmds"
+
+ if test prog = "$linkmode" || test relink != "$opt_mode"; then
+ add_shlibpath=
+ add_dir=
+ add=
+ lib_linked=yes
+ case $hardcode_action in
+ immediate | unsupported)
+ if test no = "$hardcode_direct"; then
+ add=$dir/$linklib
+ case $host in
+ *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;;
+ *-*-sysv4*uw2*) add_dir=-L$dir ;;
+ *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+ *-*-unixware7*) add_dir=-L$dir ;;
+ *-*-darwin* )
+ # if the lib is a (non-dlopened) module then we cannot
+ # link against it, someone is ignoring the earlier warnings
+ if /usr/bin/file -L $add 2> /dev/null |
+ $GREP ": [^:]* bundle" >/dev/null; then
+ if test "X$dlopenmodule" != "X$lib"; then
+ $ECHO "*** Warning: lib $linklib is a module, not a shared library"
+ if test -z "$old_library"; then
+ echo
+ echo "*** And there doesn't seem to be a static archive available"
+ echo "*** The link will probably fail, sorry"
+ else
+ add=$dir/$old_library
+ fi
+ elif test -n "$old_library"; then
+ add=$dir/$old_library
+ fi
+ fi
+ esac
+ elif test no = "$hardcode_minus_L"; then
+ case $host in
+ *-*-sunos*) add_shlibpath=$dir ;;
+ esac
+ add_dir=-L$dir
+ add=-l$name
+ elif test no = "$hardcode_shlibpath_var"; then
+ add_shlibpath=$dir
+ add=-l$name
+ else
+ lib_linked=no
+ fi
+ ;;
+ relink)
+ if test yes = "$hardcode_direct" &&
+ test no = "$hardcode_direct_absolute"; then
+ add=$dir/$linklib
+ elif test yes = "$hardcode_minus_L"; then
+ add_dir=-L$absdir
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add=-l$name
+ elif test yes = "$hardcode_shlibpath_var"; then
+ add_shlibpath=$dir
+ add=-l$name
+ else
+ lib_linked=no
+ fi
+ ;;
+ *) lib_linked=no ;;
+ esac
+
+ if test yes != "$lib_linked"; then
+ func_fatal_configuration "unsupported hardcode properties"
+ fi
+
+ if test -n "$add_shlibpath"; then
+ case :$compile_shlibpath: in
+ *":$add_shlibpath:"*) ;;
+ *) func_append compile_shlibpath "$add_shlibpath:" ;;
+ esac
+ fi
+ if test prog = "$linkmode"; then
+ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+ test -n "$add" && compile_deplibs="$add $compile_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ if test yes != "$hardcode_direct" &&
+ test yes != "$hardcode_minus_L" &&
+ test yes = "$hardcode_shlibpath_var"; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ fi
+ fi
+ fi
+
+ if test prog = "$linkmode" || test relink = "$opt_mode"; then
+ add_shlibpath=
+ add_dir=
+ add=
+ # Finalize command for both is simple: just hardcode it.
+ if test yes = "$hardcode_direct" &&
+ test no = "$hardcode_direct_absolute"; then
+ add=$libdir/$linklib
+ elif test yes = "$hardcode_minus_L"; then
+ add_dir=-L$libdir
+ add=-l$name
+ elif test yes = "$hardcode_shlibpath_var"; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ add=-l$name
+ elif test yes = "$hardcode_automatic"; then
+ if test -n "$inst_prefix_dir" &&
+ test -f "$inst_prefix_dir$libdir/$linklib"; then
+ add=$inst_prefix_dir$libdir/$linklib
+ else
+ add=$libdir/$linklib
+ fi
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ add_dir=-L$libdir
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add=-l$name
+ fi
+
+ if test prog = "$linkmode"; then
+ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+ test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ fi
+ fi
+ elif test prog = "$linkmode"; then
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test unsupported != "$hardcode_direct"; then
+ test -n "$old_library" && linklib=$old_library
+ compile_deplibs="$dir/$linklib $compile_deplibs"
+ finalize_deplibs="$dir/$linklib $finalize_deplibs"
+ else
+ compile_deplibs="-l$name -L$dir $compile_deplibs"
+ finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+ fi
+ elif test yes = "$build_libtool_libs"; then
+ # Not a shared library
+ if test pass_all != "$deplibs_check_method"; then
+ # We're trying link a shared library against a static one
+ # but the system doesn't support it.
+
+ # Just print a warning and add the library to dependency_libs so
+ # that the program can be linked against the static library.
+ echo
+ $ECHO "*** Warning: This system cannot link to static lib archive $lib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ if test yes = "$module"; then
+ echo "*** But as you try to build a module library, libtool will still create "
+ echo "*** a static module, that should work as long as the dlopening application"
+ echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** 'nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test no = "$build_old_libs"; then
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ else
+ deplibs="$dir/$old_library $deplibs"
+ link_static=yes
+ fi
+ fi # link shared/static library?
+
+ if test lib = "$linkmode"; then
+ if test -n "$dependency_libs" &&
+ { test yes != "$hardcode_into_libs" ||
+ test yes = "$build_old_libs" ||
+ test yes = "$link_static"; }; then
+ # Extract -R from dependency_libs
+ temp_deplibs=
+ for libdir in $dependency_libs; do
+ case $libdir in
+ -R*) func_stripname '-R' '' "$libdir"
+ temp_xrpath=$func_stripname_result
+ case " $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) func_append xrpath " $temp_xrpath";;
+ esac;;
+ *) func_append temp_deplibs " $libdir";;
+ esac
+ done
+ dependency_libs=$temp_deplibs
+ fi
+
+ func_append newlib_search_path " $absdir"
+ # Link against this library
+ test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ # ... and its dependency_libs
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ newdependency_libs="$deplib $newdependency_libs"
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result";;
+ *) func_resolve_sysroot "$deplib" ;;
+ esac
+ if $opt_preserve_dup_deps; then
+ case "$tmp_libs " in
+ *" $func_resolve_sysroot_result "*)
+ func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+ esac
+ fi
+ func_append tmp_libs " $func_resolve_sysroot_result"
+ done
+
+ if test no != "$link_all_deplibs"; then
+ # Add the search paths of all dependency libraries
+ for deplib in $dependency_libs; do
+ path=
+ case $deplib in
+ -L*) path=$deplib ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ deplib=$func_resolve_sysroot_result
+ func_dirname "$deplib" "" "."
+ dir=$func_dirname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ func_warning "cannot determine absolute directory name of '$dir'"
+ absdir=$dir
+ fi
+ ;;
+ esac
+ if $GREP "^installed=no" $deplib > /dev/null; then
+ case $host in
+ *-*-darwin*)
+ depdepl=
+ eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ if test -n "$deplibrary_names"; then
+ for tmp in $deplibrary_names; do
+ depdepl=$tmp
+ done
+ if test -f "$absdir/$objdir/$depdepl"; then
+ depdepl=$absdir/$objdir/$depdepl
+ darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ if test -z "$darwin_install_name"; then
+ darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ fi
+ func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl"
+ func_append linker_flags " -dylib_file $darwin_install_name:$depdepl"
+ path=
+ fi
+ fi
+ ;;
+ *)
+ path=-L$absdir/$objdir
+ ;;
+ esac
+ else
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ test -z "$libdir" && \
+ func_fatal_error "'$deplib' is not a valid libtool archive"
+ test "$absdir" != "$libdir" && \
+ func_warning "'$deplib' seems to be moved"
+
+ path=-L$absdir
+ fi
+ ;;
+ esac
+ case " $deplibs " in
+ *" $path "*) ;;
+ *) deplibs="$path $deplibs" ;;
+ esac
+ done
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
+ if test link = "$pass"; then
+ if test prog = "$linkmode"; then
+ compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+ finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ fi
+ fi
+ dependency_libs=$newdependency_libs
+ if test dlpreopen = "$pass"; then
+ # Link the dlpreopened libraries before other libraries
+ for deplib in $save_deplibs; do
+ deplibs="$deplib $deplibs"
+ done
+ fi
+ if test dlopen != "$pass"; then
+ test conv = "$pass" || {
+ # Make sure lib_search_path contains only unique directories.
+ lib_search_path=
+ for dir in $newlib_search_path; do
+ case "$lib_search_path " in
+ *" $dir "*) ;;
+ *) func_append lib_search_path " $dir" ;;
+ esac
+ done
+ newlib_search_path=
+ }
+
+ if test prog,link = "$linkmode,$pass"; then
+ vars="compile_deplibs finalize_deplibs"
+ else
+ vars=deplibs
+ fi
+ for var in $vars dependency_libs; do
+ # Add libraries to $var in reverse order
+ eval tmp_libs=\"\$$var\"
+ new_libs=
+ for deplib in $tmp_libs; do
+ # FIXME: Pedantically, this is the right thing to do, so
+ # that some nasty dependency loop isn't accidentally
+ # broken:
+ #new_libs="$deplib $new_libs"
+ # Pragmatically, this seems to cause very few problems in
+ # practice:
+ case $deplib in
+ -L*) new_libs="$deplib $new_libs" ;;
+ -R*) ;;
+ *)
+ # And here is the reason: when a library appears more
+ # than once as an explicit dependence of a library, or
+ # is implicitly linked in more than once by the
+ # compiler, it is considered special, and multiple
+ # occurrences thereof are not removed. Compare this
+ # with having the same library being listed as a
+ # dependency of multiple other libraries: in this case,
+ # we know (pedantically, we assume) the library does not
+ # need to be listed more than once, so we keep only the
+ # last copy. This is not always right, but it is rare
+ # enough that we require users that really mean to play
+ # such unportable linking tricks to link the library
+ # using -Wl,-lname, so that libtool does not consider it
+ # for duplicate removal.
+ case " $specialdeplibs " in
+ *" $deplib "*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$deplib $new_libs" ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ done
+ tmp_libs=
+ for deplib in $new_libs; do
+ case $deplib in
+ -L*)
+ case " $tmp_libs " in
+ *" $deplib "*) ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ done
+ eval $var=\"$tmp_libs\"
+ done # for var
+ fi
+
+ # Add Sun CC postdeps if required:
+ test CXX = "$tagname" && {
+ case $host_os in
+ linux*)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C++ 5.9
+ func_suncc_cstd_abi
+
+ if test no != "$suncc_use_cstd_abi"; then
+ func_append postdeps ' -library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ func_cc_basename "$CC"
+ case $func_cc_basename_result in
+ CC* | sunCC*)
+ func_suncc_cstd_abi
+
+ if test no != "$suncc_use_cstd_abi"; then
+ func_append postdeps ' -library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ }
+
+ # Last step: remove runtime libs from dependency_libs
+ # (they stay in deplibs)
+ tmp_libs=
+ for i in $dependency_libs; do
+ case " $predeps $postdeps $compiler_lib_search_path " in
+ *" $i "*)
+ i=
+ ;;
+ esac
+ if test -n "$i"; then
+ func_append tmp_libs " $i"
+ fi
+ done
+ dependency_libs=$tmp_libs
+ done # for pass
+ if test prog = "$linkmode"; then
+ dlfiles=$newdlfiles
+ fi
+ if test prog = "$linkmode" || test lib = "$linkmode"; then
+ dlprefiles=$newdlprefiles
+ fi
+
+ case $linkmode in
+ oldlib)
+ if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+ func_warning "'-dlopen' is ignored for archives"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "'-l' and '-L' are ignored for archives" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "'-rpath' is ignored for archives"
+
+ test -n "$xrpath" && \
+ func_warning "'-R' is ignored for archives"
+
+ test -n "$vinfo" && \
+ func_warning "'-version-info/-version-number' is ignored for archives"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for archives"
+
+ test -n "$export_symbols$export_symbols_regex" && \
+ func_warning "'-export-symbols' is ignored for archives"
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs=$output
+ func_append objs "$old_deplibs"
+ ;;
+
+ lib)
+ # Make sure we only generate libraries of the form 'libNAME.la'.
+ case $outputname in
+ lib*)
+ func_stripname 'lib' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ test no = "$module" \
+ && func_fatal_help "libtool library '$output' must begin with 'lib'"
+
+ if test no != "$need_lib_prefix"; then
+ # Add the "lib" prefix for modules if required
+ func_stripname '' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ else
+ func_stripname '' '.la' "$outputname"
+ libname=$func_stripname_result
+ fi
+ ;;
+ esac
+
+ if test -n "$objs"; then
+ if test pass_all != "$deplibs_check_method"; then
+ func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs"
+ else
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+ $ECHO "*** objects $objs is not portable!"
+ func_append libobjs " $objs"
+ fi
+ fi
+
+ test no = "$dlself" \
+ || func_warning "'-dlopen self' is ignored for libtool libraries"
+
+ set dummy $rpath
+ shift
+ test 1 -lt "$#" \
+ && func_warning "ignoring multiple '-rpath's for a libtool library"
+
+ install_libdir=$1
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test yes = "$build_libtool_libs"; then
+ # Building a libtool convenience library.
+ # Some compilers have problems with a '.al' extension so
+ # convenience libraries should have the same extension an
+ # archive normally would.
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+
+ test -n "$vinfo" && \
+ func_warning "'-version-info/-version-number' is ignored for convenience libraries"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for convenience libraries"
+ else
+
+ # Parse the version information argument.
+ save_ifs=$IFS; IFS=:
+ set dummy $vinfo 0 0 0
+ shift
+ IFS=$save_ifs
+
+ test -n "$7" && \
+ func_fatal_help "too many parameters to '-version-info'"
+
+ # convert absolute version numbers to libtool ages
+ # this retains compatibility with .la files and attempts
+ # to make the code below a bit more comprehensible
+
+ case $vinfo_number in
+ yes)
+ number_major=$1
+ number_minor=$2
+ number_revision=$3
+ #
+ # There are really only two kinds -- those that
+ # use the current revision as the major version
+ # and those that subtract age and use age as
+ # a minor version. But, then there is irix
+ # that has an extra 1 added just for fun
+ #
+ case $version_type in
+ # correct linux to gnu/linux during the next big refactor
+ darwin|freebsd-elf|linux|osf|windows|none)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age=$number_minor
+ revision=$number_revision
+ ;;
+ freebsd-aout|qnx|sunos)
+ current=$number_major
+ revision=$number_minor
+ age=0
+ ;;
+ irix|nonstopux)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age=$number_minor
+ revision=$number_minor
+ lt_irix_increment=no
+ ;;
+ *)
+ func_fatal_configuration "$modename: unknown library version type '$version_type'"
+ ;;
+ esac
+ ;;
+ no)
+ current=$1
+ revision=$2
+ age=$3
+ ;;
+ esac
+
+ # Check that each of the things are valid numbers.
+ case $current in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "CURRENT '$current' must be a nonnegative integer"
+ func_fatal_error "'$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $revision in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "REVISION '$revision' must be a nonnegative integer"
+ func_fatal_error "'$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $age in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "AGE '$age' must be a nonnegative integer"
+ func_fatal_error "'$vinfo' is not valid version information"
+ ;;
+ esac
+
+ if test "$age" -gt "$current"; then
+ func_error "AGE '$age' is greater than the current interface number '$current'"
+ func_fatal_error "'$vinfo' is not valid version information"
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case $version_type in
+ none) ;;
+
+ darwin)
+ # Like Linux, but with the current version available in
+ # verstring for coding it into the library header
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=$major.$age.$revision
+ # Darwin ld doesn't like 0 for these options...
+ func_arith $current + 1
+ minor_current=$func_arith_result
+ xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ # On Darwin other compilers
+ case $CC in
+ nagfor*)
+ verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
+ ;;
+ *)
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ ;;
+ esac
+ ;;
+
+ freebsd-aout)
+ major=.$current
+ versuffix=.$current.$revision
+ ;;
+
+ freebsd-elf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=$major.$age.$revision
+ ;;
+
+ irix | nonstopux)
+ if test no = "$lt_irix_increment"; then
+ func_arith $current - $age
+ else
+ func_arith $current - $age + 1
+ fi
+ major=$func_arith_result
+
+ case $version_type in
+ nonstopux) verstring_prefix=nonstopux ;;
+ *) verstring_prefix=sgi ;;
+ esac
+ verstring=$verstring_prefix$major.$revision
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test 0 -ne "$loop"; do
+ func_arith $revision - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring=$verstring_prefix$major.$iface:$verstring
+ done
+
+ # Before this point, $major must not contain '.'.
+ major=.$major
+ versuffix=$major.$revision
+ ;;
+
+ linux) # correct to gnu/linux during the next big refactor
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=$major.$age.$revision
+ ;;
+
+ osf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=.$current.$age.$revision
+ verstring=$current.$age.$revision
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test 0 -ne "$loop"; do
+ func_arith $current - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring=$verstring:$iface.0
+ done
+
+ # Make executables depend on our current version.
+ func_append verstring ":$current.0"
+ ;;
+
+ qnx)
+ major=.$current
+ versuffix=.$current
+ ;;
+
+ sco)
+ major=.$current
+ versuffix=.$current
+ ;;
+
+ sunos)
+ major=.$current
+ versuffix=.$current.$revision
+ ;;
+
+ windows)
+ # Use '-' rather than '.', since we only want one
+ # extension on DOS 8.3 file systems.
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix=-$major
+ ;;
+
+ *)
+ func_fatal_configuration "unknown library version type '$version_type'"
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ case $version_type in
+ darwin)
+ # we can't check for "0.0" in archive_cmds due to quoting
+ # problems, so we reset it completely
+ verstring=
+ ;;
+ *)
+ verstring=0.0
+ ;;
+ esac
+ if test no = "$need_version"; then
+ versuffix=
+ else
+ versuffix=.0.0
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test yes,no = "$avoid_version,$need_version"; then
+ major=
+ versuffix=
+ verstring=
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test yes = "$allow_undefined"; then
+ if test unsupported = "$allow_undefined_flag"; then
+ if test yes = "$build_old_libs"; then
+ func_warning "undefined symbols not allowed in $host shared libraries; building static only"
+ build_libtool_libs=no
+ else
+ func_fatal_error "can't build $host shared library unless -no-undefined is specified"
+ fi
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag=$no_undefined_flag
+ fi
+
+ fi
+
+ func_generate_dlsyms "$libname" "$libname" :
+ func_append libobjs " $symfileobj"
+ test " " = "$libobjs" && libobjs=
+
+ if test relink != "$opt_mode"; then
+ # Remove our outputs, but don't remove object files since they
+ # may have been created when compiling PIC objects.
+ removelist=
+ tempremovelist=`$ECHO "$output_objdir/*"`
+ for p in $tempremovelist; do
+ case $p in
+ *.$objext | *.gcno)
+ ;;
+ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*)
+ if test -n "$precious_files_regex"; then
+ if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+ then
+ continue
+ fi
+ fi
+ func_append removelist " $p"
+ ;;
+ *) ;;
+ esac
+ done
+ test -n "$removelist" && \
+ func_show_eval "${RM}r \$removelist"
+ fi
+
+ # Now set the variables for building old libraries.
+ if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then
+ func_append oldlibs " $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP`
+ fi
+
+ # Eliminate all temporary directories.
+ #for path in $notinst_path; do
+ # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+ # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+ # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
+ #done
+
+ if test -n "$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ temp_xrpath=
+ for libdir in $xrpath; do
+ func_replace_sysroot "$libdir"
+ func_append temp_xrpath " -R$func_replace_sysroot_result"
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+ fi
+
+ # Make sure dlfiles contains only unique files that won't be dlpreopened
+ old_dlfiles=$dlfiles
+ dlfiles=
+ for lib in $old_dlfiles; do
+ case " $dlprefiles $dlfiles " in
+ *" $lib "*) ;;
+ *) func_append dlfiles " $lib" ;;
+ esac
+ done
+
+ # Make sure dlprefiles contains only unique files
+ old_dlprefiles=$dlprefiles
+ dlprefiles=
+ for lib in $old_dlprefiles; do
+ case "$dlprefiles " in
+ *" $lib "*) ;;
+ *) func_append dlprefiles " $lib" ;;
+ esac
+ done
+
+ if test yes = "$build_libtool_libs"; then
+ if test -n "$rpath"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C library is in the System framework
+ func_append deplibs " System.ltframework"
+ ;;
+ *-*-netbsd*)
+ # Don't link with libc until the a.out ld.so is fixed.
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ ;;
+ *)
+ # Add libc to deplibs on all other systems if necessary.
+ if test yes = "$build_libtool_need_lc"; then
+ func_append deplibs " -lc"
+ fi
+ ;;
+ esac
+ fi
+
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=
+ versuffix=
+ major=
+ newdeplibs=
+ droppeddeps=no
+ case $deplibs_check_method in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behavior.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $opt_dry_run || $RM conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=
+ ;;
+ esac
+ fi
+ if test -n "$i"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which I believe you do not have"
+ echo "*** because a test_compile did reveal that the linker did not use it for"
+ echo "*** its dynamic dependency list that programs get resolved with at runtime."
+ fi
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ else
+ # Error occurred in the first compile. Let's try to salvage
+ # the situation: Compile a separate program for each library.
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+ ldd_output=`ldd conftest`
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=
+ ;;
+ esac
+ fi
+ if test -n "$i"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because a test_compile did reveal that the linker did not use this one"
+ echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+ fi
+ fi
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning! Library $i is needed by this library but I was not able to"
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method; shift
+ file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ if test -n "$file_magic_glob"; then
+ libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+ else
+ libnameglob=$libname
+ fi
+ test yes = "$want_nocaseglob" && nocaseglob=`shopt -p nocaseglob`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ if test yes = "$want_nocaseglob"; then
+ shopt -s nocaseglob
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ $nocaseglob
+ else
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ fi
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null |
+ $GREP " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib=$potent_lib
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | $SED 's/.* -> //'`
+ case $potliblink in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;;
+ *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+ $SED -e 10q |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib"; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib"; then
+ $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a file magic. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ potlib=$potent_lib # see symlink-check above in file_magic test
+ if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+ $EGREP "$match_pattern_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib"; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib"; then
+ $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a regex pattern. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=
+ tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ for i in $predeps $postdeps; do
+ # can't use Xsed below, because $i might contain '/'
+ tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"`
+ done
+ fi
+ case $tmp_deplibs in
+ *[!\ \ ]*)
+ echo
+ if test none = "$deplibs_check_method"; then
+ echo "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ echo "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ echo "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ ;;
+ esac
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library with the System framework
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ if test yes = "$droppeddeps"; then
+ if test yes = "$module"; then
+ echo
+ echo "*** Warning: libtool could not satisfy all declared inter-library"
+ $ECHO "*** dependencies of module $libname. Therefore, libtool will create"
+ echo "*** a static module, that should work as long as the dlopening"
+ echo "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** 'nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test no = "$build_old_libs"; then
+ oldlibs=$output_objdir/$libname.$libext
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ echo "*** The inter-library dependencies that have been dropped here will be"
+ echo "*** automatically added whenever a program is linked with this library"
+ echo "*** or is declared to -dlopen it."
+
+ if test no = "$allow_undefined"; then
+ echo
+ echo "*** Since this library must not contain undefined symbols,"
+ echo "*** because either the platform does not support them or"
+ echo "*** it was explicitly requested with -no-undefined,"
+ echo "*** libtool will only create a static version of it."
+ if test no = "$build_old_libs"; then
+ oldlibs=$output_objdir/$libname.$libext
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ case $host in
+ *-*-darwin*)
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ deplibs=$new_libs
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test yes = "$build_libtool_libs"; then
+ # Remove $wl instances when linking with ld.
+ # FIXME: should test the right _cmds variable.
+ case $archive_cmds in
+ *\$LD\ *) wl= ;;
+ esac
+ if test yes = "$hardcode_into_libs"; then
+ # Hardcode the library paths
+ hardcode_libdirs=
+ dep_rpath=
+ rpath=$finalize_rpath
+ test relink = "$opt_mode" || rpath=$compile_rpath$rpath
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ func_replace_sysroot "$libdir"
+ libdir=$func_replace_sysroot_result
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs=$libdir
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append dep_rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir=$hardcode_libdirs
+ eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
+ fi
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+ fi
+ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+ fi
+
+ shlibpath=$finalize_shlibpath
+ test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath
+ if test -n "$shlibpath"; then
+ eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+ fi
+
+ # Get the real and link names of the library.
+ eval shared_ext=\"$shrext_cmds\"
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ shift
+ realname=$1
+ shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname=$realname
+ fi
+ if test -z "$dlname"; then
+ dlname=$soname
+ fi
+
+ lib=$output_objdir/$realname
+ linknames=
+ for link
+ do
+ func_append linknames " $link"
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ test "X$libobjs" = "X " && libobjs=
+
+ delfiles=
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+ export_symbols=$output_objdir/$libname.uexp
+ func_append delfiles " $export_symbols"
+ fi
+
+ orig_export_symbols=
+ case $host_os in
+ cygwin* | mingw* | cegcc*)
+ if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+ # exporting using user supplied symfile
+ func_dll_def_p "$export_symbols" || {
+ # and it's NOT already a .def file. Must figure out
+ # which of the given symbols are data symbols and tag
+ # them as such. So, trigger use of export_symbols_cmds.
+ # export_symbols gets reassigned inside the "prepare
+ # the list of exported symbols" if statement, so the
+ # include_expsyms logic still works.
+ orig_export_symbols=$export_symbols
+ export_symbols=
+ always_export_symbols=yes
+ }
+ fi
+ ;;
+ esac
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then
+ func_verbose "generating symbol list for '$libname.la'"
+ export_symbols=$output_objdir/$libname.exp
+ $opt_dry_run || $RM $export_symbols
+ cmds=$export_symbols_cmds
+ save_ifs=$IFS; IFS='~'
+ for cmd1 in $cmds; do
+ IFS=$save_ifs
+ # Take the normal branch if the nm_file_list_spec branch
+ # doesn't work or if tool conversion is not needed.
+ case $nm_file_list_spec~$to_tool_file_cmd in
+ *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+ try_normal_branch=yes
+ eval cmd=\"$cmd1\"
+ func_len " $cmd"
+ len=$func_len_result
+ ;;
+ *)
+ try_normal_branch=no
+ ;;
+ esac
+ if test yes = "$try_normal_branch" \
+ && { test "$len" -lt "$max_cmd_len" \
+ || test "$max_cmd_len" -le -1; }
+ then
+ func_show_eval "$cmd" 'exit $?'
+ skipped_export=false
+ elif test -n "$nm_file_list_spec"; then
+ func_basename "$output"
+ output_la=$func_basename_result
+ save_libobjs=$libobjs
+ save_output=$output
+ output=$output_objdir/$output_la.nm
+ func_to_tool_file "$output"
+ libobjs=$nm_file_list_spec$func_to_tool_file_result
+ func_append delfiles " $output"
+ func_verbose "creating $NM input file list: $output"
+ for obj in $save_libobjs; do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > "$output"
+ eval cmd=\"$cmd1\"
+ func_show_eval "$cmd" 'exit $?'
+ output=$save_output
+ libobjs=$save_libobjs
+ skipped_export=false
+ else
+ # The command line is too long to execute in one step.
+ func_verbose "using reloadable object file for export list..."
+ skipped_export=:
+ # Break out early, otherwise skipped_export may be
+ # set to false by a later but shorter cmd.
+ break
+ fi
+ done
+ IFS=$save_ifs
+ if test -n "$export_symbols_regex" && test : != "$skipped_export"; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols=$export_symbols
+ test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test : != "$skipped_export" && test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands, which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+
+ tmp_deplibs=
+ for test_deplib in $deplibs; do
+ case " $convenience " in
+ *" $test_deplib "*) ;;
+ *)
+ func_append tmp_deplibs " $test_deplib"
+ ;;
+ esac
+ done
+ deplibs=$tmp_deplibs
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec" &&
+ test yes = "$compiler_needs_object" &&
+ test -z "$libobjs"; then
+ # extract the archives, so we have objects to list.
+ # TODO: could optimize this to just extract one archive.
+ whole_archive_flag_spec=
+ fi
+ if test -n "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ else
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ fi
+
+ if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ func_append linker_flags " $flag"
+ fi
+
+ # Make a backup of the uninstalled library when relinking
+ if test relink = "$opt_mode"; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+ fi
+
+ # Do each of the archive commands.
+ if test yes = "$module" && test -n "$module_cmds"; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ eval test_cmds=\"$module_expsym_cmds\"
+ cmds=$module_expsym_cmds
+ else
+ eval test_cmds=\"$module_cmds\"
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval test_cmds=\"$archive_expsym_cmds\"
+ cmds=$archive_expsym_cmds
+ else
+ eval test_cmds=\"$archive_cmds\"
+ cmds=$archive_cmds
+ fi
+ fi
+
+ if test : != "$skipped_export" &&
+ func_len " $test_cmds" &&
+ len=$func_len_result &&
+ test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ :
+ else
+ # The command line is too long to link in one step, link piecewise
+ # or, if using GNU ld and skipped_export is not :, use a linker
+ # script.
+
+ # Save the value of $output and $libobjs because we want to
+ # use them later. If we have whole_archive_flag_spec, we
+ # want to use save_libobjs as it was before
+ # whole_archive_flag_spec was expanded, because we can't
+ # assume the linker understands whole_archive_flag_spec.
+ # This may have to be revisited, in case too many
+ # convenience libraries get linked in and end up exceeding
+ # the spec.
+ if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ fi
+ save_output=$output
+ func_basename "$output"
+ output_la=$func_basename_result
+
+ # Clear the reloadable object creation command queue and
+ # initialize k to one.
+ test_cmds=
+ concat_cmds=
+ objlist=
+ last_robj=
+ k=1
+
+ if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then
+ output=$output_objdir/$output_la.lnkscript
+ func_verbose "creating GNU ld script: $output"
+ echo 'INPUT (' > $output
+ for obj in $save_libobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ echo ')' >> $output
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$func_to_tool_file_result
+ elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then
+ output=$output_objdir/$output_la.lnk
+ func_verbose "creating linker input file list: $output"
+ : > $output
+ set x $save_libobjs
+ shift
+ firstobj=
+ if test yes = "$compiler_needs_object"; then
+ firstobj="$1 "
+ shift
+ fi
+ for obj
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+ else
+ if test -n "$save_libobjs"; then
+ func_verbose "creating reloadable object files..."
+ output=$output_objdir/$output_la-$k.$objext
+ eval test_cmds=\"$reload_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+
+ # Loop over the list of objects to be linked.
+ for obj in $save_libobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ if test -z "$objlist" ||
+ test "$len" -lt "$max_cmd_len"; then
+ func_append objlist " $obj"
+ else
+ # The command $test_cmds is almost too long, add a
+ # command to the queue.
+ if test 1 -eq "$k"; then
+ # The first file doesn't have a previous command to add.
+ reload_objs=$objlist
+ eval concat_cmds=\"$reload_cmds\"
+ else
+ # All subsequent reloadable object files will link in
+ # the last one created.
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+ fi
+ last_robj=$output_objdir/$output_la-$k.$objext
+ func_arith $k + 1
+ k=$func_arith_result
+ output=$output_objdir/$output_la-$k.$objext
+ objlist=" $obj"
+ func_len " $last_robj"
+ func_arith $len0 + $func_len_result
+ len=$func_arith_result
+ fi
+ done
+ # Handle the remaining objects by creating one last
+ # reloadable object file. All subsequent reloadable object
+ # files will link in the last one created.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\$concat_cmds$reload_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ func_append delfiles " $output"
+
+ else
+ output=
+ fi
+
+ ${skipped_export-false} && {
+ func_verbose "generating symbol list for '$libname.la'"
+ export_symbols=$output_objdir/$libname.exp
+ $opt_dry_run || $RM $export_symbols
+ libobjs=$output
+ # Append the command to create the export file.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ }
+
+ test -n "$save_libobjs" &&
+ func_verbose "creating a temporary reloadable object file: $output"
+
+ # Loop through the commands generated above and execute them.
+ save_ifs=$IFS; IFS='~'
+ for cmd in $concat_cmds; do
+ IFS=$save_ifs
+ $opt_quiet || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test relink = "$opt_mode"; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS=$save_ifs
+
+ if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+
+ ${skipped_export-false} && {
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols=$export_symbols
+ test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands, which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+ }
+
+ libobjs=$output
+ # Restore the value of output.
+ output=$save_output
+
+ if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ # Expand the library linking commands again to reset the
+ # value of $libobjs for piecewise linking.
+
+ # Do each of the archive commands.
+ if test yes = "$module" && test -n "$module_cmds"; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ cmds=$module_expsym_cmds
+ else
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ cmds=$archive_expsym_cmds
+ else
+ cmds=$archive_cmds
+ fi
+ fi
+ fi
+
+ if test -n "$delfiles"; then
+ # Append the command to remove temporary files to $cmds.
+ eval cmds=\"\$cmds~\$RM $delfiles\"
+ fi
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+
+ save_ifs=$IFS; IFS='~'
+ for cmd in $cmds; do
+ IFS=$sp$nl
+ eval cmd=\"$cmd\"
+ IFS=$save_ifs
+ $opt_quiet || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test relink = "$opt_mode"; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS=$save_ifs
+
+ # Restore the uninstalled library and exit
+ if test relink = "$opt_mode"; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+ if test -n "$convenience"; then
+ if test -z "$whole_archive_flag_spec"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test yes = "$module" || test yes = "$export_dynamic"; then
+ # On all known operating systems, these are identical.
+ dlname=$soname
+ fi
+ fi
+ ;;
+
+ obj)
+ if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+ func_warning "'-dlopen' is ignored for objects"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "'-l' and '-L' are ignored for objects" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "'-rpath' is ignored for objects"
+
+ test -n "$xrpath" && \
+ func_warning "'-R' is ignored for objects"
+
+ test -n "$vinfo" && \
+ func_warning "'-version-info' is ignored for objects"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for objects"
+
+ case $output in
+ *.lo)
+ test -n "$objs$old_deplibs" && \
+ func_fatal_error "cannot build library object '$output' from non-libtool objects"
+
+ libobj=$output
+ func_lo2o "$libobj"
+ obj=$func_lo2o_result
+ ;;
+ *)
+ libobj=
+ obj=$output
+ ;;
+ esac
+
+ # Delete the old objects.
+ $opt_dry_run || $RM $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # if reload_cmds runs $LD directly, get rid of -Wl from
+ # whole_archive_flag_spec and hope we can get by with turning comma
+ # into space.
+ case $reload_cmds in
+ *\$LD[\ \$]*) wl= ;;
+ esac
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+ test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+ reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags
+ else
+ gentop=$output_objdir/${obj}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ reload_conv_objs="$reload_objs $func_extract_archives_result"
+ fi
+ fi
+
+ # If we're not building shared, we need to use non_pic_objs
+ test yes = "$build_libtool_libs" || libobjs=$non_pic_objects
+
+ # Create the old-style object.
+ reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs
+
+ output=$obj
+ func_execute_cmds "$reload_cmds" 'exit $?'
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ test yes = "$build_libtool_libs" || {
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ # $show "echo timestamp > $libobj"
+ # $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+ exit $EXIT_SUCCESS
+ }
+
+ if test -n "$pic_flag" || test default != "$pic_mode"; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output=$libobj
+ func_execute_cmds "$reload_cmds" 'exit $?'
+ fi
+
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ ;;
+
+ prog)
+ case $host in
+ *cygwin*) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result.exe;;
+ esac
+ test -n "$vinfo" && \
+ func_warning "'-version-info' is ignored for programs"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for programs"
+
+ $preload \
+ && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \
+ && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library is the System framework
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ case $host in
+ *-*-darwin*)
+ # Don't allow lazy linking, it breaks C++ global constructors
+ # But is supposedly fixed on 10.4 or later (yay!).
+ if test CXX = "$tagname"; then
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+ 10.[0123])
+ func_append compile_command " $wl-bind_at_load"
+ func_append finalize_command " $wl-bind_at_load"
+ ;;
+ esac
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $compile_deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $compile_deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ compile_deplibs=$new_libs
+
+
+ func_append compile_command " $compile_deplibs"
+ func_append finalize_command " $finalize_deplibs"
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs=$libdir
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$libdir:"*) ;;
+ ::) dllsearchpath=$libdir;;
+ *) func_append dllsearchpath ":$libdir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir=$hardcode_libdirs
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath=$rpath
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs=$libdir
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir=$hardcode_libdirs
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath=$rpath
+
+ if test -n "$libobjs" && test yes = "$build_old_libs"; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ fi
+
+ func_generate_dlsyms "$outputname" "@PROGRAM@" false
+
+ # template prelinking step
+ if test -n "$prelink_cmds"; then
+ func_execute_cmds "$prelink_cmds" 'exit $?'
+ fi
+
+ wrappers_required=:
+ case $host in
+ *cegcc* | *mingw32ce*)
+ # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+ wrappers_required=false
+ ;;
+ *cygwin* | *mingw* )
+ test yes = "$build_libtool_libs" || wrappers_required=false
+ ;;
+ *)
+ if test no = "$need_relink" || test yes != "$build_libtool_libs"; then
+ wrappers_required=false
+ fi
+ ;;
+ esac
+ $wrappers_required || {
+ # Replace the output file specification.
+ compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ link_command=$compile_command$compile_rpath
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ exit_status=0
+ func_show_eval "$link_command" 'exit_status=$?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Delete the generated files.
+ if test -f "$output_objdir/${outputname}S.$objext"; then
+ func_show_eval '$RM "$output_objdir/${outputname}S.$objext"'
+ fi
+
+ exit $exit_status
+ }
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test yes = "$no_install"; then
+ # We don't need to create a wrapper script.
+ link_command=$compile_var$compile_command$compile_rpath
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ # Delete the old output file.
+ $opt_dry_run || $RM $output
+ # Link the executable and exit
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ case $hardcode_action,$fast_install in
+ relink,*)
+ # Fast installation is not supported
+ link_command=$compile_var$compile_command$compile_rpath
+ relink_command=$finalize_var$finalize_command$finalize_rpath
+
+ func_warning "this platform does not like uninstalled shared libraries"
+ func_warning "'$output' will be relinked during installation"
+ ;;
+ *,yes)
+ link_command=$finalize_var$compile_command$finalize_rpath
+ relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+ ;;
+ *,no)
+ link_command=$compile_var$compile_command$compile_rpath
+ relink_command=$finalize_var$finalize_command$finalize_rpath
+ ;;
+ *,needless)
+ link_command=$finalize_var$compile_command$finalize_rpath
+ relink_command=
+ ;;
+ esac
+
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output_objdir/$outputname"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Now create the wrapper script.
+ func_verbose "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ relink_command="(cd `pwd`; $relink_command)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if not in dry run mode.
+ $opt_dry_run || {
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result ;;
+ esac
+ # test for cygwin because mv fails w/o .exe extensions
+ case $host in
+ *cygwin*)
+ exeext=.exe
+ func_stripname '' '.exe' "$outputname"
+ outputname=$func_stripname_result ;;
+ *) exeext= ;;
+ esac
+ case $host in
+ *cygwin* | *mingw* )
+ func_dirname_and_basename "$output" "" "."
+ output_name=$func_basename_result
+ output_path=$func_dirname_result
+ cwrappersource=$output_path/$objdir/lt-$output_name.c
+ cwrapper=$output_path/$output_name.exe
+ $RM $cwrappersource $cwrapper
+ trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_cwrapperexe_src > $cwrappersource
+
+ # The wrapper executable is built using the $host compiler,
+ # because it contains $host paths and files. If cross-
+ # compiling, it, like the target executable, must be
+ # executed on the $host or under an emulation environment.
+ $opt_dry_run || {
+ $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+ $STRIP $cwrapper
+ }
+
+ # Now, create the wrapper script for func_source use:
+ func_ltwrapper_scriptname $cwrapper
+ $RM $func_ltwrapper_scriptname_result
+ trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+ $opt_dry_run || {
+ # note: this script will not be executed, so do not chmod.
+ if test "x$build" = "x$host"; then
+ $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+ else
+ func_emit_wrapper no > $func_ltwrapper_scriptname_result
+ fi
+ }
+ ;;
+ * )
+ $RM $output
+ trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_wrapper no > $output
+ chmod +x $output
+ ;;
+ esac
+ }
+ exit $EXIT_SUCCESS
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ case $build_libtool_libs in
+ convenience)
+ oldobjs="$libobjs_save $symfileobj"
+ addlibs=$convenience
+ build_libtool_libs=no
+ ;;
+ module)
+ oldobjs=$libobjs_save
+ addlibs=$old_convenience
+ build_libtool_libs=no
+ ;;
+ *)
+ oldobjs="$old_deplibs $non_pic_objects"
+ $preload && test -f "$symfileobj" \
+ && func_append oldobjs " $symfileobj"
+ addlibs=$old_convenience
+ ;;
+ esac
+
+ if test -n "$addlibs"; then
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $addlibs
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then
+ cmds=$old_archive_from_new_cmds
+ else
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # POSIX demands no paths to be encoded in archives. We have
+ # to avoid creating archives with duplicate basenames if we
+ # might have to extract them afterwards, e.g., when creating a
+ # static archive out of a convenience library, or when linking
+ # the entirety of a libtool archive into another (currently
+ # not supported by libtool).
+ if (for obj in $oldobjs
+ do
+ func_basename "$obj"
+ $ECHO "$func_basename_result"
+ done | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ echo "copying selected object files to avoid basename conflicts..."
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+ func_mkdir_p "$gentop"
+ save_oldobjs=$oldobjs
+ oldobjs=
+ counter=1
+ for obj in $save_oldobjs
+ do
+ func_basename "$obj"
+ objbase=$func_basename_result
+ case " $oldobjs " in
+ " ") oldobjs=$obj ;;
+ *[\ /]"$objbase "*)
+ while :; do
+ # Make sure we don't pick an alternate name that also
+ # overlaps.
+ newobj=lt$counter-$objbase
+ func_arith $counter + 1
+ counter=$func_arith_result
+ case " $oldobjs " in
+ *[\ /]"$newobj "*) ;;
+ *) if test ! -f "$gentop/$newobj"; then break; fi ;;
+ esac
+ done
+ func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+ func_append oldobjs " $gentop/$newobj"
+ ;;
+ *) func_append oldobjs " $obj" ;;
+ esac
+ done
+ fi
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+ eval cmds=\"$old_archive_cmds\"
+
+ func_len " $cmds"
+ len=$func_len_result
+ if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ cmds=$old_archive_cmds
+ elif test -n "$archiver_list_spec"; then
+ func_verbose "using command file archive linking..."
+ for obj in $oldobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > $output_objdir/$libname.libcmd
+ func_to_tool_file "$output_objdir/$libname.libcmd"
+ oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+ cmds=$old_archive_cmds
+ else
+ # the command line is too long to link in one step, link in parts
+ func_verbose "using piecewise archive linking..."
+ save_RANLIB=$RANLIB
+ RANLIB=:
+ objlist=
+ concat_cmds=
+ save_oldobjs=$oldobjs
+ oldobjs=
+ # Is there a better way of finding the last object in the list?
+ for obj in $save_oldobjs
+ do
+ last_oldobj=$obj
+ done
+ eval test_cmds=\"$old_archive_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+ for obj in $save_oldobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ func_append objlist " $obj"
+ if test "$len" -lt "$max_cmd_len"; then
+ :
+ else
+ # the above command should be used before it gets too long
+ oldobjs=$objlist
+ if test "$obj" = "$last_oldobj"; then
+ RANLIB=$save_RANLIB
+ fi
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$old_archive_cmds\"
+ objlist=
+ len=$len0
+ fi
+ done
+ RANLIB=$save_RANLIB
+ oldobjs=$objlist
+ if test -z "$oldobjs"; then
+ eval cmds=\"\$concat_cmds\"
+ else
+ eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+ fi
+ fi
+ fi
+ func_execute_cmds "$cmds" 'exit $?'
+ done
+
+ test -n "$generated" && \
+ func_show_eval "${RM}r$generated"
+
+ # Now create the libtool archive.
+ case $output in
+ *.la)
+ old_library=
+ test yes = "$build_old_libs" && old_library=$libname.$libext
+ func_verbose "creating $output"
+
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ # Quote the link command for shipping.
+ relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ if test yes = "$hardcode_automatic"; then
+ relink_command=
+ fi
+
+ # Only create the output if not a dry run.
+ $opt_dry_run || {
+ for installed in no yes; do
+ if test yes = "$installed"; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output=$output_objdir/${outputname}i
+ # Replace all uninstalled libtool libraries with the installed ones
+ newdependency_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ *.la)
+ func_basename "$deplib"
+ name=$func_basename_result
+ func_resolve_sysroot "$deplib"
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+ test -z "$libdir" && \
+ func_fatal_error "'$deplib' is not a valid libtool archive"
+ func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ -L*)
+ func_stripname -L '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -L$func_replace_sysroot_result"
+ ;;
+ -R*)
+ func_stripname -R '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -R$func_replace_sysroot_result"
+ ;;
+ *) func_append newdependency_libs " $deplib" ;;
+ esac
+ done
+ dependency_libs=$newdependency_libs
+ newdlfiles=
+
+ for lib in $dlfiles; do
+ case $lib in
+ *.la)
+ func_basename "$lib"
+ name=$func_basename_result
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "'$lib' is not a valid libtool archive"
+ func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ *) func_append newdlfiles " $lib" ;;
+ esac
+ done
+ dlfiles=$newdlfiles
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ *.la)
+ # Only pass preopened files to the pseudo-archive (for
+ # eventual linking with the app. that links it) if we
+ # didn't already link the preopened objects directly into
+ # the library:
+ func_basename "$lib"
+ name=$func_basename_result
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "'$lib' is not a valid libtool archive"
+ func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ esac
+ done
+ dlprefiles=$newdlprefiles
+ else
+ newdlfiles=
+ for lib in $dlfiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlfiles " $abs"
+ done
+ dlfiles=$newdlfiles
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlprefiles " $abs"
+ done
+ dlprefiles=$newdlprefiles
+ fi
+ $RM $output
+ # place dlname in correct position for cygwin
+ # In fact, it would be nice if we could use this code for all target
+ # systems that can't hard-code library paths into their executables
+ # and that have no shared library path variable independent of PATH,
+ # but it turns out we can't easily determine that from inspecting
+ # libtool variables, so we have to hard-code the OSs to which it
+ # applies here; at the moment, that means platforms that use the PE
+ # object format with DLL files. See the long comment at the top of
+ # tests/bindir.at for full details.
+ tdlname=$dlname
+ case $host,$output,$installed,$module,$dlname in
+ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+ # If a -bindir argument was supplied, place the dll there.
+ if test -n "$bindir"; then
+ func_relative_path "$install_libdir" "$bindir"
+ tdlname=$func_relative_path_result/$dlname
+ else
+ # Otherwise fall back on heuristic.
+ tdlname=../bin/$dlname
+ fi
+ ;;
+ esac
+ $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that cannot go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+ if test no,yes = "$installed,$need_relink"; then
+ $ECHO >> $output "\
+relink_command=\"$relink_command\""
+ fi
+ done
+ }
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+ ;;
+ esac
+ exit $EXIT_SUCCESS
+}
+
+if test link = "$opt_mode" || test relink = "$opt_mode"; then
+ func_mode_link ${1+"$@"}
+fi
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+ $debug_cmd
+
+ RM=$nonopt
+ files=
+ rmforce=false
+ exit_status=0
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic=$magic
+
+ for arg
+ do
+ case $arg in
+ -f) func_append RM " $arg"; rmforce=: ;;
+ -*) func_append RM " $arg" ;;
+ *) func_append files " $arg" ;;
+ esac
+ done
+
+ test -z "$RM" && \
+ func_fatal_help "you must specify an RM program"
+
+ rmdirs=
+
+ for file in $files; do
+ func_dirname "$file" "" "."
+ dir=$func_dirname_result
+ if test . = "$dir"; then
+ odir=$objdir
+ else
+ odir=$dir/$objdir
+ fi
+ func_basename "$file"
+ name=$func_basename_result
+ test uninstall = "$opt_mode" && odir=$dir
+
+ # Remember odir for removal later, being careful to avoid duplicates
+ if test clean = "$opt_mode"; then
+ case " $rmdirs " in
+ *" $odir "*) ;;
+ *) func_append rmdirs " $odir" ;;
+ esac
+ fi
+
+ # Don't error if the file doesn't exist and rm -f was used.
+ if { test -L "$file"; } >/dev/null 2>&1 ||
+ { test -h "$file"; } >/dev/null 2>&1 ||
+ test -f "$file"; then
+ :
+ elif test -d "$file"; then
+ exit_status=1
+ continue
+ elif $rmforce; then
+ continue
+ fi
+
+ rmfiles=$file
+
+ case $name in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if func_lalib_p "$file"; then
+ func_source $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ func_append rmfiles " $odir/$n"
+ done
+ test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+
+ case $opt_mode in
+ clean)
+ case " $library_names " in
+ *" $dlname "*) ;;
+ *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+ esac
+ test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+ ;;
+ uninstall)
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1'
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1'
+ fi
+ # FIXME: should reinstall the best remaining shared library.
+ ;;
+ esac
+ fi
+ ;;
+
+ *.lo)
+ # Possibly a libtool object, so verify it.
+ if func_lalib_p "$file"; then
+
+ # Read the .lo file
+ func_source $dir/$name
+
+ # Add PIC object to the list of files to remove.
+ if test -n "$pic_object" && test none != "$pic_object"; then
+ func_append rmfiles " $dir/$pic_object"
+ fi
+
+ # Add non-PIC object to the list of files to remove.
+ if test -n "$non_pic_object" && test none != "$non_pic_object"; then
+ func_append rmfiles " $dir/$non_pic_object"
+ fi
+ fi
+ ;;
+
+ *)
+ if test clean = "$opt_mode"; then
+ noexename=$name
+ case $file in
+ *.exe)
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ func_stripname '' '.exe' "$name"
+ noexename=$func_stripname_result
+ # $file with .exe has already been added to rmfiles,
+ # add $file without .exe
+ func_append rmfiles " $file"
+ ;;
+ esac
+ # Do a test to see if this is a libtool program.
+ if func_ltwrapper_p "$file"; then
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ relink_command=
+ func_source $func_ltwrapper_scriptname_result
+ func_append rmfiles " $func_ltwrapper_scriptname_result"
+ else
+ relink_command=
+ func_source $dir/$noexename
+ fi
+
+ # note $name still contains .exe if it was in $file originally
+ # as does the version of $file that was added into $rmfiles
+ func_append rmfiles " $odir/$name $odir/${name}S.$objext"
+ if test yes = "$fast_install" && test -n "$relink_command"; then
+ func_append rmfiles " $odir/lt-$name"
+ fi
+ if test "X$noexename" != "X$name"; then
+ func_append rmfiles " $odir/lt-$noexename.c"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ func_show_eval "$RM $rmfiles" 'exit_status=1'
+ done
+
+ # Try to remove the $objdir's in the directories where we deleted files
+ for dir in $rmdirs; do
+ if test -d "$dir"; then
+ func_show_eval "rmdir $dir >/dev/null 2>&1"
+ fi
+ done
+
+ exit $exit_status
+}
+
+if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then
+ func_mode_uninstall ${1+"$@"}
+fi
+
+test -z "$opt_mode" && {
+ help=$generic_help
+ func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+ func_fatal_help "invalid operation mode '$opt_mode'"
+
+if test -n "$exec_cmd"; then
+ eval exec "$exec_cmd"
+ exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# where we disable both kinds of libraries. Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them. This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration. But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/m4/ac_define_dir.m4 b/m4/ac_define_dir.m4
new file mode 100644
index 000000000..e15cea2c9
--- /dev/null
+++ b/m4/ac_define_dir.m4
@@ -0,0 +1,34 @@
+dnl @synopsis AC_DEFINE_DIR(VARNAME, DIR [, DESCRIPTION])
+dnl
+dnl This macro sets VARNAME to the expansion of the DIR variable,
+dnl taking care of fixing up ${prefix} and such.
+dnl
+dnl VARNAME is then offered as both an output variable and a C
+dnl preprocessor symbol.
+dnl
+dnl Example:
+dnl
+dnl AC_DEFINE_DIR([DATADIR], [datadir], [Where data are placed to.])
+dnl
+dnl @category Misc
+dnl @author Stepan Kasal <kasal@ucw.cz>
+dnl @author Andreas Schwab <schwab@suse.de>
+dnl @author Guido U. Draheim <guidod@gmx.de>
+dnl @author Alexandre Oliva
+dnl @version 2006-10-13
+dnl @license AllPermissive
+
+AC_DEFUN([AC_DEFINE_DIR], [
+ prefix_NONE=
+ exec_prefix_NONE=
+ test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix
+ test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix
+dnl In Autoconf 2.60, ${datadir} refers to ${datarootdir}, which in turn
+dnl refers to ${prefix}. Thus we have to use `eval' twice.
+ eval ac_define_dir="\"[$]$2\""
+ eval ac_define_dir="\"$ac_define_dir\""
+ AC_SUBST($1, "$ac_define_dir")
+ AC_DEFINE_UNQUOTED($1, "$ac_define_dir", [$3])
+ test "$prefix_NONE" && prefix=NONE
+ test "$exec_prefix_NONE" && exec_prefix=NONE
+])
diff --git a/m4/ax_compare_version.m4 b/m4/ax_compare_version.m4
new file mode 100644
index 000000000..74dc0fdd9
--- /dev/null
+++ b/m4/ax_compare_version.m4
@@ -0,0 +1,177 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_compare_version.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
+#
+# DESCRIPTION
+#
+# This macro compares two version strings. Due to the various number of
+# minor-version numbers that can exist, and the fact that string
+# comparisons are not compatible with numeric comparisons, this is not
+# necessarily trivial to do in a autoconf script. This macro makes doing
+# these comparisons easy.
+#
+# The six basic comparisons are available, as well as checking equality
+# limited to a certain number of minor-version levels.
+#
+# The operator OP determines what type of comparison to do, and can be one
+# of:
+#
+# eq - equal (test A == B)
+# ne - not equal (test A != B)
+# le - less than or equal (test A <= B)
+# ge - greater than or equal (test A >= B)
+# lt - less than (test A < B)
+# gt - greater than (test A > B)
+#
+# Additionally, the eq and ne operator can have a number after it to limit
+# the test to that number of minor versions.
+#
+# eq0 - equal up to the length of the shorter version
+# ne0 - not equal up to the length of the shorter version
+# eqN - equal up to N sub-version levels
+# neN - not equal up to N sub-version levels
+#
+# When the condition is true, shell commands ACTION-IF-TRUE are run,
+# otherwise shell commands ACTION-IF-FALSE are run. The environment
+# variable 'ax_compare_version' is always set to either 'true' or 'false'
+# as well.
+#
+# Examples:
+#
+# AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8])
+# AX_COMPARE_VERSION([3.15],[lt],[3.15.8])
+#
+# would both be true.
+#
+# AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8])
+# AX_COMPARE_VERSION([3.15],[gt],[3.15.8])
+#
+# would both be false.
+#
+# AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8])
+#
+# would be true because it is only comparing two minor versions.
+#
+# AX_COMPARE_VERSION([3.15.7],[eq0],[3.15])
+#
+# would be true because it is only comparing the lesser number of minor
+# versions of the two values.
+#
+# Note: The characters that separate the version numbers do not matter. An
+# empty string is the same as version 0. OP is evaluated by autoconf, not
+# configure, so must be a string, not a variable.
+#
+# The author would like to acknowledge Guido Draheim whose advice about
+# the m4_case and m4_ifvaln functions make this macro only include the
+# portions necessary to perform the specific comparison specified by the
+# OP argument in the final configure script.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Tim Toolan <toolan@ele.uri.edu>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 11
+
+dnl #########################################################################
+AC_DEFUN([AX_COMPARE_VERSION], [
+ AC_REQUIRE([AC_PROG_AWK])
+
+ # Used to indicate true or false condition
+ ax_compare_version=false
+
+ # Convert the two version strings to be compared into a format that
+ # allows a simple string comparison. The end result is that a version
+ # string of the form 1.12.5-r617 will be converted to the form
+ # 0001001200050617. In other words, each number is zero padded to four
+ # digits, and non digits are removed.
+ AS_VAR_PUSHDEF([A],[ax_compare_version_A])
+ A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
+ -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/[[^0-9]]//g'`
+
+ AS_VAR_PUSHDEF([B],[ax_compare_version_B])
+ B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
+ -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/[[^0-9]]//g'`
+
+ dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary
+ dnl # then the first line is used to determine if the condition is true.
+ dnl # The sed right after the echo is to remove any indented white space.
+ m4_case(m4_tolower($2),
+ [lt],[
+ ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"`
+ ],
+ [gt],[
+ ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"`
+ ],
+ [le],[
+ ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"`
+ ],
+ [ge],[
+ ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"`
+ ],[
+ dnl Split the operator from the subversion count if present.
+ m4_bmatch(m4_substr($2,2),
+ [0],[
+ # A count of zero means use the length of the shorter version.
+ # Determine the number of characters in A and B.
+ ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'`
+ ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'`
+
+ # Set A to no more than B's length and B to no more than A's length.
+ A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"`
+ B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"`
+ ],
+ [[0-9]+],[
+ # A count greater than zero means use only that many subversions
+ A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
+ B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
+ ],
+ [.+],[
+ AC_WARNING(
+ [illegal OP numeric parameter: $2])
+ ],[])
+
+ # Pad zeros at end of numbers to make same length.
+ ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`"
+ B="$B`echo $A | sed 's/./0/g'`"
+ A="$ax_compare_version_tmp_A"
+
+ # Check for equality or inequality as necessary.
+ m4_case(m4_tolower(m4_substr($2,0,2)),
+ [eq],[
+ test "x$A" = "x$B" && ax_compare_version=true
+ ],
+ [ne],[
+ test "x$A" != "x$B" && ax_compare_version=true
+ ],[
+ AC_WARNING([illegal OP parameter: $2])
+ ])
+ ])
+
+ AS_VAR_POPDEF([A])dnl
+ AS_VAR_POPDEF([B])dnl
+
+ dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE.
+ if test "$ax_compare_version" = "true" ; then
+ m4_ifvaln([$4],[$4],[:])dnl
+ m4_ifvaln([$5],[else $5])dnl
+ fi
+]) dnl AX_COMPARE_VERSION
diff --git a/m4/ax_cxx_compile_stdcxx.m4 b/m4/ax_cxx_compile_stdcxx.m4
new file mode 100644
index 000000000..5032bba80
--- /dev/null
+++ b/m4/ax_cxx_compile_stdcxx.m4
@@ -0,0 +1,982 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
+#
+# DESCRIPTION
+#
+# Check for baseline language coverage in the compiler for the specified
+# version of the C++ standard. If necessary, add switches to CXX and
+# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard)
+# or '14' (for the C++14 standard).
+#
+# The second argument, if specified, indicates whether you insist on an
+# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
+# -std=c++11). If neither is specified, you get whatever works, with
+# preference for an extended mode.
+#
+# The third argument, if specified 'mandatory' or if left unspecified,
+# indicates that baseline support for the specified C++ standard is
+# required and that the macro should error out if no mode with that
+# support is found. If specified 'optional', then configuration proceeds
+# regardless, after defining HAVE_CXX${VERSION} if and only if a
+# supporting mode is found.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
+# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
+# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
+# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
+# Copyright (c) 2015 Paul Norman <penorman@mac.com>
+# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
+# Copyright (c) 2016 Krzesimir Nowak <qdlacz@gmail.com>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 7
+
+dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
+dnl (serial version number 13).
+
+AX_REQUIRE_DEFINED([AC_MSG_WARN])
+AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
+ m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
+ [$1], [14], [ax_cxx_compile_alternatives="14 1y"],
+ [$1], [17], [ax_cxx_compile_alternatives="17 1z"],
+ [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
+ m4_if([$2], [], [],
+ [$2], [ext], [],
+ [$2], [noext], [],
+ [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
+ m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
+ [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
+ [$3], [optional], [ax_cxx_compile_cxx$1_required=false],
+ [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
+ AC_LANG_PUSH([C++])dnl
+ ac_success=no
+ AC_CACHE_CHECK(whether $CXX supports C++$1 features by default,
+ ax_cv_cxx_compile_cxx$1,
+ [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
+ [ax_cv_cxx_compile_cxx$1=yes],
+ [ax_cv_cxx_compile_cxx$1=no])])
+ if test x$ax_cv_cxx_compile_cxx$1 = xyes; then
+ ac_success=yes
+ fi
+
+ m4_if([$2], [noext], [], [dnl
+ if test x$ac_success = xno; then
+ for alternative in ${ax_cxx_compile_alternatives}; do
+ switch="-std=gnu++${alternative}"
+ cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
+ AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
+ $cachevar,
+ [ac_save_CXX="$CXX"
+ CXX="$CXX $switch"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
+ [eval $cachevar=yes],
+ [eval $cachevar=no])
+ CXX="$ac_save_CXX"])
+ if eval test x\$$cachevar = xyes; then
+ CXX="$CXX $switch"
+ if test -n "$CXXCPP" ; then
+ CXXCPP="$CXXCPP $switch"
+ fi
+ ac_success=yes
+ break
+ fi
+ done
+ fi])
+
+ m4_if([$2], [ext], [], [dnl
+ if test x$ac_success = xno; then
+ dnl HP's aCC needs +std=c++11 according to:
+ dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
+ dnl Cray's crayCC needs "-h std=c++11"
+ for alternative in ${ax_cxx_compile_alternatives}; do
+ for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
+ cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
+ AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
+ $cachevar,
+ [ac_save_CXX="$CXX"
+ CXX="$CXX $switch"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
+ [eval $cachevar=yes],
+ [eval $cachevar=no])
+ CXX="$ac_save_CXX"])
+ if eval test x\$$cachevar = xyes; then
+ CXX="$CXX $switch"
+ if test -n "$CXXCPP" ; then
+ CXXCPP="$CXXCPP $switch"
+ fi
+ ac_success=yes
+ break
+ fi
+ done
+ if test x$ac_success = xyes; then
+ break
+ fi
+ done
+ fi])
+ AC_LANG_POP([C++])
+ if test x$ax_cxx_compile_cxx$1_required = xtrue; then
+ if test x$ac_success = xno; then
+ AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
+ fi
+ fi
+ if test x$ac_success = xno; then
+ HAVE_CXX$1=0
+ AC_MSG_NOTICE([No compiler with C++$1 support was found])
+ else
+ HAVE_CXX$1=1
+ AC_DEFINE(HAVE_CXX$1,1,
+ [define if the compiler supports basic C++$1 syntax])
+ fi
+ AC_SUBST(HAVE_CXX$1)
+ m4_if([$1], [17], [AC_MSG_WARN([C++17 is not yet standardized, so the checks may change in incompatible ways anytime])])
+])
+
+
+dnl Test body for checking C++11 support
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
+)
+
+
+dnl Test body for checking C++14 support
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
+)
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_17
+)
+
+dnl Tests for new features in C++11
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
+
+// If the compiler admits that it is not ready for C++11, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201103L
+
+#error "This is not a C++11 compiler"
+
+#else
+
+namespace cxx11
+{
+
+ namespace test_static_assert
+ {
+
+ template <typename T>
+ struct check
+ {
+ static_assert(sizeof(int) <= sizeof(T), "not big enough");
+ };
+
+ }
+
+ namespace test_final_override
+ {
+
+ struct Base
+ {
+ virtual void f() {}
+ };
+
+ struct Derived : public Base
+ {
+ virtual void f() override {}
+ };
+
+ }
+
+ namespace test_double_right_angle_brackets
+ {
+
+ template < typename T >
+ struct check {};
+
+ typedef check<void> single_type;
+ typedef check<check<void>> double_type;
+ typedef check<check<check<void>>> triple_type;
+ typedef check<check<check<check<void>>>> quadruple_type;
+
+ }
+
+ namespace test_decltype
+ {
+
+ int
+ f()
+ {
+ int a = 1;
+ decltype(a) b = 2;
+ return a + b;
+ }
+
+ }
+
+ namespace test_type_deduction
+ {
+
+ template < typename T1, typename T2 >
+ struct is_same
+ {
+ static const bool value = false;
+ };
+
+ template < typename T >
+ struct is_same<T, T>
+ {
+ static const bool value = true;
+ };
+
+ template < typename T1, typename T2 >
+ auto
+ add(T1 a1, T2 a2) -> decltype(a1 + a2)
+ {
+ return a1 + a2;
+ }
+
+ int
+ test(const int c, volatile int v)
+ {
+ static_assert(is_same<int, decltype(0)>::value == true, "");
+ static_assert(is_same<int, decltype(c)>::value == false, "");
+ static_assert(is_same<int, decltype(v)>::value == false, "");
+ auto ac = c;
+ auto av = v;
+ auto sumi = ac + av + 'x';
+ auto sumf = ac + av + 1.0;
+ static_assert(is_same<int, decltype(ac)>::value == true, "");
+ static_assert(is_same<int, decltype(av)>::value == true, "");
+ static_assert(is_same<int, decltype(sumi)>::value == true, "");
+ static_assert(is_same<int, decltype(sumf)>::value == false, "");
+ static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
+ return (sumf > 0.0) ? sumi : add(c, v);
+ }
+
+ }
+
+ namespace test_noexcept
+ {
+
+ int f() { return 0; }
+ int g() noexcept { return 0; }
+
+ static_assert(noexcept(f()) == false, "");
+ static_assert(noexcept(g()) == true, "");
+
+ }
+
+ namespace test_constexpr
+ {
+
+ template < typename CharT >
+ unsigned long constexpr
+ strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
+ {
+ return *s ? strlen_c_r(s + 1, acc + 1) : acc;
+ }
+
+ template < typename CharT >
+ unsigned long constexpr
+ strlen_c(const CharT *const s) noexcept
+ {
+ return strlen_c_r(s, 0UL);
+ }
+
+ static_assert(strlen_c("") == 0UL, "");
+ static_assert(strlen_c("1") == 1UL, "");
+ static_assert(strlen_c("example") == 7UL, "");
+ static_assert(strlen_c("another\0example") == 7UL, "");
+
+ }
+
+ namespace test_rvalue_references
+ {
+
+ template < int N >
+ struct answer
+ {
+ static constexpr int value = N;
+ };
+
+ answer<1> f(int&) { return answer<1>(); }
+ answer<2> f(const int&) { return answer<2>(); }
+ answer<3> f(int&&) { return answer<3>(); }
+
+ void
+ test()
+ {
+ int i = 0;
+ const int c = 0;
+ static_assert(decltype(f(i))::value == 1, "");
+ static_assert(decltype(f(c))::value == 2, "");
+ static_assert(decltype(f(0))::value == 3, "");
+ }
+
+ }
+
+ namespace test_uniform_initialization
+ {
+
+ struct test
+ {
+ static const int zero {};
+ static const int one {1};
+ };
+
+ static_assert(test::zero == 0, "");
+ static_assert(test::one == 1, "");
+
+ }
+
+ namespace test_lambdas
+ {
+
+ void
+ test1()
+ {
+ auto lambda1 = [](){};
+ auto lambda2 = lambda1;
+ lambda1();
+ lambda2();
+ }
+
+ int
+ test2()
+ {
+ auto a = [](int i, int j){ return i + j; }(1, 2);
+ auto b = []() -> int { return '0'; }();
+ auto c = [=](){ return a + b; }();
+ auto d = [&](){ return c; }();
+ auto e = [a, &b](int x) mutable {
+ const auto identity = [](int y){ return y; };
+ for (auto i = 0; i < a; ++i)
+ a += b--;
+ return x + identity(a + b);
+ }(0);
+ return a + b + c + d + e;
+ }
+
+ int
+ test3()
+ {
+ const auto nullary = [](){ return 0; };
+ const auto unary = [](int x){ return x; };
+ using nullary_t = decltype(nullary);
+ using unary_t = decltype(unary);
+ const auto higher1st = [](nullary_t f){ return f(); };
+ const auto higher2nd = [unary](nullary_t f1){
+ return [unary, f1](unary_t f2){ return f2(unary(f1())); };
+ };
+ return higher1st(nullary) + higher2nd(nullary)(unary);
+ }
+
+ }
+
+ namespace test_variadic_templates
+ {
+
+ template <int...>
+ struct sum;
+
+ template <int N0, int... N1toN>
+ struct sum<N0, N1toN...>
+ {
+ static constexpr auto value = N0 + sum<N1toN...>::value;
+ };
+
+ template <>
+ struct sum<>
+ {
+ static constexpr auto value = 0;
+ };
+
+ static_assert(sum<>::value == 0, "");
+ static_assert(sum<1>::value == 1, "");
+ static_assert(sum<23>::value == 23, "");
+ static_assert(sum<1, 2>::value == 3, "");
+ static_assert(sum<5, 5, 11>::value == 21, "");
+ static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
+
+ }
+
+ // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
+ // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
+ // because of this.
+ namespace test_template_alias_sfinae
+ {
+
+ struct foo {};
+
+ template<typename T>
+ using member = typename T::member_type;
+
+ template<typename T>
+ void func(...) {}
+
+ template<typename T>
+ void func(member<T>*) {}
+
+ void test();
+
+ void test() { func<foo>(0); }
+
+ }
+
+} // namespace cxx11
+
+#endif // __cplusplus >= 201103L
+
+]])
+
+
+dnl Tests for new features in C++14
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
+
+// If the compiler admits that it is not ready for C++14, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201402L
+
+#error "This is not a C++14 compiler"
+
+#else
+
+namespace cxx14
+{
+
+ namespace test_polymorphic_lambdas
+ {
+
+ int
+ test()
+ {
+ const auto lambda = [](auto&&... args){
+ const auto istiny = [](auto x){
+ return (sizeof(x) == 1UL) ? 1 : 0;
+ };
+ const int aretiny[] = { istiny(args)... };
+ return aretiny[0];
+ };
+ return lambda(1, 1L, 1.0f, '1');
+ }
+
+ }
+
+ namespace test_binary_literals
+ {
+
+ constexpr auto ivii = 0b0000000000101010;
+ static_assert(ivii == 42, "wrong value");
+
+ }
+
+ namespace test_generalized_constexpr
+ {
+
+ template < typename CharT >
+ constexpr unsigned long
+ strlen_c(const CharT *const s) noexcept
+ {
+ auto length = 0UL;
+ for (auto p = s; *p; ++p)
+ ++length;
+ return length;
+ }
+
+ static_assert(strlen_c("") == 0UL, "");
+ static_assert(strlen_c("x") == 1UL, "");
+ static_assert(strlen_c("test") == 4UL, "");
+ static_assert(strlen_c("another\0test") == 7UL, "");
+
+ }
+
+ namespace test_lambda_init_capture
+ {
+
+ int
+ test()
+ {
+ auto x = 0;
+ const auto lambda1 = [a = x](int b){ return a + b; };
+ const auto lambda2 = [a = lambda1(x)](){ return a; };
+ return lambda2();
+ }
+
+ }
+
+ namespace test_digit_separators
+ {
+
+ constexpr auto ten_million = 100'000'000;
+ static_assert(ten_million == 100000000, "");
+
+ }
+
+ namespace test_return_type_deduction
+ {
+
+ auto f(int& x) { return x; }
+ decltype(auto) g(int& x) { return x; }
+
+ template < typename T1, typename T2 >
+ struct is_same
+ {
+ static constexpr auto value = false;
+ };
+
+ template < typename T >
+ struct is_same<T, T>
+ {
+ static constexpr auto value = true;
+ };
+
+ int
+ test()
+ {
+ auto x = 0;
+ static_assert(is_same<int, decltype(f(x))>::value, "");
+ static_assert(is_same<int&, decltype(g(x))>::value, "");
+ return x;
+ }
+
+ }
+
+} // namespace cxx14
+
+#endif // __cplusplus >= 201402L
+
+]])
+
+
+dnl Tests for new features in C++17
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
+
+// If the compiler admits that it is not ready for C++17, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus <= 201402L
+
+#error "This is not a C++17 compiler"
+
+#else
+
+#if defined(__clang__)
+ #define REALLY_CLANG
+#else
+ #if defined(__GNUC__)
+ #define REALLY_GCC
+ #endif
+#endif
+
+#include <initializer_list>
+#include <utility>
+#include <type_traits>
+
+namespace cxx17
+{
+
+#if !defined(REALLY_CLANG)
+ namespace test_constexpr_lambdas
+ {
+
+ // TODO: test it with clang++ from git
+
+ constexpr int foo = [](){return 42;}();
+
+ }
+#endif // !defined(REALLY_CLANG)
+
+ namespace test::nested_namespace::definitions
+ {
+
+ }
+
+ namespace test_fold_expression
+ {
+
+ template<typename... Args>
+ int multiply(Args... args)
+ {
+ return (args * ... * 1);
+ }
+
+ template<typename... Args>
+ bool all(Args... args)
+ {
+ return (args && ...);
+ }
+
+ }
+
+ namespace test_extended_static_assert
+ {
+
+ static_assert (true);
+
+ }
+
+ namespace test_auto_brace_init_list
+ {
+
+ auto foo = {5};
+ auto bar {5};
+
+ static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
+ static_assert(std::is_same<int, decltype(bar)>::value);
+ }
+
+ namespace test_typename_in_template_template_parameter
+ {
+
+ template<template<typename> typename X> struct D;
+
+ }
+
+ namespace test_fallthrough_nodiscard_maybe_unused_attributes
+ {
+
+ int f1()
+ {
+ return 42;
+ }
+
+ [[nodiscard]] int f2()
+ {
+ [[maybe_unused]] auto unused = f1();
+
+ switch (f1())
+ {
+ case 17:
+ f1();
+ [[fallthrough]];
+ case 42:
+ f1();
+ }
+ return f1();
+ }
+
+ }
+
+ namespace test_extended_aggregate_initialization
+ {
+
+ struct base1
+ {
+ int b1, b2 = 42;
+ };
+
+ struct base2
+ {
+ base2() {
+ b3 = 42;
+ }
+ int b3;
+ };
+
+ struct derived : base1, base2
+ {
+ int d;
+ };
+
+ derived d1 {{1, 2}, {}, 4}; // full initialization
+ derived d2 {{}, {}, 4}; // value-initialized bases
+
+ }
+
+ namespace test_general_range_based_for_loop
+ {
+
+ struct iter
+ {
+ int i;
+
+ int& operator* ()
+ {
+ return i;
+ }
+
+ const int& operator* () const
+ {
+ return i;
+ }
+
+ iter& operator++()
+ {
+ ++i;
+ return *this;
+ }
+ };
+
+ struct sentinel
+ {
+ int i;
+ };
+
+ bool operator== (const iter& i, const sentinel& s)
+ {
+ return i.i == s.i;
+ }
+
+ bool operator!= (const iter& i, const sentinel& s)
+ {
+ return !(i == s);
+ }
+
+ struct range
+ {
+ iter begin() const
+ {
+ return {0};
+ }
+
+ sentinel end() const
+ {
+ return {5};
+ }
+ };
+
+ void f()
+ {
+ range r {};
+
+ for (auto i : r)
+ {
+ [[maybe_unused]] auto v = i;
+ }
+ }
+
+ }
+
+ namespace test_lambda_capture_asterisk_this_by_value
+ {
+
+ struct t
+ {
+ int i;
+ int foo()
+ {
+ return [*this]()
+ {
+ return i;
+ }();
+ }
+ };
+
+ }
+
+ namespace test_enum_class_construction
+ {
+
+ enum class byte : unsigned char
+ {};
+
+ byte foo {42};
+
+ }
+
+ namespace test_constexpr_if
+ {
+
+ template <bool cond>
+ int f ()
+ {
+ if constexpr(cond)
+ {
+ return 13;
+ }
+ else
+ {
+ return 42;
+ }
+ }
+
+ }
+
+ namespace test_selection_statement_with_initializer
+ {
+
+ int f()
+ {
+ return 13;
+ }
+
+ int f2()
+ {
+ if (auto i = f(); i > 0)
+ {
+ return 3;
+ }
+
+ switch (auto i = f(); i + 4)
+ {
+ case 17:
+ return 2;
+
+ default:
+ return 1;
+ }
+ }
+
+ }
+
+#if !defined(REALLY_CLANG)
+ namespace test_template_argument_deduction_for_class_templates
+ {
+
+ // TODO: test it with clang++ from git
+
+ template <typename T1, typename T2>
+ struct pair
+ {
+ pair (T1 p1, T2 p2)
+ : m1 {p1},
+ m2 {p2}
+ {}
+
+ T1 m1;
+ T2 m2;
+ };
+
+ void f()
+ {
+ [[maybe_unused]] auto p = pair{13, 42u};
+ }
+
+ }
+#endif // !defined(REALLY_CLANG)
+
+ namespace test_non_type_auto_template_parameters
+ {
+
+ template <auto n>
+ struct B
+ {};
+
+ B<5> b1;
+ B<'a'> b2;
+
+ }
+
+#if !defined(REALLY_CLANG)
+ namespace test_structured_bindings
+ {
+
+ // TODO: test it with clang++ from git
+
+ int arr[2] = { 1, 2 };
+ std::pair<int, int> pr = { 1, 2 };
+
+ auto f1() -> int(&)[2]
+ {
+ return arr;
+ }
+
+ auto f2() -> std::pair<int, int>&
+ {
+ return pr;
+ }
+
+ struct S
+ {
+ int x1 : 2;
+ volatile double y1;
+ };
+
+ S f3()
+ {
+ return {};
+ }
+
+ auto [ x1, y1 ] = f1();
+ auto& [ xr1, yr1 ] = f1();
+ auto [ x2, y2 ] = f2();
+ auto& [ xr2, yr2 ] = f2();
+ const auto [ x3, y3 ] = f3();
+
+ }
+#endif // !defined(REALLY_CLANG)
+
+#if !defined(REALLY_CLANG)
+ namespace test_exception_spec_type_system
+ {
+
+ // TODO: test it with clang++ from git
+
+ struct Good {};
+ struct Bad {};
+
+ void g1() noexcept;
+ void g2();
+
+ template<typename T>
+ Bad
+ f(T*, T*);
+
+ template<typename T1, typename T2>
+ Good
+ f(T1*, T2*);
+
+ static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
+
+ }
+#endif // !defined(REALLY_CLANG)
+
+ namespace test_inline_variables
+ {
+
+ template<class T> void f(T)
+ {}
+
+ template<class T> inline T g(T)
+ {
+ return T{};
+ }
+
+ template<> inline void f<>(int)
+ {}
+
+ template<> int g<>(int)
+ {
+ return 5;
+ }
+
+ }
+
+} // namespace cxx17
+
+#endif // __cplusplus <= 201402L
+
+]])
diff --git a/m4/basic-directories.m4 b/m4/basic-directories.m4
new file mode 100644
index 000000000..7729dac24
--- /dev/null
+++ b/m4/basic-directories.m4
@@ -0,0 +1,105 @@
+dnl
+dnl Fix basic directories (Taken from CUPS)
+dnl
+dnl Copyright 2007-2014 by Apple Inc.
+dnl Copyright 1997-2007 by Easy Software Products, all rights reserved.
+dnl
+dnl These coded instructions, statements, and computer programs are the
+dnl property of Apple Inc. and are protected by Federal copyright
+dnl law. Distribution and use rights are outlined in the file "COPYING"
+dnl which should have been included with this file.
+dnl
+
+AC_PREFIX_DEFAULT(/)
+
+dnl Fix "prefix" variable if it hasn't been specified...
+if test "$prefix" = "NONE"; then
+ prefix="/"
+fi
+
+dnl Fix "exec_prefix" variable if it hasn't been specified...
+if test "$exec_prefix" = "NONE"; then
+ if test "$prefix" = "/"; then
+ exec_prefix="/usr"
+ else
+ exec_prefix="$prefix"
+ fi
+fi
+
+dnl Fix "bindir" variable...
+if test "$bindir" = "\${exec_prefix}/bin"; then
+ bindir="$exec_prefix/bin"
+fi
+
+dnl Fix "sbindir" variable...
+if test "$sbindir" = "\${exec_prefix}/sbin"; then
+ sbindir="$exec_prefix/sbin"
+fi
+
+dnl Fix "sharedstatedir" variable if it hasn't been specified...
+if test "$sharedstatedir" = "\${prefix}/com" -a "$prefix" = "/"; then
+ sharedstatedir="/usr/com"
+fi
+
+dnl Fix "datarootdir" variable if it hasn't been specified...
+if test "$datarootdir" = "\${prefix}/share"; then
+ if test "$prefix" = "/"; then
+ datarootdir="/usr/share"
+ else
+ datarootdir="$prefix/share"
+ fi
+fi
+
+dnl Fix "datadir" variable if it hasn't been specified...
+if test "$datadir" = "\${prefix}/share"; then
+ if test "$prefix" = "/"; then
+ datadir="/usr/share"
+ else
+ datadir="$prefix/share"
+ fi
+elif test "$datadir" = "\${datarootdir}"; then
+ datadir="$datarootdir"
+fi
+
+dnl Fix "includedir" variable if it hasn't been specified...
+if test "$includedir" = "\${prefix}/include" -a "$prefix" = "/"; then
+ includedir="/usr/include"
+fi
+
+dnl Fix "localstatedir" variable if it hasn't been specified...
+if test "$localstatedir" = "\${prefix}/var"; then
+ if test "$prefix" = "/"; then
+ if test "$uname" = Darwin; then
+ localstatedir="/private/var"
+ else
+ localstatedir="/var"
+ fi
+ else
+ localstatedir="$prefix/var"
+ fi
+fi
+
+dnl Fix "sysconfdir" variable if it hasn't been specified...
+if test "$sysconfdir" = "\${prefix}/etc"; then
+ if test "$prefix" = "/"; then
+ if test "$uname" = Darwin; then
+ sysconfdir="/private/etc"
+ else
+ sysconfdir="/etc"
+ fi
+ else
+ sysconfdir="$prefix/etc"
+ fi
+fi
+
+dnl Fix "libdir" variable...
+if test "$libdir" = "\${exec_prefix}/lib"; then
+ case "$uname" in
+ Linux*)
+ if test -d /usr/lib64 -a ! -d /usr/lib64/fakeroot; then
+ libdir="$exec_prefix/lib64"
+ fi
+ ;;
+ esac
+fi
+
diff --git a/m4/libtool.m4 b/m4/libtool.m4
new file mode 100644
index 000000000..ee80844b6
--- /dev/null
+++ b/m4/libtool.m4
@@ -0,0 +1,8387 @@
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+# Copyright (C) 2014 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.
+
+# GNU Libtool 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 2 of of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program or library that is built
+# using GNU Libtool, you may include this file under the same
+# distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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/>.
+])
+
+# serial 58 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+ [m4_default([$3],
+ [m4_fatal([Libtool version $1 or higher is required],
+ 63)])],
+ [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+ *\ * | *\ *)
+ AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS=$ltmain
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_PREPARE_CC_BASENAME
+# -----------------------
+m4_defun([_LT_PREPARE_CC_BASENAME], [
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+ for cc_temp in @S|@*""; do
+ case $cc_temp in
+ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+ done
+ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+])# _LT_PREPARE_CC_BASENAME
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME,
+# but that macro is also expanded into generated libtool script, which
+# arranges for $SED and $ECHO to be set by different means.
+m4_defun([_LT_CC_BASENAME],
+[m4_require([_LT_PREPARE_CC_BASENAME])dnl
+AC_REQUIRE([_LT_DECL_SED])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+func_cc_basename $1
+cc_basename=$func_cc_basename_result
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
+m4_require([_LT_CMD_TRUNCATE])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options that allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+old_CC=$CC
+old_CFLAGS=$CFLAGS
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ _LT_PATH_MAGIC
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from 'configure', and 'config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably,
+# 'config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain=$ac_aux_dir/ltmain.sh
+])# _LT_PROG_LTMAIN
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the 'libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+ [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME. Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+ [m4_ifval([$1], [$1], [$2])])
+ lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+ m4_ifval([$4],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+ lt_dict_add_subkey([lt_decl_dict], [$2],
+ [tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+ [0], [m4_fatal([$0: too few arguments: $#])],
+ [1], [m4_fatal([$0: too few arguments: $#: $1])],
+ [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+ [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+ [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+ m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_if([$2], [],
+ m4_quote(lt_decl_varnames),
+ m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+ lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to 'config.status' so that its
+# declaration there will have the same value as in 'configure'. VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly. In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+ [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags='_LT_TAGS'dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+# # Some comment about what VAR is for.
+# visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+ [description])))[]dnl
+m4_pushdef([_libtool_name],
+ m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+ [0], [_libtool_name=[$]$1],
+ [1], [_libtool_name=$lt_[]$1],
+ [2], [_libtool_name=$lt_[]$1],
+ [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool'
+# script. Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+ m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into 'config.status', and then the shell code to quote escape them in
+# for loops in 'config.status'. Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+ dnl If the libtool generation code has been placed in $CONFIG_LT,
+ dnl instead of duplicating it all over again into config.status,
+ dnl then we will have config.status run $CONFIG_LT later, so it
+ dnl needs to know what name is stored there:
+ [AC_CONFIG_COMMANDS([libtool],
+ [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+ dnl If the libtool generation code is destined for config.status,
+ dnl expand the accumulated commands and init code now:
+ [AC_CONFIG_COMMANDS([libtool],
+ [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable. If COMMENT is supplied, it is inserted after the
+# '#!' sequence but before initialization text begins. After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script. The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test 0 = "$lt_write_fail" && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+ echo
+ AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+'$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2011 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test 0 != $[#]
+do
+ case $[1] in
+ --version | --v* | -V )
+ echo "$lt_cl_version"; exit 0 ;;
+ --help | --h* | -h )
+ echo "$lt_cl_help"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --quiet | --q* | --silent | --s* | -q )
+ lt_cl_silent=: ;;
+
+ -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try '$[0] --help' for more information.]) ;;
+
+ *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try '$[0] --help' for more information.]) ;;
+ esac
+ shift
+done
+
+if $lt_cl_silent; then
+ exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure. Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+lt_cl_success=:
+test yes = "$silent" &&
+ lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars. Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+ m4_if(_LT_TAG, [C], [
+ # See if we are running on zsh, and set the options that allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile=${ofile}T
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+# Generated automatically by $as_me ($PACKAGE) $VERSION
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit, 1996
+
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# Configured defaults for sys_lib_dlsearch_path munging.
+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ cat <<'_LT_EOF' >> "$cfgfile"
+
+# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_PREPARE_MUNGE_PATH_LIST
+_LT_PREPARE_CC_BASENAME
+
+# ### END FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+ _LT_PROG_LTMAIN
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ RM='$RM'
+ ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+# autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+ [C], [_LT_LANG(C)],
+ [C++], [_LT_LANG(CXX)],
+ [Go], [_LT_LANG(GO)],
+ [Java], [_LT_LANG(GCJ)],
+ [Fortran 77], [_LT_LANG(F77)],
+ [Fortran], [_LT_LANG(FC)],
+ [Windows Resource], [_LT_LANG(RC)],
+ [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+ [_LT_LANG($1)],
+ [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+ [LT_SUPPORTED_TAG([$1])dnl
+ m4_append([_LT_TAGS], [$1 ])dnl
+ m4_define([_LT_LANG_]$1[_enabled], [])dnl
+ _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+m4_ifndef([AC_PROG_GO], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_GO. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC], [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+ if test -n "$ac_tool_prefix"; then
+ AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
+ fi
+fi
+if test -z "$GOC"; then
+ AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [LT_LANG(CXX)],
+ [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+ [LT_LANG(F77)],
+ [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+ [LT_LANG(FC)],
+ [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [m4_ifdef([AC_PROG_GCJ],
+ [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([A][M_PROG_GCJ],
+ [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([LT_PROG_GCJ],
+ [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([AC_PROG_GO],
+ [LT_LANG(GO)],
+ [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+ [LT_LANG(RC)],
+ [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+ case $host_os in
+ rhapsody* | darwin*)
+ AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+ AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+ AC_CHECK_TOOL([LIPO], [lipo], [:])
+ AC_CHECK_TOOL([OTOOL], [otool], [:])
+ AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+ _LT_DECL([], [DSYMUTIL], [1],
+ [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+ _LT_DECL([], [NMEDIT], [1],
+ [Tool to change global to local symbols on Mac OS X])
+ _LT_DECL([], [LIPO], [1],
+ [Tool to manipulate fat objects and archives on Mac OS X])
+ _LT_DECL([], [OTOOL], [1],
+ [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+ _LT_DECL([], [OTOOL64], [1],
+ [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+ [lt_cv_apple_cc_single_mod=no
+ if test -z "$LT_MULTI_MODULE"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi])
+
+ AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+ [lt_cv_ld_exported_symbols_list],
+ [lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [lt_cv_ld_exported_symbols_list=yes],
+ [lt_cv_ld_exported_symbols_list=no])
+ LDFLAGS=$save_LDFLAGS
+ ])
+
+ AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+ [lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+ echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+ $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+ echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+ $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+ ])
+ case $host_os in
+ rhapsody* | darwin1.[[012]])
+ _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ 10.[[012]][[,.]]*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test yes = "$lt_cv_apple_cc_single_mod"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test yes = "$lt_cv_ld_exported_symbols_list"; then
+ _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+ fi
+ if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+ m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ if test yes = "$lt_cv_ld_force_load"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+ [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes])
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined
+ case $cc_basename in
+ ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test yes = "$_lt_dar_can_shared"; then
+ output_verbose_link_cmd=func_echo_all
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+ _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+ m4_if([$1], [CXX],
+[ if test yes != "$lt_cv_apple_cc_single_mod"; then
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
+ fi
+],[])
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+ lt_aix_libpath_sed='[
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }]'
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi],[])
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib
+ fi
+ ])
+ aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script that will find a shell with a builtin
+# printf (that we can use as an echo command).
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+case $ECHO in
+ printf*) AC_MSG_RESULT([printf]) ;;
+ print*) AC_MSG_RESULT([print -r]) ;;
+ *) AC_MSG_RESULT([cat]) ;;
+esac
+
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test "X`printf %s $ECHO`" = "X$ECHO" \
+ || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
+
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@],
+ [Search for dependent libraries within DIR (or the compiler's sysroot
+ if not specified).])],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted. We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case $with_sysroot in #(
+ yes)
+ if test yes = "$GCC"; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ AC_MSG_RESULT([$with_sysroot])
+ AC_MSG_ERROR([The sysroot must be an absolute path.])
+ ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and where our libraries should be installed.])])
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+ [AS_HELP_STRING([--disable-libtool-lock],
+ [avoid locking (might break parallel builds)])])
+test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out what ABI is being produced by ac_compile, and set mode
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE=32
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE=64
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+mips64*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ emul=elf
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ emul="${emul}32"
+ ;;
+ *64-bit*)
+ emul="${emul}64"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *MSB*)
+ emul="${emul}btsmip"
+ ;;
+ *LSB*)
+ emul="${emul}ltsmip"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *N32*)
+ emul="${emul}n32"
+ ;;
+ esac
+ LD="${LD-ld} -m $emul"
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly. Note that the listed cases only cover the
+ # situations where additional linker options are needed (such as when
+ # doing 32-bit compilation for a host where ld defaults to 64-bit, or
+ # vice versa); the common cases where no linker options are needed do
+ # not appear in the list.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
+ ;;
+ powerpc64le-*linux*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ powerpcle-*linux*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS=$CFLAGS
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_PUSH(C)
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_POP])
+ if test yes != "$lt_cv_cc_needs_belf"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS=$SAVE_CFLAGS
+ fi
+ ;;
+*-*solaris*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*|x86_64-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD=${LD-ld}_sol2
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks=$enable_libtool_lock
+])# _LT_ENABLE_LOCK
+
+
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+ [lt_cv_ar_at_file=no
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+ [echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([lt_ar_try])
+ if test 0 -eq "$ac_status"; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ AC_TRY_EVAL([lt_ar_try])
+ if test 0 -ne "$ac_status"; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+ ])
+ ])
+
+if test no = "$lt_cv_ar_at_file"; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+ [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[_LT_PROG_AR
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+ [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ bitrig* | openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+ [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+ [Whether to use a lock for old archive extraction])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ fi
+ $RM conftest*
+])
+
+if test yes = "[$]$2"; then
+ m4_if([$5], , :, [$5])
+else
+ m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS $3"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&AS_MESSAGE_LOG_FD
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ else
+ $2=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+])
+
+if test yes = "[$]$2"; then
+ m4_if([$4], , :, [$4])
+else
+ m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+ i=0
+ teststring=ABCD
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len" && \
+ test undefined != "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test 17 != "$i" # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+])
+if test -n "$lt_cv_sys_max_cmd_len"; then
+ AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+ AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+ [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test yes = "$cross_compiling"; then :
+ [$4]
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+[#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}]
+_LT_EOF
+ if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then
+ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) $1 ;;
+ x$lt_dlneed_uscore) $2 ;;
+ x$lt_dlunknown|x*) $3 ;;
+ esac
+ else :
+ # compilation failed
+ $3
+ fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test yes != "$enable_dlopen"; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen=load_add_on
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen=LoadLibrary
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[
+ lt_cv_dlopen=dyld
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ])
+ ;;
+
+ tpf*)
+ # Don't try to run any link tests for TPF. We know it's impossible
+ # because TPF is a cross-compiler, and we know how we open DSOs.
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=no
+ ;;
+
+ *)
+ AC_CHECK_FUNC([shl_load],
+ [lt_cv_dlopen=shl_load],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld],
+ [AC_CHECK_FUNC([dlopen],
+ [lt_cv_dlopen=dlopen],
+ [AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld],
+ [AC_CHECK_LIB([dld], [dld_link],
+ [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld])
+ ])
+ ])
+ ])
+ ])
+ ])
+ ;;
+ esac
+
+ if test no = "$lt_cv_dlopen"; then
+ enable_dlopen=no
+ else
+ enable_dlopen=yes
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS=$CPPFLAGS
+ test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS=$LDFLAGS
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS=$LIBS
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ AC_CACHE_CHECK([whether a program can dlopen itself],
+ lt_cv_dlopen_self, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+ ])
+
+ if test yes = "$lt_cv_dlopen_self"; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+ lt_cv_dlopen_self_static, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
+ ])
+ fi
+
+ CPPFLAGS=$save_CPPFLAGS
+ LDFLAGS=$save_LDFLAGS
+ LIBS=$save_LIBS
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+ [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+ [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+ [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+ fi
+ fi
+ chmod u+w . 2>&AS_MESSAGE_LOG_FD
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+ [Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links=nottested
+if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then
+ # do not overwrite the value of need_locks provided by the user
+ AC_MSG_CHECKING([if we can lock with hard links])
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ AC_MSG_RESULT([$hard_links])
+ if test no = "$hard_links"; then
+ AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe])
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+ [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/",
+ [Define to the sub-directory where libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+ test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+ test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then
+
+ # We can hardcode non-existent directories.
+ if test no != "$_LT_TAGVAR(hardcode_direct, $1)" &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" &&
+ test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then
+ # Linking always hardcodes the temporary library directory.
+ _LT_TAGVAR(hardcode_action, $1)=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ _LT_TAGVAR(hardcode_action, $1)=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test relink = "$_LT_TAGVAR(hardcode_action, $1)" ||
+ test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test yes = "$shlibpath_overrides_runpath" ||
+ test no = "$enable_shared"; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+ [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP"; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT([no])
+ ;;
+ esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_PREPARE_MUNGE_PATH_LIST
+# ---------------------------
+# Make sure func_munge_path_list() is defined correctly.
+m4_defun([_LT_PREPARE_MUNGE_PATH_LIST],
+[[# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+# string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+# string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+# "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+# VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+ case x@S|@2 in
+ x)
+ ;;
+ *:)
+ eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\"
+ ;;
+ x:*)
+ eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\"
+ ;;
+ *::*)
+ eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+ eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\"
+ ;;
+ *)
+ eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\"
+ ;;
+ esac
+}
+]])# _LT_PREPARE_PATH_LIST
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+ [], [
+if test yes = "$GCC"; then
+ case $host_os in
+ darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
+ *) lt_awk_arg='/^libraries:/' ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;
+ *) lt_sed_strip_eq='s|=/|/|g' ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary...
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ # ...but if some path component already ends with the multilib dir we assume
+ # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
+ case "$lt_multi_os_dir; $lt_search_path_spec " in
+ "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
+ lt_multi_os_dir=
+ ;;
+ esac
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
+ elif test -n "$lt_multi_os_dir"; then
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS = " "; FS = "/|\n";} {
+ lt_foo = "";
+ lt_count = 0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo = "/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+ if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=.so
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+AC_ARG_VAR([LT_SYS_LIBRARY_PATH],
+[User-defined run-time library search path.])
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+
+aix[[4-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 supports IA64
+ library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line '#! .'. This would cause the generated library to
+ # depend on '.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[[01]] | aix4.[[01]].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # Using Import Files as archive members, it is possible to support
+ # filename-based versioning of shared library archives on AIX. While
+ # this would work for both with and without runtime linking, it will
+ # prevent static linking of such archives. So we do filename-based
+ # shared library versioning with .so extension only, which is used
+ # when both runtime linking and shared linking is enabled.
+ # Unfortunately, runtime linking may impact performance, so we do
+ # not want this to be the default eventually. Also, we use the
+ # versioned .so libs for executables only if there is the -brtl
+ # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
+ # To allow for filename-based versioning support, we need to create
+ # libNAME.so.V as an archive file, containing:
+ # *) an Import File, referring to the versioned filename of the
+ # archive as well as the shared archive member, telling the
+ # bitwidth (32 or 64) of that shared object, and providing the
+ # list of exported symbols of that shared object, eventually
+ # decorated with the 'weak' keyword
+ # *) the shared object with the F_LOADONLY flag set, to really avoid
+ # it being seen by the linker.
+ # At run time we better use the real file rather than another symlink,
+ # but for link time we create the symlink libNAME.so -> libNAME.so.V
+
+ case $with_aix_soname,$aix_use_runtimelinking in
+ # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ aix,yes) # traditional libtool
+ dynamic_linker='AIX unversionable lib.so'
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ aix,no) # traditional AIX only
+ dynamic_linker='AIX lib.a[(]lib.so.V[)]'
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ svr4,*) # full svr4 only
+ dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,yes) # both, prefer svr4
+ dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # unpreferred sharedlib libNAME.a needs extra handling
+ postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
+ postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,no) # both, prefer aix
+ dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]"
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
+ postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
+ postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
+ ;;
+ esac
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='$libname$shared_ext'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[[45]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ library_names_spec='$libname.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec=$LIB
+ if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$major$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[[23]].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ if test 32 = "$HPUX_IA64_MODE"; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux32
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux64
+ fi
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[[3-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+ sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+linux*android*)
+ version_type=none # Android doesn't support versioned libraries.
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext'
+ soname_spec='$libname$release$shared_ext'
+ finish_cmds=
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ dynamic_linker='Android linker'
+ # Don't embed -rpath directories since the linker doesn't support them.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+ [lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+ [lt_cv_shlibpath_overrides_runpath=yes])])
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+ ])
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Ideally, we could use ldconfig to report *all* directores which are
+ # searched for libraries, however this is still not possible. Aside from not
+ # being certain /sbin/ldconfig is available, command
+ # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
+ # even though it is searched at run-time. Try to do the best guess by
+ # appending ld.so.conf contents (and includes) to the search path.
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd* | bitrig*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec=/usr/lib
+ need_lib_prefix=no
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ need_version=no
+ else
+ need_version=yes
+ fi
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+os2*)
+ libname_spec='$name'
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+ # OS/2 can only load a DLL with a base name of 8 characters or less.
+ soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
+ v=$($ECHO $release$versuffix | tr -d .-);
+ n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
+ $ECHO $n$v`$shared_ext'
+ library_names_spec='${libname}_dll.$libext'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=BEGINLIBPATH
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test yes = "$with_gnu_ld"; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+ soname_spec='$libname$shared_ext.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=sco
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test yes = "$with_gnu_ld"; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test no = "$dynamic_linker" && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test yes = "$GCC"; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+ sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+fi
+
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+ sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+fi
+
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
+
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+ [Variables whose values should be saved in libtool wrapper scripts and
+ restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+ [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+ [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+ [[List of archive names. First name is the real one, the rest are links.
+ The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+ [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+ [Permission mode override for installation of shared libraries])
+_LT_DECL([], [postinstall_cmds], [2],
+ [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+ [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+ [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+ [[As "finish_cmds", except a single script fragment to be evaled but
+ not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+ [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+ [Compile-time system search path for libraries])
+_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2],
+ [Detected run-time system search path for libraries])
+_LT_DECL([], [configure_time_lt_sys_library_path], [2],
+ [Explicit LT_SYS_LIBRARY_PATH set during ./configure time])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program that can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] | ?:[\\/]*])
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="m4_if([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$1"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
+ ;;
+esac])
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+ [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program that can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
+
+AC_ARG_WITH([gnu-ld],
+ [AS_HELP_STRING([--with-gnu-ld],
+ [assume the C compiler uses GNU ld @<:@default=no@:>@])],
+ [test no = "$withval" || with_gnu_ld=yes],
+ [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test yes = "$GCC"; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by $CC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return, which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]]* | ?:[[\\/]]*)
+ re_direlt='/[[^/]][[^/]]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD=$ac_prog
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test yes = "$with_gnu_ld"; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD=$ac_dir/$ac_prog
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test no != "$with_gnu_ld" && break
+ ;;
+ *)
+ test yes != "$with_gnu_ld" && break
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+else
+ lt_cv_path_LD=$LD # Let the user override the test with a path.
+fi])
+LD=$lt_cv_path_LD
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+ lt_cv_ld_reload_flag,
+ [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test yes != "$GCC"; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test yes = "$GCC"; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_PATH_DD
+# -----------
+# find a working dd
+m4_defun([_LT_PATH_DD],
+[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+: ${lt_DD:=$DD}
+AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd],
+[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
+fi])
+rm -f conftest.i conftest2.i conftest.out])
+])# _LT_PATH_DD
+
+
+# _LT_CMD_TRUNCATE
+# ----------------
+# find command to truncate a binary pipe
+m4_defun([_LT_CMD_TRUNCATE],
+[m4_require([_LT_PATH_DD])
+AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+lt_cv_truncate_bin=
+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
+fi
+rm -f conftest.i conftest2.i conftest.out
+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"])
+_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1],
+ [Command to truncate a binary pipe])
+])# _LT_CMD_TRUNCATE
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# 'unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# that responds to the $file_magic_cmd with a given extended regex.
+# If you have 'file' or equivalent on your system and you're not sure
+# whether 'pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[[45]]*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ if ( file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[[3-9]]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd* | bitrig*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+os2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+ [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+ [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+ [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+ [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM=$NM
+else
+ lt_nm_to_check=${ac_tool_prefix}nm
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/$lt_tmp_nm
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
+ case $build_os in
+ mingw*) lt_bad_file=conftest.nm/nofile ;;
+ *) lt_bad_file=/dev/null ;;
+ esac
+ case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
+ *$lt_bad_file* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break 2
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break 2
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+ done
+ : ${lt_cv_path_NM=no}
+fi])
+if test no != "$lt_cv_path_NM"; then
+ NM=$lt_cv_path_NM
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+ case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols -headers"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+ AC_SUBST([DUMPBIN])
+ if test : != "$DUMPBIN"; then
+ NM=$DUMPBIN
+ fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+ [lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
+ cat conftest.out >&AS_MESSAGE_LOG_FD
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh;
+ # decide which one to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd=$ECHO
+ ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+ [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+ [lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*])
+if test yes != "$lt_cv_path_mainfest_tool"; then
+ MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
+
+# _LT_DLL_DEF_P([FILE])
+# ---------------------
+# True iff FILE is a Windows DLL '.def' file.
+# Keep in sync with func_dll_def_p in the libtool script
+AC_DEFUN([_LT_DLL_DEF_P],
+[dnl
+ test DEF = "`$SED -n dnl
+ -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace
+ -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments
+ -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl
+ -e q dnl Only consider the first "real" line
+ $1`" dnl
+])# _LT_DLL_DEF_P
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+ # These system don't have libm, or don't need it
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw)
+ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, cos, LIBM=-lm)
+ ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test yes = "$GCC"; then
+ case $cc_basename in
+ nvcc*)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+ esac
+
+ _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+ lt_cv_prog_compiler_rtti_exceptions,
+ [-fno-rtti -fno-exceptions], [],
+ [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+ [Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[[BCDT]]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[[ABCDGISTW]]'
+ ;;
+hpux*)
+ if test ia64 = "$host_cpu"; then
+ symcode='[[ABCDEGRST]]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[[BCDEGRST]]'
+ ;;
+osf*)
+ symcode='[[BCDEGQRST]]'
+ ;;
+solaris*)
+ symcode='[[BDRT]]'
+ ;;
+sco3.2v5*)
+ symcode='[[DT]]'
+ ;;
+sysv4.2uw2*)
+ symcode='[[DT]]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[[ABDT]]'
+ ;;
+sysv4)
+ symcode='[[DFNSTU]]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Gets list of data symbols to import.
+ lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
+ # Adjust the below global symbol transforms to fixup imported variables.
+ lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
+ lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'"
+ lt_c_name_lib_hook="\
+ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\
+ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'"
+else
+ # Disable hooks by default.
+ lt_cv_sys_global_symbol_to_import=
+ lt_cdecl_hook=
+ lt_c_name_hook=
+ lt_c_name_lib_hook=
+fi
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n"\
+$lt_cdecl_hook\
+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
+$lt_c_name_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'"
+
+# Transform an extracted symbol line into symbol name with lib prefix and
+# symbol address.
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
+$lt_c_name_lib_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function,
+ # D for any global variable and I for any imported variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK ['"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
+" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
+" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
+" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
+" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx]"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT@&t@_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data. */
+# define LT@&t@_DLSYM_CONST
+#else
+# define LT@&t@_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT@&t@_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS=conftstm.$ac_objext
+ CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+ if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test yes = "$pipe_works"; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ AC_MSG_RESULT(failed)
+else
+ AC_MSG_RESULT(ok)
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+ [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+ [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1],
+ [Transform the output of nm into a list of symbols to manually relocate])
+_LT_DECL([global_symbol_to_c_name_address],
+ [lt_cv_sys_global_symbol_to_c_name_address], [1],
+ [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+ [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+ [Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([nm_interface], [lt_cv_nm_interface], [1],
+ [The name lister interface])
+_LT_DECL([], [nm_file_list_spec], [1],
+ [Specify filename containing input files for $NM])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+m4_if([$1], [CXX], [
+ # C++ specific cases for pic, static, wl, etc.
+ if test yes = "$GXX"; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ case $host_os in
+ os2*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix[[4-9]]*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ if test ia64 != "$host_cpu"; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ fi
+ ;;
+ aCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ ecpc* )
+ # old Intel C++ for x86_64, which still supported -KPIC.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+ # IBM XL 8.0, 9.0 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd* | netbsdelf*-gnu)
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+],
+[
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ case $host_os in
+ os2*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+ if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ case $cc_basename in
+ nagfor*)
+ # NAG Fortran compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ case $host_os in
+ os2*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+ ;;
+ esac
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC (with -KPIC) is the default.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ # old Intel for x86_64, which still supported -KPIC.
+ ecc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ ccc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All Alpha code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ ;;
+ *Intel*\ [[CF]]*Compiler*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ *Portland\ Group*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All OSF/1 code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ rdos*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ unicos*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+])
+case $host_os in
+ # For platforms that do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+ ;;
+esac
+
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+ [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+ [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+ "" | " "*) ;;
+ *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+ esac],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+ [Additional compiler flags for building library objects])
+
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+ [How to pass a linker flag through the compiler])
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+ _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+ $lt_tmp_static_flag,
+ [],
+ [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+ [Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ case $host_os in
+ aix[[4-9]]*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+ # Without the "-l" option, or with the "-B" option, AIX nm treats
+ # weak defined symbols like other global defined symbols, whereas
+ # GNU nm marks them as "W".
+ # While the 'weak' keyword is ignored in the Export File, we need
+ # it in the Import File for the 'aix-soname' feature, so we have
+ # to replace the "-B" option with "-P" for AIX nm.
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds
+ ;;
+ cygwin* | mingw* | cegcc*)
+ case $cc_basename in
+ cl*)
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | gnu*)
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+], [
+ runpath_var=
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(archive_cmds, $1)=
+ _LT_TAGVAR(archive_expsym_cmds, $1)=
+ _LT_TAGVAR(compiler_needs_object, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(hardcode_automatic, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ _LT_TAGVAR(hardcode_minus_L, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_TAGVAR(inherit_rpath, $1)=no
+ _LT_TAGVAR(link_all_deplibs, $1)=unknown
+ _LT_TAGVAR(module_cmds, $1)=
+ _LT_TAGVAR(module_expsym_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+ _LT_TAGVAR(thread_safe_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ _LT_TAGVAR(include_expsyms, $1)=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ' (' and ')$', so one must not match beginning or
+ # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
+ # as well as any symbol that contains 'd'.
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test yes != "$GCC"; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd* | bitrig*)
+ with_gnu_ld=no
+ ;;
+ linux* | k*bsd*-gnu | gnu*)
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ ;;
+ esac
+
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test yes = "$with_gnu_ld"; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+ *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test yes = "$lt_use_gnu_ld_interface"; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='$wl'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[[3-9]]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test ia64 != "$host_cpu"; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ shrext_cmds=.dll
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test linux-dietlibc = "$host_os"; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test no = "$tmp_diet"
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ tmp_sharedflag='--shared' ;;
+ nagfor*) # NAGFOR 5.3
+ tmp_sharedflag='-Wl,-shared' ;;
+ xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+
+ if test yes = "$supports_anon_versioning"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ tcc*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'
+ ;;
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+
+ if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then
+ runpath_var=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+ # Without the "-l" option, or with the "-B" option, AIX nm treats
+ # weak defined symbols like other global defined symbols, whereas
+ # GNU nm marks them as "W".
+ # While the 'weak' keyword is ignored in the Export File, we need
+ # it in the Import File for the 'aix-soname' feature, so we have
+ # to replace the "-B" option with "-P" for AIX nm.
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # have runtime linking enabled, and use it for executables.
+ # For shared libraries, we enable/disable runtime linking
+ # depending on the kind of the shared library created -
+ # when "with_aix_soname,aix_use_runtimelinking" is:
+ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
+ # "aix,yes" lib.so shared, rtl:yes, for executables
+ # lib.a static archive
+ # "both,no" lib.so.V(shr.o) shared, rtl:yes
+ # lib.a(lib.so.V) shared, rtl:no, for executables
+ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a(lib.so.V) shared, rtl:no
+ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a static archive
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # With aix-soname=svr4, we create the lib.so.V shared archives only,
+ # so we don't have lib.a shared libs to link our executables.
+ # We have to force runtime linking in this case.
+ aix_use_runtimelinking=yes
+ LDFLAGS="$LDFLAGS -Wl,-brtl"
+ fi
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+ case $with_aix_soname,$aix_use_runtimelinking in
+ aix,*) ;; # traditional, no import file
+ svr4,* | *,yes) # use import file
+ # The Import File defines what to hardcode.
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ ;;
+ esac
+
+ if test yes = "$GCC"; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag="$shared_flag "'$wl-G'
+ fi
+ # Need to ensure runtime linking is disabled for the traditional
+ # shared library, or the linker may eventually find shared libraries
+ # /with/ Import File - we do not want to mix them.
+ shared_flag_aix='-shared'
+ shared_flag_svr4='-shared $wl-G'
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ shared_flag_aix='$wl-bM:SRE'
+ shared_flag_svr4='$wl-G'
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+ # -brtl affects multiple linker settings, -berok does not and is overridden later
+ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
+ if test svr4 != "$with_aix_soname"; then
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+ fi
+ if test aix != "$with_aix_soname"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+ else
+ # used by -dlpreopen to get the symbols
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
+ fi
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[[45]]*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ # FIXME: Should let the user specify the lib program.
+ _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ hpux9*)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ ;;
+
+ hpux10*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ m4_if($1, [], [
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ _LT_LINKER_OPTION([if $CC understands -b],
+ _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+ [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+ ;;
+ esac
+ fi
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+ [lt_cv_irix_exported_symbol],
+ [save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+ AC_LINK_IFELSE(
+ [AC_LANG_SOURCE(
+ [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+ [C++], [[int foo (void) { return 0; }]],
+ [Fortran 77], [[
+ subroutine foo
+ end]],
+ [Fortran], [[
+ subroutine foo
+ end]])])],
+ [lt_cv_irix_exported_symbol=yes],
+ [lt_cv_irix_exported_symbol=no])
+ LDFLAGS=$save_LDFLAGS])
+ if test yes = "$lt_cv_irix_exported_symbol"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ linux*)
+ case $cc_basename in
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ fi
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ shrext_cmds=.dll
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
+ osf3*)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+ if test yes = "$GCC"; then
+ wlarc='$wl'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='$wl'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'. GCC discards it without '$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ sunos4*)
+ if test sequent = "$host_vendor"; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ ;;
+ motorola)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4.3*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ if test sni = "$host_vendor"; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+ [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+ # Assume -lc should be added
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+ if test yes,yes = "$GCC,$enable_shared"; then
+ case $_LT_TAGVAR(archive_cmds, $1) in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+ [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+ [$RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+ pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+ then
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ else
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ fi
+ _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ ])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+ [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+ [enable_shared_with_static_runtimes], [0],
+ [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+ [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+ [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+ [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+ [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+ [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+ [Commands used to build a loadable module if different from building
+ a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+ [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+ [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+ [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+ [Flag to hardcode $libdir into a binary during linking.
+ This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+ [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+ [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+ DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+ [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+ DIR into the resulting binary and the resulting library dependency is
+ "absolute", i.e impossible to change by setting $shlibpath_var if the
+ library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+ [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+ [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+ [Set to "yes" if building a shared library automatically hardcodes DIR
+ into the library and all subsequent libraries and executables linked
+ against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+ [Set to yes if linker adds runtime paths of dependent libraries
+ to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+ [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [always_export_symbols], [0],
+ [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+ [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+ [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+ [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+ [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+ [Commands necessary for finishing linking programs])
+_LT_TAGDECL([], [file_list_spec], [1],
+ [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC=$CC
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+ LT_SYS_DLOPEN_SELF
+ _LT_CMD_STRIPLIB
+
+ # Report what library types will actually be built
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC=$lt_save_CC
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test no != "$CXX" &&
+ ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
+ (test g++ != "$CXX"))); then
+ AC_PROG_CXXCPP
+else
+ _lt_caught_CXX_error=yes
+fi
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_caught_CXX_error"; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="int some_variable = 0;"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_CFLAGS=$CFLAGS
+ lt_save_LD=$LD
+ lt_save_GCC=$GCC
+ GCC=$GXX
+ lt_save_with_gnu_ld=$with_gnu_ld
+ lt_save_path_LD=$lt_cv_path_LD
+ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+ else
+ $as_unset lt_cv_prog_gnu_ld
+ fi
+ if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+ else
+ $as_unset lt_cv_path_LD
+ fi
+ test -z "${LDCXX+set}" || LD=$LDCXX
+ CC=${CXX-"c++"}
+ CFLAGS=$CXXFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ # We don't want -fno-exception when compiling C++ code, so set the
+ # no_builtin_flag separately
+ if test yes = "$GXX"; then
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+ else
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+ fi
+
+ if test yes = "$GXX"; then
+ # Set up default GNU C++ configuration
+
+ LT_PATH_LD
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test yes = "$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='$wl'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+ $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+ fi
+
+ # PORTME: fill in a description of your system's C++ link characteristics
+ AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aix[[4-9]]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # have runtime linking enabled, and use it for executables.
+ # For shared libraries, we enable/disable runtime linking
+ # depending on the kind of the shared library created -
+ # when "with_aix_soname,aix_use_runtimelinking" is:
+ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
+ # "aix,yes" lib.so shared, rtl:yes, for executables
+ # lib.a static archive
+ # "both,no" lib.so.V(shr.o) shared, rtl:yes
+ # lib.a(lib.so.V) shared, rtl:no, for executables
+ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a(lib.so.V) shared, rtl:no
+ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a static archive
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # With aix-soname=svr4, we create the lib.so.V shared archives only,
+ # so we don't have lib.a shared libs to link our executables.
+ # We have to force runtime linking in this case.
+ aix_use_runtimelinking=yes
+ LDFLAGS="$LDFLAGS -Wl,-brtl"
+ fi
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+ case $with_aix_soname,$aix_use_runtimelinking in
+ aix,*) ;; # no import file
+ svr4,* | *,yes) # use import file
+ # The Import File defines what to hardcode.
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ ;;
+ esac
+
+ if test yes = "$GXX"; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag=$shared_flag' $wl-G'
+ fi
+ # Need to ensure runtime linking is disabled for the traditional
+ # shared library, or the linker may eventually find shared libraries
+ # /with/ Import File - we do not want to mix them.
+ shared_flag_aix='-shared'
+ shared_flag_svr4='-shared $wl-G'
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ shared_flag_aix='$wl-bM:SRE'
+ shared_flag_svr4='$wl-G'
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to
+ # export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ # The "-G" linker flag allows undefined symbols.
+ _LT_TAGVAR(no_undefined_flag, $1)='-bernotok'
+ # Determine the default libpath from the value encoded in an empty
+ # executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+ # -brtl affects multiple linker settings, -berok does not and is overridden later
+ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
+ if test svr4 != "$with_aix_soname"; then
+ # This is similar to how AIX traditionally builds its shared
+ # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+ fi
+ if test aix != "$with_aix_soname"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+ else
+ # used by -dlpreopen to get the symbols
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
+ fi
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $GXX,$cc_basename in
+ ,cl* | no,cl*)
+ # Native MSVC
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ func_to_tool_file "$lt_outputfile"~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # g++
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ shrext_cmds=.dll
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ freebsd2.*)
+ # C++ shared libraries reported to be fairly broken before
+ # switch to ELF
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ freebsd-elf*)
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ ;;
+
+ freebsd* | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ hpux9*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ hpux10*|hpux11*)
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ if test no = "$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
+ fi
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+ esac
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc* | ecpc* )
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ case `$CC -V` in
+ *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
+ _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+ _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+ $RANLIB $oldlib'
+ _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 6 and above use weak symbols
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+ ;;
+ xl* | mpixl* | bgxl*)
+ # IBM XL 8.0 on PPC, with GNU ld
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+ # Not sure whether something based on
+ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+ # would be better.
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ m88k*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+
+ *nto* | *qnx*)
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ fi
+ output_verbose_link_cmd=func_echo_all
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ case $host in
+ osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+ *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+ esac
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ cxx*)
+ case $host in
+ osf3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
+ $RM $lib.exp'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes,no = "$GXX,$with_gnu_ld"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ case $host in
+ osf3*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ psos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test yes,no = "$GXX,$with_gnu_ld"; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs'
+ if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ else
+ # g++ 2.7 appears to require '-G' NOT '-shared' on this
+ # platform.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ fi
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+ '"$_LT_TAGVAR(old_archive_cmds, $1)"
+ _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+ '"$_LT_TAGVAR(reload_cmds, $1)"
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+ test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+
+ _LT_TAGVAR(GCC, $1)=$GXX
+ _LT_TAGVAR(LD, $1)=$LD
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+ LDCXX=$LD
+ LD=$lt_save_LD
+ GCC=$lt_save_GCC
+ with_gnu_ld=$lt_save_with_gnu_ld
+ lt_cv_path_LDCXX=$lt_cv_path_LD
+ lt_cv_path_LD=$lt_save_path_LD
+ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test yes != "$_lt_caught_CXX_error"
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+ case @S|@2 in
+ .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;;
+ *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;;
+ esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library. It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer*4 a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+ private int a;
+ public void bar (void) {
+ a = 0;
+ }
+};
+_LT_EOF
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
+])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ for p in `eval "$output_verbose_link_cmd"`; do
+ case $prev$p in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test x-L = "$p" ||
+ test x-R = "$p"; then
+ prev=$p
+ continue
+ fi
+
+ # Expand the sysroot to ease extracting the directories later.
+ if test -z "$prev"; then
+ case $p in
+ -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+ -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+ -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+ esac
+ fi
+ case $p in
+ =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+ esac
+ if test no = "$pre_test_object_deps_done"; then
+ case $prev in
+ -L | -R)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+ _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p
+ else
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+ _LT_TAGVAR(postdeps, $1)=$prev$p
+ else
+ _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p"
+ fi
+ fi
+ prev=
+ ;;
+
+ *.lto.$objext) ;; # Ignore GCC LTO objects
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test no = "$pre_test_object_deps_done"; then
+ if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+ _LT_TAGVAR(predep_objects, $1)=$p
+ else
+ _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+ fi
+ else
+ if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+ _LT_TAGVAR(postdep_objects, $1)=$p
+ else
+ _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ _LT_TAGVAR(predep_objects,$1)=
+ _LT_TAGVAR(postdep_objects,$1)=
+ _LT_TAGVAR(postdeps,$1)=
+ ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+ [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+ [Dependencies to place before and after the objects being linked to
+ create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+ [The library search path used internally by the compiler when linking
+ a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test no = "$F77"; then
+ _lt_disable_F77=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_disable_F77"; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${F77-"f77"}
+ CFLAGS=$FFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+ GCC=$G77
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)=$G77
+ _LT_TAGVAR(LD, $1)=$LD
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+fi # test yes != "$_lt_disable_F77"
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test no = "$FC"; then
+ _lt_disable_FC=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_disable_FC"; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${FC-"f95"}
+ CFLAGS=$FCFLAGS
+ compiler=$CC
+ GCC=$ac_cv_fc_compiler_gnu
+
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu
+ _LT_TAGVAR(LD, $1)=$LD
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+fi # test yes != "$_lt_disable_FC"
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)=$LD
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_SAVE
+
+# Source file extension for Go test sources.
+ac_ext=go
+
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)=$LD
+_LT_CC_BASENAME([$compiler])
+
+# Go did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code=$lt_simple_compile_test_code
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+ :
+ _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+ [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+ [AC_CHECK_TOOL(GCJ, gcj,)
+ test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2"
+ AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible. Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+ [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_SED. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for lt_ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+ fi
+ done
+ done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+ test ! -f "$lt_ac_sed" && continue
+ cat /dev/null > conftest.in
+ lt_ac_count=0
+ echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+ # Check for GNU sed and select it if it is found.
+ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+ lt_cv_path_SED=$lt_ac_sed
+ break
+ fi
+ while true; do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo >>conftest.nl
+ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+ cmp -s conftest.out conftest.nl || break
+ # 10000 chars as input seems more than enough
+ test 10 -lt "$lt_ac_count" && break
+ lt_ac_count=`expr $lt_ac_count + 1`
+ if test "$lt_ac_count" -gt "$lt_ac_max"; then
+ lt_ac_max=$lt_ac_count
+ lt_cv_path_SED=$lt_ac_sed
+ fi
+ done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine what file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path). These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+ [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+ [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
diff --git a/m4/ltoptions.m4 b/m4/ltoptions.m4
new file mode 100644
index 000000000..94b082976
--- /dev/null
+++ b/m4/ltoptions.m4
@@ -0,0 +1,437 @@
+# Helper functions for option handling. -*- Autoconf -*-
+#
+# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
+# Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 8 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it. Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+ _LT_MANGLE_DEFUN([$1], [$2]),
+ [m4_warning([Unknown $1 option '$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+ [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME. If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+ dnl
+ dnl Simply set some default values (i.e off) if boolean options were not
+ dnl specified:
+ _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+ ])
+ _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+ ])
+ dnl
+ dnl If no reference was made to various pairs of opposing options, then
+ dnl we run the default mode handler for the pair. For example, if neither
+ dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
+ dnl archives by default:
+ _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+ _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+ [_LT_ENABLE_FAST_INSTALL])
+ _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
+ [_LT_WITH_AIX_SONAME([aix])])
+ ])
+])# _LT_SET_OPTIONS
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT options. ##
+## --------------------------------- ##
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS], [1], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the 'shared' and
+# 'disable-shared' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+ [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+ [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+ _LT_DECL([build_libtool_libs], [enable_shared], [0],
+ [Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the 'static' and
+# 'disable-static' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+ [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+ [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+ _LT_DECL([build_old_libs], [enable_static], [0],
+ [Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the 'fast-install'
+# and 'disable-fast-install' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+ [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+ [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+ [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the 'fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the 'disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_AIX_SONAME([DEFAULT])
+# ----------------------------------
+# implement the --with-aix-soname flag, and support the `aix-soname=aix'
+# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
+# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'.
+m4_define([_LT_WITH_AIX_SONAME],
+[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
+shared_archive_member_spec=
+case $host,$enable_shared in
+power*-*-aix[[5-9]]*,yes)
+ AC_MSG_CHECKING([which variant of shared library versioning to provide])
+ AC_ARG_WITH([aix-soname],
+ [AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
+ [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
+ [case $withval in
+ aix|svr4|both)
+ ;;
+ *)
+ AC_MSG_ERROR([Unknown argument to --with-aix-soname])
+ ;;
+ esac
+ lt_cv_with_aix_soname=$with_aix_soname],
+ [AC_CACHE_VAL([lt_cv_with_aix_soname],
+ [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
+ with_aix_soname=$lt_cv_with_aix_soname])
+ AC_MSG_RESULT([$with_aix_soname])
+ if test aix != "$with_aix_soname"; then
+ # For the AIX way of multilib, we name the shared archive member
+ # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
+ # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
+ # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
+ # the AIX toolchain works better with OBJECT_MODE set (default 32).
+ if test 64 = "${OBJECT_MODE-32}"; then
+ shared_archive_member_spec=shr_64
+ else
+ shared_archive_member_spec=shr
+ fi
+ fi
+ ;;
+*)
+ with_aix_soname=aix
+ ;;
+esac
+
+_LT_DECL([], [shared_archive_member_spec], [0],
+ [Shared archive member basename, for filename based shared library versioning on AIX])dnl
+])# _LT_WITH_AIX_SONAME
+
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
+# LT_INIT options.
+# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+ [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
+ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+ [lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for lt_pkg in $withval; do
+ IFS=$lt_save_ifs
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [pic_mode=m4_default([$1], [default])])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+ [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+ [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+ [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+ [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+ [m4_define([_LTDL_TYPE], [convenience])])
diff --git a/m4/ltsugar.m4 b/m4/ltsugar.m4
new file mode 100644
index 000000000..48bc9344a
--- /dev/null
+++ b/m4/ltsugar.m4
@@ -0,0 +1,124 @@
+# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
+#
+# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
+# Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+ [$#], [2], [[$2]],
+ [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+ [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59, which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+ [$#], 1, [],
+ [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+ m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+ [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+ [m4_foreach([_Lt_suffix],
+ ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+ [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+ [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+ [lt_append([$1], [$2], [$3])$4],
+ [$5])],
+ [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+ m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+ m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+ [$5],
+ [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+ [lt_join(m4_quote(m4_default([$4], [[, ]])),
+ lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+ [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
diff --git a/m4/ltversion.m4 b/m4/ltversion.m4
new file mode 100644
index 000000000..fa04b52a3
--- /dev/null
+++ b/m4/ltversion.m4
@@ -0,0 +1,23 @@
+# ltversion.m4 -- version numbers -*- Autoconf -*-
+#
+# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# @configure_input@
+
+# serial 4179 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.4.6])
+m4_define([LT_PACKAGE_REVISION], [2.4.6])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.4.6'
+macro_revision='2.4.6'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
diff --git a/m4/lt~obsolete.m4 b/m4/lt~obsolete.m4
new file mode 100644
index 000000000..c6b26f88f
--- /dev/null
+++ b/m4/lt~obsolete.m4
@@ -0,0 +1,99 @@
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
+#
+# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
+# Foundation, Inc.
+# Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 5 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else. This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
diff --git a/mime/braille.convs b/mime/braille.convs
new file mode 100644
index 000000000..fabbafccb
--- /dev/null
+++ b/mime/braille.convs
@@ -0,0 +1,108 @@
+#
+# Copyright (c) 2015, 2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+# Textual conversions
+text/plain text/vnd.cups-brf 0 texttobrf
+
+text/html text/vnd.cups-brf 10 texttobrf
+application/xhtml text/vnd.cups-brf 10 texttobrf
+application/xml text/vnd.cups-brf 10 texttobrf
+application/sgml text/vnd.cups-brf 10 texttobrf
+
+application/vnd.recordare.musicxml+xml text/vnd.cups-brf 30 musicxmltobrf
+
+application/vnd.oasis.opendocument.chart text/vnd.cups-brf 30 texttobrf
+application/vnd.oasis.opendocument.formula text/vnd.cups-brf 30 texttobrf
+application/vnd.oasis.opendocument.graphics text/vnd.cups-brf 30 texttobrf
+application/vnd.oasis.opendocument.graphics-template text/vnd.cups-brf 30 texttobrf
+application/vnd.oasis.opendocument.presentation text/vnd.cups-brf 30 texttobrf
+application/vnd.oasis.opendocument.presentation-template text/vnd.cups-brf 30 texttobrf
+application/vnd.oasis.opendocument.spreadsheet text/vnd.cups-brf 30 texttobrf
+application/vnd.oasis.opendocument.spreadsheet-template text/vnd.cups-brf 30 texttobrf
+application/vnd.oasis.opendocument.text text/vnd.cups-brf 30 texttobrf
+application/vnd.oasis.opendocument.text-master text/vnd.cups-brf 30 texttobrf
+application/vnd.oasis.opendocument.text-template text/vnd.cups-brf 30 texttobrf
+application/vnd.oasis.opendocument.text-web text/vnd.cups-brf 30 texttobrf
+
+application/msword text/vnd.cups-brf 30 texttobrf
+application/vnd.openxmlformats-officedocument.presentationml.presentation text/vnd.cups-brf 30 texttobrf
+application/vnd.openxmlformats-officedocument.presentationml.slide text/vnd.cups-brf 30 texttobrf
+application/vnd.openxmlformats-officedocument.presentationml.slideshow text/vnd.cups-brf 30 texttobrf
+application/vnd.openxmlformats-officedocument.presentationml.template text/vnd.cups-brf 30 texttobrf
+application/vnd.openxmlformats-officedocument.spreadsheetml.sheet text/vnd.cups-brf 30 texttobrf
+application/vnd.openxmlformats-officedocument.spreadsheetml.template text/vnd.cups-brf 30 texttobrf
+application/vnd.openxmlformats-officedocument.wordprocessingml.document text/vnd.cups-brf 30 texttobrf
+application/vnd.openxmlformats-officedocument.wordprocessingml.template text/vnd.cups-brf 30 texttobrf
+
+text/rtf text/vnd.cups-brf 30 texttobrf
+application/rtf text/vnd.cups-brf 30 texttobrf
+
+application/pdf text/vnd.cups-brf 100 texttobrf
+
+
+# Picture conversions
+image/gif image/vnd.cups-brf 70 imagetobrf
+image/jpeg image/vnd.cups-brf 70 imagetobrf
+image/pcx image/vnd.cups-brf 70 imagetobrf
+image/png image/vnd.cups-brf 70 imagetobrf
+image/tiff image/vnd.cups-brf 70 imagetobrf
+image/vnd.microsoft.icon image/vnd.cups-brf 70 imagetobrf
+image/x-ms-bmp image/vnd.cups-brf 70 imagetobrf
+image/x-portable-anymap image/vnd.cups-brf 70 imagetobrf
+image/x-portable-bitmap image/vnd.cups-brf 70 imagetobrf
+image/x-portable-graymap image/vnd.cups-brf 70 imagetobrf
+image/x-portable-pixmap image/vnd.cups-brf 70 imagetobrf
+image/x-xbitmap image/vnd.cups-brf 70 imagetobrf
+image/x-xpixmap image/vnd.cups-brf 70 imagetobrf
+image/x-xwindowdump image/vnd.cups-brf 70 imagetobrf
+
+image/gif image/vnd.cups-ubrl 70 imagetoubrl
+image/jpeg image/vnd.cups-ubrl 70 imagetoubrl
+image/pcx image/vnd.cups-ubrl 70 imagetoubrl
+image/png image/vnd.cups-ubrl 70 imagetoubrl
+image/tiff image/vnd.cups-ubrl 70 imagetoubrl
+image/vnd.microsoft.icon image/vnd.cups-ubrl 70 imagetoubrl
+image/x-ms-bmp image/vnd.cups-ubrl 70 imagetoubrl
+image/x-portable-anymap image/vnd.cups-ubrl 70 imagetoubrl
+image/x-portable-bitmap image/vnd.cups-ubrl 70 imagetoubrl
+image/x-portable-graymap image/vnd.cups-ubrl 70 imagetoubrl
+image/x-portable-pixmap image/vnd.cups-ubrl 70 imagetoubrl
+image/x-xbitmap image/vnd.cups-ubrl 70 imagetoubrl
+image/x-xpixmap image/vnd.cups-ubrl 70 imagetoubrl
+image/x-xwindowdump image/vnd.cups-ubrl 70 imagetoubrl
+
+image/svg image/vnd.cups-pdf 30 svgtopdf
+image/svg+xml image/vnd.cups-pdf 30 svgtopdf
+application/x-xfig image/vnd.cups-pdf 30 xfigtopdf
+image/wmf image/vnd.cups-pdf 30 wmftopdf
+image/x-wmf image/vnd.cups-pdf 30 wmftopdf
+windows/metafile image/vnd.cups-pdf 30 wmftopdf
+application/x-msmetafile image/vnd.cups-pdf 30 wmftopdf
+image/emf image/vnd.cups-pdf 30 emftopdf
+image/x-emf image/vnd.cups-pdf 30 emftopdf
+image/cgm image/vnd.cups-pdf 30 cgmtopdf
+image/x-cmx image/vnd.cups-pdf 30 cmxtopdf
+
+image/vnd.cups-pdf image/vnd.cups-brf 30 vectortobrf
+image/vnd.cups-pdf image/vnd.cups-ubrl 30 vectortoubrl
diff --git a/mime/braille.types b/mime/braille.types
new file mode 100644
index 000000000..55c8fe763
--- /dev/null
+++ b/mime/braille.types
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2015, 2017 Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+text/vnd.cups-brf brf
+text/vnd.cups-ubrl
+image/vnd.cups-brf
+image/vnd.cups-ubrl
+image/vnd.cups-pdf
+
+application/sgml sgml
+
+application/vnd.recordare.musicxml+xml xml contains(0,1000,"<score-partwise")
+
+application/vnd.oasis.opendocument.chart odc
+application/vnd.oasis.opendocument.database odb
+application/vnd.oasis.opendocument.formula odf
+application/vnd.oasis.opendocument.graphics odg
+application/vnd.oasis.opendocument.graphics-template otg
+application/vnd.oasis.opendocument.image odi
+application/vnd.oasis.opendocument.presentation odp
+application/vnd.oasis.opendocument.presentation-template otp
+application/vnd.oasis.opendocument.spreadsheet ods
+application/vnd.oasis.opendocument.spreadsheet-template ots
+application/vnd.oasis.opendocument.text odt
+application/vnd.oasis.opendocument.text-master odm
+application/vnd.oasis.opendocument.text-template ott
+application/vnd.oasis.opendocument.text-web oth
+
+application/msword doc string(0,<D0CF11E0A1B11AE1>)
+application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
+application/vnd.openxmlformats-officedocument.presentationml.slide sldx
+application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx
+application/vnd.openxmlformats-officedocument.presentationml.template potx
+application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx
+application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx
+application/vnd.openxmlformats-officedocument.wordprocessingml.document docx
+application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx
+
+image/svg+xml svg svgz
+application/x-xfig fig
+image/wmf wmf
+image/emf emf
+image/cgm cgm
+image/x-cmx cmx
diff --git a/mime/cupsfilters-ghostscript.convs b/mime/cupsfilters-ghostscript.convs
new file mode 100644
index 000000000..9ccb0a1a3
--- /dev/null
+++ b/mime/cupsfilters-ghostscript.convs
@@ -0,0 +1,21 @@
+#
+# MIME conversions file for OpenPrinting CUPS Filters.
+#
+# Copyright 2007-2011 by Apple Inc.
+# Copyright 1997-2007 by Easy Software Products.
+# Copyright 2012-2016 by Till Kamppeter.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Apple Inc. and are protected by Federal copyright
+# law. Distribution and use rights are outlined in the file "COPYING"
+# which should have been included with this file.
+#
+
+#
+# Ghostscript-based filters...
+#
+
+application/postscript application/pdf 0 gstopdf
+application/vnd.cups-pdf application/vnd.cups-raster 99 gstoraster
+application/vnd.cups-pdf image/pwg-raster 99 gstoraster
+application/vnd.cups-postscript application/vnd.cups-raster 175 gstoraster
diff --git a/mime/cupsfilters-mupdf.convs b/mime/cupsfilters-mupdf.convs
new file mode 100644
index 000000000..20a68beb4
--- /dev/null
+++ b/mime/cupsfilters-mupdf.convs
@@ -0,0 +1,19 @@
+#
+# MIME conversions file for OpenPrinting CUPS Filters.
+#
+# Copyright 2007-2011 by Apple Inc.
+# Copyright 1997-2007 by Easy Software Products.
+# Copyright 2012-2016 by Till Kamppeter.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Apple Inc. and are protected by Federal copyright
+# law. Distribution and use rights are outlined in the file "COPYING"
+# which should have been included with this file.
+#
+
+#
+# MuPDF-based filters...
+#
+
+application/vnd.cups-pdf application/vnd.cups-raster 101 mupdftoraster
+application/vnd.cups-pdf image/pwg-raster 101 mupdftoraster
diff --git a/mime/cupsfilters-poppler.convs b/mime/cupsfilters-poppler.convs
new file mode 100644
index 000000000..4fd91c1e7
--- /dev/null
+++ b/mime/cupsfilters-poppler.convs
@@ -0,0 +1,19 @@
+#
+# MIME conversions file for OpenPrinting CUPS Filters.
+#
+# Copyright 2007-2011 by Apple Inc.
+# Copyright 1997-2007 by Easy Software Products.
+# Copyright 2012-2016 by Till Kamppeter.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Apple Inc. and are protected by Federal copyright
+# law. Distribution and use rights are outlined in the file "COPYING"
+# which should have been included with this file.
+#
+
+#
+# Poppler-based filters...
+#
+
+application/vnd.cups-pdf application/vnd.cups-raster 100 pdftoraster
+application/vnd.cups-pdf image/pwg-raster 100 pdftoraster
diff --git a/mime/cupsfilters.convs b/mime/cupsfilters.convs
new file mode 100644
index 000000000..b92603f02
--- /dev/null
+++ b/mime/cupsfilters.convs
@@ -0,0 +1,114 @@
+#
+# MIME conversions file for OpenPrinting CUPS Filters.
+#
+# Copyright 2007-2011 by Apple Inc.
+# Copyright 1997-2007 by Easy Software Products.
+# Copyright 2012-2016 by Till Kamppeter.
+# Copyright 2017 by Sahil Arora.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Apple Inc. and are protected by Federal copyright
+# law. Distribution and use rights are outlined in the file "COPYING"
+# which should have been included with this file.
+#
+
+########################################################################
+#
+# Format of Lines:
+#
+# source/type destination/type cost filter
+#
+# General Notes:
+#
+# The "cost" field is used to find the least costly filters to run
+# when converting a job file to a printable format.
+#
+# All filters *must* accept the standard command-line arguments
+# (job-id, user, title, copies, options, [filename or stdin]) to
+# work with CUPS.
+#
+
+########################################################################
+#
+# PDF filters
+#
+
+# CUPS file conversion rules for PostScript input when we are working with
+# the PDF printing workflow. General PostScript input should be converted to
+# PDF (see cupsfilters-ghostscript.convs as this is done by Ghostscript), so
+# that pdftopdf is doing the page management on PDF data and the
+# renderer/driver part renders PDF. An exception is made for PostScript
+# coming from the Adobe Reader. As this PostScript cannot be converted to PDF
+# if it comes from an encrypted PDF file, we simply override pstopdf and the
+# PDF workflow.
+
+application/vnd.adobe-reader-postscript application/vnd.cups-postscript 66 pstops
+
+application/pdf application/vnd.cups-pdf 66 pdftopdf
+application/x-cshell application/pdf 32 texttopdf
+application/x-csource application/pdf 32 texttopdf
+application/x-perl application/pdf 32 texttopdf
+application/x-shell application/pdf 32 texttopdf
+text/plain application/pdf 32 texttopdf
+text/html application/pdf 32 texttopdf
+image/pwg-raster application/pdf 32 rastertopdf
+image/gif application/vnd.cups-pdf 65 imagetopdf
+image/png application/vnd.cups-pdf 65 imagetopdf
+image/jpeg application/vnd.cups-pdf 65 imagetopdf
+image/tiff application/vnd.cups-pdf 65 imagetopdf
+image/x-bitmap application/vnd.cups-pdf 65 imagetopdf
+image/x-photocd application/vnd.cups-pdf 65 imagetopdf
+image/x-portable-anymap application/vnd.cups-pdf 65 imagetopdf
+image/x-portable-bitmap application/vnd.cups-pdf 65 imagetopdf
+image/x-portable-graymap application/vnd.cups-pdf 65 imagetopdf
+image/x-portable-pixmap application/vnd.cups-pdf 65 imagetopdf
+image/x-sgi-rgb application/vnd.cups-pdf 65 imagetopdf
+image/x-xbitmap application/vnd.cups-pdf 65 imagetopdf
+image/x-xpixmap application/vnd.cups-pdf 65 imagetopdf
+image/x-xwindowdump application/vnd.cups-pdf 65 imagetopdf
+image/x-sun-raster application/vnd.cups-pdf 65 imagetopdf
+application/vnd.cups-pdf-banner application/pdf 32 bannertopdf
+image/urf application/pdf 0 rastertopdf
+application/vnd.cups-raster application/PCLm 32 rastertopclm
+
+########################################################################
+#
+# PostScript filters
+#
+
+#application/pdf application/vnd.cups-postscript 66 pdftops
+application/vnd.cups-pdf application/vnd.cups-postscript 100 pdftops
+#application/postscript application/vnd.cups-postscript 66 pstops
+
+########################################################################
+#
+# Raster filters...
+#
+
+image/gif application/vnd.cups-raster 100 imagetoraster
+image/png application/vnd.cups-raster 100 imagetoraster
+image/jpeg application/vnd.cups-raster 100 imagetoraster
+image/tiff application/vnd.cups-raster 100 imagetoraster
+image/x-bitmap application/vnd.cups-raster 100 imagetoraster
+image/x-photocd application/vnd.cups-raster 100 imagetoraster
+image/x-portable-anymap application/vnd.cups-raster 100 imagetoraster
+image/x-portable-bitmap application/vnd.cups-raster 100 imagetoraster
+image/x-portable-graymap application/vnd.cups-raster 100 imagetoraster
+image/x-portable-pixmap application/vnd.cups-raster 100 imagetoraster
+image/x-sgi-rgb application/vnd.cups-raster 100 imagetoraster
+image/x-xbitmap application/vnd.cups-raster 100 imagetoraster
+image/x-xpixmap application/vnd.cups-raster 100 imagetoraster
+image/x-sun-raster application/vnd.cups-raster 100 imagetoraster
+
+########################################################################
+#
+# Text filters (only for text-only printers)...
+#
+
+application/x-cshell text/plain 100 -
+application/x-csource text/plain 100 -
+application/x-perl text/plain 100 -
+application/x-shell text/plain 100 -
+text/html text/plain 100 -
+text/css text/plain 100 -
+
diff --git a/mime/cupsfilters.convs.in b/mime/cupsfilters.convs.in
new file mode 100644
index 000000000..82a9403bf
--- /dev/null
+++ b/mime/cupsfilters.convs.in
@@ -0,0 +1,114 @@
+#
+# MIME conversions file for OpenPrinting CUPS Filters.
+#
+# Copyright 2007-2011 by Apple Inc.
+# Copyright 1997-2007 by Easy Software Products.
+# Copyright 2012-2016 by Till Kamppeter.
+# Copyright 2017 by Sahil Arora.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Apple Inc. and are protected by Federal copyright
+# law. Distribution and use rights are outlined in the file "COPYING"
+# which should have been included with this file.
+#
+
+########################################################################
+#
+# Format of Lines:
+#
+# source/type destination/type cost filter
+#
+# General Notes:
+#
+# The "cost" field is used to find the least costly filters to run
+# when converting a job file to a printable format.
+#
+# All filters *must* accept the standard command-line arguments
+# (job-id, user, title, copies, options, [filename or stdin]) to
+# work with CUPS.
+#
+
+########################################################################
+#
+# PDF filters
+#
+
+# CUPS file conversion rules for PostScript input when we are working with
+# the PDF printing workflow. General PostScript input should be converted to
+# PDF (see cupsfilters-ghostscript.convs as this is done by Ghostscript), so
+# that pdftopdf is doing the page management on PDF data and the
+# renderer/driver part renders PDF. An exception is made for PostScript
+# coming from the Adobe Reader. As this PostScript cannot be converted to PDF
+# if it comes from an encrypted PDF file, we simply override pstopdf and the
+# PDF workflow.
+
+application/vnd.adobe-reader-postscript application/vnd.cups-postscript 66 pstops
+
+application/pdf application/vnd.cups-pdf 66 pdftopdf
+application/x-cshell application/pdf 32 texttopdf
+application/x-csource application/pdf 32 texttopdf
+application/x-perl application/pdf 32 texttopdf
+application/x-shell application/pdf 32 texttopdf
+text/plain application/pdf 32 texttopdf
+text/html application/pdf 32 texttopdf
+image/pwg-raster application/pdf 32 rastertopdf
+image/gif application/vnd.cups-pdf 65 imagetopdf
+image/png application/vnd.cups-pdf 65 imagetopdf
+image/jpeg application/vnd.cups-pdf 65 imagetopdf
+image/tiff application/vnd.cups-pdf 65 imagetopdf
+image/x-bitmap application/vnd.cups-pdf 65 imagetopdf
+image/x-photocd application/vnd.cups-pdf 65 imagetopdf
+image/x-portable-anymap application/vnd.cups-pdf 65 imagetopdf
+image/x-portable-bitmap application/vnd.cups-pdf 65 imagetopdf
+image/x-portable-graymap application/vnd.cups-pdf 65 imagetopdf
+image/x-portable-pixmap application/vnd.cups-pdf 65 imagetopdf
+image/x-sgi-rgb application/vnd.cups-pdf 65 imagetopdf
+image/x-xbitmap application/vnd.cups-pdf 65 imagetopdf
+image/x-xpixmap application/vnd.cups-pdf 65 imagetopdf
+image/x-xwindowdump application/vnd.cups-pdf 65 imagetopdf
+image/x-sun-raster application/vnd.cups-pdf 65 imagetopdf
+application/vnd.cups-pdf-banner application/pdf 32 bannertopdf
+image/urf application/pdf 0 @APPLE_RASTER_FILTER@
+@QPDF_NO_PCLM@application/vnd.cups-raster application/PCLm 32 rastertopclm
+
+########################################################################
+#
+# PostScript filters
+#
+
+#application/pdf application/vnd.cups-postscript 66 pdftops
+application/vnd.cups-pdf application/vnd.cups-postscript 100 pdftops
+#application/postscript application/vnd.cups-postscript 66 pstops
+
+########################################################################
+#
+# Raster filters...
+#
+
+image/gif application/vnd.cups-raster 100 imagetoraster
+image/png application/vnd.cups-raster 100 imagetoraster
+image/jpeg application/vnd.cups-raster 100 imagetoraster
+image/tiff application/vnd.cups-raster 100 imagetoraster
+image/x-bitmap application/vnd.cups-raster 100 imagetoraster
+image/x-photocd application/vnd.cups-raster 100 imagetoraster
+image/x-portable-anymap application/vnd.cups-raster 100 imagetoraster
+image/x-portable-bitmap application/vnd.cups-raster 100 imagetoraster
+image/x-portable-graymap application/vnd.cups-raster 100 imagetoraster
+image/x-portable-pixmap application/vnd.cups-raster 100 imagetoraster
+image/x-sgi-rgb application/vnd.cups-raster 100 imagetoraster
+image/x-xbitmap application/vnd.cups-raster 100 imagetoraster
+image/x-xpixmap application/vnd.cups-raster 100 imagetoraster
+image/x-sun-raster application/vnd.cups-raster 100 imagetoraster
+
+########################################################################
+#
+# Text filters (only for text-only printers)...
+#
+
+application/x-cshell text/plain 100 -
+application/x-csource text/plain 100 -
+application/x-perl text/plain 100 -
+application/x-shell text/plain 100 -
+text/html text/plain 100 -
+text/css text/plain 100 -
+
diff --git a/mime/cupsfilters.types b/mime/cupsfilters.types
new file mode 100644
index 000000000..ceb45633a
--- /dev/null
+++ b/mime/cupsfilters.types
@@ -0,0 +1,105 @@
+#
+# MIME types file for OpenPrinting CUPS Filters.
+#
+# DO NOT EDIT THIS FILE, AS IT IS OVERWRITTEN WHEN YOU INSTALL NEW
+# VERSIONS OF OPENPRINTING CUPS FILTERS. Instead, create a "local.types"
+# file that reflects your local configuration changes.
+#
+# Copyright 2007-2011 by Apple Inc.
+# Copyright 1997-2007 by Easy Software Products.
+# Copyright 2012-2016 by Till Kamppeter.
+# Copyright 2017 by Sahil Arora.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Apple Inc. and are protected by Federal copyright
+# law. Distribution and use rights are outlined in the file "COPYING"
+# which should have been included with this file.
+#
+
+########################################################################
+#
+# Format of Lines:
+#
+# super/type rules
+#
+# "rules" can be any combination of:
+#
+# ( expr ) Parenthesis for expression grouping
+# + Logical AND
+# , or whitespace Logical OR
+# ! Logical NOT
+# match("pattern") Pattern match on filename
+# extension Pattern match on "*.extension"
+# ascii(offset,length) True if bytes are valid printable ASCII
+# (CR, NL, TAB, BS, 32-126)
+# priority(number) Sets priority of type (0=lowest,
+# 100=default, 200=highest)
+# printable(offset,length) True if bytes are printable 8-bit chars
+# (CR, NL, TAB, BS, 32-126, 128-254)
+# string(offset,"string") True if bytes are identical to string
+# istring(offset,"string") True if bytes are identical to
+# case-insensitive string
+# char(offset,value) True if byte is identical
+# short(offset,value) True if 16-bit integer is identical
+# int(offset,value) True if 32-bit integer is identical
+# locale("string") True if current locale matches string
+# contains(offset,range,"string") True if the range contains the string
+#
+# General Notes:
+#
+# MIME type names are case-insensitive. Internally they are converted
+# to lowercase. Multiple occurrences of a type will cause the provided
+# rules to be appended to the existing definition. If two types use the same
+# rules to resolve a type and have the same priority, e.g. "doc" extension for
+# "text/bar" and "text/foo", the returned type will be the first type as
+# sorted in alphanumerically ascending order without regard to case. Thus,
+# the "text/bar" type will match the "doc" extension first unless the
+# "text/foo" type has specified a higher priority.
+#
+# The "printable" rule differs from the "ascii" rule in that it also
+# accepts 8-bit characters in the range 128-255.
+#
+# String constants must be surrounded by "" if they contain whitespace.
+# To insert binary data into a string, use the <hex> notation.
+#
+
+########################################################################
+#
+# Application-generated files...
+#
+
+# CUPS file detection rule for PostScript which is generated by the Adobe
+# Reader. We distinguish PostScript from the Adobe reader here so that we
+# can override pstopdf and the PDF workflow for these PostScript files as the
+# conversion of them to PDF does not work if the original PDF file was
+# encrypted.
+
+application/vnd.adobe-reader-postscript priority(150) contains(0,4096,"%%Creator: Adobe Acrobat") + \
+ (ai eps ps string(0,%!) string(0,<04>%!) \
+ contains(0,128,<1B>%-12345X) + \
+ (contains(0,4096,"LANGUAGE=POSTSCRIPT") \
+ contains(0,4096,"LANGUAGE = Postscript") \
+ contains(0,4096,"LANGUAGE = PostScript") \
+ contains(0,4096,"LANGUAGE = POSTSCRIPT") \
+ (contains(0,4096,<0a>%!) + \
+ !contains(0,4096,"ENTER LANGUAGE"))))
+
+########################################################################
+#
+# Image files...
+#
+
+image/x-xbitmap xbm string(0,"#define");
+image/x-xpixmap xpm string(3,"XPM")
+image/x-xwindowdump xwd string(4,<00000007>)
+image/urf urf string(0,UNIRAST<00>)
+
+########################################################################
+#
+# CUPS-specific types...
+#
+
+application/vnd.cups-pdf
+application/vnd.cups-pdf-banner string(0,'#PDF-BANNER')
+application/PCLm
+
diff --git a/missing b/missing
new file mode 100755
index 000000000..f62bbae30
--- /dev/null
+++ b/missing
@@ -0,0 +1,215 @@
+#! /bin/sh
+# Common wrapper for a few potentially missing GNU programs.
+
+scriptversion=2013-10-28.13; # UTC
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# 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 2, 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/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try '$0 --help' for more information"
+ exit 1
+fi
+
+case $1 in
+
+ --is-lightweight)
+ # Used by our autoconf macros to check whether the available missing
+ # script is modern enough.
+ exit 0
+ ;;
+
+ --run)
+ # Back-compat with the calling convention used by older automake.
+ shift
+ ;;
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
+to PROGRAM being missing or too old.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+
+Supported PROGRAM values:
+ aclocal autoconf autoheader autom4te automake makeinfo
+ bison yacc flex lex help2man
+
+Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
+'g' are ignored when checking the name.
+
+Send bug reports to <bug-automake@gnu.org>."
+ exit $?
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing $scriptversion (GNU Automake)"
+ exit $?
+ ;;
+
+ -*)
+ echo 1>&2 "$0: unknown '$1' option"
+ echo 1>&2 "Try '$0 --help' for more information"
+ exit 1
+ ;;
+
+esac
+
+# Run the given program, remember its exit status.
+"$@"; st=$?
+
+# If it succeeded, we are done.
+test $st -eq 0 && exit 0
+
+# Also exit now if we it failed (or wasn't found), and '--version' was
+# passed; such an option is passed most likely to detect whether the
+# program is present and works.
+case $2 in --version|--help) exit $st;; esac
+
+# Exit code 63 means version mismatch. This often happens when the user
+# tries to use an ancient version of a tool on a file that requires a
+# minimum version.
+if test $st -eq 63; then
+ msg="probably too old"
+elif test $st -eq 127; then
+ # Program was missing.
+ msg="missing on your system"
+else
+ # Program was found and executed, but failed. Give up.
+ exit $st
+fi
+
+perl_URL=http://www.perl.org/
+flex_URL=http://flex.sourceforge.net/
+gnu_software_URL=http://www.gnu.org/software
+
+program_details ()
+{
+ case $1 in
+ aclocal|automake)
+ echo "The '$1' program is part of the GNU Automake package:"
+ echo "<$gnu_software_URL/automake>"
+ echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/autoconf>"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ autoconf|autom4te|autoheader)
+ echo "The '$1' program is part of the GNU Autoconf package:"
+ echo "<$gnu_software_URL/autoconf/>"
+ echo "It also requires GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ esac
+}
+
+give_advice ()
+{
+ # Normalize program name to check for.
+ normalized_program=`echo "$1" | sed '
+ s/^gnu-//; t
+ s/^gnu//; t
+ s/^g//; t'`
+
+ printf '%s\n' "'$1' is $msg."
+
+ configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
+ case $normalized_program in
+ autoconf*)
+ echo "You should only need it if you modified 'configure.ac',"
+ echo "or m4 files included by it."
+ program_details 'autoconf'
+ ;;
+ autoheader*)
+ echo "You should only need it if you modified 'acconfig.h' or"
+ echo "$configure_deps."
+ program_details 'autoheader'
+ ;;
+ automake*)
+ echo "You should only need it if you modified 'Makefile.am' or"
+ echo "$configure_deps."
+ program_details 'automake'
+ ;;
+ aclocal*)
+ echo "You should only need it if you modified 'acinclude.m4' or"
+ echo "$configure_deps."
+ program_details 'aclocal'
+ ;;
+ autom4te*)
+ echo "You might have modified some maintainer files that require"
+ echo "the 'autom4te' program to be rebuilt."
+ program_details 'autom4te'
+ ;;
+ bison*|yacc*)
+ echo "You should only need it if you modified a '.y' file."
+ echo "You may want to install the GNU Bison package:"
+ echo "<$gnu_software_URL/bison/>"
+ ;;
+ lex*|flex*)
+ echo "You should only need it if you modified a '.l' file."
+ echo "You may want to install the Fast Lexical Analyzer package:"
+ echo "<$flex_URL>"
+ ;;
+ help2man*)
+ echo "You should only need it if you modified a dependency" \
+ "of a man page."
+ echo "You may want to install the GNU Help2man package:"
+ echo "<$gnu_software_URL/help2man/>"
+ ;;
+ makeinfo*)
+ echo "You should only need it if you modified a '.texi' file, or"
+ echo "any other file indirectly affecting the aspect of the manual."
+ echo "You might want to install the Texinfo package:"
+ echo "<$gnu_software_URL/texinfo/>"
+ echo "The spurious makeinfo call might also be the consequence of"
+ echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
+ echo "want to install GNU make:"
+ echo "<$gnu_software_URL/make/>"
+ ;;
+ *)
+ echo "You might have modified some files without having the proper"
+ echo "tools for further handling them. Check the 'README' file, it"
+ echo "often tells you about the needed prerequisites for installing"
+ echo "this package. You may also peek at any GNU archive site, in"
+ echo "case some other package contains this missing '$1' program."
+ ;;
+ esac
+}
+
+give_advice "$1" | sed -e '1s/^/WARNING: /' \
+ -e '2,$s/^/ /' >&2
+
+# Propagate the correct exit status (expected to be 127 for a program
+# not found, 63 for a program that failed due to version mismatch).
+exit $st
+
+# Local variables:
+# 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/ppd/Fuji_Xerox-DocuPrint_CM305_df-PDF.ppd b/ppd/Fuji_Xerox-DocuPrint_CM305_df-PDF.ppd
new file mode 100644
index 000000000..229870fb5
--- /dev/null
+++ b/ppd/Fuji_Xerox-DocuPrint_CM305_df-PDF.ppd
@@ -0,0 +1,250 @@
+*PPD-Adobe: "4.3"
+*%
+*% This PPD file is for using the Fuji Xerox DocuPrint CM305 df in native PDF
+*% mode, using CUPS with the OpenPrinting CUPS Filters package
+*% option settings controlled via PJL commands. It uses CUPS with the
+*% OpenPrinting CUPS Filters package.
+*%
+*% This PPD is experimental. It is possible that some of the options
+*% and settings do not make sense or do not cause any change on the output.
+*% It can even happen that with certain settings nothing or an error page
+*% comes out.
+*%
+*% This file is published under the GNU General Public License
+*%
+*% You may save this file as 'Fuji_Xerox-DocuPrint_CM305_df-PDF.ppd'
+*%
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "CM305PDF.PPD"
+*Manufacturer: "(Fuji Xerox)"
+*Product: "(Fuji Xerox DocuPrint CM305 df)"
+*cupsVersion: 1.0
+*cupsManualCopies: True
+*cupsModelNumber: 2
+*ModelName: "Fuji Xerox DocuPrint CM305 df"
+*ShortNickName: "Fuji Xerox DocuPrint CM305 df"
+*NickName: "Fuji Xerox DocuPrint CM305 df PDF"
+*PSVersion: "(3010.107) 0"
+*LanguageLevel: "3"
+*ColorDevice: True
+*DefaultColorSpace: CMYK
+*FileSystem: False
+*Throughput: "23"
+*LandscapeOrientation: Plus90
+*TTRasterizer: Type42
+*1284DeviceID: "MFG:FUJI XEROX;CMD:PJL,PCLXL,PCL,PDF,HBPL,POSTSCRIPT;MDL:DocuPrint CM305 df;DES:FUJI XEROX DocuPrint CM305 df;CLS:PRINTER;"
+*JCLBegin: "<1B>%-12345X@PJL JOB<0A>"
+*JCLToPDFInterpreter: "@PJL ENTER LANGUAGE = PDF<0A>"
+*JCLEnd: "<1B>%-12345X@PJL EOJ <0A><1B>%-12345X"
+*cupsFilter: "application/vnd.cups-pdf 0 -"
+*cupsFilter2: "application/pdf application/vnd.cups-pdf 0 pdftopdf"
+
+*OpenGroup: General/General
+*JCLOpenUI *PageSize/Page Size: PickOne
+*OrderDependency: 100 JCLSetup *PageSize
+*DefaultPageSize: A4
+*PageSize A4/A4: "@PJL SET PAPER=A4<0A>"
+*PageSize A5/A5: "@PJL SET PAPER=A5<0A>"
+*PageSize B5/B5: "@PJL SET PAPER=JISB5<0A>"
+*PageSize Letter/Letter: "@PJL SET PAPER=LETTER<0A>"
+*PageSize FanFoldGermanLegal/8.5 x 13: "@PJL SET PAPER=FOLIO<0A>"
+*PageSize Legal/Legal: "@PJL SET PAPER=LEGAL<0A>"
+*PageSize Executive/Executive: "@PJL SET PAPER=EXECUTIVE<0A>"
+*PageSize EnvMonarch/Monarch: "@PJL SET PAPER=MONARCH<0A>"
+*PageSize EnvDL/DL: "@PJL SET PAPER=DL<0A>"
+*PageSize EnvC5/C5: "@PJL SET PAPER=C5<0A>"
+*PageSize Env10/Com 10: "@PJL SET PAPER=COM10<0A>"
+*JCLCloseUI: *PageSize
+
+*JCLOpenUI *PageRegion: PickOne
+*OrderDependency: 100 JCLSetup *PageRegion
+*DefaultPageRegion: A4
+*PageRegion A4/A4: "@PJL SET PAPER=A4<0A>"
+*PageRegion A5/A5: "@PJL SET PAPER=A5<0A>"
+*PageRegion B5/B5: "@PJL SET PAPER=JISB5<0A>"
+*PageRegion Letter/Letter: "@PJL SET PAPER=LETTER<0A>"
+*PageRegion FanFoldGermanLegal/8.5 x 13: "@PJL SET PAPER=FOLIO<0A>"
+*PageRegion Legal/Legal: "@PJL SET PAPER=LEGAL<0A>"
+*PageRegion Executive/Executive: "@PJL SET PAPER=EXECUTIVE<0A>"
+*PageRegion EnvMonarch/Monarch: "@PJL SET PAPER=MONARCH<0A>"
+*PageRegion EnvDL/DL: "@PJL SET PAPER=DL<0A>"
+*PageRegion EnvC5/C5: "@PJL SET PAPER=C5<0A>"
+*PageRegion Env10/Com 10: "@PJL SET PAPER=COM10<0A>"
+*JCLCloseUI: *PageRegion
+
+*DefaultImageableArea: A4
+*ImageableArea A4/A4: "11.62 11.62 583.65 830.27"
+*ImageableArea A5/A5: "11.62 11.62 407.91 583.65"
+*ImageableArea B5/B5: "11.62 11.62 504.28 716.88"
+*ImageableArea Letter/Letter: "11.62 11.62 600.38 780.38"
+*ImageableArea FanFoldGermanLegal/8.5 x 13: "11.62 11.62 600.38 924.38"
+*ImageableArea Legal/Legal: "11.62 11.62 600.38 996.38"
+*ImageableArea Executive/Executive: "11.62 11.62 510.38 744.38"
+*ImageableArea EnvMonarch/Monarch: "11.62 11.62 267.38 528.38"
+*ImageableArea EnvDL/DL: "11.62 17.01 300.19 606.61"
+*ImageableArea EnvC5/C5: "11.62 11.62 447.59 637.51"
+*ImageableArea Env10/Com 10: "11.62 11.62 285.38 672.38"
+
+*DefaultPaperDimension: A4
+*PaperDimension A4/A4: "595 842"
+*PaperDimension A5/A5: "420 595"
+*PaperDimension B5/B5: "516 729"
+*PaperDimension Letter/Letter: "612 792"
+*PaperDimension FanFoldGermanLegal/8.5 x 13: "612 936"
+*PaperDimension Legal/Legal: "612 1008"
+*PaperDimension Executive/Executive: "522 756"
+*PaperDimension EnvMonarch/Monarch: "279 540"
+*PaperDimension EnvDL/DL: "312 624"
+*PaperDimension EnvC5/C5: "459 649"
+*PaperDimension Env10/Com 10: "297 684"
+
+*HWMargins: 11 11 11 11
+*LeadingEdge Short: ""
+*DefaultLeadingEdge: Short
+*MaxMediaWidth: "612"
+*MaxMediaHeight: "1008"
+*NonUIOrderDependency: 100 JCLSetup *CustomPageSize
+*CustomPageSize True: "@PJL SET PAPER=AUTO<0A>"
+
+*JCLOpenUI *InputSlot/Paper Tray: PickOne
+*OrderDependency: 100 JCLSetup *InputSlot
+*DefaultInputSlot: AutoSelect
+*InputSlot AutoSelect/Auto Select: "@PJL SET MEDIASOURCE=AUTO<0A>"
+*InputSlot 1stTray/Tray 1: "@PJL SET MEDIASOURCE=TRAY1<0A>"
+*InputSlot 2ndTray/Tray 2: "@PJL SET MEDIASOURCE=TRAY2<0A>"
+*InputSlot BypassTray/Manual Feeder: "@PJL SET MEDIASOURCE=SMH<0A>"
+*JCLCloseUI: *InputSlot
+
+*JCLOpenUI *MediaType/Paper Type: PickOne
+*OrderDependency: 100 JCLSetup *MediaType
+*DefaultMediaType: Default
+*MediaType Default/None: "@PJL SET MEDIATYPE=OFF<0A>"
+*MediaType Plain/Plain: "@PJL SET MEDIATYPE=NORMAL<0A>"
+*MediaType ThickPaper/Lightweight Cardstock: "@PJL SET MEDIATYPE=THICK<0A>"
+*MediaType ThickPaper2/Heavyweight Cardstock: "@PJL SET MEDIATYPE=THICK2<0A>"
+*MediaType Envelope/Envelope: "@PJL SET MEDIATYPE=ENVELOPE<0A>"
+*MediaType LabelPaper/Labels: "@PJL SET MEDIATYPE=LABEL<0A>"
+*MediaType Letterhead/Letterhead: "@PJL SET MEDIATYPE=LETTERHEAD<0A>"
+*MediaType CoatingPaper2/Lightweight Glossy Cardstock: "@PJL SET MEDIATYPE=COAT2<0A>"
+*MediaType CoatingPaper3/Heavyweight Glossy Cardstock: "@PJL SET MEDIATYPE=COAT3<0A>"
+*MediaType Prepunched/Hole Punched: "@PJL SET MEDIATYPE=PREPUNCHED<0A>"
+*MediaType ColoredPaper/Colored: "@PJL SET MEDIATYPE=COLOR<0A>"
+*MediaType SpecialPaper/Special: "@PJL SET MEDIATYPE=SPECIAL<0A>"
+*JCLCloseUI: *MediaType
+
+*JCLOpenUI *Duplex/Double-Sided Printing: PickOne
+*OrderDependency: 100 JCLSetup *Duplex
+*DefaultDuplex: None
+*Duplex None/Off: "@PJL SET DUPLEX=OFF<0A>"
+*Duplex DuplexNoTumble/Long-Edge binding: "@PJL SET DUPLEX=ON<0A>@PJL SET BINDING=LONGEDGE<0A>"
+*Duplex DuplexTumble/Short-Edge binding: "@PJL SET DUPLEX=ON<0A>@PJL SET BINDING=SHORTEDGE<0A>"
+*JCLCloseUI: *Duplex
+
+*DefaultResolution: 600dpi
+
+*DefaultHalftoneType: 5
+*ScreenFreq: "141.0"
+*ScreenAngle: "45.0"
+*DefaultScreenProc: Dot
+
+*JCLOpenUI *colormode/Color Mode: PickOne
+*OrderDependency: 100 JCLSetup *colormode
+*Defaultcolormode: color
+*colormode color/Color: "@PJL SET RENDERMODE=AUTOCOLOR<0A>"
+*colormode blackwhite/Black and White: "@PJL SET RENDERMODE=GRAYSCALE<0A>"
+*JCLCloseUI: *colormode
+
+*JCLOpenUI *draftMode/Draft Mode: PickOne
+*OrderDependency: 100 JCLSetup *draftMode
+*DefaultdraftMode: False
+*draftMode False/Off: "@PJL SET ECONOMODE=OFF<0A>"
+*draftMode True/On: "@PJL SET ECONOMODE=ON<0A>"
+*JCLCloseUI: *draftMode
+
+*JCLOpenUI *ret/Image Enhancement: PickOne
+*OrderDependency: 100 JCLSetup *ret
+*Defaultret: True
+*ret False/Off: "@PJL SET RET=OFF<0A>"
+*ret True/On: "@PJL SET RET=ON<0A>"
+*JCLCloseUI: *ret
+
+*UIConstraints: *PageSize A5 *Duplex DuplexNoTumble
+*UIConstraints: *PageSize A5 *Duplex DuplexTumble
+*UIConstraints: *PageSize B5 *Duplex DuplexNoTumble
+*UIConstraints: *PageSize B5 *Duplex DuplexTumble
+*UIConstraints: *PageSize Executive *Duplex DuplexNoTumble
+*UIConstraints: *PageSize Executive *Duplex DuplexTumble
+*UIConstraints: *PageSize EnvMonarch *Duplex DuplexNoTumble
+*UIConstraints: *PageSize EnvMonarch *Duplex DuplexTumble
+*UIConstraints: *PageSize EnvDL *Duplex DuplexNoTumble
+*UIConstraints: *PageSize EnvDL *Duplex DuplexTumble
+*UIConstraints: *PageSize Env10 *Duplex DuplexNoTumble
+*UIConstraints: *PageSize Env10 *Duplex DuplexTumble
+*UIConstraints: *PageSize EnvC5 *Duplex DuplexNoTumble
+*UIConstraints: *PageSize EnvC5 *Duplex DuplexTumble
+*UIConstraints: *Duplex DuplexNoTumble *PageSize A5
+*UIConstraints: *Duplex DuplexTumble *PageSize A5
+*UIConstraints: *Duplex DuplexNoTumble *PageSize B5
+*UIConstraints: *Duplex DuplexTumble *PageSize B5
+*UIConstraints: *Duplex DuplexNoTumble *PageSize Executive
+*UIConstraints: *Duplex DuplexTumble *PageSize Executive
+*UIConstraints: *Duplex DuplexNoTumble *PageSize EnvMonarch
+*UIConstraints: *Duplex DuplexTumble *PageSize EnvMonarch
+*UIConstraints: *Duplex DuplexNoTumble *PageSize EnvDL
+*UIConstraints: *Duplex DuplexTumble *PageSize EnvDL
+*UIConstraints: *Duplex DuplexNoTumble *PageSize EnvC5
+*UIConstraints: *Duplex DuplexTumble *PageSize EnvC5
+*UIConstraints: *Duplex DuplexNoTumble *PageSize Env10
+*UIConstraints: *Duplex DuplexTumble *PageSize Env10
+
+*UIConstraints: *InputSlot BypassTray *Duplex DuplexNoTumble
+*UIConstraints: *InputSlot BypassTray *Duplex DuplexTumble
+*UIConstraints: *Duplex DuplexNoTumble *InputSlot BypassTray
+*UIConstraints: *Duplex DuplexTumble *InputSlot BypassTray
+
+*CloseGroup: General
+
+*% Generic boilerplate PPD stuff as standard PostScript fonts and so on
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+
+
diff --git a/ppd/Generic-PDF_Printer-PDF.ppd b/ppd/Generic-PDF_Printer-PDF.ppd
new file mode 100644
index 000000000..71174954d
--- /dev/null
+++ b/ppd/Generic-PDF_Printer-PDF.ppd
@@ -0,0 +1,245 @@
+*PPD-Adobe: "4.3"
+*%
+*% This PPD file is for using a PDF printer in its native PDF mode, with
+*% option settings controlled via PJL commands. It uses CUPS with the
+*% OpenPrinting CUPS Filters package.
+*%
+*% This PPD is experimental. It is possible that some of the options
+*% and settings do not make sense or do not cause any change on the output.
+*% It can even happen that with certain settings nothing or an error page
+*% comes out.
+*%
+*% This file is published under the GNU General Public License
+*%
+*% You may save this file as 'Generic-PDF_Printer-PDF.ppd'
+*%
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "PDF.PPD"
+*Manufacturer: "Generic"
+*Product: "(Generic PDF Printer)"
+*cupsVersion: 1.0
+*cupsManualCopies: True
+*cupsModelNumber: 2
+*ModelName: "Generic PDF Printer"
+*ShortNickName: "Generic PDF Printer"
+*NickName: "Generic PDF Printer"
+*PSVersion: "(3010.107) 0"
+*LanguageLevel: "3"
+*ColorDevice: True
+*DefaultColorSpace: CMYK
+*FileSystem: False
+*Throughput: "30"
+*LandscapeOrientation: Plus90
+*TTRasterizer: Type42
+*1284DeviceID: "MFG:Generic;CMD:PJL,PDF;MDL:PDF Printer;CLS:PRINTER;DES:Generic PDF Printer;DRV:DPDF,R1,M0;"
+*JCLBegin: "<1B>%-12345X@PJL JOB<0A>"
+*JCLToPDFInterpreter: "@PJL ENTER LANGUAGE = PDF<0A>"
+*JCLEnd: "<1B>%-12345X@PJL EOJ <0A><1B>%-12345X"
+*cupsFilter: "application/vnd.cups-pdf 0 -"
+*cupsFilter2: "application/pdf application/vnd.cups-pdf 0 pdftopdf"
+
+*OpenGroup: General/General
+*JCLOpenUI *PageSize/Page Size: PickOne
+*OrderDependency: 100 JCLSetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter/Letter: "@PJL SET PAPER=LETTER<0A>"
+*PageSize A4/A4: "@PJL SET PAPER=A4<0A>"
+*PageSize A5/A5: "@PJL SET PAPER=A5<0A>"
+*PageSize A6/A6: "@PJL SET PAPER=A6<0A>"
+*PageSize ISOB5/ISO B5: "@PJL SET PAPER=B5<0A>"
+*PageSize EnvC5/C5: "@PJL SET PAPER=C5<0A>"
+*PageSize Env10/Com 10: "@PJL SET PAPER=COM10<0A>"
+*PageSize EnvDL/DL: "@PJL SET PAPER=DL<0A>"
+*PageSize 5x13/Eight Point 5x13: "@PJL SET PAPER=EIGHTPOINT5X13<0A>"
+*PageSize EnvC6/Envelope C6: "@PJL SET PAPER=ENVELOPEC6<0A>"
+*PageSize Executive/Executive: "@PJL SET PAPER=EXECUTIVE<0A>"
+*PageSize B5/JIS B5: "@PJL SET PAPER=JISB5<0A>"
+*PageSize B6/JIS B6: "@PJL SET PAPER=JISB6<0A>"
+*PageSize Legal/Legal: "@PJL SET PAPER=LEGAL<0A>"
+*PageSize EnvMonarch/Monarch: "@PJL SET PAPER=MONARCH<0A>"
+*PageSize 69x95mm/16K: "@PJL SET PAPER=SIZE16K195x270<0A>"
+*PageSize Statement/Statement: "@PJL SET PAPER=STATEMENT<0A>"
+*JCLCloseUI: *PageSize
+
+*JCLOpenUI *PageRegion: PickOne
+*OrderDependency: 100 JCLSetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter/Letter: "@PJL SET PAPER=LETTER<0A>"
+*PageRegion A4/A4: "@PJL SET PAPER=A4<0A>"
+*PageRegion A5/A5: "@PJL SET PAPER=A5<0A>"
+*PageRegion A6/A6: "@PJL SET PAPER=A6<0A>"
+*PageRegion ISOB5/ISO B5: "@PJL SET PAPER=B5<0A>"
+*PageRegion EnvC5/C5: "@PJL SET PAPER=C5<0A>"
+*PageRegion Env10/Com 10: "@PJL SET PAPER=COM10<0A>"
+*PageRegion EnvDL/DL: "@PJL SET PAPER=DL<0A>"
+*PageRegion 5x13/Eight Point 5x13: "@PJL SET PAPER=EIGHTPOINT5X13<0A>"
+*PageRegion EnvC6/Envelope C6: "@PJL SET PAPER=ENVELOPEC6<0A>"
+*PageRegion Executive/Executive: "@PJL SET PAPER=EXECUTIVE<0A>"
+*PageRegion B5/JIS B5: "@PJL SET PAPER=JISB5<0A>"
+*PageRegion B6/JIS B6: "@PJL SET PAPER=JISB6<0A>"
+*PageRegion Legal/Legal: "@PJL SET PAPER=LEGAL<0A>"
+*PageRegion EnvMonarch/Monarch: "@PJL SET PAPER=MONARCH<0A>"
+*PageRegion 69x95mm/16K: "@PJL SET PAPER=SIZE16K195x270<0A>"
+*PageRegion Statement/Statement: "@PJL SET PAPER=STATEMENT<0A>"
+*JCLCloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter/Letter: "18 36 594 756"
+*ImageableArea A4/A4: "18 36 577 806"
+*ImageableArea A5/A5: "18 36 402 559"
+*ImageableArea A6/A6: "18 36 279 384"
+*ImageableArea ISOB5/ISO B5: "18 36 480 672"
+*ImageableArea EnvC5/C5: "18 36 441 613"
+*ImageableArea Env10/Com 10: "18 36 279 648"
+*ImageableArea EnvDL/DL: "18 36 293 587"
+*ImageableArea 5x13/Eight Point 5x13: "18 36 342 900"
+*ImageableArea EnvC6/Envelope C6: "18 36 305 423"
+*ImageableArea Executive/Executive: "18 36 504 720"
+*ImageableArea B5/JIS B5: "18 36 500 691"
+*ImageableArea B6/JIS B6: "18 36 344 482"
+*ImageableArea Legal/Legal: "18 36 594 972"
+*ImageableArea EnvMonarch/Monarch: "18 36 261 504"
+*ImageableArea 69x95mm/16K: "18 36 177 234"
+*ImageableArea Statement/Statement: "18 36 378 576"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter/Letter: "612 792"
+*PaperDimension A4/A4: "595 842"
+*PaperDimension A5/A5: "420 595"
+*PaperDimension A6/A6: "297 420"
+*PaperDimension ISOB5/ISO B5: "498 708"
+*PaperDimension EnvC5/C5: "459 649"
+*PaperDimension Env10/Com 10: "297 684"
+*PaperDimension EnvDL/DL: "311 623"
+*PaperDimension 5x13/Eight Point 5x13: "360 936"
+*PaperDimension EnvC6/Envelope C6: "323 459"
+*PaperDimension Executive/Executive: "522 756"
+*PaperDimension B5/JIS B5: "518 727"
+*PaperDimension B6/JIS B6: "362 518"
+*PaperDimension Legal/Legal: "612 1008"
+*PaperDimension EnvMonarch/Monarch: "279 540"
+*PaperDimension 69x95mm/16K: "195 270"
+*PaperDimension Statement/Statement: "396 612"
+
+*JCLOpenUI *manualfeed/Manual Feed of Paper: PickOne
+*OrderDependency: 100 JCLSetup *manualfeed
+*Defaultmanualfeed: off
+*manualfeed off/Off: "@PJL SET MANUALFEED=OFF<0A>"
+*manualfeed on/On: "@PJL SET MANUALFEED=ON<0A>"
+*JCLCloseUI: *manualfeed
+
+*JCLOpenUI *manualduplex/Manual duplex: PickOne
+*OrderDependency: 100 JCLSetup *manualduplex
+*Defaultmanualduplex: off
+*manualduplex off/Off: "@PJL SET MANUALDUPLEX=OFF<0A>"
+*manualduplex on/On: "@PJL SET MANUALDUPLEX=ON<0A>"
+*JCLCloseUI: *manualduplex
+
+*JCLOpenUI *Duplex/Double-Sided Printing: PickOne
+*OrderDependency: 100 JCLSetup *Duplex
+*DefaultDuplex: None
+*Duplex None/Off: "@PJL SET DUPLEX=OFF<0A>"
+*Duplex DuplexNoTumble/Long-Edge binding: "@PJL SET DUPLEX=ON<0A>@PJL SET BINDING=LONGEDGE<0A>"
+*Duplex DuplexTumble/Short-Edge binding: "@PJL SET DUPLEX=ON<0A>@PJL SET BINDING=SHORTEDGE<0A>"
+*JCLCloseUI: *Duplex
+
+*JCLOpenUI *Resolution/Resolution: PickOne
+*OrderDependency: 100 JCLSetup *Resolution
+*DefaultResolution: 600dpi
+*Resolution 300dpi/300 dpi: "@PJL SET RESOLUTION=300<0A>"
+*Resolution 600dpi/600 dpi: "@PJL SET RESOLUTION=600<0A>"
+*Resolution 1200dpi/1200 dpi: "@PJL SET RESOLUTION=1200<0A>"
+*JCLCloseUI: *Resolution
+
+*JCLOpenUI *ret/Resolution Enhancement: PickOne
+*OrderDependency: 100 JCLSetup *ret
+*Defaultret: notset
+*ret dark/Dark: "@PJL SET RET=DARK<0A>"
+*ret light/Light: "@PJL SET RET=LIGHT<0A>"
+*ret medium/Medium: "@PJL SET RET=MEDIUM<0A>"
+*ret notset/notset: "@PJL SET RET=NOTSET<0A>"
+*ret off/Off: "@PJL SET RET=OFF<0A>"
+*JCLCloseUI: *ret
+
+*JCLOpenUI *borderless/Borderless Printing: PickOne
+*OrderDependency: 100 JCLSetup *borderless
+*Defaultborderless: on
+*borderless off/Off: "@PJL SET BORDERLESS=OFF<0A>"
+*borderless on/On: "@PJL SET BORDERLESS=ON<0A>"
+*JCLCloseUI: *borderless
+
+*JCLOpenUI *edgetoedge/Edge to edge: PickOne
+*OrderDependency: 100 JCLSetup *edgetoedge
+*Defaultedgetoedge: yes
+*edgetoedge no/No: "@PJL SET EDGETOEDGE=NO<0A>"
+*edgetoedge yes/Yes: "@PJL SET EDGETOEDGE=YES<0A>"
+*JCLCloseUI: *edgetoedge
+
+*JCLOpenUI *joboffset/Job Offset: PickOne
+*OrderDependency: 100 JCLSetup *joboffset
+*Defaultjoboffset: on
+*joboffset off/Off: "@PJL SET JOBOFFSET=OFF<0A>"
+*joboffset on/On: "@PJL SET JOBOFFSET=ON<0A>"
+*JCLCloseUI: *joboffset
+
+*JCLOpenUI *lowsupplies/On low supplies: PickOne
+*OrderDependency: 100 JCLSetup *lowsupplies
+*Defaultlowsupplies: continue
+*lowsupplies continue/Continue: "@PJL SET LOWSUPPLIES=CONTINUE<0A>"
+*lowsupplies stop/Stop: "@PJL SET LOWSUPPLIES=STOP<0A>"
+*JCLCloseUI: *lowsupplies
+
+*JCLOpenUI *overridea4withletter/Override A4 with Letter: PickOne
+*OrderDependency: 100 JCLSetup *overridea4withletter
+*Defaultoverridea4withletter: yes
+*overridea4withletter no/No: "@PJL SET OVERRIDEA4WITHLETTER=NO<0A>"
+*overridea4withletter yes/Yes: "@PJL SET OVERRIDEA4WITHLETTER=YES<0A>"
+*JCLCloseUI: *overridea4withletter
+
+*CloseGroup: General
+
+
+*% Generic boilerplate PPD stuff as standard PostScript fonts and so on
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+
+
diff --git a/ppd/HP-Color_LaserJet_CM3530_MFP-PDF.ppd b/ppd/HP-Color_LaserJet_CM3530_MFP-PDF.ppd
new file mode 100644
index 000000000..5e71d95e7
--- /dev/null
+++ b/ppd/HP-Color_LaserJet_CM3530_MFP-PDF.ppd
@@ -0,0 +1,415 @@
+*PPD-Adobe: "4.3"
+*%
+*% This PPD file is for using the HP Color LaserJet CM3530 MFP in native
+*% PDF mode, using CUPS with the OpenPrinting CUPS Filters package
+*%
+*% This PPD is experimental. It is possible that some of the options
+*% and settings do not make sense or do not cause any change on the output.
+*% It can even happen that with certain settings nothing or an error page
+*% comes out.
+*%
+*% This file is published under the GNU General Public License
+*%
+*% You may save this file as 'HP-Color_LaserJet_CM3530_MFP-PDF.ppd'
+*%
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "CM353PDF.PPD"
+*Manufacturer: "HP"
+*Product: "(HP Color LaserJet CM3530 MFP)"
+*Product: "(Hewlett-Packard HP Color LaserJet CM3530 MFP)"
+*cupsVersion: 1.0
+*cupsManualCopies: True
+*cupsModelNumber: 2
+*ModelName: "HP Color LaserJet CM3530 MFP"
+*ShortNickName: "HP Color LaserJet CM3530 MFP"
+*NickName: "HP Color LaserJet CM3530 MFP PDF"
+*PSVersion: "(3010.107) 0"
+*LanguageLevel: "3"
+*ColorDevice: True
+*DefaultColorSpace: CMYK
+*FileSystem: False
+*Throughput: "30"
+*LandscapeOrientation: Plus90
+*TTRasterizer: Type42
+*1284DeviceID: "MFG:Hewlett-Packard;CMD:PJL,BIDI-ECP,PCLXL,PCL,PDF,PJL,POSTSCRIPT;MDL:HP Color LaserJet CM3530 MFP;CLS:PRINTER;DES:Hewlett-Packard Color LaserJet CM3530 MFP;DRV:DPDF,R0,M0;"
+*JCLBegin: "<1B>%-12345X@PJL JOB<0A>"
+*JCLToPDFInterpreter: "@PJL ENTER LANGUAGE = PDF <0A>"
+*JCLEnd: "<1B>%-12345X@PJL EOJ <0A><1B>%-12345X"
+*cupsFilter: "application/vnd.cups-pdf 0 -"
+*cupsFilter2: "application/pdf application/vnd.cups-pdf 0 pdftopdf"
+
+*OpenGroup: General/General
+*JCLOpenUI *PageSize/Page Size: PickOne
+*OrderDependency: 100 JCLSetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter/Letter: "@PJL SET PAPER=LETTER<0A>"
+*PageSize A4/A4: "@PJL SET PAPER=A4<0A>"
+*PageSize A5/A5: "@PJL SET PAPER=A5<0A>"
+*PageSize A6/A6: "@PJL SET PAPER=A6<0A>"
+*PageSize ISOB5/ISO B5: "@PJL SET PAPER=B5<0A>"
+*PageSize EnvC5/C5: "@PJL SET PAPER=C5<0A>"
+*PageSize Env10/Com 10: "@PJL SET PAPER=COM10<0A>"
+*PageSize EnvDL/DL: "@PJL SET PAPER=DL<0A>"
+*PageSize 5x13/Eight Point 5x13: "@PJL SET PAPER=EIGHTPOINT5X13<0A>"
+*PageSize EnvC6/Envelope C6: "@PJL SET PAPER=ENVELOPEC6<0A>"
+*PageSize Executive/Executive: "@PJL SET PAPER=EXECUTIVE<0A>"
+*PageSize B5/JIS B5: "@PJL SET PAPER=JISB5<0A>"
+*PageSize B6/JIS B6: "@PJL SET PAPER=JISB6<0A>"
+*PageSize Legal/Legal: "@PJL SET PAPER=LEGAL<0A>"
+*PageSize EnvMonarch/Monarch: "@PJL SET PAPER=MONARCH<0A>"
+*PageSize 69x95mm/16K: "@PJL SET PAPER=SIZE16K195x270<0A>"
+*PageSize Statement/Statement: "@PJL SET PAPER=STATEMENT<0A>"
+*JCLCloseUI: *PageSize
+
+*JCLOpenUI *PageRegion: PickOne
+*OrderDependency: 100 JCLSetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter/Letter: "@PJL SET PAPER=LETTER<0A>"
+*PageRegion A4/A4: "@PJL SET PAPER=A4<0A>"
+*PageRegion A5/A5: "@PJL SET PAPER=A5<0A>"
+*PageRegion A6/A6: "@PJL SET PAPER=A6<0A>"
+*PageRegion ISOB5/ISO B5: "@PJL SET PAPER=B5<0A>"
+*PageRegion EnvC5/C5: "@PJL SET PAPER=C5<0A>"
+*PageRegion Env10/Com 10: "@PJL SET PAPER=COM10<0A>"
+*PageRegion EnvDL/DL: "@PJL SET PAPER=DL<0A>"
+*PageRegion 5x13/Eight Point 5x13: "@PJL SET PAPER=EIGHTPOINT5X13<0A>"
+*PageRegion EnvC6/Envelope C6: "@PJL SET PAPER=ENVELOPEC6<0A>"
+*PageRegion Executive/Executive: "@PJL SET PAPER=EXECUTIVE<0A>"
+*PageRegion B5/JIS B5: "@PJL SET PAPER=JISB5<0A>"
+*PageRegion B6/JIS B6: "@PJL SET PAPER=JISB6<0A>"
+*PageRegion Legal/Legal: "@PJL SET PAPER=LEGAL<0A>"
+*PageRegion EnvMonarch/Monarch: "@PJL SET PAPER=MONARCH<0A>"
+*PageRegion 69x95mm/16K: "@PJL SET PAPER=SIZE16K195x270<0A>"
+*PageRegion Statement/Statement: "@PJL SET PAPER=STATEMENT<0A>"
+*JCLCloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter/Letter: "18 36 594 756"
+*ImageableArea A4/A4: "18 36 577 806"
+*ImageableArea A5/A5: "18 36 402 559"
+*ImageableArea A6/A6: "18 36 279 384"
+*ImageableArea ISOB5/ISO B5: "18 36 480 672"
+*ImageableArea EnvC5/C5: "18 36 441 613"
+*ImageableArea Env10/Com 10: "18 36 279 648"
+*ImageableArea EnvDL/DL: "18 36 293 587"
+*ImageableArea 5x13/Eight Point 5x13: "18 36 342 900"
+*ImageableArea EnvC6/Envelope C6: "18 36 305 423"
+*ImageableArea Executive/Executive: "18 36 504 720"
+*ImageableArea B5/JIS B5: "18 36 500 691"
+*ImageableArea B6/JIS B6: "18 36 344 482"
+*ImageableArea Legal/Legal: "18 36 594 972"
+*ImageableArea EnvMonarch/Monarch: "18 36 261 504"
+*ImageableArea 69x95mm/16K: "18 36 177 234"
+*ImageableArea Statement/Statement: "18 36 378 576"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter/Letter: "612 792"
+*PaperDimension A4/A4: "595 842"
+*PaperDimension A5/A5: "420 595"
+*PaperDimension A6/A6: "297 420"
+*PaperDimension ISOB5/ISO B5: "498 708"
+*PaperDimension EnvC5/C5: "459 649"
+*PaperDimension Env10/Com 10: "297 684"
+*PaperDimension EnvDL/DL: "311 623"
+*PaperDimension 5x13/Eight Point 5x13: "360 936"
+*PaperDimension EnvC6/Envelope C6: "323 459"
+*PaperDimension Executive/Executive: "522 756"
+*PaperDimension B5/JIS B5: "518 727"
+*PaperDimension B6/JIS B6: "362 518"
+*PaperDimension Legal/Legal: "612 1008"
+*PaperDimension EnvMonarch/Monarch: "279 540"
+*PaperDimension 69x95mm/16K: "195 270"
+*PaperDimension Statement/Statement: "396 612"
+
+*JCLOpenUI *manualfeed/Manual Feed of Paper: PickOne
+*OrderDependency: 100 JCLSetup *manualfeed
+*Defaultmanualfeed: off
+*manualfeed off/Off: "@PJL SET MANUALFEED=OFF<0A>"
+*manualfeed on/On: "@PJL SET MANUALFEED=ON<0A>"
+*JCLCloseUI: *manualfeed
+
+*JCLOpenUI *manualduplex/Manual duplex: PickOne
+*OrderDependency: 100 JCLSetup *manualduplex
+*Defaultmanualduplex: off
+*manualduplex off/Off: "@PJL SET MANUALDUPLEX=OFF<0A>"
+*manualduplex on/On: "@PJL SET MANUALDUPLEX=ON<0A>"
+*JCLCloseUI: *manualduplex
+
+*JCLOpenUI *Duplex/Double-Sided Printing: PickOne
+*OrderDependency: 100 JCLSetup *Duplex
+*DefaultDuplex: None
+*Duplex None/Off: "@PJL SET DUPLEX=OFF<0A>"
+*Duplex DuplexNoTumble/Long-Edge binding: "@PJL SET DUPLEX=ON<0A>@PJL SET BINDING=LONGEDGE<0A>"
+*Duplex DuplexTumble/Short-Edge binding: "@PJL SET DUPLEX=ON<0A>@PJL SET BINDING=SHORTEDGE<0A>"
+*JCLCloseUI: *Duplex
+
+*JCLOpenUI *Resolution/Resolution: PickOne
+*OrderDependency: 100 JCLSetup *Resolution
+*DefaultResolution: 600dpi
+*Resolution 300dpi/300 dpi: "@PJL SET RESOLUTION=300<0A>"
+*Resolution 600dpi/600 dpi: "@PJL SET RESOLUTION=600<0A>"
+*Resolution 1200dpi/1200 dpi: "@PJL SET RESOLUTION=1200<0A>"
+*JCLCloseUI: *Resolution
+
+
+*JCLOpenUI *colorbalanceblack/Color balance black: PickOne
+*OrderDependency: 100 JCLSetup *colorbalanceblack
+*Defaultcolorbalanceblack: 4
+*colorbalanceblack 0/0: "@PJL SET COLORBALANCEBLACK=0<0A>"
+*colorbalanceblack 1/1: "@PJL SET COLORBALANCEBLACK=1<0A>"
+*colorbalanceblack 2/2: "@PJL SET COLORBALANCEBLACK=2<0A>"
+*colorbalanceblack 3/3: "@PJL SET COLORBALANCEBLACK=3<0A>"
+*colorbalanceblack 4/4: "@PJL SET COLORBALANCEBLACK=4<0A>"
+*colorbalanceblack 5/5: "@PJL SET COLORBALANCEBLACK=5<0A>"
+*colorbalanceblack 6/6: "@PJL SET COLORBALANCEBLACK=6<0A>"
+*colorbalanceblack 7/7: "@PJL SET COLORBALANCEBLACK=7<0A>"
+*colorbalanceblack 8/8: "@PJL SET COLORBALANCEBLACK=8<0A>"
+*JCLCloseUI: *colorbalanceblack
+
+*CustomJCLcolorbalanceblack True: "@PJL SET COLORBALANCEBLACK=\1<0A>"
+*ParamCustomJCLcolorbalanceblack colorbalanceblack/colorbalanceblack: 1 int 0 8
+
+*JCLOpenUI *colorbalancecyan/Color balance cyan: PickOne
+*OrderDependency: 100 JCLSetup *colorbalancecyan
+*Defaultcolorbalancecyan: 4
+*colorbalancecyan 0/0: "@PJL SET COLORBALANCECYAN=0<0A>"
+*colorbalancecyan 1/1: "@PJL SET COLORBALANCECYAN=1<0A>"
+*colorbalancecyan 2/2: "@PJL SET COLORBALANCECYAN=2<0A>"
+*colorbalancecyan 3/3: "@PJL SET COLORBALANCECYAN=3<0A>"
+*colorbalancecyan 4/4: "@PJL SET COLORBALANCECYAN=4<0A>"
+*colorbalancecyan 5/5: "@PJL SET COLORBALANCECYAN=5<0A>"
+*colorbalancecyan 6/6: "@PJL SET COLORBALANCECYAN=6<0A>"
+*colorbalancecyan 7/7: "@PJL SET COLORBALANCECYAN=7<0A>"
+*colorbalancecyan 8/8: "@PJL SET COLORBALANCECYAN=8<0A>"
+*JCLCloseUI: *colorbalancecyan
+
+*CustomJCLcolorbalancecyan True: "@PJL SET COLORBALANCECYAN=\1<0A>"
+*ParamCustomJCLcolorbalancecyan colorbalancecyan/colorbalancecyan: 1 int 0 8
+
+*JCLOpenUI *colorbalancemagenta/Color balance magenta: PickOne
+*OrderDependency: 100 JCLSetup *colorbalancemagenta
+*Defaultcolorbalancemagenta: 4
+*colorbalancemagenta 0/0: "@PJL SET COLORBALANCEMAGENTA=0<0A>"
+*colorbalancemagenta 1/1: "@PJL SET COLORBALANCEMAGENTA=1<0A>"
+*colorbalancemagenta 2/2: "@PJL SET COLORBALANCEMAGENTA=2<0A>"
+*colorbalancemagenta 3/3: "@PJL SET COLORBALANCEMAGENTA=3<0A>"
+*colorbalancemagenta 4/4: "@PJL SET COLORBALANCEMAGENTA=4<0A>"
+*colorbalancemagenta 5/5: "@PJL SET COLORBALANCEMAGENTA=5<0A>"
+*colorbalancemagenta 6/6: "@PJL SET COLORBALANCEMAGENTA=6<0A>"
+*colorbalancemagenta 7/7: "@PJL SET COLORBALANCEMAGENTA=7<0A>"
+*colorbalancemagenta 8/8: "@PJL SET COLORBALANCEMAGENTA=8<0A>"
+*JCLCloseUI: *colorbalancemagenta
+
+*CustomJCLcolorbalancemagenta True: "@PJL SET COLORBALANCEMAGENTA=\1<0A>"
+*ParamCustomJCLcolorbalancemagenta colorbalancemagenta/colorbalancemagenta: 1 int 0 8
+
+*JCLOpenUI *colorbalanceyellow/Color balance yellow: PickOne
+*OrderDependency: 100 JCLSetup *colorbalanceyellow
+*Defaultcolorbalanceyellow: 4
+*colorbalanceyellow 0/0: "@PJL SET COLORBALANCEYELLOW=0<0A>"
+*colorbalanceyellow 1/1: "@PJL SET COLORBALANCEYELLOW=1<0A>"
+*colorbalanceyellow 2/2: "@PJL SET COLORBALANCEYELLOW=2<0A>"
+*colorbalanceyellow 3/3: "@PJL SET COLORBALANCEYELLOW=3<0A>"
+*colorbalanceyellow 4/4: "@PJL SET COLORBALANCEYELLOW=4<0A>"
+*colorbalanceyellow 5/5: "@PJL SET COLORBALANCEYELLOW=5<0A>"
+*colorbalanceyellow 6/6: "@PJL SET COLORBALANCEYELLOW=6<0A>"
+*colorbalanceyellow 7/7: "@PJL SET COLORBALANCEYELLOW=7<0A>"
+*colorbalanceyellow 8/8: "@PJL SET COLORBALANCEYELLOW=8<0A>"
+*JCLCloseUI: *colorbalanceyellow
+
+*CustomJCLcolorbalanceyellow True: "@PJL SET COLORBALANCEYELLOW=\1<0A>"
+*ParamCustomJCLcolorbalanceyellow colorbalanceyellow/colorbalanceyellow: 1 int 0 8
+
+
+*JCLOpenUI *colorsupplyout/On color supply out: PickOne
+*OrderDependency: 100 JCLSetup *colorsupplyout
+*Defaultcolorsupplyout: autocontinueblack
+*colorsupplyout autocontinueblack/Continue in grayscale: "@PJL SET COLORSUPPLYOUT=AUTOCONTINUEBLACK<0A>"
+*colorsupplyout stop/Stop: "@PJL SET COLORSUPPLYOUT=STOP<0A>"
+*JCLCloseUI: *colorsupplyout
+
+*JCLOpenUI *ret/Resolution Enhancement: PickOne
+*OrderDependency: 100 JCLSetup *ret
+*Defaultret: notset
+*ret dark/Dark: "@PJL SET RET=DARK<0A>"
+*ret light/Light: "@PJL SET RET=LIGHT<0A>"
+*ret medium/Medium: "@PJL SET RET=MEDIUM<0A>"
+*ret notset/notset: "@PJL SET RET=NOTSET<0A>"
+*ret off/Off: "@PJL SET RET=OFF<0A>"
+*JCLCloseUI: *ret
+
+*JCLOpenUI *borderless/Borderless Printing: PickOne
+*OrderDependency: 100 JCLSetup *borderless
+*Defaultborderless: on
+*borderless off/Off: "@PJL SET BORDERLESS=OFF<0A>"
+*borderless on/On: "@PJL SET BORDERLESS=ON<0A>"
+*JCLCloseUI: *borderless
+
+*JCLOpenUI *contentorientation/Content Orientation: PickOne
+*OrderDependency: 100 JCLSetup *contentorientation
+*Defaultcontentorientation: notspecified
+*contentorientation landscape/Landscape: "@PJL SET CONTENTORIENTATION=LANDSCAPE<0A>"
+*contentorientation notspecified/Not specified: "@PJL SET CONTENTORIENTATION=NOTSPECIFIED<0A>"
+*contentorientation portrait/Portrait: "@PJL SET CONTENTORIENTATION=PORTRAIT<0A>"
+*contentorientation reverselandscape/Reverse landscape: "@PJL SET CONTENTORIENTATION=REVERSELANDSCAPE<0A>"
+*contentorientation reverseportrait/Reverse portrait: "@PJL SET CONTENTORIENTATION=REVERSEPORTRAIT<0A>"
+*JCLCloseUI: *contentorientation
+
+*JCLOpenUI *edgecontrol/Edge control: PickOne
+*OrderDependency: 100 JCLSetup *edgecontrol
+*Defaultedgecontrol: maximum
+*edgecontrol normal/Normal: "@PJL SET EDGECONTROL=NORMAL<0A>"
+*edgecontrol light/Light: "@PJL SET EDGECONTROL=LIGHT<0A>"
+*edgecontrol maximum/Maximum: "@PJL SET EDGECONTROL=MAXIMUM<0A>"
+*edgecontrol off/Off: "@PJL SET EDGECONTROL=OFF<0A>"
+*JCLCloseUI: *edgecontrol
+
+*JCLOpenUI *edgetoedge/Edge to edge: PickOne
+*OrderDependency: 100 JCLSetup *edgetoedge
+*Defaultedgetoedge: yes
+*edgetoedge no/No: "@PJL SET EDGETOEDGE=NO<0A>"
+*edgetoedge yes/Yes: "@PJL SET EDGETOEDGE=YES<0A>"
+*JCLCloseUI: *edgetoedge
+
+*JCLOpenUI *finish/Finisher: PickOne
+*OrderDependency: 100 JCLSetup *finish
+*Defaultfinish: none
+*finish none/None: "@PJL SET FINISH=NONE<0A>"
+*finish on/On: "@PJL SET FINISH=ON<0A>"
+*finish staple/Staple: "@PJL SET FINISH=STAPLE<0A>"
+*JCLCloseUI: *finish
+
+*JCLOpenUI *hold/Hold Job: PickOne
+*OrderDependency: 100 JCLSetup *hold
+*Defaulthold: off
+*hold off/Off: "@PJL SET HOLD=OFF<0A>"
+*hold on/On: "@PJL SET HOLD=ON<0A>"
+*hold proof/Proof: "@PJL SET HOLD=PROOF<0A>"
+*hold store/Store: "@PJL SET HOLD=STORE<0A>"
+*JCLCloseUI: *hold
+
+*JCLOpenUI *joboffset/Job Offset: PickOne
+*OrderDependency: 100 JCLSetup *joboffset
+*Defaultjoboffset: on
+*joboffset off/Off: "@PJL SET JOBOFFSET=OFF<0A>"
+*joboffset on/On: "@PJL SET JOBOFFSET=ON<0A>"
+*JCLCloseUI: *joboffset
+
+*JCLOpenUI *lowsupplies/On low supplies: PickOne
+*OrderDependency: 100 JCLSetup *lowsupplies
+*Defaultlowsupplies: continue
+*lowsupplies continue/Continue: "@PJL SET LOWSUPPLIES=CONTINUE<0A>"
+*lowsupplies stop/Stop: "@PJL SET LOWSUPPLIES=STOP<0A>"
+*JCLCloseUI: *lowsupplies
+
+*JCLOpenUI *overridea4withletter/Override A4 with Letter: PickOne
+*OrderDependency: 100 JCLSetup *overridea4withletter
+*Defaultoverridea4withletter: yes
+*overridea4withletter no/No: "@PJL SET OVERRIDEA4WITHLETTER=NO<0A>"
+*overridea4withletter yes/Yes: "@PJL SET OVERRIDEA4WITHLETTER=YES<0A>"
+*JCLCloseUI: *overridea4withletter
+
+*JCLOpenUI *planesinuse/Planes in use: PickOne
+*OrderDependency: 100 JCLSetup *planesinuse
+*Defaultplanesinuse: 3
+*planesinuse 1/1: "@PJL SET PLANESINUSE=1<0A>"
+*planesinuse 3/3: "@PJL SET PLANESINUSE=3<0A>"
+*JCLCloseUI: *planesinuse
+
+*JCLOpenUI *printonbackside/Print on back side: PickOne
+*OrderDependency: 100 JCLSetup *printonbackside
+*Defaultprintonbackside: on
+*printonbackside off/Off: "@PJL SET PRINTONBACKSIDE=OFF<0A>"
+*printonbackside on/On: "@PJL SET PRINTONBACKSIDE=ON<0A>"
+*JCLCloseUI: *printonbackside
+
+*JCLOpenUI *processingaction/Processing Action: PickOne
+*OrderDependency: 100 JCLSetup *processingaction
+*Defaultprocessingaction: replace
+*processingaction append/Append: "@PJL SET PROCESSINGACTION=APPEND<0A>"
+*processingaction replace/Replace: "@PJL SET PROCESSINGACTION=REPLACE<0A>"
+*JCLCloseUI: *processingaction
+
+*JCLOpenUI *processingboundary/Processing Boundary: PickOne
+*OrderDependency: 100 JCLSetup *processingboundary
+*Defaultprocessingboundary: job
+*processingboundary job/Job: "@PJL SET PROCESSINGBOUNDARY=JOB<0A>"
+*processingboundary mopy/Mopy: "@PJL SET PROCESSINGBOUNDARY=MOPY<0A>"
+*JCLCloseUI: *processingboundary
+
+*JCLOpenUI *reprint/Reprint job: PickOne
+*OrderDependency: 100 JCLSetup *reprint
+*Defaultreprint: auto
+*reprint auto/Automatic: "@PJL SET REPRINT=AUTO<0A>"
+*reprint off/Off: "@PJL SET REPRINT=OFF<0A>"
+*reprint on/On: "@PJL SET REPRINT=ON<0A>"
+*JCLCloseUI: *reprint
+
+*JCLOpenUI *stapleoption/Stapling Mode: PickOne
+*OrderDependency: 100 JCLSetup *stapleoption
+*Defaultstapleoption: none
+*stapleoption default/Default: "@PJL SET STAPLEOPTION=DEFAULT<0A>"
+*stapleoption custom/Custom Size: "@PJL SET STAPLEOPTION=CUSTOM<0A>"
+*stapleoption five/5: "@PJL SET STAPLEOPTION=FIVE<0A>"
+*stapleoption four/4: "@PJL SET STAPLEOPTION=FOUR<0A>"
+*stapleoption none/None: "@PJL SET STAPLEOPTION=NONE<0A>"
+*stapleoption one/1: "@PJL SET STAPLEOPTION=ONE<0A>"
+*stapleoption oneangled/One Angled: "@PJL SET STAPLEOPTION=ONEANGLED<0A>"
+*stapleoption oneopposed/One Opposed: "@PJL SET STAPLEOPTION=ONEOPPOSED<0A>"
+*stapleoption option3/Option 3: "@PJL SET STAPLEOPTION=OPTION3<0A>"
+*stapleoption option4/Option 4: "@PJL SET STAPLEOPTION=OPTION4<0A>"
+*stapleoption option5/Option 5: "@PJL SET STAPLEOPTION=OPTION5<0A>"
+*stapleoption option6/Option 6: "@PJL SET STAPLEOPTION=OPTION6<0A>"
+*stapleoption seven/7: "@PJL SET STAPLEOPTION=SEVEN<0A>"
+*stapleoption six/6: "@PJL SET STAPLEOPTION=SIX<0A>"
+*stapleoption three/3: "@PJL SET STAPLEOPTION=THREE<0A>"
+*stapleoption two/2: "@PJL SET STAPLEOPTION=TWO<0A>"
+*JCLCloseUI: *stapleoption
+
+*CloseGroup: General
+
+
+*% Generic boilerplate PPD stuff as standard PostScript fonts and so on
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+
+
diff --git a/ppd/HP-PhotoSmart_Pro_B8300-hpijs-pdftoijs.ppd b/ppd/HP-PhotoSmart_Pro_B8300-hpijs-pdftoijs.ppd
new file mode 100644
index 000000000..798181b2d
--- /dev/null
+++ b/ppd/HP-PhotoSmart_Pro_B8300-hpijs-pdftoijs.ppd
@@ -0,0 +1,342 @@
+*PPD-Adobe: "4.3"
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "HPIJS.PPD"
+*Manufacturer: "HP"
+*Product: "(PhotoSmart Pro B8300)"
+*cupsVersion: 1.0
+*cupsManualCopies: True
+*cupsModelNumber: 2
+*cupsFilter: "application/vnd.cups-pdf 0 pdftoijs"
+*ModelName: "HP PhotoSmart Pro B8300"
+*ShortNickName: "HP PhotoSmart Pro B8300 hpijs"
+*NickName: "HP PhotoSmart Pro B8300 CUPS/pdftoijs/hpijs"
+*PSVersion: "(3010.000) 800"
+*LanguageLevel: "3"
+*ColorDevice: True
+*DefaultColorSpace: RGB
+*FileSystem: False
+*Throughput: "1"
+*LandscapeOrientation: Plus90
+*TTRasterizer: Type42
+*1284DeviceID: "DRV:Dhpijs,R1,M1,F1,Sv,TI,X1200,Y1200,C1,t90,l90,g100,p100,s70;"
+
+*driverName hpijs/hpijs - HP's IJS driver for most of their non-PostScript printers: ""
+*driverType I/IJS: ""
+*driverUrl: "http://hplipopensource.com/"
+*driverObsolete: False
+*driverSupplier: "Hewlett-Packard"
+*driverManufacturerSupplied: True
+*driverLicense: "BSD"
+*driverFreeSoftware: True
+*driverSupportContactVoluntary: "https://launchpad.net/hplip HPLIP support and bug tracking system"
+*driverMaxResolution: 1200 1200
+*driverColor: True
+*driverTextSupport: 90
+*driverLineartSupport: 90
+*driverGraphicsSupport: 100
+*driverPhotoSupport: 100
+*driverRenderingSpeed: 70
+
+*DefaultResolution: 1200dpi
+
+
+
+*HWMargins: 18 36 18 9
+*VariablePaperSize: True
+*MaxMediaWidth: 100000
+*MaxMediaHeight: 100000
+*NonUIOrderDependency: 105 AnySetup *CustomPageSize
+*CustomPageSize True: ""
+*ParamCustomPageSize Width: 1 points 36 100000
+*ParamCustomPageSize Height: 2 points 36 100000
+*ParamCustomPageSize Orientation: 3 int 0 0
+*ParamCustomPageSize WidthOffset: 4 points 0 0
+*ParamCustomPageSize HeightOffset: 5 points 0 0
+
+*ijsServer: "hpijs"
+*ijsManufacturer: "HP"
+*ijsModel: "deskjet 5600"
+*ijsColorSpace: "rgb"
+
+*OpenGroup: General/General
+
+*OpenUI *Quality/Resolution, Quality, Ink Type, Media Type: PickOne
+*OrderDependency: 100 AnySetup *Quality
+*DefaultQuality: 600ColorCMYK
+
+*Quality 300ColorCMYK/300 dpi, Color, Black + Color Cartr.: ""
+*ijsParams Quality=300ColorCMYK: "Quality:Quality=0,Quality:ColorMode=2,Quality:MediaType=0,Quality:PenSet=2"
+*ijsResolution Quality=300ColorCMYK: "300 300"
+
+*Quality 300ColorCMYKFullBleed/300 dpi, Color, Full Bleed, Black + Color Cartr.: ""
+*ijsParams Quality=300ColorCMYKFullbleed: "Quality:Quality=0,Quality:ColorMode=2,Quality:MediaType=0,Quality:PenSet=2,Quality:FullBleed=1"
+*ijsResolution Quality=300ColorCMYKFullbleed: "300 300"
+
+*Quality 300DraftColorCMYK/300 dpi, Draft, Color, Black + Color Cartr.: ""
+*ijsParams Quality=300DraftColorCMYK: "Quality:Quality=1,Quality:ColorMode=2,Quality:MediaType=0,Quality:PenSet=2"
+*ijsResolution Quality=300DraftColorCMYK: "300 300"
+
+*Quality 300DraftGrayscaleCMYK/300 dpi, Draft, Grayscale, Black + Color Cartr.: ""
+*ijsParams Quality=300DraftGrayscaleCMYK: "Quality:Quality=1,Quality:ColorMode=0,Quality:MediaType=0,Quality:PenSet=2"
+*ijsResolution Quality=300DraftGrayscaleCMYK: "300 300"
+
+*Quality 300FastDraftColorCMYK/300 dpi, FastDraft, Color, Black + Color Cartr.: ""
+*ijsParams Quality=300FastDraftColorCMYK: "Quality:Quality=4,Quality:ColorMode=2,Quality:MediaType=0,Quality:PenSet=2"
+*ijsResolution 300FastDraftColorCMYK: "300 300"
+
+*Quality 300FastDraftGrayscaleCMYK/300 dpi, FastDraft, Grayscale, Black + Color Cartr.: ""
+*ijsParams Quality=300FastDraftGrayscaleCMYK: "Quality:Quality=4,Quality:ColorMode=0,Quality:MediaType=0,Quality:PenSet=2"
+*ijsResolution Quality=300FastDraftGrayscaleCMYK: "300 300"
+
+*Quality 300GrayscaleCMYK/300 dpi, Grayscale, Black + Color Cartr.: ""
+*ijsParams Quality=300GrayscaleCMYK: "Quality:Quality=0,Quality:ColorMode=0,Quality:MediaType=0,Quality:PenSet=2"
+*ijsResolution Quality=300GrayscaleCMYK: "300 300"
+
+*Quality 600ColorCMYK/600 dpi, Color, Black + Color Cartr.: ""
+*ijsParams Quality=600ColorCMYK: "Quality:Quality=0,Quality:ColorMode=2,Quality:MediaType=0,Quality:PenSet=2"
+*ijsResolution Quality=600ColorCMYK: "600 600"
+
+*Quality 600ColorCMYKFullBleed/600 dpi, Color, Full Bleed, Black + Color Cartr.: ""
+*ijsParams Quality=600ColorCMYKFullbleed: "Quality:Quality=0,Quality:ColorMode=2,Quality:MediaType=0,Quality:PenSet=2,Quality:FullBleed=1"
+*ijsResolution Quality=600ColorCMYKFullbleed: "600 600"
+
+*Quality 600GrayscaleCMYK/600 dpi, Grayscale, Black + Color Cartr.: ""
+*ijsParams Quality=600GrayscaleCMYK: "Quality:Quality=0,Quality:ColorMode=0,Quality:MediaType=0,Quality:PenSet=2"
+*ijsResolution Quality=600GrayscaleCMYK: "600 600"
+
+*Quality 1200PhotoCMYK/1200 dpi, Photo, Black + Color Cartr., Photo Paper: ""
+*ijsParams Quality=1200PhotoCMYK: "Quality:Quality=3,Quality:ColorMode=2,Quality:MediaType=2,Quality:PenSet=2"
+*ijsResolution Quality=1200PhotoCMYK: "1200 1200"
+
+*Quality 1200PhotoCMYKFullBleed/1200 dpi, Photo, Full Bleed, Black + Color Cartr., Photo Paper: ""
+*ijsParams Quality=1200PhotoCMYKFullBleed: "Quality:Quality=3,Quality:ColorMode=2,Quality:MediaType=3,Quality:PenSet=2,Quality:FullBleed=1"
+*ijsResolution Quality=1200PhotoCMYKFullBleed: "1200 1200"
+
+*CloseUI: *Quality
+
+*OpenUI *InputSlot/Media Source: PickOne
+*OrderDependency: 100 AnySetup *InputSlot
+*DefaultInputSlot: Default
+
+*InputSlot Default/Printer default: ""
+*ijsParams InputSlot=Default: "PS:MediaPosition=7"
+
+*InputSlot PhotoTray/Photo Tray: ""
+*ijsParams InputSlot=PhotoTray: "PS:MediaPosition=6"
+
+*InputSlot Upper/Upper Tray: ""
+*ijsParams InputSlot=Upper: "PS:MediaPosition=1"
+
+*InputSlot Lower/Lower Tray: ""
+*ijsParams InputSlot=Lower: "PS:MediaPosition=4"
+
+*InputSlot CDDVDTray/CD or DVD Tray: ""
+*ijsParams InputSlot=CDDVDTray: "PS:MediaPosition=14"
+
+*InputSlot Envelope/Envelope Feeder: ""
+*ijsParams InputSlot=Envelope: "PS:MediaPosition=3"
+
+*InputSlot LargeCapacity/Large Capacity Tray: ""
+*ijsParams InputSlot=LargeCapacity: "PS:MediaPosition=5"
+
+*InputSlot Manual/Manual Feeder: ""
+*ijsParams InputSlot=Manual: "PS:MediaPosition=2"
+
+*InputSlot MPTray/Multi Purpose Tray: ""
+*ijsParams InputSlot=MPTray: "PS:MediaPosition=8"
+
+*CloseUI: *InputSlot
+
+*OpenUI *PageSize/Page Size: PickOne
+*OrderDependency: 105 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter/Letter: ""
+*PageSize A4/A4: ""
+*PageSize Photo/Photo or 4x6 inch index card: ""
+*PageSize Photo5x7/Photo or 5x7 inch index card: ""
+*PageSize PhotoTearOff/Photo with tear-off tab: ""
+*PageSize 3x5/3x5 inch index card: ""
+*PageSize 5x8/5x8 inch index card: ""
+*PageSize A3/A3: ""
+*PageSize A5/A5: ""
+*PageSize A6/A6: ""
+*PageSize A6TearOff/A6 with tear-off tab: ""
+*PageSize B4JIS/B4 (JIS): ""
+*PageSize B5JIS/B5 (JIS): ""
+*PageSize CDDVD80/CD or DVD 80 mm: ""
+*PageSize CDDVD120/CD or DVD 120 mm: ""
+*PageSize Env10/Envelope #10: ""
+*PageSize EnvC5/Envelope C5: ""
+*PageSize EnvC6/Envelope C6: ""
+*PageSize EnvDL/Envelope DL: ""
+*PageSize EnvISOB5/Envelope B5: ""
+*PageSize EnvMonarch/Envelope Monarch: ""
+*PageSize Executive/Executive: ""
+*PageSize FLSA/American Foolscap: ""
+*PageSize Hagaki/Hagaki: ""
+*PageSize Ledger/Ledger: ""
+*PageSize Legal/Legal: ""
+*PageSize Oufuku/Oufuku-Hagaki: ""
+*PageSize SuperB/Super B: ""
+*PageSize w558h774/16K: ""
+*PageSize w612h935/Executive (JIS): ""
+*PageSize w774h1116/8K: ""
+*CloseUI: *PageSize
+
+*OpenUI *PageRegion: PickOne
+*OrderDependency: 105 AnySetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter/Letter: ""
+*PageRegion A4/A4: ""
+*PageRegion Photo/Photo or 4x6 inch index card: ""
+*PageRegion Photo5x7/Photo or 5x7 inch index card: ""
+*PageRegion PhotoTearOff/Photo with tear-off tab: ""
+*PageRegion 3x5/3x5 inch index card: ""
+*PageRegion 5x8/5x8 inch index card: ""
+*PageRegion A3/A3: ""
+*PageRegion A5/A5: ""
+*PageRegion A6/A6: ""
+*PageRegion A6TearOff/A6 with tear-off tab: ""
+*PageRegion B4JIS/B4 (JIS): ""
+*PageRegion B5JIS/B5 (JIS): ""
+*PageRegion CDDVD80/CD or DVD 80 mm: ""
+*PageRegion CDDVD120/CD or DVD 120 mm: ""
+*PageRegion Env10/Envelope #10: ""
+*PageRegion EnvC5/Envelope C5: ""
+*PageRegion EnvC6/Envelope C6: ""
+*PageRegion EnvDL/Envelope DL: ""
+*PageRegion EnvISOB5/Envelope B5: ""
+*PageRegion EnvMonarch/Envelope Monarch: ""
+*PageRegion Executive/Executive: ""
+*PageRegion FLSA/American Foolscap: ""
+*PageRegion Hagaki/Hagaki: ""
+*PageRegion Ledger/Ledger: ""
+*PageRegion Legal/Legal: ""
+*PageRegion Oufuku/Oufuku-Hagaki: ""
+*PageRegion SuperB/Super B: ""
+*PageRegion w558h774/16K: ""
+*PageRegion w612h935/Executive (JIS): ""
+*PageRegion w774h1116/8K: ""
+*CloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter/Letter: "18 36 594 783"
+*ImageableArea A4/A4: "9.72 36 585.28 833"
+*ImageableArea Photo/Photo or 4x6 inch index card: "0 36 288 432"
+*ImageableArea Photo5x7/Photo or 5x7 inch index card: "0 36 360 504"
+*ImageableArea PhotoTearOff/Photo with tear-off tab: "0 0 288 432"
+*ImageableArea 3x5/3x5 inch index card: "0 36 216 360"
+*ImageableArea 5x8/5x8 inch index card: "0 36 360 576"
+*ImageableArea A3/A3: "14.40 36.00 827.60 1181"
+*ImageableArea A5/A5: "9 36 411 586"
+*ImageableArea A6/A6: "0 36 297 420"
+*ImageableArea A6TearOff/A6 with tear-off tab: "0 0 297 420"
+*ImageableArea B4JIS/B4 (JIS): "18 36 711 1024"
+*ImageableArea B5JIS/B5 (JIS): "18 36 498 720"
+*ImageableArea CDDVD80/CD or DVD 80 mm: "0 36 237 237"
+*ImageableArea CDDVD120/CD or DVD 120 mm: "0 36 360 360"
+*ImageableArea Env10/Envelope #10: "0 36 297 684"
+*ImageableArea EnvC5/Envelope C5: "18 36 441 640"
+*ImageableArea EnvC6/Envelope C6: "0 36 323 459"
+*ImageableArea EnvDL/Envelope DL: "0 36 312 624"
+*ImageableArea EnvISOB5/Envelope B5: "18 36 481 700"
+*ImageableArea EnvMonarch/Envelope Monarch: "0 36 279 540"
+*ImageableArea Executive/Executive: "18 36 504 747"
+*ImageableArea FLSA/American Foolscap: "18 36 594 927"
+*ImageableArea Hagaki/Hagaki: "0 36 283 420"
+*ImageableArea Ledger/Ledger: "14.40 36 777.60 1215"
+*ImageableArea Legal/Legal: "18 36 594 999"
+*ImageableArea Oufuku/Oufuku-Hagaki: "0 36 420 567"
+*ImageableArea SuperB/Super B: "14.40 36 921.60 1359"
+*ImageableArea w558h774/16K: "18 36 540 765"
+*ImageableArea w612h935/Executive (JIS): "18 36 594 926"
+*ImageableArea w774h1116/8K: "18 36 756 1107"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter/Letter: "612 792"
+*PaperDimension A4/A4: "595 842"
+*PaperDimension Photo/Photo or 4x6 inch index card: "288 432"
+*PaperDimension Photo5x7/Photo or 5x7 inch index card: "360 504"
+*PaperDimension PhotoTearOff/Photo with tear-off tab: "288 432"
+*PaperDimension 3x5/3x5 inch index card: "216 360"
+*PaperDimension 5x8/5x8 inch index card: "360 576"
+*PaperDimension A3/A3: "842 1190"
+*PaperDimension A5/A5: "420 595"
+*PaperDimension A6/A6: "297 420"
+*PaperDimension A6TearOff/A6 with tear-off tab: "297 420"
+*PaperDimension B4JIS/B4 (JIS): "729 1033"
+*PaperDimension B5JIS/B5 (JIS): "516 729"
+*PaperDimension CDDVD80/CD or DVD 80 mm: "237 237"
+*PaperDimension CDDVD120/CD or DVD 120 mm: "360 360"
+*PaperDimension Env10/Envelope #10: "297 684"
+*PaperDimension EnvC5/Envelope C5: "459 649"
+*PaperDimension EnvC6/Envelope C6: "323 459"
+*PaperDimension EnvDL/Envelope DL: "312 624"
+*PaperDimension EnvISOB5/Envelope B5: "499 709"
+*PaperDimension EnvMonarch/Envelope Monarch: "279 540"
+*PaperDimension Executive/Executive: "522 756"
+*PaperDimension FLSA/American Foolscap: "612 936"
+*PaperDimension Hagaki/Hagaki: "283 420"
+*PaperDimension Ledger/Ledger: "792 1224"
+*PaperDimension Legal/Legal: "612 1008"
+*PaperDimension Oufuku/Oufuku-Hagaki: "420 567"
+*PaperDimension SuperB/Super B: "936 1368"
+*PaperDimension w558h774/16K: "558 774"
+*PaperDimension w612h935/Executive (JIS): "612 935"
+*PaperDimension w774h1116/8K: "774 1116"
+
+*OpenUI *Duplex/Double-Sided Printing: PickOne
+*FoomaticRIPOption Duplex: enum CmdLine A
+*OrderDependency: 120 AnySetup *Duplex
+*DefaultDuplex: None
+*Duplex DuplexNoTumble/Long Edge (Standard): ""
+*Duplex DuplexTumble/Short Edge (Flip): ""
+*Duplex None/Off: ""
+*CloseUI: *Duplex
+
+*CloseGroup: General
+
+
+*% Generic boilerplate PPD stuff as standard PostScript fonts and so on
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+
diff --git a/ppd/Ricoh-PDF_Printer-PDF.ppd b/ppd/Ricoh-PDF_Printer-PDF.ppd
new file mode 100644
index 000000000..24cf674ee
--- /dev/null
+++ b/ppd/Ricoh-PDF_Printer-PDF.ppd
@@ -0,0 +1,413 @@
+*PPD-Adobe: "4.3"
+*%
+*% This PPD file is for using a Ricoh PDF printer in its native PDF mode, with
+*% option settings controlled via PJL commands. It uses CUPS with the
+*% OpenPrinting CUPS Filters package.
+*%
+*% This PPD is experimental. It is possible that some of the options
+*% and settings do not make sense or do not cause any change on the output.
+*% It can even happen that with certain settings nothing or an error page
+*% comes out.
+*%
+*% This file is published under the GNU General Public License
+*%
+*% You may save this file as 'Ricoh-PDF_Printer-PDF.ppd'
+*%
+*%
+*FormatVersion: "4.3"
+*FileVersion: "2.0"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "RICOHPDF.PPD"
+*Manufacturer: "Ricoh"
+*Product: "(RICOH PDF Printer)"
+*cupsVersion: 1.0
+*cupsManualCopies: False
+*cupsModelNumber: 2
+*ModelName: "Ricoh PDF Printer"
+*ShortNickName: "Ricoh PDF Printer"
+*NickName: "Ricoh PDF Printer"
+*PSVersion: "(3010.107) 0"
+*LanguageLevel: "3"
+*ColorDevice: True
+*DefaultColorSpace: CMYK
+*FileSystem: False
+*Throughput: "30"
+*LandscapeOrientation: Plus90
+*TTRasterizer: Type42
+*1284DeviceID: "MFG:RICOH;CMD:PJL,PDF;MDL:PDF Printer;CLS:PRINTER;DES:Ricoh PDF Printer;DRV:DPDF,R1,M0;"
+*JCLBegin: "<1B>%-12345X@PJL JOB<0A>"
+*JCLToPDFInterpreter: "@PJL ENTER LANGUAGE = PDF<0A>"
+*JCLEnd: "<1B>%-12345X@PJL EOJ <0A><1B>%-12345X"
+*cupsFilter: "application/vnd.cups-pdf 0 -"
+
+*OpenGroup: General/General
+*JCLOpenUI *PageSize/Page Size: PickOne
+*OrderDependency: 100 JCLSetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter/Letter: "@PJL SET FITTOPAGESIZE=LETTER<0A>"
+*PageSize A4/A4: "@PJL SET FITTOPAGESIZE=A4<0A>"
+*PageSize A5/A5: "@PJL SET FITTOPAGESIZE=A5<0A>"
+*PageSize A6/A6: "@PJL SET FITTOPAGESIZE=A6<0A>"
+*PageSize ISOB5/ISO B5: "@PJL SET FITTOPAGESIZE=B5<0A>"
+*PageSize EnvC5/C5: "@PJL SET FITTOPAGESIZE=C5<0A>"
+*PageSize Env10/Com 10: "@PJL SET FITTOPAGESIZE=COM10<0A>"
+*PageSize EnvDL/DL: "@PJL SET FITTOPAGESIZE=DL<0A>"
+*PageSize 5x13/Eight Point 5x13: "@PJL SET FITTOPAGESIZE=EIGHTPOINT5X13<0A>"
+*PageSize EnvC6/Envelope C6: "@PJL SET FITTOPAGESIZE=ENVELOPEC6<0A>"
+*PageSize Executive/Executive: "@PJL SET FITTOPAGESIZE=EXECUTIVE<0A>"
+*PageSize 183x256mm/JIS B5: "@PJL SET FITTOPAGESIZE=JISB5<0A>"
+*PageSize 128x183mm/JIS B6: "@PJL SET FITTOPAGESIZE=JISB6<0A>"
+*PageSize Legal/Legal: "@PJL SET FITTOPAGESIZE=LEGAL<0A>"
+*PageSize Tabloid/11x17: "@PJL SET FITTOPAGESIZE=LEDGER<0A>"
+*PageSize EnvMonarch/Monarch: "@PJL SET FITTOPAGESIZE=MONARCH<0A>"
+*PageSize 69x95mm/16K: "@PJL SET FITTOPAGESIZE=SIZE16K195x270<0A>"
+*PageSize Statement/Statement: "@PJL SET FITTOPAGESIZE=STATEMENT<0A>"
+*JCLCloseUI: *PageSize
+
+*JCLOpenUI *PageRegion: PickOne
+*OrderDependency: 100 JCLSetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter/Letter: "@PJL SET PAPER=LETTER<0A>"
+*PageRegion A4/A4: "@PJL SET PAPER=A4<0A>"
+*PageRegion A5/A5: "@PJL SET PAPER=A5<0A>"
+*PageRegion A6/A6: "@PJL SET PAPER=A6<0A>"
+*PageRegion ISOB5/ISO B5: "@PJL SET PAPER=B5<0A>"
+*PageRegion EnvC5/C5: "@PJL SET PAPER=C5<0A>"
+*PageRegion Env10/Com 10: "@PJL SET PAPER=COM10<0A>"
+*PageRegion EnvDL/DL: "@PJL SET PAPER=DL<0A>"
+*PageRegion 5x13/Eight Point 5x13: "@PJL SET PAPER=EIGHTPOINT5X13<0A>"
+*PageRegion EnvC6/Envelope C6: "@PJL SET PAPER=ENVELOPEC6<0A>"
+*PageRegion Executive/Executive: "@PJL SET PAPER=EXECUTIVE<0A>"
+*PageRegion 183x256mm/JIS B5: "@PJL SET PAPER=JISB5<0A>"
+*PageRegion 128x183mm/JIS B6: "@PJL SET PAPER=JISB6<0A>"
+*PageRegion Legal/Legal: "@PJL SET PAPER=LEGAL<0A>"
+*PageRegion Tabloid/11x17: "@PJL SET PAPER=LEDGER<0A>"
+*PageRegion EnvMonarch/Monarch: "@PJL SET PAPER=MONARCH<0A>"
+*PageRegion 69x95mm/16K: "@PJL SET PAPER=SIZE16K195x270<0A>"
+*PageRegion Statement/Statement: "@PJL SET PAPER=STATEMENT<0A>"
+*JCLCloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter/Letter: "18 36 594 756"
+*ImageableArea A4/A4: "18 36 577 806"
+*ImageableArea A5/A5: "18 36 402 559"
+*ImageableArea A6/A6: "18 36 279 384"
+*ImageableArea ISOB5/ISO B5: "18 36 480 672"
+*ImageableArea EnvC5/C5: "18 36 441 613"
+*ImageableArea Env10/Com 10: "18 36 279 648"
+*ImageableArea EnvDL/DL: "18 36 293 587"
+*ImageableArea 5x13/Eight Point 5x13: "18 36 342 900"
+*ImageableArea EnvC6/Envelope C6: "18 36 305 423"
+*ImageableArea Executive/Executive: "18 36 504 720"
+*ImageableArea 183x256mm/JIS B5: "18 36 500 691"
+*ImageableArea 128x183mm/JIS B6: "18 36 344 482"
+*ImageableArea Legal/Legal: "18 36 594 972"
+*ImageableArea Tabloid/11x17: "12 12 780 1212"
+*ImageableArea EnvMonarch/Monarch: "18 36 261 504"
+*ImageableArea 69x95mm/16K: "18 36 177 234"
+*ImageableArea Statement/Statement: "18 36 378 576"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter/Letter: "612 792"
+*PaperDimension A4/A4: "595 842"
+*PaperDimension A5/A5: "420 595"
+*PaperDimension A6/A6: "297 420"
+*PaperDimension ISOB5/ISO B5: "498 708"
+*PaperDimension EnvC5/C5: "459 649"
+*PaperDimension Env10/Com 10: "297 684"
+*PaperDimension EnvDL/DL: "311 623"
+*PaperDimension 5x13/Eight Point 5x13: "360 936"
+*PaperDimension EnvC6/Envelope C6: "323 459"
+*PaperDimension Executive/Executive: "522 756"
+*PaperDimension 183x256mm/JIS B5: "518 727"
+*PaperDimension 128x183mm/JIS B6: "362 518"
+*PaperDimension Legal/Legal: "612 1008"
+*PaperDimension Tabloid/11x17: "792 1224"
+*PaperDimension EnvMonarch/Monarch: "279 540"
+*PaperDimension 69x95mm/16K: "195 270"
+*PaperDimension Statement/Statement: "396 612"
+
+*JCLOpenUI *Duplex/Double-Sided Printing: PickOne
+*OrderDependency: 100 JCLSetup *Duplex
+*DefaultDuplex: DuplexNoTumble
+*Duplex None/Off: "@PJL SET DUPLEX=OFF<0A>"
+*Duplex DuplexNoTumble/Long-Edge binding: "@PJL SET DUPLEX=ON<0A>@PJL SET BINDING=LONGEDGE<0A>"
+*Duplex DuplexTumble/Short-Edge binding: "@PJL SET DUPLEX=ON<0A>@PJL SET BINDING=SHORTEDGE<0A>"
+*JCLCloseUI: *Duplex
+
+*JCLOpenUI *Resolution/Resolution: PickOne
+*OrderDependency: 100 JCLSetup *Resolution
+*DefaultResolution: 600dpi
+*Resolution 600dpi/600 dpi: "@PJL SET RESOLUTION=600<0A>"
+*Resolution 1200dpi/1200 dpi: "@PJL SET RESOLUTION=1200<0A>"
+*JCLCloseUI: *Resolution
+
+*JCLOpenUI *borderline/Borderline Printing: PickOne
+*OrderDependency: 100 JCLSetup *borderline
+*Defaultborderline: off
+*borderline off/Off: "@PJL SET BORDERLINE=OFF<0A>"
+*borderline on/On: "@PJL SET BORDERLINE=ON<0A>"
+*JCLCloseUI: *borderline
+
+*JCLOpenUI *edgetoedge/Edge to edge: PickOne
+*OrderDependency: 100 JCLSetup *edgetoedge
+*Defaultedgetoedge: no
+*edgetoedge no/No: "@PJL SET EDGETOEDGE=NO<0A>"
+*edgetoedge yes/Yes: "@PJL SET EDGETOEDGE=YES<0A>"
+*JCLCloseUI: *edgetoedge
+
+*JCLOpenUI *joboffset/Job Offset: PickOne
+*OrderDependency: 100 JCLSetup *joboffset
+*Defaultjoboffset: shift
+*joboffset off/Off: "@PJL SET JOBOFFSET=OFF<0A>"
+*joboffset on/On: "@PJL SET JOBOFFSET=ON<0A>"
+*joboffset shift/Shift: "@PJL SET JOBOFFSET=SHIFT<0A>@PJL SET OUTBIN=FINISHERSHIFT<0A>"
+*joboffset rotate/Rotate: "@PJL SET JOBOFFSET=ROTATE<0A>"
+*JCLCloseUI: *joboffset
+
+*JCLOpenUI *WideA4/Wide A4: PickOne
+*OrderDependency: 100 JCLSetup *WideA4
+*DefaultWideA4: no
+*WideA4 no/No: "@PJL SET WIDEA4=NO<0A>"
+*WideA4 yes/Yes: "@PJL SET WIDEA4=YES<0A>"
+*JCLCloseUI: *WideA4
+
+*JCLOpenUI *ColorModel/Color Mode: PickOne
+*OrderDependency: 100 JCLSetup *ColorModel
+*DefaultColorModel: CMYK
+*ColorModel Gray/Black and White: "@PJL SET RENDERMODE=GRAYSCALE<0A>@PJL SET DATAMODE=GRAYSCALE<0A>"
+*ColorModel CMYK/Color: "@PJL SET RENDERMODE=COLOR<0A>@PJL SET DATAMODE=COLOR<0A>"
+*JCLCloseUI: *ColorModel
+
+*JCLOpenUI *InputSlot/InputSlot: PickOne
+*OrderDependency: 30 JCLSetup *InputSlot
+*DefaultInputSlot: Auto
+*InputSlot MultiTray/Bypass Tray: "@PJL SET TRAY = BYPASS<0A>"
+*InputSlot 1Tray/Tray 1: "@PJL SET TRAY = Tray1<0A>"
+*InputSlot 2Tray/Tray 2: "@PJL SET TRAY = Tray2<0A>"
+*InputSlot 3Tray/Tray 3: "@PJL SET TRAY = Tray3<0A>"
+*InputSlot 4Tray/Tray 4: "@PJL SET TRAY = Tray4<0A>"
+*InputSlot 5Tray/Large Capacity Tray: "@PJL SET TRAY = LCT<0A>"
+*InputSlot Auto/Auto Select: "@PJL SET TRAY = ALL<0A>"
+*CloseUI: *InputSlot
+
+*JCLOpenUI *MediaType/Paper Type: PickOne
+*OrderDependency: 205 JCLSetup *MediaType
+*DefaultMediaType: Plain
+*MediaType Auto/Plain/Recycled: "@PJL SET MEDIATYPE=PLAINORRECYCLED<0A>"
+*MediaType Plain/Plain: "@PJL SET MEDIATYPE=PLAIN<0A>"
+*MediaType Recycled/Recycled: "@PJL SET MEDIATYPE=RECYCLED<0A>"
+*MediaType Special/Special: "@PJL SET MEDIATYPE=SPECIAL<0A>"
+*MediaType Special2/Special 2: "@PJL SET MEDIATYPE=SPECIAL2<0A>"
+*MediaType Special3/Special 3: "@PJL SET MEDIATYPE=SPECIAL3<0A>"
+*MediaType Colored/Color: "@PJL SET MEDIATYPE=COLOR<0A>"
+*MediaType Letterhead/Letterhead: "@PJL SET MEDIATYPE=LETTERHEAD<0A>"
+*MediaType Preprinted/Preprinted: "@PJL SET MEDIATYPE=PREPRINTED<0A>"
+*MediaType Labels/Labels: "@PJL SET MEDIATYPE=LABELS<0A>"
+*MediaType Coated/Coated: "@PJL SET MEDIATYPE=COATED<0A>"
+*MediaType Bond/Bond: "@PJL SET MEDIATYPE=BOND<0A>"
+*MediaType Cardstock/Cardstock: "@PJL SET MEDIATYPE=CARDSTOCK<0A>"
+*MediaType OHP/Transparency: "@PJL SET MEDIATYPE=TRANSPARENCY<0A>"
+*MediaType Thick/Thick: "@PJL SET MEDIATYPE=THICK<0A>"
+*MediaType Thick2/Thick 2: "@PJL SET MEDIATYPE=THICK2<0A>"
+*MediaType Thick3/Thick 3: "@PJL SET MEDIATYPE=THICK3<0A>"
+*MediaType Thin/Thin: "@PJL SET MEDIATYPE=THIN<0A>"
+*MediaType Middlethick/Middle Thick: "@PJL SET MEDIATYPE=MIDDLETHICK<0A>"
+*MediaType Glossy/Glossy: "@PJL SET MEDIATYPE=GLOSSY<0A>"
+*MediaType Envelope/Envelope: "@PJL SET MEDIATYPE=ENVELOPE<0A>"
+*CloseUI: *MediaType
+
+*JCLOpenUI *StapleLocation/Staple: PickOne
+*OrderDependency: 220 JCLSetup *StapleLocation
+*DefaultStapleLocation: None
+*StapleLocation None/Off: "@PJL SET STAPLE=OFF<0A>"
+*StapleLocation UpperLeft/Top left: "@PJL SET STAPLE=LEFTTOP<0A>"
+*StapleLocation UpperRight/Top right: "@PJL SET STAPLE=RIGHTTOP<0A>"
+*StapleLocation LeftW/2 at left: "@PJL SET STAPLE=LEFT2PORT<0A>"
+*StapleLocation RightW/2 at right: "@PJL SET STAPLE=RIGHT2PORT<0A>"
+*StapleLocation UpperW/2 at top: "@PJL SET STAPLE=TOP2PORT<0A>"
+*StapleLocation CenterW/2 at center: "@PJL SET STAPLE=BOOKLET<0A>"
+*CloseUI: *StapleLocation
+
+*JCLOpenUI *RIPunch/Punch: PickOne
+*OrderDependency: 230 JCLSetup *RIPunch
+*DefaultRIPunch: None
+*RIPunch None/Off: "@PJL SET PUNCH=OFF<0A>"
+*RIPunch LeftJP2/2 at left (Japan/Europe): "@PJL SET PUNCH=LEFTPORT<0A>@PJL SET PUNCHHOLE=JP2<0A>"
+*RIPunch LeftUS2/2 at left (North America): "@PJL SET PUNCH=LEFTPORT<0A>@PJL SET PUNCHHOLE=US2<0A>"
+*RIPunch LeftUS3/3 at left (North America): "@PJL SET PUNCH=LEFTPORT<0A>@PJL SET PUNCHHOLE=US3<0A>"
+*RIPunch LeftEU4/4 at left (Europe): "@PJL SET PUNCH=LEFTPORT<0A>@PJL SET PUNCHHOLE=EU4<0A>"
+*RIPunch LeftNEU4/4 at left (Northern Europe): "@PJL SET PUNCH=LEFTPORT<0A>@PJL SET PUNCHHOLE=NEU4<0A>"
+*RIPunch RightJP2/2 at right (Japan/Europe): "@PJL SET IMAGEDIRECTION=REVERSE<0A>@PJL SET PUNCH=LEFTPORT<0A>@PJL SET PUNCHHOLE=JP2<0A>"
+*RIPunch RightUS2/2 at right (North America): "@PJL SET IMAGEDIRECTION=REVERSE<0A>@PJL SET PUNCH=LEFTPORT<0A>@PJL SET PUNCHHOLE=US2<0A>"
+*RIPunch RightUS3/3 at right (North America): "@PJL SET IMAGEDIRECTION=REVERSE<0A>@PJL SET PUNCH=LEFTPORT<0A>@PJL SET PUNCHHOLE=US3<0A>"
+*RIPunch RightEU4/4 at right (Europe): "@PJL SET IMAGEDIRECTION=REVERSE<0A>@PJL SET PUNCH=LEFTPORT<0A>@PJL SET PUNCHHOLE=EU4<0A>"
+*RIPunch RightNEU4/4 at right (Northern Europe): "@PJL SET IMAGEDIRECTION=REVERSE<0A>@PJL SET PUNCH=LEFTPORT<0A>@PJL SET PUNCHHOLE=NEU4<0A>"
+*RIPunch UpperJP2/2 at top (Japan/Europe): "@PJL SET PUNCH=TOPPORT<0A>@PJL SET PUNCHHOLE=JP2<0A>"
+*RIPunch UpperUS2/2 at top (North America): "@PJL SET PUNCH=TOPPORT<0A>@PJL SET PUNCHHOLE=US2<0A>"
+*RIPunch UpperUS3/3 at top (North America): "@PJL SET PUNCH=TOPPORT<0A>@PJL SET PUNCHHOLE=US3<0A>"
+*RIPunch UpperEU4/4 at top (Europe): "@PJL SET PUNCH=TOPPORT<0A>@PJL SET PUNCHHOLE=EU4<0A>"
+*RIPunch UpperNEU4/4 at top (Northern Europe): "@PJL SET PUNCH=TOPPORT<0A>@PJL SET PUNCHHOLE=NEU4<0A>"
+*CloseUI: *RIPunch
+
+*JCLOpenUI *N-up/N-up: PickOne
+*OrderDependency: 240 JCLSetup *N-up
+*DefaultN-up: 1up
+*N-up 1up/Off: "@PJL SET NUP = <0A>"
+*N-up 2up/2-up: "@PJL SET NUP = 2<0A>"
+*N-up 4up/4-up: "@PJL SET NUP = 4<0A>"
+*N-up 6up/6-up: "@PJL SET NUP = 6<0A>"
+*N-up 9up/9-up: "@PJL SET NUP = 9<0A>"
+*N-up 16up/16-up: "@PJL SET NUP = 16<0A>"
+*CloseUI: *N-up
+
+*JCLOpenUI *NupPageOrder/N-up PageOrder: PickOne
+*OrderDependency: 240 JCLSetup *NupPageOrder
+*DefaultNupPageOrder: RightThenDown
+*NupPageOrder RightThenDown/Right then Down: "@PJL SET NUPPAGEORDER = <0A>"
+*NupPageOrder DownThenRight/Down then Right: "@PJL SET NUPPAGEORDER = DOWNTHENRIGHT<0A>"
+*NupPageOrder LeftThenDown/Left then Down: "@PJL SET NUPPAGEORDER = LEFTTHENDOWN<0A>"
+*NupPageOrder DownThenLeft/Down then Left: "@PJL SET NUPPAGEORDER = DOWNTHENLEFT<0A>"
+*CloseUI: *NupPageOrder
+
+*CloseGroup: General
+
+*%========== Font ==========
+*DefaultFont: Courier
+*Font AlbertusMT: Standard "(001.000)" Standard ROM
+*Font AlbertusMT-Italic: Standard "(001.000)" Standard ROM
+*Font AlbertusMT-Light: Standard "(001.000)" Standard ROM
+*Font AntiqueOlive-Bold: Standard "(501.009)" ExtendedRoman ROM
+*Font AntiqueOlive-Compact: Standard "(501.008)" ExtendedRoman ROM
+*Font AntiqueOlive-Italic: Standard "(501.010)" ExtendedRoman ROM
+*Font AntiqueOlive-Roman: Standard "(501.008)" ExtendedRoman ROM
+*Font Apple-Chancery: Standard "(001.001)" ExtendedRoman ROM
+*Font ArialMT: Standard "(501.009)" ExtendedRoman ROM
+*Font Arial-BoldMT: Standard "(501.009)" ExtendedRoman ROM
+*Font Arial-BoldItalicMT: Standard "(501.009)" ExtendedRoman ROM
+*Font Arial-ItalicMT: Standard "(501.012)" ExtendedRoman ROM
+*Font AvantGarde-Book: Standard "(501.009)" ExtendedRoman ROM
+*Font AvantGarde-BookOblique: Standard "(501.009)" ExtendedRoman ROM
+*Font AvantGarde-Demi: Standard "(501.010)" ExtendedRoman ROM
+*Font AvantGarde-DemiOblique: Standard "(501.010)" ExtendedRoman ROM
+*Font Bodoni: Standard "(501.008)" ExtendedRoman ROM
+*Font Bodoni-Bold: Standard "(501.006)" ExtendedRoman ROM
+*Font Bodoni-BoldItalic: Standard "(501.007)" ExtendedRoman ROM
+*Font Bodoni-Italic: Standard "(501.007)" ExtendedRoman ROM
+*Font Bodoni-Poster: Standard "(501.009)" ExtendedRoman ROM
+*Font Bodoni-PosterCompressed: Standard "(501.007)" ExtendedRoman ROM
+*Font Bookman-Demi: Standard "(501.007)" ExtendedRoman ROM
+*Font Bookman-DemiItalic: Standard "(501.008)" ExtendedRoman ROM
+*Font Bookman-Light: Standard "(501.006)" ExtendedRoman ROM
+*Font Bookman-LightItalic: Standard "(501.007)" ExtendedRoman ROM
+*Font Carta: Special "(001.001)" Special ROM
+*Font Chicago: Standard "(501.011)" ExtendedRoman ROM
+*Font Clarendon-Bold: Standard "(501.008)" ExtendedRoman ROM
+*Font Clarendon-Light: Standard "(501.009)" ExtendedRoman ROM
+*Font Clarendon: Standard "(501.009)" ExtendedRoman ROM
+*Font CooperBlack-Italic: Standard "(001.003)" Standard ROM
+*Font CooperBlack: Standard "(001.003)" Standard ROM
+*Font Copperplate-ThirtyThreeBC: Standard "(001.002)" Standard ROM
+*Font Copperplate-ThirtyTwoBC: Standard "(001.002)" Standard ROM
+*Font Coronet-Regular: Standard "(001.000)" ExtendedRoman ROM
+*Font Courier-Bold: Standard "(501.010)" ExtendedRoman ROM
+*Font Courier-BoldOblique: Standard "(501.010)" ExtendedRoman ROM
+*Font Courier-Oblique: Standard "(501.010)" ExtendedRoman ROM
+*Font Courier: Standard "(501.010)" ExtendedRoman ROM
+*Font Eurostile-Bold: Standard "(501.008)" ExtendedRoman ROM
+*Font Eurostile-BoldExtendedTwo: Standard "(501.008)" ExtendedRoman ROM
+*Font Eurostile-ExtendedTwo: Standard "(501.010)" ExtendedRoman ROM
+*Font Eurostile: Standard "(501.008)" ExtendedRoman ROM
+*Font Geneva: Standard "(501.007)" ExtendedRoman ROM
+*Font GillSans: Standard "(501.009)" ExtendedRoman ROM
+*Font GillSans-Bold: Standard "(501.007)" ExtendedRoman ROM
+*Font GillSans-BoldCondensed: Standard "(501.006)" ExtendedRoman ROM
+*Font GillSans-BoldItalic: Standard "(501.008)" ExtendedRoman ROM
+*Font GillSans-Condensed: Standard "(501.007)" ExtendedRoman ROM
+*Font GillSans-ExtraBold: Standard "(501.008)" ExtendedRoman ROM
+*Font GillSans-Italic: Standard "(501.008)" ExtendedRoman ROM
+*Font GillSans-Light: Standard "(501.009)" ExtendedRoman ROM
+*Font GillSans-LightItalic: Standard "(501.009)" ExtendedRoman ROM
+*Font Goudy: Standard "(001.003)" Standard ROM
+*Font Goudy-Bold: Standard "(001.002)" Standard ROM
+*Font Goudy-BoldItalic: Standard "(001.002)" Standard ROM
+*Font Goudy-ExtraBold: Standard "(001.001)" Standard ROM
+*Font Goudy-Italic: Standard "(001.002)" Standard ROM
+*Font Helvetica: Standard "(501.008)" ExtendedRoman ROM
+*Font Helvetica-Bold: Standard "(501.010)" ExtendedRoman ROM
+*Font Helvetica-BoldOblique: Standard "(501.010)" ExtendedRoman ROM
+*Font Helvetica-Condensed-Bold: Standard "(501.009)" ExtendedRoman ROM
+*Font Helvetica-Condensed-BoldObl: Standard "(501.009)" ExtendedRoman ROM
+*Font Helvetica-Condensed-Oblique: Standard "(501.010)" ExtendedRoman ROM
+*Font Helvetica-Condensed: Standard "(501.010)" ExtendedRoman ROM
+*Font Helvetica-Narrow-Bold: Standard "(501.010)" ExtendedRoman ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(501.010)" ExtendedRoman ROM
+*Font Helvetica-Narrow-Oblique: Standard "(501.008)" ExtendedRoman ROM
+*Font Helvetica-Narrow: Standard "(501.008)" ExtendedRoman ROM
+*Font Helvetica-Oblique: Standard "(501.008)" ExtendedRoman ROM
+*Font HoeflerText-Black: Standard "(501.008)" ExtendedRoman ROM
+*Font HoeflerText-BlackItalic: Standard "(501.009)" ExtendedRoman ROM
+*Font HoeflerText-Italic: Standard "(501.010)" ExtendedRoman ROM
+*Font HoeflerText-Ornaments: Special "(001.001)" Special ROM
+*Font HoeflerText-Regular: Standard "(501.009)" ExtendedRoman ROM
+*Font JoannaMT: Standard "(501.009)" ExtendedRoman ROM
+*Font JoannaMT-Bold: Standard "(501.008)" ExtendedRoman ROM
+*Font JoannaMT-BoldItalic: Standard "(501.008)" ExtendedRoman ROM
+*Font JoannaMT-Italic: Standard "(501.008)" ExtendedRoman ROM
+*Font LetterGothic: Standard "(501.009)" ExtendedRoman ROM
+*Font LetterGothic-Bold: Standard "(501.010)" ExtendedRoman ROM
+*Font LetterGothic-BoldSlanted: Standard "(501.010)" ExtendedRoman ROM
+*Font LetterGothic-Slanted: Standard "(501.010)" ExtendedRoman ROM
+*Font LubalinGraph-Book: Standard "(501.009)" ExtendedRoman ROM
+*Font LubalinGraph-BookOblique: Standard "(501.009)" ExtendedRoman ROM
+*Font LubalinGraph-Demi: Standard "(501.009)" ExtendedRoman ROM
+*Font LubalinGraph-DemiOblique: Standard "(501.009)" ExtendedRoman ROM
+*Font Marigold: Standard "(001.000)" Standard ROM
+*Font MonaLisa-Recut: Standard "(001.000)" Standard ROM
+*Font Monaco: Standard "(501.012)" ExtendedRoman ROM
+*Font NewCenturySchlbk-Bold: Standard "(501.008)" ExtendedRoman ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(501.009)" ExtendedRoman ROM
+*Font NewCenturySchlbk-Italic: Standard "(501.011)" ExtendedRoman ROM
+*Font NewCenturySchlbk-Roman: Standard "(501.008)" ExtendedRoman ROM
+*Font NewYork: Standard "(501.013)" ExtendedRoman ROM
+*Font Optima-Bold: Standard "(501.008)" ExtendedRoman ROM
+*Font Optima-BoldItalic: Standard "(501.009)" ExtendedRoman ROM
+*Font Optima-Italic: Standard "(501.010)" ExtendedRoman ROM
+*Font Optima: Standard "(501.010)" ExtendedRoman ROM
+*Font Oxford: Standard "(001.000)" Standard ROM
+*Font Palatino-Bold: Standard "(501.008)" ExtendedRoman ROM
+*Font Palatino-BoldItalic: Standard "(501.007)" ExtendedRoman ROM
+*Font Palatino-Italic: Standard "(501.008)" ExtendedRoman ROM
+*Font Palatino-Roman: Standard "(501.006)" ExtendedRoman ROM
+*Font StempelGaramond-Bold: Standard "(501.007)" ExtendedRoman ROM
+*Font StempelGaramond-BoldItalic: Standard "(501.012)" ExtendedRoman ROM
+*Font StempelGaramond-Italic: Standard "(501.009)" ExtendedRoman ROM
+*Font StempelGaramond-Roman: Standard "(501.011)" ExtendedRoman ROM
+*Font Symbol: Special "(001.008)" Special ROM
+*Font Tekton: Standard "(001.001)" Standard ROM
+*Font Times-Bold: Standard "(501.009)" ExtendedRoman ROM
+*Font Times-BoldItalic: Standard "(501.009)" ExtendedRoman ROM
+*Font Times-Italic: Standard "(501.010)" ExtendedRoman ROM
+*Font Times-Roman: Standard "(501.010)" ExtendedRoman ROM
+*Font TimesNewRomanPS-BoldItalicMT: Standard "(501.011)" ExtendedRoman ROM
+*Font TimesNewRomanPS-BoldMT: Standard "(501.009)" ExtendedRoman ROM
+*Font TimesNewRomanPS-ItalicMT: Standard "(501.011)" ExtendedRoman ROM
+*Font TimesNewRomanPSMT: Standard "(501.010)" ExtendedRoman ROM
+*Font Univers: Standard "(501.009)" ExtendedRoman ROM
+*Font Univers-Bold: Standard "(501.008)" ExtendedRoman ROM
+*Font Univers-BoldExt: Standard "(501.010)" ExtendedRoman ROM
+*Font Univers-BoldExtObl: Standard "(501.010)" ExtendedRoman ROM
+*Font Univers-BoldOblique: Standard "(501.008)" ExtendedRoman ROM
+*Font Univers-Condensed: Standard "(501.011)" ExtendedRoman ROM
+*Font Univers-CondensedBold: Standard "(501.009)" ExtendedRoman ROM
+*Font Univers-CondensedBoldOblique: Standard "(501.009)" ExtendedRoman ROM
+*Font Univers-CondensedOblique: Standard "(501.011)" ExtendedRoman ROM
+*Font Univers-Extended: Standard "(501.009)" ExtendedRoman ROM
+*Font Univers-ExtendedObl: Standard "(501.009)" ExtendedRoman ROM
+*Font Univers-Light: Standard "(501.009)" ExtendedRoman ROM
+*Font Univers-LightOblique: Standard "(501.009)" ExtendedRoman ROM
+*Font Univers-Oblique: Standard "(501.009)" ExtendedRoman ROM
+*Font Wingdings-Regular: Special "(001.001)" Special ROM
+*Font ZapfChancery-MediumItalic: Standard "(002.000)" ExtendedRoman ROM
+*Font ZapfDingbats: Special "(001.005S)" Special ROM
diff --git a/ppd/pxlcolor.ppd b/ppd/pxlcolor.ppd
new file mode 100644
index 000000000..4c9785d55
--- /dev/null
+++ b/ppd/pxlcolor.ppd
@@ -0,0 +1,204 @@
+*PPD-Adobe: "4.3"
+*%
+*%
+*% Sample color PCL XL/PCL 6 driver PPD file for the Common UNIX
+*% Printing System (CUPS).
+*%
+*% Copyright 1997-2005 by Easy Software Products.
+*%
+*% These coded instructions, statements, and computer programs are the
+*% property of Easy Software Products and are protected by Federal
+*% copyright law. Distribution and use rights are outlined in the file
+*% "COPYING" which should have been included with this file.
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "PXLCOLOR.PPD"
+*Manufacturer: "HP"
+*Product: "(GPL Ghostscript)"
+*cupsVersion: 1.1
+*cupsManualCopies: False
+*cupsFilter: "application/vnd.cups-postscript 100 gstopxl"
+*cupsFilter: "application/vnd.cups-pdf 0 gstopxl"
+*ModelName: "HP Color LaserJet Series PCL 6"
+*ShortNickName: "HP Color LaserJet Series PCL 6"
+*NickName: "HP Color LaserJet Series PCL 6 CUPS"
+*PSVersion: "(3010.000) 86000"
+*LanguageLevel: "3"
+*ColorDevice: True
+*DefaultColorSpace: RGB
+*FileSystem: False
+*Throughput: "8"
+*LandscapeOrientation: Plus90
+*TTRasterizer: Type42
+
+*UIConstraints: *PageSize Executive *InputSlot Envelope
+*UIConstraints: *PageSize Letter *InputSlot Envelope
+*UIConstraints: *PageSize Legal *InputSlot Envelope
+*UIConstraints: *PageSize Tabloid *InputSlot Envelope
+*UIConstraints: *PageSize A3 *InputSlot Envelope
+*UIConstraints: *PageSize A4 *InputSlot Envelope
+*UIConstraints: *PageSize A5 *InputSlot Envelope
+*UIConstraints: *PageSize B5 *InputSlot Envelope
+*UIConstraints: *Duplex *OptionDuplex False
+*UIConstraints: *InputSlot Envelope *PageSize Executive
+*UIConstraints: *InputSlot Envelope *PageSize Letter
+*UIConstraints: *InputSlot Envelope *PageSize Legal
+*UIConstraints: *InputSlot Envelope *PageSize Tabloid
+*UIConstraints: *InputSlot Envelope *PageSize A3
+*UIConstraints: *InputSlot Envelope *PageSize A4
+*UIConstraints: *InputSlot Envelope *PageSize A5
+*UIConstraints: *InputSlot Envelope *PageSize B5
+*UIConstraints: *OptionDuplex False *Duplex
+
+*OpenUI *PageSize/Media Size: PickOne
+*OrderDependency: 10 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter/US Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageSize Legal/US Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageSize Executive/US Executive: "<</PageSize[522 756]/ImagingBBox null>>setpagedevice"
+*PageSize Tabloid/US Tabloid: "<</PageSize[792 1224]/ImagingBBox null>>setpagedevice"
+*PageSize A3/A3: "<</PageSize[842 1191]/ImagingBBox null>>setpagedevice"
+*PageSize A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageSize A5/A5: "<</PageSize[421 595]/ImagingBBox null>>setpagedevice"
+*PageSize B5/B5 (JIS): "<</PageSize[516 729]/ImagingBBox null>>setpagedevice"
+*PageSize EnvISOB5/Envelope B5: "<</PageSize[499 709]/ImagingBBox null>>setpagedevice"
+*PageSize Env10/Envelope #10: "<</PageSize[297 684]/ImagingBBox null>>setpagedevice"
+*PageSize EnvC5/Envelope C5: "<</PageSize[459 649]/ImagingBBox null>>setpagedevice"
+*PageSize EnvDL/Envelope DL: "<</PageSize[312 624]/ImagingBBox null>>setpagedevice"
+*PageSize EnvMonarch/Envelope Monarch: "<</PageSize[279 540]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageSize
+
+*OpenUI *PageRegion: PickOne
+*OrderDependency: 10 AnySetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter/US Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageRegion Legal/US Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageRegion Executive/US Executive: "<</PageSize[522 756]/ImagingBBox null>>setpagedevice"
+*PageRegion Tabloid/US Tabloid: "<</PageSize[792 1224]/ImagingBBox null>>setpagedevice"
+*PageRegion A3/A3: "<</PageSize[842 1191]/ImagingBBox null>>setpagedevice"
+*PageRegion A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageRegion A5/A5: "<</PageSize[421 595]/ImagingBBox null>>setpagedevice"
+*PageRegion B5/B5 (JIS): "<</PageSize[516 729]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvISOB5/Envelope B5: "<</PageSize[499 709]/ImagingBBox null>>setpagedevice"
+*PageRegion Env10/Envelope #10: "<</PageSize[297 684]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvC5/Envelope C5: "<</PageSize[459 649]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvDL/Envelope DL: "<</PageSize[312 624]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvMonarch/Envelope Monarch: "<</PageSize[279 540]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter/US Letter: "12 12 600 780"
+*ImageableArea Legal/US Legal: "12 12 600 996"
+*ImageableArea Executive/US Executive: "12 12 510 708"
+*ImageableArea Tabloid/US Tabloid: "12 12 780 1212"
+*ImageableArea A3/A3: "12 12 830 1179"
+*ImageableArea A4/A4: "12 12 583 830"
+*ImageableArea A5/A5: "12 12 409 583"
+*ImageableArea B5/JIS B5: "12 12 504 717"
+*ImageableArea EnvISOB5/B5 (ISO): "12 12 469 697"
+*ImageableArea Env10/Com-10: "12 12 285 672"
+*ImageableArea EnvC5/EnvC5: "12 12 447 637"
+*ImageableArea EnvDL/EnvDL: "12 12 300 612"
+*ImageableArea EnvMonarch/Envelope Monarch: "12 12 267 528"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter/US Letter: "612 792"
+*PaperDimension Legal/US Legal: "612 1008"
+*PaperDimension Executive/US Executive: "522 756"
+*PaperDimension Tabloid/US Tabloid: "792 1224"
+*PaperDimension A3/A3: "842 1191"
+*PaperDimension A4/A4: "595 842"
+*PaperDimension A5/A5: "421 595"
+*PaperDimension B5/B5 (JIS): "516 729"
+*PaperDimension EnvISOB5/Envelope B5: "499 709"
+*PaperDimension Env10/Envelope #10: "297 684"
+*PaperDimension EnvC5/Envelope C5: "459 649"
+*PaperDimension EnvDL/Envelope DL: "312 624"
+*PaperDimension EnvMonarch/Envelope Monarch: "279 540"
+
+*OpenUI *InputSlot/Media Source: PickOne
+*OrderDependency: 10 AnySetup *InputSlot
+*DefaultInputSlot: Default
+*InputSlot Default/Default: "<</MediaPosition 0>>setpagedevice"
+*InputSlot Auto/Automatically Select: "<</MediaPosition 0>>setpagedevice"
+*InputSlot MultiPurpose/Tray 1: "<</MediaPosition 19>>setpagedevice"
+*InputSlot Upper/Tray 2: "<</MediaPosition 1>>setpagedevice"
+*InputSlot Lower/Tray 3: "<</MediaPosition 2>>setpagedevice"
+*InputSlot LargeCapacity/Tray 4: "<</MediaPosition 3>>setpagedevice"
+*InputSlot Manual/Manual Feed: "<</MediaPosition 4>>setpagedevice"
+*InputSlot Envelope/Envelope Feed: "<</MediaPosition 5>>setpagedevice"
+*CloseUI: *InputSlot
+
+*OpenUI *ColorModel/Output Mode: PickOne
+*OrderDependency: 10 AnySetup *ColorModel
+*DefaultColorModel: RGB
+*ColorModel RGB/Color: "<</cupsColorSpace 19>>setpagedevice"
+*ColorModel Gray/Grayscale: "<</cupsColorSpace 18>>setpagedevice"
+*CloseUI: *ColorModel
+
+*OpenUI *Resolution/Output Resolution: PickOne
+*OrderDependency: 20 AnySetup *Resolution
+*DefaultResolution: 600dpi
+*Resolution 150dpi/150 DPI: "<</HWResolution[150 150]>>setpagedevice"
+*Resolution 300dpi/300 DPI: "<</HWResolution[300 300]>>setpagedevice"
+*Resolution 600dpi/600 DPI: "<</HWResolution[600 600]>>setpagedevice"
+*Resolution 1200dpi/1200 DPI: "<</HWResolution[1200 1200]>>setpagedevice"
+*CloseUI: *Resolution
+
+*OpenUI *Duplex/Double-Sided Printing: PickOne
+*OrderDependency: 20 AnySetup *Duplex
+*DefaultDuplex: None
+*Duplex None/Off: "<</Duplex false>>setpagedevice"
+*Duplex DuplexNoTumble/Long Edge (Standard): "<</Duplex true/Tumble false>>setpagedevice"
+*Duplex DuplexTumble/Short Edge (Flip): "<</Duplex true/Tumble true>>setpagedevice"
+*CloseUI: *Duplex
+
+*OpenGroup: InstallableOptions
+*OpenUI *OptionDuplex/Duplexer: Boolean
+*DefaultOptionDuplex: False
+*OptionDuplex True/Installed: ""
+*OptionDuplex False/Not Installed: ""
+*CloseUI: *OptionDuplex
+*CloseGroup: InstallableOptions
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+*%
+*%
diff --git a/ppd/pxlmono.ppd b/ppd/pxlmono.ppd
new file mode 100644
index 000000000..26a4065d9
--- /dev/null
+++ b/ppd/pxlmono.ppd
@@ -0,0 +1,197 @@
+*PPD-Adobe: "4.3"
+*%
+*%
+*% Sample monochrome PCL XL/PCL 6 driver PPD file for the Common UNIX
+*% Printing System (CUPS).
+*%
+*% Copyright 1997-2005 by Easy Software Products.
+*%
+*% These coded instructions, statements, and computer programs are the
+*% property of Easy Software Products and are protected by Federal
+*% copyright law. Distribution and use rights are outlined in the file
+*% "COPYING" which should have been included with this file.
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "PXLMONO.PPD"
+*Manufacturer: "HP"
+*Product: "(GPL Ghostscript)"
+*cupsVersion: 1.1
+*cupsManualCopies: False
+*cupsFilter: "application/vnd.cups-postscript 100 gstopxl"
+*cupsFilter: "application/vnd.cups-pdf 0 gstopxl"
+*ModelName: "HP LaserJet Series PCL 6"
+*ShortNickName: "HP LaserJet Series PCL 6"
+*NickName: "HP LaserJet Series PCL 6 CUPS"
+*PSVersion: "(3010.000) 86000"
+*LanguageLevel: "3"
+*ColorDevice: False
+*DefaultColorSpace: Gray
+*FileSystem: False
+*Throughput: "8"
+*LandscapeOrientation: Plus90
+*TTRasterizer: Type42
+
+*UIConstraints: *PageSize Executive *InputSlot Envelope
+*UIConstraints: *PageSize Letter *InputSlot Envelope
+*UIConstraints: *PageSize Legal *InputSlot Envelope
+*UIConstraints: *PageSize Tabloid *InputSlot Envelope
+*UIConstraints: *PageSize A3 *InputSlot Envelope
+*UIConstraints: *PageSize A4 *InputSlot Envelope
+*UIConstraints: *PageSize A5 *InputSlot Envelope
+*UIConstraints: *PageSize B5 *InputSlot Envelope
+*UIConstraints: *Duplex *OptionDuplex False
+*UIConstraints: *InputSlot Envelope *PageSize Executive
+*UIConstraints: *InputSlot Envelope *PageSize Letter
+*UIConstraints: *InputSlot Envelope *PageSize Legal
+*UIConstraints: *InputSlot Envelope *PageSize Tabloid
+*UIConstraints: *InputSlot Envelope *PageSize A3
+*UIConstraints: *InputSlot Envelope *PageSize A4
+*UIConstraints: *InputSlot Envelope *PageSize A5
+*UIConstraints: *InputSlot Envelope *PageSize B5
+*UIConstraints: *OptionDuplex False *Duplex
+
+*OpenUI *PageSize/Media Size: PickOne
+*OrderDependency: 10 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter/US Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageSize Legal/US Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageSize Executive/US Executive: "<</PageSize[522 756]/ImagingBBox null>>setpagedevice"
+*PageSize Tabloid/US Tabloid: "<</PageSize[792 1224]/ImagingBBox null>>setpagedevice"
+*PageSize A3/A3: "<</PageSize[842 1191]/ImagingBBox null>>setpagedevice"
+*PageSize A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageSize A5/A5: "<</PageSize[421 595]/ImagingBBox null>>setpagedevice"
+*PageSize B5/B5 (JIS): "<</PageSize[516 729]/ImagingBBox null>>setpagedevice"
+*PageSize EnvISOB5/Envelope B5: "<</PageSize[499 709]/ImagingBBox null>>setpagedevice"
+*PageSize Env10/Envelope #10: "<</PageSize[297 684]/ImagingBBox null>>setpagedevice"
+*PageSize EnvC5/Envelope C5: "<</PageSize[459 649]/ImagingBBox null>>setpagedevice"
+*PageSize EnvDL/Envelope DL: "<</PageSize[312 624]/ImagingBBox null>>setpagedevice"
+*PageSize EnvMonarch/Envelope Monarch: "<</PageSize[279 540]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageSize
+
+*OpenUI *PageRegion: PickOne
+*OrderDependency: 10 AnySetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter/US Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageRegion Legal/US Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageRegion Executive/US Executive: "<</PageSize[522 756]/ImagingBBox null>>setpagedevice"
+*PageRegion Tabloid/US Tabloid: "<</PageSize[792 1224]/ImagingBBox null>>setpagedevice"
+*PageRegion A3/A3: "<</PageSize[842 1191]/ImagingBBox null>>setpagedevice"
+*PageRegion A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageRegion A5/A5: "<</PageSize[421 595]/ImagingBBox null>>setpagedevice"
+*PageRegion B5/B5 (JIS): "<</PageSize[516 729]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvISOB5/Envelope B5: "<</PageSize[499 709]/ImagingBBox null>>setpagedevice"
+*PageRegion Env10/Envelope #10: "<</PageSize[297 684]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvC5/Envelope C5: "<</PageSize[459 649]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvDL/Envelope DL: "<</PageSize[312 624]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvMonarch/Envelope Monarch: "<</PageSize[279 540]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter/US Letter: "12 12 600 780"
+*ImageableArea Legal/US Legal: "12 12 600 996"
+*ImageableArea Executive/US Executive: "12 12 510 708"
+*ImageableArea Tabloid/US Tabloid: "12 12 780 1212"
+*ImageableArea A3/A3: "12 12 830 1179"
+*ImageableArea A4/A4: "12 12 583 830"
+*ImageableArea A5/A5: "12 12 409 583"
+*ImageableArea B5/JIS B5: "12 12 504 717"
+*ImageableArea EnvISOB5/B5 (ISO): "12 12 469 697"
+*ImageableArea Env10/Com-10: "12 12 285 672"
+*ImageableArea EnvC5/EnvC5: "12 12 447 637"
+*ImageableArea EnvDL/EnvDL: "12 12 300 612"
+*ImageableArea EnvMonarch/Envelope Monarch: "12 12 267 528"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter/US Letter: "612 792"
+*PaperDimension Legal/US Legal: "612 1008"
+*PaperDimension Executive/US Executive: "522 756"
+*PaperDimension Tabloid/US Tabloid: "792 1224"
+*PaperDimension A3/A3: "842 1191"
+*PaperDimension A4/A4: "595 842"
+*PaperDimension A5/A5: "421 595"
+*PaperDimension B5/B5 (JIS): "516 729"
+*PaperDimension EnvISOB5/Envelope B5: "499 709"
+*PaperDimension Env10/Envelope #10: "297 684"
+*PaperDimension EnvC5/Envelope C5: "459 649"
+*PaperDimension EnvDL/Envelope DL: "312 624"
+*PaperDimension EnvMonarch/Envelope Monarch: "279 540"
+
+*OpenUI *InputSlot/Media Source: PickOne
+*OrderDependency: 10 AnySetup *InputSlot
+*DefaultInputSlot: Default
+*InputSlot Default/Default: "<</MediaPosition 0>>setpagedevice"
+*InputSlot Auto/Automatically Select: "<</MediaPosition 0>>setpagedevice"
+*InputSlot MultiPurpose/Tray 1: "<</MediaPosition 19>>setpagedevice"
+*InputSlot Upper/Tray 2: "<</MediaPosition 1>>setpagedevice"
+*InputSlot Lower/Tray 3: "<</MediaPosition 2>>setpagedevice"
+*InputSlot LargeCapacity/Tray 4: "<</MediaPosition 3>>setpagedevice"
+*InputSlot Manual/Manual Feed: "<</MediaPosition 4>>setpagedevice"
+*InputSlot Envelope/Envelope Feed: "<</MediaPosition 5>>setpagedevice"
+*CloseUI: *InputSlot
+
+*OpenUI *Resolution/Output Resolution: PickOne
+*OrderDependency: 20 AnySetup *Resolution
+*DefaultResolution: 600dpi
+*Resolution 150dpi/150 DPI: "<</HWResolution[150 150]>>setpagedevice"
+*Resolution 300dpi/300 DPI: "<</HWResolution[300 300]>>setpagedevice"
+*Resolution 600dpi/600 DPI: "<</HWResolution[600 600]>>setpagedevice"
+*Resolution 1200dpi/1200 DPI: "<</HWResolution[1200 1200]>>setpagedevice"
+*CloseUI: *Resolution
+
+*OpenUI *Duplex/Double-Sided Printing: PickOne
+*OrderDependency: 20 AnySetup *Duplex
+*DefaultDuplex: None
+*Duplex None/Off: "<</Duplex false>>setpagedevice"
+*Duplex DuplexNoTumble/Long Edge (Standard): "<</Duplex true/Tumble false>>setpagedevice"
+*Duplex DuplexTumble/Short Edge (Flip): "<</Duplex true/Tumble true>>setpagedevice"
+*CloseUI: *Duplex
+
+*OpenGroup: InstallableOptions
+*OpenUI *OptionDuplex/Duplexer: Boolean
+*DefaultOptionDuplex: False
+*OptionDuplex True/Installed: ""
+*OptionDuplex False/Not Installed: ""
+*CloseUI: *OptionDuplex
+*CloseGroup: InstallableOptions
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+*%
+*%
diff --git a/scripting/perl/CUPS.pm b/scripting/perl/CUPS.pm
new file mode 100644
index 000000000..5f2ed5f14
--- /dev/null
+++ b/scripting/perl/CUPS.pm
@@ -0,0 +1,144 @@
+package CUPS;
+
+use 5.006;
+use strict;
+use warnings;
+use Carp;
+
+require Exporter;
+require DynaLoader;
+use AutoLoader;
+
+our @ISA = qw(Exporter DynaLoader);
+
+# Items to export into callers namespace by default. Note: do not export
+# names by default without a very good reason. Use EXPORT_OK instead.
+# Do not simply export all your public functions/methods/constants.
+
+# This allows declaration use CUPS ':all';
+# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
+# will save memory.
+our %EXPORT_TAGS = ( 'all' => [ qw(
+ CUPS_DATE_ANY
+ CUPS_VERSION
+ HTTP_MAX_BUFFER
+ HTTP_MAX_HOST
+ HTTP_MAX_URI
+ HTTP_MAX_VALUE
+ IPP_MAX_NAME
+ IPP_MAX_VALUES
+ IPP_PORT
+ PPD_MAX_LINE
+ PPD_MAX_NAME
+ PPD_MAX_TEXT
+ PPD_VERSION
+) ] );
+
+our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
+
+our @EXPORT = qw(
+ CUPS_DATE_ANY
+ CUPS_VERSION
+ HTTP_MAX_BUFFER
+ HTTP_MAX_HOST
+ HTTP_MAX_URI
+ HTTP_MAX_VALUE
+ IPP_MAX_NAME
+ IPP_MAX_VALUES
+ IPP_PORT
+ PPD_MAX_LINE
+ PPD_MAX_NAME
+ PPD_MAX_TEXT
+ PPD_VERSION
+);
+our $VERSION = '1.2';
+
+sub AUTOLOAD {
+ # This AUTOLOAD is used to 'autoload' constants from the constant()
+ # XS function. If a constant is not found then control is passed
+ # to the AUTOLOAD in AutoLoader.
+
+ my $constname;
+ our $AUTOLOAD;
+ ($constname = $AUTOLOAD) =~ s/.*:://;
+ croak "& not defined" if $constname eq 'constant';
+ my $val = constant($constname, @_ ? $_[0] : 0);
+ if ($! != 0) {
+ if ($! =~ /Invalid/ || $!{EINVAL}) {
+ $AutoLoader::AUTOLOAD = $AUTOLOAD;
+ goto &AutoLoader::AUTOLOAD;
+ }
+ else {
+ croak "Your vendor has not defined CUPS macro $constname";
+ }
+ }
+ {
+ no strict 'refs';
+ # Fixed between 5.005_53 and 5.005_61
+ if ($] >= 5.00561) {
+ *$AUTOLOAD = sub () { $val };
+ }
+ else {
+ *$AUTOLOAD = sub { $val };
+ }
+ }
+ goto &$AUTOLOAD;
+}
+
+bootstrap CUPS $VERSION;
+
+# Preloaded methods go here.
+
+# Autoload methods go after =cut, and are processed by the autosplit program.
+
+1;
+__END__
+# Below is stub documentation for your module. You better edit it!
+
+=head1 NAME
+
+CUPS - Perl extension for blah blah blah
+
+=head1 SYNOPSIS
+
+ use CUPS;
+ blah blah blah
+
+=head1 DESCRIPTION
+
+Stub documentation for CUPS, created by h2xs. It looks like the
+author of the extension was negligent enough to leave the stub
+unedited.
+
+Blah blah blah.
+
+=head2 EXPORT
+
+None by default.
+
+=head2 Exportable constants
+
+ CUPS_DATE_ANY
+ CUPS_VERSION
+ HTTP_MAX_BUFFER
+ HTTP_MAX_HOST
+ HTTP_MAX_URI
+ HTTP_MAX_VALUE
+ IPP_MAX_NAME
+ IPP_MAX_VALUES
+ IPP_PORT
+ PPD_MAX_LINE
+ PPD_MAX_NAME
+ PPD_MAX_TEXT
+ PPD_VERSION
+
+
+=head1 AUTHOR
+
+A. U. Thor, E<lt>a.u.thor@a.galaxy.far.far.awayE<gt>
+
+=head1 SEE ALSO
+
+L<perl>.
+
+=cut
diff --git a/scripting/perl/CUPS.xs b/scripting/perl/CUPS.xs
new file mode 100644
index 000000000..efaf6dc7a
--- /dev/null
+++ b/scripting/perl/CUPS.xs
@@ -0,0 +1,270 @@
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#include <cups/cups.h>
+#include <cups/http.h>
+#include <cups/ipp.h>
+#include <cups/language.h>
+#include <cups/ppd.h>
+
+static int
+not_here(char *s)
+{
+ croak("%s not implemented on this architecture", s);
+ return -1;
+}
+
+static double
+constant_PPD_M(char *name, int len, int arg)
+{
+ if (5 + 3 >= len ) {
+ errno = EINVAL;
+ return 0;
+ }
+ switch (name[5 + 3]) {
+ case 'L':
+ if (strEQ(name + 5, "AX_LINE")) { /* PPD_M removed */
+#ifdef PPD_MAX_LINE
+ return PPD_MAX_LINE;
+#else
+ goto not_there;
+#endif
+ }
+ case 'N':
+ if (strEQ(name + 5, "AX_NAME")) { /* PPD_M removed */
+#ifdef PPD_MAX_NAME
+ return PPD_MAX_NAME;
+#else
+ goto not_there;
+#endif
+ }
+ case 'T':
+ if (strEQ(name + 5, "AX_TEXT")) { /* PPD_M removed */
+#ifdef PPD_MAX_TEXT
+ return PPD_MAX_TEXT;
+#else
+ goto not_there;
+#endif
+ }
+ }
+ errno = EINVAL;
+ return 0;
+
+not_there:
+ errno = ENOENT;
+ return 0;
+}
+
+static double
+constant_P(char *name, int len, int arg)
+{
+ if (1 + 3 >= len ) {
+ errno = EINVAL;
+ return 0;
+ }
+ switch (name[1 + 3]) {
+ case 'M':
+ if (!strnEQ(name + 1,"PD_", 3))
+ break;
+ return constant_PPD_M(name, len, arg);
+ case 'V':
+ if (strEQ(name + 1, "PD_VERSION")) { /* P removed */
+#ifdef PPD_VERSION
+ return PPD_VERSION;
+#else
+ goto not_there;
+#endif
+ }
+ }
+ errno = EINVAL;
+ return 0;
+
+not_there:
+ errno = ENOENT;
+ return 0;
+}
+
+static double
+constant_H(char *name, int len, int arg)
+{
+ if (1 + 8 >= len ) {
+ errno = EINVAL;
+ return 0;
+ }
+ switch (name[1 + 8]) {
+ case 'B':
+ if (strEQ(name + 1, "TTP_MAX_BUFFER")) { /* H removed */
+#ifdef HTTP_MAX_BUFFER
+ return HTTP_MAX_BUFFER;
+#else
+ goto not_there;
+#endif
+ }
+ case 'H':
+ if (strEQ(name + 1, "TTP_MAX_HOST")) { /* H removed */
+#ifdef HTTP_MAX_HOST
+ return HTTP_MAX_HOST;
+#else
+ goto not_there;
+#endif
+ }
+ case 'U':
+ if (strEQ(name + 1, "TTP_MAX_URI")) { /* H removed */
+#ifdef HTTP_MAX_URI
+ return HTTP_MAX_URI;
+#else
+ goto not_there;
+#endif
+ }
+ case 'V':
+ if (strEQ(name + 1, "TTP_MAX_VALUE")) { /* H removed */
+#ifdef HTTP_MAX_VALUE
+ return HTTP_MAX_VALUE;
+#else
+ goto not_there;
+#endif
+ }
+ }
+ errno = EINVAL;
+ return 0;
+
+not_there:
+ errno = ENOENT;
+ return 0;
+}
+
+static double
+constant_IPP_M(char *name, int len, int arg)
+{
+ if (5 + 3 >= len ) {
+ errno = EINVAL;
+ return 0;
+ }
+ switch (name[5 + 3]) {
+ case 'N':
+ if (strEQ(name + 5, "AX_NAME")) { /* IPP_M removed */
+#ifdef IPP_MAX_NAME
+ return IPP_MAX_NAME;
+#else
+ goto not_there;
+#endif
+ }
+ case 'V':
+ if (strEQ(name + 5, "AX_VALUES")) { /* IPP_M removed */
+#ifdef IPP_MAX_VALUES
+ return IPP_MAX_VALUES;
+#else
+ goto not_there;
+#endif
+ }
+ }
+ errno = EINVAL;
+ return 0;
+
+not_there:
+ errno = ENOENT;
+ return 0;
+}
+
+static double
+constant_I(char *name, int len, int arg)
+{
+ if (1 + 3 >= len ) {
+ errno = EINVAL;
+ return 0;
+ }
+ switch (name[1 + 3]) {
+ case 'M':
+ if (!strnEQ(name + 1,"PP_", 3))
+ break;
+ return constant_IPP_M(name, len, arg);
+ case 'P':
+ if (strEQ(name + 1, "PP_PORT")) { /* I removed */
+#ifdef IPP_PORT
+ return IPP_PORT;
+#else
+ goto not_there;
+#endif
+ }
+ }
+ errno = EINVAL;
+ return 0;
+
+not_there:
+ errno = ENOENT;
+ return 0;
+}
+
+static double
+constant_C(char *name, int len, int arg)
+{
+ if (1 + 4 >= len ) {
+ errno = EINVAL;
+ return 0;
+ }
+ switch (name[1 + 4]) {
+ case 'D':
+ if (strEQ(name + 1, "UPS_DATE_ANY")) { /* C removed */
+#ifdef CUPS_DATE_ANY
+ return CUPS_DATE_ANY;
+#else
+ goto not_there;
+#endif
+ }
+ case 'V':
+ if (strEQ(name + 1, "UPS_VERSION")) { /* C removed */
+#ifdef CUPS_VERSION
+ return CUPS_VERSION;
+#else
+ goto not_there;
+#endif
+ }
+ }
+ errno = EINVAL;
+ return 0;
+
+not_there:
+ errno = ENOENT;
+ return 0;
+}
+
+static double
+constant(char *name, int len, int arg)
+{
+ errno = 0;
+ switch (name[0 + 0]) {
+ case 'C':
+ return constant_C(name, len, arg);
+ case 'H':
+ return constant_H(name, len, arg);
+ case 'I':
+ return constant_I(name, len, arg);
+ case 'P':
+ return constant_P(name, len, arg);
+ }
+ errno = EINVAL;
+ return 0;
+
+not_there:
+ errno = ENOENT;
+ return 0;
+}
+
+
+MODULE = CUPS PACKAGE = CUPS
+
+
+double
+constant(sv,arg)
+ PREINIT:
+ STRLEN len;
+ INPUT:
+ SV * sv
+ char * s = SvPV(sv, len);
+ int arg
+ CODE:
+ RETVAL = constant(s,len,arg);
+ OUTPUT:
+ RETVAL
+
diff --git a/scripting/perl/Makefile.PL b/scripting/perl/Makefile.PL
new file mode 100644
index 000000000..f5e4bdd27
--- /dev/null
+++ b/scripting/perl/Makefile.PL
@@ -0,0 +1,17 @@
+use ExtUtils::MakeMaker;
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+WriteMakefile(
+ 'NAME' => 'CUPS',
+ 'VERSION_FROM' => 'CUPS.pm', # finds $VERSION
+ 'PREREQ_PM' => {}, # e.g., Module::Name => 1.1
+ ($] >= 5.005 ? ## Add these new keywords supported since 5.005
+ (ABSTRACT_FROM => 'CUPS.pm', # retrieve abstract from module
+ AUTHOR => 'A. U. Thor <a.u.thor@a.galaxy.far.far.away>') : ()),
+ 'LIBS' => ['-lcups '], # e.g., '-lm'
+ 'DEFINE' => '', # e.g., '-DHAVE_SOMETHING'
+ # Insert -I. if you add *.h files later:
+ 'INC' => '', # e.g., '-I/usr/include/other'
+ # Un-comment this if you add C files to link with later:
+ # 'OBJECT' => '$(O_FILES)', # link all the C files too
+);
diff --git a/scripting/perl/README b/scripting/perl/README
new file mode 100644
index 000000000..ddf8c228e
--- /dev/null
+++ b/scripting/perl/README
@@ -0,0 +1,35 @@
+CUPS version 1.2
+================
+
+The README is used to introduce the module and provide instructions on
+how to install the module, any machine dependencies it may have (for
+example C compilers and installed libraries) and any other information
+that should be provided before the module is installed.
+
+A README file is required for CPAN modules since CPAN extracts the
+README file from a module distribution so that people browsing the
+archive can use it get an idea of the modules uses. It is usually a
+good idea to provide version information here so that people can
+decide whether fixes for the module are worth downloading.
+
+INSTALLATION
+
+To install this module type the following:
+
+ perl Makefile.PL
+ make
+ make test
+ make install
+
+DEPENDENCIES
+
+This module requires these other modules and libraries:
+
+ blah blah blah
+
+COPYRIGHT AND LICENSE
+
+Put the correct copyright and license information here.
+
+Copyright (C) 2002 A. U. Thor blah blah blah
+
diff --git a/scripting/perl/test.pl b/scripting/perl/test.pl
new file mode 100644
index 000000000..acf31916b
--- /dev/null
+++ b/scripting/perl/test.pl
@@ -0,0 +1,17 @@
+# Before `make install' is performed this script should be runnable with
+# `make test'. After `make install' it should work as `perl test.pl'
+
+#########################
+
+# change 'tests => 1' to 'tests => last_test_to_print';
+
+use Test;
+BEGIN { plan tests => 1 };
+use CUPS;
+ok(1); # If we made it this far, we're ok.
+
+#########################
+
+# Insert your test code below, the Test module is use()ed here so read
+# its man page ( perldoc Test ) for help writing this test script.
+
diff --git a/scripting/php/README b/scripting/php/README
new file mode 100644
index 000000000..4af74cc63
--- /dev/null
+++ b/scripting/php/README
@@ -0,0 +1,154 @@
+README - 02/25/2006
+-------------------
+
+INTRODUCTION
+
+ This directory contains a dynamically loadable CUPS extension
+ module for PHP 4 and 5. The CUPS 1.2 module has been
+ substantially updated to provide an API more consistent with
+ the C API and is NOT compatible with the CUPS 1.1 module.
+
+
+COMPILING AND INSTALLING
+
+ Run "make" to compile the PHP CUPS extension:
+
+ make
+
+ To install it, type:
+
+ make install
+
+
+BUG REPORTS
+
+ Bug reports and enhancement requests can be submitted via the
+ form at:
+
+ https://bugs.linuxfoundation.org/
+
+ Use "OpenPrinting" as product and "cups-filters" as component.
+
+
+QUICK REFERENCE DOCUMENTATION
+
+ In lieu of actual documentation, the following definitions
+ can be used as a quick reference to the supported functions:
+
+
+ CUPS_CANCEL_JOB
+
+ Cancels a job on the named destination:
+
+ bool cups_cancel_job(string dest, int id)
+
+ The return value is TRUE on success and FALSE on failure.
+
+ Example:
+
+ if (!cups_cancel_job("myprinter", 123))
+ print("Unable to cancel job: " . cups_last_error_string() . "\n");
+
+
+ CUPS_GET_DESTS
+
+ Gets a list of available destinations:
+
+ array cups_get_dests()
+
+ The return value is an array of objects with the following
+ properties:
+
+ name The name of the printer or class
+ instance The instance of the printer or class
+ is_default TRUE if the printer or class is the default destination
+ options Associative array of options and their values
+
+ Example:
+
+ $dest = cups_get_dests();
+
+
+ CUPS_GET_JOBS
+
+ Gets a list of jobs:
+
+ array cups_get_jobs(string dest, bool myjobs, int completed)
+
+ The "dest" string can be blank for jobs on all destinations.
+ Pass TRUE for "myjobs" to only get jobs for the current user.
+ The "completed" argument can be 0 for pending jobs, 1 for
+ completed jobs, and -1 for all jobs.
+
+ The return value is an array of objects with the following
+ properties:
+
+ id The job ID
+ dest Printer or class name
+ title Title/job name
+ user User the submitted the job
+ format Document format
+ state Job state
+ size Size in kilobytes
+ priority Priority (1-100)
+ completed_time Time the job was completed
+ creation_time Time the job was created
+ processing_time Time the job was processed
+
+ Example:
+
+ $jobs = cups_get_jobs("", FALSE, -1);
+
+
+ CUPS_LAST_ERROR
+
+ Returns the IPP status code for the most recent request:
+
+ int cups_last_error()
+
+ Example:
+
+ $error = cups_last_error();
+
+
+ CUPS_LAST_ERROR_STRING
+
+ Returns the IPP status-message string for the most recent request:
+
+ string cups_last_error_string()
+
+ Example:
+
+ $message = cups_last_error_string();
+
+
+ CUPS_PRINT_FILE
+
+ Prints a single file to a printer or class:
+
+ int cups_print_file(string dest, string filename, string title,
+ array options)
+
+ The return value is the job ID or 0 if there was an error.
+
+ Example:
+
+ $options = array("name" => "value", "name2" => "value2");
+ $id = cups_print_file("dest", "filename", "title", $options);
+
+
+ CUPS_PRINT_FILES
+
+ Prints one or more files to a printer or class:
+
+ int cups_print_files(string dest, array files, string title,
+ array options);
+
+ The return value is the job ID or 0 if there was an error.
+
+ Example:
+
+ $files = array("file1", "file2", "file3");
+ $options = array("name" => "value", "name2" => "value2");
+ $id = cups_print_file("dest", $files, "title", $options);
+
diff --git a/scripting/php/phpcups.c b/scripting/php/phpcups.c
new file mode 100644
index 000000000..c8fa57e47
--- /dev/null
+++ b/scripting/php/phpcups.c
@@ -0,0 +1,480 @@
+/*
+ * Printing utilities for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ *
+ * Contents:
+ *
+ * cups_convert_options() - Convert a PHP options array to a CUPS options array.
+ * zm_startup_phpcups() - Initialize the CUPS module.
+ * zif_cups_cancel_job() - Cancel a job.
+ * zif_cups_get_dests() - Get a list of printers and classes.
+ * zif_cups_get_jobs() - Get a list of jobs.
+ * zif_cups_last_error() - Return the last IPP status code.
+ * zif_cups_last_error_string() - Return the last IPP status
+ * zif_cups_print_file() - Print a single file.
+ * zif_cups_print_files() - Print multiple files.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <cups/string-private.h>
+#include "php.h"
+#include "php_ini.h"
+#include "ext/standard/info.h"
+#include "phpcups.h"
+
+
+/*
+ * PHP function list...
+ */
+
+function_entry phpcups_functions[] =
+{
+ PHP_FE(cups_cancel_job, NULL)
+ PHP_FE(cups_get_dests, NULL)
+ PHP_FE(cups_get_jobs, NULL)
+ PHP_FE(cups_last_error, NULL)
+ PHP_FE(cups_last_error_string, NULL)
+ PHP_FE(cups_print_file, NULL)
+ PHP_FE(cups_print_files, NULL)
+ {NULL, NULL, NULL}
+};
+
+
+/*
+ * PHP module info...
+ */
+
+zend_module_entry phpcups_module_entry =
+{
+ STANDARD_MODULE_HEADER,
+ "phpcups",
+ phpcups_functions,
+ PHP_MINIT(phpcups),
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ CUPS_SVERSION,
+ STANDARD_MODULE_PROPERTIES
+};
+
+
+ZEND_GET_MODULE(phpcups)
+
+
+/*
+ * 'cups_convert_options()' - Convert a PHP options array to a CUPS options array.
+ */
+
+static int /* O - Number of options */
+cups_convert_options(
+ zval *optionsobj, /* I - Options array object */
+ cups_option_t **options) /* O - Options */
+{
+ int num_options; /* Number of options */
+ HashTable *ht; /* Option array hash table */
+ Bucket *current; /* Current element in array */
+ zval *value; /* Current value in array */
+ char temp[255]; /* String value for numbers */
+
+
+ ht = Z_ARRVAL_P(optionsobj);
+ num_options = 0;
+
+ for (current = ht->pListHead; current; current = current->pListNext)
+ {
+ value = (zval *)current->pDataPtr;
+
+ switch (Z_TYPE_P(value))
+ {
+ case IS_LONG :
+ sprintf(temp, "%ld", Z_LVAL_P(value));
+ num_options = cupsAddOption(current->arKey, temp, num_options,
+ options);
+ break;
+
+ case IS_DOUBLE :
+ sprintf(temp, "%g", Z_DVAL_P(value));
+ num_options = cupsAddOption(current->arKey, temp, num_options,
+ options);
+ break;
+
+ case IS_BOOL :
+ num_options = cupsAddOption(current->arKey,
+ Z_BVAL_P(value) ? "true" : "false",
+ num_options, options);
+ break;
+
+ case IS_STRING :
+ num_options = cupsAddOption(current->arKey, Z_STRVAL_P(value),
+ num_options, options);
+ break;
+ }
+ }
+
+ return (num_options);
+}
+
+
+/*
+ * 'zm_startup_phpcups()' - Initialize the CUPS module.
+ */
+
+PHP_MINIT_FUNCTION(phpcups)
+{
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_LOCAL", CUPS_PRINTER_LOCAL, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_CLASS", CUPS_PRINTER_CLASS, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_REMOTE", CUPS_PRINTER_REMOTE, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_BW", CUPS_PRINTER_BW, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_COLOR", CUPS_PRINTER_COLOR, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_DUPLEX", CUPS_PRINTER_DUPLEX, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_STAPLE", CUPS_PRINTER_STAPLE, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_COPIES", CUPS_PRINTER_COPIES, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_COLLATE", CUPS_PRINTER_COLLATE, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_PUNCH", CUPS_PRINTER_PUNCH, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_COVER", CUPS_PRINTER_COVER, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_BIND", CUPS_PRINTER_BIND, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_SORT", CUPS_PRINTER_SORT, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_SMALL", CUPS_PRINTER_SMALL, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_MEDIUM", CUPS_PRINTER_MEDIUM, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_LARGE", CUPS_PRINTER_LARGE, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_VARIABLE", CUPS_PRINTER_VARIABLE, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_IMPLICIT", CUPS_PRINTER_IMPLICIT, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_DEFAULT", CUPS_PRINTER_DEFAULT, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_FAX", CUPS_PRINTER_FAX, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_REJECTING", CUPS_PRINTER_REJECTING, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_DELETE", CUPS_PRINTER_DELETE, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_NOT_SHARED", CUPS_PRINTER_NOT_SHARED, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_AUTHENTICATED", CUPS_PRINTER_AUTHENTICATED, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_COMMANDS", CUPS_PRINTER_COMMANDS, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_DISCOVERED", CUPS_PRINTER_DISCOVERED, CONST_CS);
+ REGISTER_LONG_CONSTANT("CUPS_PRINTER_OPTIONS", CUPS_PRINTER_OPTIONS, CONST_CS);
+
+ REGISTER_LONG_CONSTANT("IPP_OK", IPP_OK, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_OK_SUBST", IPP_OK_SUBST, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_OK_CONFLICT", IPP_OK_CONFLICT, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_OK_IGNORED_SUBSCRIPTIONS", IPP_OK_IGNORED_SUBSCRIPTIONS, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_OK_IGNORED_NOTIFICATIONS", IPP_OK_IGNORED_NOTIFICATIONS, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_OK_TOO_MANY_EVENTS", IPP_OK_TOO_MANY_EVENTS, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_OK_BUT_CANCEL_SUBSCRIPTION", IPP_OK_BUT_CANCEL_SUBSCRIPTION, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_OK_EVENTS_COMPLETE", IPP_OK_EVENTS_COMPLETE, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_REDIRECTION_OTHER_SITE", IPP_REDIRECTION_OTHER_SITE, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_BAD_REQUEST", IPP_BAD_REQUEST, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_FORBIDDEN", IPP_FORBIDDEN, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_NOT_AUTHENTICATED", IPP_NOT_AUTHENTICATED, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_NOT_AUTHORIZED", IPP_NOT_AUTHORIZED, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_NOT_POSSIBLE", IPP_NOT_POSSIBLE, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_TIMEOUT", IPP_TIMEOUT, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_NOT_FOUND", IPP_NOT_FOUND, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_GONE", IPP_GONE, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_REQUEST_ENTITY", IPP_REQUEST_ENTITY, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_REQUEST_VALUE", IPP_REQUEST_VALUE, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_DOCUMENT_FORMAT", IPP_DOCUMENT_FORMAT, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_ATTRIBUTES", IPP_ATTRIBUTES, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_URI_SCHEME", IPP_URI_SCHEME, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_CHARSET", IPP_CHARSET, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_CONFLICT", IPP_CONFLICT, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_COMPRESSION_NOT_SUPPORTED", IPP_COMPRESSION_NOT_SUPPORTED, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_COMPRESSION_ERROR", IPP_COMPRESSION_ERROR, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_DOCUMENT_FORMAT_ERROR", IPP_DOCUMENT_FORMAT_ERROR, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_DOCUMENT_ACCESS_ERROR", IPP_DOCUMENT_ACCESS_ERROR, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_ATTRIBUTES_NOT_SETTABLE", IPP_ATTRIBUTES_NOT_SETTABLE, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_IGNORED_ALL_SUBSCRIPTIONS", IPP_IGNORED_ALL_SUBSCRIPTIONS, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_TOO_MANY_SUBSCRIPTIONS", IPP_TOO_MANY_SUBSCRIPTIONS, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_IGNORED_ALL_NOTIFICATIONS", IPP_IGNORED_ALL_NOTIFICATIONS, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_PRINT_SUPPORT_FILE_NOT_FOUND", IPP_PRINT_SUPPORT_FILE_NOT_FOUND, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_INTERNAL_ERROR", IPP_INTERNAL_ERROR, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_OPERATION_NOT_SUPPORTED", IPP_OPERATION_NOT_SUPPORTED, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_SERVICE_UNAVAILABLE", IPP_SERVICE_UNAVAILABLE, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_VERSION_NOT_SUPPORTED", IPP_VERSION_NOT_SUPPORTED, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_DEVICE_ERROR", IPP_DEVICE_ERROR, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_TEMPORARY_ERROR", IPP_TEMPORARY_ERROR, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_NOT_ACCEPTING", IPP_NOT_ACCEPTING, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_PRINTER_BUSY", IPP_PRINTER_BUSY, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_ERROR_JOB_CANCELLED", IPP_ERROR_JOB_CANCELLED, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_MULTIPLE_JOBS_NOT_SUPPORTED", IPP_MULTIPLE_JOBS_NOT_SUPPORTED, CONST_CS);
+ REGISTER_LONG_CONSTANT("IPP_PRINTER_IS_DEACTIVATED", IPP_PRINTER_IS_DEACTIVATED, CONST_CS);
+
+ return (SUCCESS);
+}
+
+/*
+ * 'zif_cups_cancel_job()' - Cancel a job.
+ */
+
+PHP_FUNCTION(cups_cancel_job)
+{
+ char *dest; /* Destination */
+ int dest_len, /* Length of destination */
+ id; /* Job ID */
+
+
+ if (ZEND_NUM_ARGS() != 2 ||
+ zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &dest, &dest_len, &id))
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ RETURN_LONG(cupsCancelJob(dest, id));
+}
+
+
+/*
+ * 'zif_cups_get_dests()' - Get a list of printers and classes.
+ */
+
+PHP_FUNCTION(cups_get_dests)
+{
+ int i, j, /* Looping vars */
+ num_dests; /* Number of destinations */
+ cups_dest_t *dests, /* Destinations */
+ *dest; /* Current destination */
+ cups_option_t *option; /* Current option */
+ zval *destobj, /* Destination object */
+ *optionsobj; /* Options object */
+
+
+ if (ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ if ((num_dests = cupsGetDests(&dests)) <= 0)
+ {
+ RETURN_NULL();
+ }
+
+ if (array_init(return_value) == SUCCESS)
+ {
+ for (i = 0, dest = dests; i < num_dests; i ++, dest ++)
+ {
+ MAKE_STD_ZVAL(destobj);
+
+ if (object_init(destobj) == SUCCESS)
+ {
+ /*
+ * Add properties to the destination for each of the cups_dest_t
+ * members...
+ */
+
+ add_property_string(destobj, "name", dest->name, 1);
+ add_property_string(destobj, "instance",
+ dest->instance ? dest->instance : "", 1);
+ add_property_long(destobj, "is_default", dest->is_default);
+
+ /*
+ * Create an associative array for the options...
+ */
+
+ MAKE_STD_ZVAL(optionsobj);
+
+ if (array_init(optionsobj) == SUCCESS)
+ {
+ for (j = 0, option = dest->options;
+ j < dest->num_options;
+ j ++, option ++)
+ add_assoc_string(optionsobj, option->name, option->value, 1);
+
+ add_property_zval(destobj, "options", optionsobj);
+ }
+
+ add_index_zval(return_value, i, destobj);
+ }
+ }
+ }
+
+ cupsFreeDests(num_dests, dests);
+}
+
+
+/*
+ * 'zif_cups_get_jobs()' - Get a list of jobs.
+ */
+
+PHP_FUNCTION(cups_get_jobs)
+{
+ char *dest; /* Destination */
+ int dest_len, /* Length of destination */
+ myjobs, /* Only show my jobs? */
+ completed; /* Show completed jobs? */
+ int i, /* Looping var */
+ num_jobs; /* Number of jobs */
+ cups_job_t *jobs, /* Jobs */
+ *job; /* Current job */
+ zval *jobobj; /* Job object */
+
+
+
+
+ if (ZEND_NUM_ARGS() != 3 ||
+ zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll", &dest, &dest_len, &myjobs, &completed))
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ if (!*dest)
+ dest = NULL;
+
+ if ((num_jobs = cupsGetJobs(&jobs, dest, myjobs, completed)) <= 0)
+ {
+ RETURN_NULL();
+ }
+
+ if (array_init(return_value) == SUCCESS)
+ {
+ for (i = 0, job = jobs; i < num_jobs; i ++, job ++)
+ {
+ MAKE_STD_ZVAL(jobobj);
+
+ if (object_init(jobobj) == SUCCESS)
+ {
+ /*
+ * Add properties to the job for each of the cups_job_t
+ * members...
+ */
+
+ add_property_long(jobobj, "id", job->id);
+ add_property_string(jobobj, "dest", job->dest, 1);
+ add_property_string(jobobj, "title", job->title, 1);
+ add_property_string(jobobj, "user", job->user, 1);
+ add_property_string(jobobj, "format", job->format, 1);
+ add_property_long(jobobj, "state", job->state);
+ add_property_long(jobobj, "size", job->size);
+ add_property_long(jobobj, "priority", job->priority);
+ add_property_long(jobobj, "completed_time", job->completed_time);
+ add_property_long(jobobj, "creation_time", job->creation_time);
+ add_property_long(jobobj, "processing_time", job->processing_time);
+
+ add_index_zval(return_value, i, jobobj);
+ }
+ }
+ }
+
+ cupsFreeJobs(num_jobs, jobs);
+}
+
+
+/*
+ * 'zif_cups_last_error()' - Return the last IPP status code.
+ */
+
+PHP_FUNCTION(cups_last_error)
+{
+ if (ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ RETURN_LONG(cupsLastError());
+}
+
+
+/*
+ * 'zif_cups_last_error_string()' - Return the last IPP status-message.
+ */
+
+PHP_FUNCTION(cups_last_error_string)
+{
+ if (ZEND_NUM_ARGS() != 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ RETURN_STRING((char *)cupsLastErrorString(), 1);
+}
+
+
+/*
+ * 'zif_cups_print_file()' - Print a single file.
+ */
+
+PHP_FUNCTION(cups_print_file)
+{
+ char *dest; /* Destination */
+ int dest_len; /* Length of destination */
+ char *filename; /* Filename */
+ int filename_len; /* Length of filename */
+ char *title; /* Title */
+ int title_len; /* Length of title */
+ zval *optionsobj; /* Array of options */
+ int num_options; /* Number of options */
+ cups_option_t *options; /* Options */
+ int id; /* Job ID */
+
+
+ if (ZEND_NUM_ARGS() != 4 ||
+ zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sssa", &dest, &dest_len,
+ &filename, &filename_len,
+ &title, &title_len, &optionsobj))
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ num_options = cups_convert_options(optionsobj, &options);
+
+ id = cupsPrintFile(dest, filename, title, num_options, options);
+
+ cupsFreeOptions(num_options, options);
+
+ RETURN_LONG(id);
+}
+
+
+/*
+ * 'zif_cups_print_files()' - Print multiple files.
+ */
+
+PHP_FUNCTION(cups_print_files)
+{
+ char *dest; /* Destination */
+ int dest_len; /* Length of destination */
+ zval *filesobj; /* Files array */
+ int num_files; /* Number of files */
+ const char *files[1000]; /* Files */
+ char *title; /* Title */
+ int title_len; /* Length of title */
+ zval *optionsobj; /* Array of options */
+ int num_options; /* Number of options */
+ cups_option_t *options; /* Options */
+ HashTable *ht2; /* Option array hash table */
+ Bucket *current; /* Current element in array */
+ int id; /* Job ID */
+
+
+ if (ZEND_NUM_ARGS() != 4 ||
+ zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sasa", &dest, &dest_len, &filesobj,
+ &title, &title_len, &optionsobj))
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ ht2 = Z_ARRVAL_P(filesobj);
+ num_files = 0;
+
+ for (current = ht2->pListHead; current; current = current->pListNext)
+ {
+ files[num_files ++] = Z_STRVAL_P(((zval *)current->pDataPtr));
+
+ if (num_files >= (int)(sizeof(files) / sizeof(files[0])))
+ break;
+ }
+
+ num_options = cups_convert_options(optionsobj, &options);
+
+ id = cupsPrintFiles(dest, num_files, files, title, num_options, options);
+
+ cupsFreeOptions(num_options, options);
+
+ RETURN_LONG(id);
+}
+
diff --git a/scripting/php/phpcups.h b/scripting/php/phpcups.h
new file mode 100644
index 000000000..36ca1d5fd
--- /dev/null
+++ b/scripting/php/phpcups.h
@@ -0,0 +1,60 @@
+/*
+ * PHP module include file for CUPS.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1997-2006 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "COPYING"
+ * which should have been included with this file.
+ */
+
+#ifndef PHPCUPS_H
+# define PHPCUPS_H
+
+/*
+ * Include necessary headers...
+ */
+
+# include <cups/cups.h>
+# include <cups/language.h>
+# include <cups/debug-private.h>
+# include <fcntl.h>
+# include <sys/stat.h>
+# if defined(WIN32) || defined(__EMX__)
+# include <io.h>
+# else
+# include <unistd.h>
+# endif /* WIN32 || __EMX__ */
+
+
+/*
+ * Zend definitions...
+ */
+
+extern zend_module_entry phpcups_module_entry;
+# define phpext_phpcups_ptr &phpcups_module_entry
+
+# ifdef PHP_WIN32
+# define PHP_PHPCUPS_API __declspec(dllexport)
+# else
+# define PHP_PHPCUPS_API
+# endif
+
+# ifdef ZTS
+# include "TSRM.h"
+# endif
+
+PHP_MINIT_FUNCTION(phpcups);
+
+PHP_FUNCTION(cups_cancel_job);
+PHP_FUNCTION(cups_get_dests);
+PHP_FUNCTION(cups_get_jobs);
+PHP_FUNCTION(cups_last_error);
+PHP_FUNCTION(cups_last_error_string);
+PHP_FUNCTION(cups_print_file);
+PHP_FUNCTION(cups_print_files);
+
+#endif /* !PHPCUPS_H */
+
diff --git a/scripting/php/phpcups.php b/scripting/php/phpcups.php
new file mode 100755
index 000000000..0386e8d64
--- /dev/null
+++ b/scripting/php/phpcups.php
@@ -0,0 +1,54 @@
+#!/usr/bin/php -f
+<?
+//
+// PHP test script for CUPS.
+//
+// Copyright 2007-2011 by Apple Inc.
+// Copyright 1997-2006 by Easy Software Products, all rights reserved.
+//
+// These coded instructions, statements, and computer programs are the
+// property of Apple Inc. and are protected by Federal copyright
+// law. Distribution and use rights are outlined in the file "COPYING"
+// which should have been included with this file.
+//
+
+// Make sure the module is loaded...
+if(!extension_loaded("phpcups"))
+{
+ dl("phpcups.so");
+}
+
+// Get the list of functions in the module...
+$module = "phpcups";
+$functions = get_extension_funcs($module);
+
+print("Functions available in the $module extension:\n");
+
+foreach ($functions as $func)
+{
+ print("$func\n");
+}
+
+print("\n");
+
+print("cups_get_dests:\n");
+print_r(cups_get_dests());
+
+print("cups_get_jobs(\"\", 0, -1):\n");
+print_r(cups_get_jobs("", 0, -1));
+
+print("cups_print_file(\"test\", \"../../test/testfile.jpg\", "
+ ."\"testfile.jpg\", ...):\n");
+print_r(cups_print_file("test", "../../test/testfile.jpg", "testfile.jpg",
+ array("scaling" => "100",
+ "page-label" => "testfile.jpg")));
+
+print("cups_print_files(\"test\", array(\"../../test/testfile.jpg\", "
+ ."\"../../test/testfile.ps\"), \"testfiles\", ...):\n");
+print_r(cups_print_files("test", array("../../test/testfile.jpg",
+ "../../test/testfile.ps"),
+ "testfiles",
+ array("scaling" => "100",
+ "page-label" => "testfile.jpg")));
+
+?>
diff --git a/test-driver b/test-driver
new file mode 100755
index 000000000..8e575b017
--- /dev/null
+++ b/test-driver
@@ -0,0 +1,148 @@
+#! /bin/sh
+# test-driver - basic testsuite driver script.
+
+scriptversion=2013-07-13.22; # UTC
+
+# Copyright (C) 2011-2014 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+# Make unconditional expansion of undefined variables an error. This
+# helps a lot in preventing typo-related bugs.
+set -u
+
+usage_error ()
+{
+ echo "$0: $*" >&2
+ print_usage >&2
+ exit 2
+}
+
+print_usage ()
+{
+ cat <<END
+Usage:
+ test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
+ [--expect-failure={yes|no}] [--color-tests={yes|no}]
+ [--enable-hard-errors={yes|no}] [--]
+ TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
+The '--test-name', '--log-file' and '--trs-file' options are mandatory.
+END
+}
+
+test_name= # Used for reporting.
+log_file= # Where to save the output of the test script.
+trs_file= # Where to save the metadata of the test run.
+expect_failure=no
+color_tests=no
+enable_hard_errors=yes
+while test $# -gt 0; do
+ case $1 in
+ --help) print_usage; exit $?;;
+ --version) echo "test-driver $scriptversion"; exit $?;;
+ --test-name) test_name=$2; shift;;
+ --log-file) log_file=$2; shift;;
+ --trs-file) trs_file=$2; shift;;
+ --color-tests) color_tests=$2; shift;;
+ --expect-failure) expect_failure=$2; shift;;
+ --enable-hard-errors) enable_hard_errors=$2; shift;;
+ --) shift; break;;
+ -*) usage_error "invalid option: '$1'";;
+ *) break;;
+ esac
+ shift
+done
+
+missing_opts=
+test x"$test_name" = x && missing_opts="$missing_opts --test-name"
+test x"$log_file" = x && missing_opts="$missing_opts --log-file"
+test x"$trs_file" = x && missing_opts="$missing_opts --trs-file"
+if test x"$missing_opts" != x; then
+ usage_error "the following mandatory options are missing:$missing_opts"
+fi
+
+if test $# -eq 0; then
+ usage_error "missing argument"
+fi
+
+if test $color_tests = yes; then
+ # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
+ red='' # Red.
+ grn='' # Green.
+ lgn='' # Light green.
+ blu='' # Blue.
+ mgn='' # Magenta.
+ std='' # No color.
+else
+ red= grn= lgn= blu= mgn= std=
+fi
+
+do_exit='rm -f $log_file $trs_file; (exit $st); exit $st'
+trap "st=129; $do_exit" 1
+trap "st=130; $do_exit" 2
+trap "st=141; $do_exit" 13
+trap "st=143; $do_exit" 15
+
+# Test script is run here.
+"$@" >$log_file 2>&1
+estatus=$?
+
+if test $enable_hard_errors = no && test $estatus -eq 99; then
+ tweaked_estatus=1
+else
+ tweaked_estatus=$estatus
+fi
+
+case $tweaked_estatus:$expect_failure in
+ 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
+ 0:*) col=$grn res=PASS recheck=no gcopy=no;;
+ 77:*) col=$blu res=SKIP recheck=no gcopy=yes;;
+ 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;;
+ *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;;
+ *:*) col=$red res=FAIL recheck=yes gcopy=yes;;
+esac
+
+# Report the test outcome and exit status in the logs, so that one can
+# know whether the test passed or failed simply by looking at the '.log'
+# file, without the need of also peaking into the corresponding '.trs'
+# file (automake bug#11814).
+echo "$res $test_name (exit status: $estatus)" >>$log_file
+
+# Report outcome to console.
+echo "${col}${res}${std}: $test_name"
+
+# Register the test result, and other relevant metadata.
+echo ":test-result: $res" > $trs_file
+echo ":global-test-result: $res" >> $trs_file
+echo ":recheck: $recheck" >> $trs_file
+echo ":copy-in-global-log: $gcopy" >> $trs_file
+
+# 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/utils/cups-browsed-upstart.conf b/utils/cups-browsed-upstart.conf
new file mode 100644
index 000000000..536e1ce98
--- /dev/null
+++ b/utils/cups-browsed-upstart.conf
@@ -0,0 +1,20 @@
+# cups-browsed - Bonjour remote printer browsing daemon
+
+description "cups-browsed - Bonjour remote printer browsing daemon"
+author "Till Kamppeter <till.kamppeter@gmail.com>"
+
+start on (filesystem
+ and (started cups or runlevel [2345]))
+stop on runlevel [016]
+
+respawn
+respawn limit 3 240
+
+pre-start script
+ [ -x /usr/sbin/cups-browsed ]
+ if [ -x /lib/init/apparmor-profile-load ]; then
+ /lib/init/apparmor-profile-load usr.sbin.cups-browsed
+ fi
+end script
+
+exec /usr/sbin/cups-browsed
diff --git a/utils/cups-browsed.8 b/utils/cups-browsed.8
new file mode 100644
index 000000000..cc8374cec
--- /dev/null
+++ b/utils/cups-browsed.8
@@ -0,0 +1,107 @@
+.\"Text automatically generated by txt2man
+.TH cups-browsed 8 "29 June 2013" "" ""
+.SH NAME
+\fBcups-browsed \fP- A daemon for browsing the Bonjour broadcasts of shared, remote CUPS printers
+\fB
+.SH SYNOPSIS
+.nf
+.fam C
+\fBcups-browsed\fP [\fB-v\fP | \fB-d\fP | \fB--debug\fP] [\fB-c\fP \fIconfig-file\fP]
+[\fB-o\fP \fIoption\fB=\fIvalue\fP] [\fB-o\fP '\fIconfig file line\fP'] ...
+[\fB--autoshutdown=\fImode\fP] [\fB--autoshutdown-timeout=\fItimeout\fP]
+[\fB-h\fP | \fB--help\fP | \fB--version\fP]
+
+.fam T
+.fi
+.fam T
+.fi
+.SH DESCRIPTION
+\fBcups-browsed\fP has four independently switchable functions:
+.IP 1. 4
+Browse Bonjour broadcasts of remote printers and create/remove local
+raw queues pointing to these printers.
+.IP 2. 4
+Browse CUPS broadcasts of remote printers and create/remove local raw
+queues pointing to these printers.
+.IP 3. 4
+Browse an LDAP server for printers and create/remove local raw
+queues pointing to these printers.
+.IP 4. 4
+Broadcast local queues with the CUPS protocol.
+.PP
+Note that 2. and 4. are only to allow communication with legacy CUPS servers (1.5.x or older) on the remote machine(s). The standard method to broadcast for shared/network printers to broadcast their presence is Bonjour. The CUPS broadcasting/browsing protocol is deprecated.
+
+cups-browsed can be run permanently (from system boot to shutdown) or on-demand (for example to save resources on mobile devices). For running it on-demand an auto-shutdown feature can be activated to let cups-browsed terminate when it does not have queues any more to take care of.
+
+.SH OPTIONS
+.TP
+.B
+\fB-v\fP, \fB-d\fP, \fB--debug\fP
+Debug mode, verbose logging to stderr
+.TP
+.B
+\fB-l\fP, \fB--logfile\fP
+Debug logging into /var/log/cups/cups-browsed_log file.
+.TP
+.B
+\fB-c\fP \fIconfig-file\fP
+Uses the alternative configuration file \fIconfig-file\fP instead of the standard one.
+.TP
+.B
+\fB-o\fP \fIoption\fB=\fIvalue\fB, -o\fP '\fIconfig file line\fP'
+Supply configuration options via the command line. You can supply any line which also could be put into the configuration file, but note that due to the spaces the line has to be put into quotes, or for a simple key/value pair the space between key and value can get replaced by '='. If command-line-supplied configuration settings are contradicting with the ones in the configuration file, the ones in the configuration file will get used.
+.TP
+.B
+\fB--autoshutdown=mode\fP
+Auto shutdown mode, \fBmode\fP is \fBoff\fP for no auto shutdown, \fBon\fP for auto shutdown being active, and \fBavahi\fP for control by the avahi-daemon being run on-demand, getting auto-shutdown turned off while avahi-daemon is present and on when avahi-daemon is shut down.
+.TP
+.B
+\fB--autoshutdown-on=inactivity-type\fP
+What cups-browsed considers as inactivity for auto-shutdown. \fBinactivity-type\fP set to \fBno-queues\fP (the default) means that auto-shutdown is initiated if there are no queues generated by cups-browsed any more, \fBno-jobs\fP means that auto-shutdown will get initiated if all queues generated by cups-browsed are without jobs.
+.TP
+.B
+\fB--autoshutdown-timeout=timeout\fP
+\fBtimeout\fP tells after how many seconds cups-browsed should shut down if it has no local queues set up for any discovered remote printer any more or jobs on these. Default is 30 seconds. 0 means immediate shutdown.
+.TP
+.B
+\fB-h, --help, --version\fP
+Display usage and version info and do not start the daemon.
+.SH FILES
+/etc/cups/cups-browsed.conf
+.SH SIGNALS
+\fISIGINT, SIGTERM\f1: cups-browsed will shutdown.
+
+\fISIGUSR1\f1: Switches cups-browsed into permanent mode (no auto shutdown).
+
+\fISIGUSR2\f1: Switches cups-browsed into auto shutdown mode.
+
+.SH NOTES
+Please take references to cups 1.6.x to include newer versions.
+Similarly, cups 1.5.x is intended to encompass older versions too.
+.PP
+In environments with only cups 1.6.x servers and clients (plus
+\fBcups-browsed\fP on either server or client or both) the function described in 1.
+enables the automatic discovery of remote queues and their display in
+printing dialogues of applications and with command line tools.
+.PP
+The facility provided by 3. allows printers that are registered in an LDAP
+server to be added as local queues. CUPS servers 1.5.x are able to automatically
+register printers in LDAP. The facility provided by \fBcups-browsed\fP allows
+a filter string to further limit the printers that are browsed from LDAP.
+.PP
+The facility provided by 4. means that servers running cups 1.6.x plus
+\fBcups-browsed\fP can broadcast their local queues so that clients with cups
+1.5.x get these queues automatically available. The outcome of 2. is
+that clients running cups 1.6.x plus \fBcups-browsed\fP can use the CUPS
+broadcasts from servers with cups 1.5.x. As with browsing of Bonjour
+broadcasts, the created local raw queues are available to applications
+and command line tools.
+.SH SEE ALSO
+
+\fBcups-browsed.conf\fP(5)
+.PP
+/usr/share/doc/\fBcups-browsed\fP/README.gz
+.SH AUTHOR
+The authors of \fBcups-browsed\fP are listed in /usr/share/doc/\fBcups-browsed\fP/AUTHORS.
+.PP
+This manual page was written for the Debian Project, but it may be used by others.
diff --git a/utils/cups-browsed.c b/utils/cups-browsed.c
new file mode 100644
index 000000000..d803fca5f
--- /dev/null
+++ b/utils/cups-browsed.c
@@ -0,0 +1,8266 @@
+ /***
+ This file is part of cups-filters.
+
+ This file is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ This file is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+ Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with avahi; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#if defined(__OpenBSD__)
+#include <sys/socket.h>
+#endif /* __OpenBSD__ */
+#include <sys/types.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <ifaddrs.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <time.h>
+#include <signal.h>
+#include <regex.h>
+#include <pthread.h>
+
+#include <glib.h>
+
+#ifdef HAVE_AVAHI
+#include <avahi-client/client.h>
+#include <avahi-client/lookup.h>
+
+#include <avahi-glib/glib-watch.h>
+#include <avahi-common/malloc.h>
+#include <avahi-common/error.h>
+#endif /* HAVE_AVAHI */
+
+#include <gio/gio.h>
+
+
+#ifdef HAVE_LDAP
+# ifdef __sun
+# include <lber.h>
+# endif /* __sun */
+# include <ldap.h>
+# ifdef HAVE_LDAP_SSL_H
+# include <ldap_ssl.h>
+# endif /* HAVE_LDAP_SSL_H */
+#endif /* HAVE_LDAP */
+
+
+#ifdef HAVE_LDAP
+LDAP *BrowseLDAPHandle = NULL;
+ /* Handle to LDAP server */
+char *BrowseLDAPBindDN = NULL,
+ /* LDAP login DN */
+ *BrowseLDAPDN = NULL,
+ /* LDAP search DN */
+ *BrowseLDAPPassword = NULL,
+ /* LDAP login password */
+ *BrowseLDAPServer = NULL,
+ /* LDAP server to use */
+ *BrowseLDAPFilter = NULL;
+ /* LDAP query filter */
+int BrowseLDAPUpdate = TRUE,
+ /* enables LDAP updates */
+ BrowseLDAPInitialised = FALSE;
+ /* the init stuff has been done */
+# ifdef HAVE_LDAP_SSL
+char *BrowseLDAPCACertFile = NULL;
+ /* LDAP CA CERT file to use */
+# endif /* HAVE_LDAP_SSL */
+#endif /* HAVE_LDAP */
+
+
+#ifdef HAVE_LDAP
+#define LDAP_BROWSE_FILTER "(objectclass=cupsPrinter)"
+static LDAP *ldap_connect(void);
+static LDAP *ldap_reconnect(void);
+static void ldap_disconnect(LDAP *ld);
+static int ldap_search_rec(LDAP *ld, char *base, int scope,
+ char *filter, char *attrs[],
+ int attrsonly, LDAPMessage **res);
+static int ldap_getval_firststring(LDAP *ld, LDAPMessage *entry,
+ char *attr, char *retval,
+ unsigned long maxsize);
+static void ldap_freeres(LDAPMessage *entry);
+# ifdef HAVE_LDAP_REBIND_PROC
+# if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+static int ldap_rebind_proc(LDAP *RebindLDAPHandle,
+ LDAP_CONST char *refsp,
+ ber_tag_t request,
+ ber_int_t msgid,
+ void *params);
+# else
+static int ldap_rebind_proc(LDAP *RebindLDAPHandle,
+ char **dnp,
+ char **passwdp,
+ int *authmethodp,
+ int freeit,
+ void *arg);
+# endif /* defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) */
+# endif /* HAVE_LDAP_REBIND_PROC */
+#endif /* HAVE_LDAP */
+
+#include <cups/cups.h>
+#include <cups/ppd.h>
+#include <cups/raster.h>
+#include <cupsfilters/ppdgenerator.h>
+
+#include "cups-notifier.h"
+
+/* Attribute to mark a CUPS queue as created by us */
+#define CUPS_BROWSED_MARK "cups-browsed"
+
+/* Attribute to tell the implicitclass backend the destination queue for
+ the current job */
+#define CUPS_BROWSED_DEST_PRINTER "cups-browsed-dest-printer"
+
+/* Timeout values in sec */
+#define TIMEOUT_IMMEDIATELY -1
+#define TIMEOUT_CONFIRM 10
+#define TIMEOUT_RETRY 10
+#define TIMEOUT_REMOVE -1
+#define TIMEOUT_CHECK_LIST 2
+
+#define NOTIFY_LEASE_DURATION (24 * 60 * 60)
+#define CUPS_DBUS_NAME "org.cups.cupsd.Notifier"
+#define CUPS_DBUS_PATH "/org/cups/cupsd/Notifier"
+#define CUPS_DBUS_INTERFACE "org.cups.cupsd.Notifier"
+
+#define DEFAULT_CACHEDIR "/var/cache/cups"
+#define DEFAULT_LOGDIR "/var/log/cups"
+#define LOCAL_DEFAULT_PRINTER_FILE "/cups-browsed-local-default-printer"
+#define REMOTE_DEFAULT_PRINTER_FILE "/cups-browsed-remote-default-printer"
+#define SAVE_OPTIONS_FILE "/cups-browsed-options-%s"
+#define DEBUG_LOG_FILE "/cups-browsed_log"
+
+/* Status of remote printer */
+typedef enum printer_status_e {
+ STATUS_UNCONFIRMED = 0, /* Generated in a previous session */
+ STATUS_CONFIRMED, /* Avahi confirms UNCONFIRMED printer */
+ STATUS_TO_BE_CREATED, /* Scheduled for creation */
+ STATUS_DISAPPEARED /* Scheduled for removal */
+} printer_status_t;
+
+/* Data structure for remote printers */
+typedef struct remote_printer_s {
+ char *queue_name;
+ char *location;
+ char *info;
+ char *uri;
+ char *ppd;
+ char *model;
+ char *ifscript;
+ int num_options;
+ cups_option_t *options;
+ printer_status_t status;
+ time_t timeout;
+ void *slave_of;
+ int last_printer;
+ char *host;
+ char *ip;
+ int port;
+ char *service_name;
+ char *type;
+ char *domain;
+ int no_autosave;
+ int netprinter;
+ int is_legacy;
+} remote_printer_t;
+
+/* Data structure for network interfaces */
+typedef struct netif_s {
+ char *address;
+ http_addr_t broadcast;
+} netif_t;
+
+/* Data structures for browse allow/deny rules */
+typedef enum browse_order_e {
+ ORDER_ALLOW_DENY,
+ ORDER_DENY_ALLOW
+} browse_order_t;
+typedef enum allow_type_e {
+ ALLOW_IP,
+ ALLOW_NET,
+ ALLOW_INVALID
+} allow_type_t;
+typedef enum allow_sense_e {
+ ALLOW_ALLOW,
+ ALLOW_DENY
+} allow_sense_t;
+typedef struct allow_s {
+ allow_type_t type;
+ allow_sense_t sense;
+ http_addr_t addr;
+ http_addr_t mask;
+} allow_t;
+
+/* Data structures for browse filter rules */
+typedef enum filter_sense_s {
+ FILTER_MATCH,
+ FILTER_NOT_MATCH
+} filter_sense_t;
+typedef struct browse_filter_s {
+ filter_sense_t sense;
+ char *field;
+ char *regexp;
+ regex_t *cregexp;
+} browse_filter_t;
+
+/* Data structure for a printer discovered using BrowsePoll */
+typedef struct browsepoll_printer_s {
+ char *uri_supported;
+ char *location;
+ char *info;
+} browsepoll_printer_t;
+
+/* Data structure for a BrowsePoll server */
+typedef struct browsepoll_s {
+ char *server;
+ int port;
+ int major;
+ int minor;
+ gboolean can_subscribe;
+ int subscription_id;
+ int sequence_number;
+
+ /* Remember which printers we discovered. This way we can just ask
+ * if anything has changed, and if not we know these printers are
+ * still there. */
+ GList *printers; /* of browsepoll_printer_t */
+} browsepoll_t;
+
+/* Data structure for destination list obtained with cupsEnumDests() */
+typedef struct dest_list_s {
+ int num_dests;
+ cups_dest_t *dests;
+} dest_list_t;
+
+/* Local printer (key is name) */
+typedef struct local_printer_s {
+ char *device_uri;
+ gboolean cups_browsed_controlled;
+} local_printer_t;
+
+/* Browse data to send for local printer */
+typedef struct browse_data_s {
+ int type;
+ int state;
+ char *uri;
+ char *location;
+ char *info;
+ char *make_model;
+ char *browse_options;
+} browse_data_t;
+
+/* Data structure for manual definition of load-balancing clusters */
+typedef struct cluster_s {
+ char *local_queue_name;
+ cups_array_t *members;
+} cluster_t;
+
+/* Ways how to represent the remote printer's IP in the device URI */
+typedef enum ip_based_uris_e {
+ IP_BASED_URIS_NO,
+ IP_BASED_URIS_ANY,
+ IP_BASED_URIS_IPV4_ONLY,
+ IP_BASED_URIS_IPV6_ONLY
+} ip_based_uris_t;
+
+/* Ways how to name local queues for remote printers */
+typedef enum local_queue_naming_e {
+ LOCAL_QUEUE_NAMING_DNSSD,
+ LOCAL_QUEUE_NAMING_MAKE_MODEL,
+ LOCAL_QUEUE_NAMING_REMOTE_NAME
+} local_queue_naming_t;
+
+/* Automatically create queues for IPP network printers: No, only for
+ IPP printers, for all printers */
+typedef enum create_ipp_printer_queues_e {
+ IPP_PRINTERS_NO,
+ IPP_PRINTERS_LOCAL_ONLY,
+ IPP_PRINTERS_PWGRASTER,
+ IPP_PRINTERS_APPLERASTER,
+ IPP_PRINTERS_PCLM,
+ IPP_PRINTERS_PDF,
+ IPP_PRINTERS_DRIVERLESS,
+ IPP_PRINTERS_ALL
+} create_ipp_printer_queues_t;
+
+/* Ways how to set up a queue for an IPP network printer */
+typedef enum ipp_queue_type_e {
+ PPD_YES,
+ PPD_NO
+} ipp_queue_type_t;
+
+/* Ways how we can do load balancing on remote queues with the same name */
+typedef enum load_balancing_type_e {
+ QUEUE_ON_CLIENT,
+ QUEUE_ON_SERVERS
+} load_balancing_type_t;
+
+/* Ways how inactivity for auto-shutdown is defined */
+typedef enum autoshutdown_inactivity_type_e {
+ NO_QUEUES,
+ NO_JOBS
+} autoshutdown_inactivity_type_t;
+
+cups_array_t *remote_printers;
+static char *alt_config_file = NULL;
+static cups_array_t *command_line_config;
+static cups_array_t *netifs;
+static cups_array_t *browseallow;
+static gboolean browseallow_all = FALSE;
+static gboolean browsedeny_all = FALSE;
+static browse_order_t browse_order;
+static cups_array_t *browsefilter;
+
+static GHashTable *local_printers;
+static GHashTable *cups_supported_remote_printers;
+static browsepoll_t *local_printers_context = NULL;
+static http_t *local_conn = NULL;
+static gboolean inhibit_local_printers_update = FALSE;
+
+static GList *browse_data = NULL;
+
+static CupsNotifier *cups_notifier = NULL;
+
+static GMainLoop *gmainloop = NULL;
+#ifdef HAVE_AVAHI
+static AvahiGLibPoll *glib_poll = NULL;
+static AvahiClient *client = NULL;
+static AvahiServiceBrowser *sb1 = NULL, *sb2 = NULL;
+static int avahi_present = 0;
+#endif /* HAVE_AVAHI */
+#ifdef HAVE_LDAP
+static const char * const ldap_attrs[] =/* CUPS LDAP attributes */
+ {
+ "printerDescription",
+ "printerLocation",
+ "printerMakeAndModel",
+ "printerType",
+ "printerURI",
+ NULL
+ };
+#endif /* HAVE_LDAP */
+static guint queues_timer_id = 0;
+static int browsesocket = -1;
+
+#define BROWSE_DNSSD (1<<0)
+#define BROWSE_CUPS (1<<1)
+#define BROWSE_LDAP (1<<2)
+static unsigned int BrowseLocalProtocols = 0;
+static unsigned int BrowseRemoteProtocols = BROWSE_DNSSD;
+static unsigned int BrowseInterval = 60;
+static unsigned int BrowseTimeout = 300;
+static uint16_t BrowsePort = 631;
+static browsepoll_t **BrowsePoll = NULL;
+static size_t NumBrowsePoll = 0;
+static guint update_netifs_sourceid = 0;
+static char local_server_str[1024];
+static char *DomainSocket = NULL;
+static unsigned int HttpLocalTimeout = 5;
+static unsigned int HttpRemoteTimeout = 10;
+static ip_based_uris_t IPBasedDeviceURIs = IP_BASED_URIS_NO;
+static local_queue_naming_t LocalQueueNamingRemoteCUPS=LOCAL_QUEUE_NAMING_DNSSD;
+static local_queue_naming_t LocalQueueNamingIPPPrinter=LOCAL_QUEUE_NAMING_DNSSD;
+static unsigned int OnlyUnsupportedByCUPS = 0;
+static unsigned int CreateRemoteRawPrinterQueues = 0;
+static unsigned int CreateRemoteCUPSPrinterQueues = 1;
+#ifdef DRIVERLESS_IPP_PRINTERS_AUTO_SETUP
+static create_ipp_printer_queues_t CreateIPPPrinterQueues = IPP_PRINTERS_DRIVERLESS;
+#else
+static create_ipp_printer_queues_t CreateIPPPrinterQueues = IPP_PRINTERS_LOCAL_ONLY;
+#endif
+static ipp_queue_type_t IPPPrinterQueueType = PPD_YES;
+static int NewIPPPrinterQueuesShared = 0;
+static int AutoClustering = 1;
+static cups_array_t *clusters;
+static load_balancing_type_t LoadBalancingType = QUEUE_ON_CLIENT;
+static const char *DefaultOptions = NULL;
+static int terminating = 0; /* received SIGTERM, ignore callbacks,
+ break loops */
+static int in_shutdown = 0;
+static int autoshutdown = 0;
+static int autoshutdown_avahi = 0;
+static int autoshutdown_timeout = 30;
+static autoshutdown_inactivity_type_t autoshutdown_on = NO_QUEUES;
+static guint autoshutdown_exec_id = 0;
+static const char *default_printer = NULL;
+
+static int debug_stderr = 0;
+static int debug_logfile = 0;
+static FILE *lfp = NULL;
+
+static char cachedir[1024];
+static char logdir[1024];
+static char local_default_printer_file[1024];
+static char remote_default_printer_file[1024];
+static char save_options_file[1024];
+static char debug_log_file[1024];
+
+static void recheck_timer (void);
+static void browse_poll_create_subscription (browsepoll_t *context,
+ http_t *conn);
+static gboolean browse_poll_get_notifications (browsepoll_t *context,
+ http_t *conn);
+static remote_printer_t
+*examine_discovered_printer_record(const char *host,
+ const char *ip,
+ uint16_t port,
+ char *resource,
+ const char *service_name,
+ const char *location,
+ const char *info,
+ const char *type,
+ const char *domain,
+ void *txt);
+
+#if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 5)
+#define HAVE_CUPS_1_6 1
+#endif
+
+/*
+ * CUPS 1.6 makes various structures private and
+ * introduces these ippGet and ippSet functions
+ * for all of the fields in these structures.
+ * http://www.cups.org/str.php?L3928
+ * We define (same signatures) our own accessors when CUPS < 1.6.
+ */
+#ifndef HAVE_CUPS_1_6
+const char *
+ippGetName(ipp_attribute_t *attr)
+{
+ return (attr->name);
+}
+
+ipp_op_t
+ippGetOperation(ipp_t *ipp)
+{
+ return (ipp->request.op.operation_id);
+}
+
+ipp_status_t
+ippGetStatusCode(ipp_t *ipp)
+{
+ return (ipp->request.status.status_code);
+}
+
+ipp_tag_t
+ippGetGroupTag(ipp_attribute_t *attr)
+{
+ return (attr->group_tag);
+}
+
+ipp_tag_t
+ippGetValueTag(ipp_attribute_t *attr)
+{
+ return (attr->value_tag);
+}
+
+int
+ippGetCount(ipp_attribute_t *attr)
+{
+ return (attr->num_values);
+}
+
+int
+ippGetInteger(ipp_attribute_t *attr,
+ int element)
+{
+ return (attr->values[element].integer);
+}
+
+int
+ippGetBoolean(ipp_attribute_t *attr,
+ int element)
+{
+ return (attr->values[element].boolean);
+}
+
+const char *
+ippGetString(ipp_attribute_t *attr,
+ int element,
+ const char **language)
+{
+ return (attr->values[element].string.text);
+}
+
+ipp_attribute_t *
+ippFirstAttribute(ipp_t *ipp)
+{
+ if (!ipp)
+ return (NULL);
+ return (ipp->current = ipp->attrs);
+}
+
+ipp_attribute_t *
+ippNextAttribute(ipp_t *ipp)
+{
+ if (!ipp || !ipp->current)
+ return (NULL);
+ return (ipp->current = ipp->current->next);
+}
+
+int
+ippSetVersion(ipp_t *ipp, int major, int minor)
+{
+ if (!ipp || major < 0 || minor < 0)
+ return (0);
+ ipp->request.any.version[0] = major;
+ ipp->request.any.version[1] = minor;
+ return (1);
+}
+#endif
+
+
+#if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 6)
+#define HAVE_CUPS_1_7 1
+#endif
+
+/*
+ * The httpAddrPort() function was only introduced in CUPS 1.7.x
+ */
+#ifndef HAVE_CUPS_1_7
+int /* O - Port number */
+httpAddrPort(http_addr_t *addr) /* I - Address */
+{
+ if (!addr)
+ return (-1);
+#ifdef AF_INET6
+ else if (addr->addr.sa_family == AF_INET6)
+ return (ntohs(addr->ipv6.sin6_port));
+#endif /* AF_INET6 */
+ else if (addr->addr.sa_family == AF_INET)
+ return (ntohs(addr->ipv4.sin_port));
+ else
+ return (0);
+}
+#endif
+
+
+#if (CUPS_VERSION_MAJOR > 1)
+#define HAVE_CUPS_2_0 1
+#endif
+
+
+void
+start_debug_logging()
+{
+ if (debug_log_file[0] == '\0')
+ return;
+ if (lfp == NULL)
+ lfp = fopen(debug_log_file, "a+");
+ if (lfp == NULL) {
+ fprintf(stderr, "cups-browsed: ERROR: Failed creating debug log file %s\n",
+ debug_log_file);
+ exit(1);
+ }
+}
+
+void
+stop_debug_logging()
+{
+ debug_logfile = 0;
+ if (lfp)
+ fclose(lfp);
+ lfp = NULL;
+}
+
+void
+debug_printf(const char *format, ...) {
+ if (debug_stderr || debug_logfile) {
+ time_t curtime = time(NULL);
+ char buf[64];
+ ctime_r(&curtime, buf);
+ while(isspace(buf[strlen(buf)-1])) buf[strlen(buf)-1] = '\0';
+ va_list arglist;
+ if (debug_stderr) {
+ va_start(arglist, format);
+ fprintf(stderr, "%s ", buf);
+ vfprintf(stderr, format, arglist);
+ fflush(stderr);
+ va_end(arglist);
+ }
+ if (debug_logfile && lfp) {
+ va_start(arglist, format);
+ fprintf(lfp, "%s ", buf);
+ vfprintf(lfp, format, arglist);
+ fflush(lfp);
+ va_end(arglist);
+ }
+ }
+}
+
+static const char *
+password_callback (const char *prompt,
+ http_t *http,
+ const char *method,
+ const char *resource,
+ void *user_data)
+{
+ return NULL;
+}
+
+http_t *
+httpConnectEncryptShortTimeout(const char *host, int port,
+ http_encryption_t encryption)
+{
+ return (httpConnect2(host, port, NULL, AF_UNSPEC, encryption, 1, 3000,
+ NULL));
+}
+
+int
+http_timeout_cb(http_t *http, void *user_data)
+{
+ debug_printf("HTTP timeout! (consider increasing HttpLocalTimeout/HttpRemoteTimeout value)\n");
+ return 0;
+}
+
+static http_t *
+http_connect_local (void)
+{
+ if (!local_conn) {
+ debug_printf("cups-browsed: Creating http connection to local CUPS daemon: %s:%d\n", cupsServer(), ippPort());
+ local_conn = httpConnectEncryptShortTimeout(cupsServer(), ippPort(),
+ cupsEncryption());
+ }
+ if (local_conn)
+ httpSetTimeout(local_conn, HttpLocalTimeout, http_timeout_cb, NULL);
+ else
+ debug_printf("cups-browsed: Failed creating http connection to local CUPS daemon: %s:%d\n", cupsServer(), ippPort());
+
+ return local_conn;
+}
+
+static void
+http_close_local (void)
+{
+ if (local_conn) {
+ httpClose (local_conn);
+ local_conn = NULL;
+ }
+}
+
+
+/*
+ * Remove all illegal characters and replace each group of such characters
+ * by a single separator character (dash or underscore), return a free()-able
+ * string.
+ *
+ * mode = 0: Only allow letters, numbers, dashes, and underscores for
+ * turning make/model info into a valid print queue name or
+ * into a string which can be supplied as option value in a
+ * filter command line without need of quoting. Replace all
+ * groups of illegal characters by single dashes and remove
+ * leading and trailing dashes.
+ * mode = 1: Allow also '/', '.', ',' for cleaning up MIME type
+ * strings (here available Page Description Languages, PDLs) to
+ * supply them on a filter command line without quoting.
+ * Replace all groups of illegal characters by single dashes
+ * and remove leading and trailing dashes.
+ * mode = 2: Keep all locale-free alphanumeric characters (a-z, A-Z, 0-9)
+ * and replace everything else by underscores. Replace all
+ * groups of illegal characters by single underscores. This is
+ * for generating print queue names from DNS-SD service names
+ * to do it exactly as CUPS 2.2.x (or newer) does, so that CUPS
+ * does not create its own temporary queues in addition.
+ *
+ * Especially this prevents from arbitrary code execution by interface scripts
+ * generated for print queues to native IPP printers when a malicious IPP
+ * print service with forged PDL and/or make/model info gets broadcasted into
+ * the local network.
+ */
+
+char * /* O - Cleaned string */
+remove_bad_chars(const char *str_orig, /* I - Original string */
+ int mode) /* I - 0: Make/Model, queue name */
+ /* 1: MIME types/PDLs */
+ /* 2: Queue name from DNS-SD */
+ /* service name */
+{
+ int i, j;
+ int havesep = 0;
+ char sep, *str;
+
+ if (str_orig == NULL)
+ return NULL;
+
+ str = strdup(str_orig);
+
+ /* for later str[strlen(str)-1] access */
+ if (strlen(str) < 1)
+ return str;
+
+ /* Select separator character */
+ if (mode == 2)
+ sep = '_';
+ else
+ sep = '-';
+
+ for (i = 0, j = 0; i < strlen(str); i++, j++) {
+ if (((str[i] >= 'A') && (str[i] <= 'Z')) ||
+ ((str[i] >= 'a') && (str[i] <= 'z')) ||
+ ((str[i] >= '0') && (str[i] <= '9')) ||
+ (mode != 2 && (str[i] == '_' ||
+ str[i] == '.')) ||
+ (mode == 1 && (str[i] == '/' ||
+ str[i] == ','))) {
+ /* Allowed character, keep it */
+ havesep = 0;
+ str[j] = str[i];
+ } else {
+ /* Replace all other characters by a single separator */
+ if (havesep == 1)
+ j --;
+ else {
+ havesep = 1;
+ str[j] = sep;
+ }
+ }
+ }
+ /* Add terminating zero */
+ str[j] = '\0';
+
+ i = 0;
+ if (mode != 2) {
+ /* Cut off trailing separators */
+ while (strlen(str) > 0 && str[strlen(str)-1] == sep)
+ str[strlen(str)-1] = '\0';
+
+ /* Cut off leading separators */
+ while (str[i] == sep)
+ ++i;
+ }
+
+ /* keep a free()-able string. +1 for trailing \0 */
+ return memmove(str, str + i, strlen(str) - i + 1);
+}
+
+
+static local_printer_t *
+new_local_printer (const char *device_uri,
+ gboolean cups_browsed_controlled)
+{
+ local_printer_t *printer = g_malloc (sizeof (local_printer_t));
+ printer->device_uri = strdup (device_uri);
+ printer->cups_browsed_controlled = cups_browsed_controlled;
+ return printer;
+}
+
+static void
+free_local_printer (gpointer data)
+{
+ local_printer_t *printer = data;
+ debug_printf("free_local_printer() in THREAD %ld\n", pthread_self());
+ free (printer->device_uri);
+ free (printer);
+}
+
+static gboolean
+local_printer_has_uri (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ local_printer_t *printer = value;
+ char *device_uri = user_data;
+ debug_printf("local_printer_has_uri() in THREAD %ld\n", pthread_self());
+ return g_str_equal (printer->device_uri, device_uri);
+}
+
+static gboolean
+local_printer_service_name_matches (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ char *queue_name = key;
+ char *service_name = user_data;
+ char *p;
+ debug_printf("local_printer_service_name_matches() in THREAD %ld\n",
+ pthread_self());
+ p = remove_bad_chars(service_name, 2);
+ if (p && strncasecmp(p, queue_name, 63) == 0) {
+ free(p);
+ return TRUE;
+ }
+ if (p) free(p);
+ return FALSE;
+}
+
+static void
+local_printers_create_subscription (http_t *conn)
+{
+ char temp[1024];
+ if (!local_printers_context) {
+ local_printers_context = g_malloc0 (sizeof (browsepoll_t));
+ /* The httpGetAddr() function was introduced in CUPS 2.0.0 */
+#ifdef HAVE_CUPS_2_0
+ local_printers_context->server =
+ strdup(httpAddrString(httpGetAddress(conn),
+ temp, sizeof(temp)));
+ local_printers_context->port = httpAddrPort(httpGetAddress(conn));
+#else
+ local_printers_context->server = cupsServer();
+ local_printers_context->port = ippPort();
+#endif
+ local_printers_context->can_subscribe = TRUE;
+ }
+
+ browse_poll_create_subscription (local_printers_context, conn);
+}
+
+int
+add_dest_cb(dest_list_t *user_data, unsigned flags, cups_dest_t *dest)
+{
+ if (flags & CUPS_DEST_FLAGS_REMOVED)
+ /* Remove destination from array */
+ user_data->num_dests =
+ cupsRemoveDest(dest->name, dest->instance, user_data->num_dests,
+ &(user_data->dests));
+ else
+ /* Add destination to array... */
+ user_data->num_dests =
+ cupsCopyDest(dest, user_data->num_dests,
+ &(user_data->dests));
+ return (1);
+}
+
+static void
+get_local_printers (void)
+{
+ dest_list_t dest_list = {0, NULL};
+ /* We only want to have a list of actually existing CUPS queues, not of
+ DNS-SD-discovered printers for which CUPS can auto-setup a driverless
+ print queue */
+ if (OnlyUnsupportedByCUPS)
+ cupsEnumDests(CUPS_DEST_FLAGS_NONE, 1000, NULL, 0, 0,
+ (cups_dest_cb_t)add_dest_cb, &dest_list);
+ else
+ cupsEnumDests(CUPS_DEST_FLAGS_NONE, 1000, NULL, CUPS_PRINTER_LOCAL,
+ CUPS_PRINTER_DISCOVERED, (cups_dest_cb_t)add_dest_cb,
+ &dest_list);
+ debug_printf ("cups-browsed (%s): cupsEnumDests\n", local_server_str);
+ g_hash_table_remove_all (local_printers);
+ if (OnlyUnsupportedByCUPS)
+ g_hash_table_remove_all (cups_supported_remote_printers);
+ int num_dests = dest_list.num_dests;
+ cups_dest_t *dests = dest_list.dests;
+ for (int i = 0; i < num_dests; i++) {
+ const char *val;
+ cups_dest_t *dest = &dests[i];
+ local_printer_t *printer;
+ gboolean cups_browsed_controlled;
+ gboolean is_temporary;
+ gboolean is_cups_supported_remote;
+
+ const char *device_uri = cupsGetOption ("device-uri",
+ dest->num_options,
+ dest->options);
+
+ /* Temporary CUPS queue? */
+ val = cupsGetOption ("printer-is-temporary",
+ dest->num_options,
+ dest->options);
+ is_temporary = (val && (!strcasecmp (val, "yes") ||
+ !strcasecmp (val, "on") ||
+ !strcasecmp (val, "true")));
+
+ if (OnlyUnsupportedByCUPS) {
+ /* Printer discovered by DNS-SD and supported by CUPS' temporary
+ queues? */
+ val = cupsGetOption ("printer-uri-supported",
+ dest->num_options,
+ dest->options);
+ /* Printer has no local CUPS queue but CUPS would create a
+ temporary queue on-demand */
+ is_cups_supported_remote = (val == NULL || is_temporary);
+ } else {
+ is_cups_supported_remote = 0;
+ if (is_temporary)
+ continue;
+ }
+
+ val = cupsGetOption (CUPS_BROWSED_MARK,
+ dest->num_options,
+ dest->options);
+ cups_browsed_controlled = val && (!strcasecmp (val, "yes") ||
+ !strcasecmp (val, "on") ||
+ !strcasecmp (val, "true"));
+ printer = new_local_printer (device_uri,
+ cups_browsed_controlled);
+
+ if (is_cups_supported_remote)
+ g_hash_table_insert (cups_supported_remote_printers,
+ g_ascii_strdown (dest->name, -1),
+ printer);
+ else
+ g_hash_table_insert (local_printers,
+ g_ascii_strdown (dest->name, -1),
+ printer);
+ }
+
+ cupsFreeDests (num_dests, dests);
+}
+
+static browse_data_t *
+new_browse_data (int type, int state, const gchar *uri,
+ const gchar *location, const gchar *info,
+ const gchar *make_model, const gchar *browse_options)
+{
+ browse_data_t *data = g_malloc (sizeof (browse_data_t));
+ data->type = type;
+ data->state = state;
+ data->uri = g_strdup (uri);
+ data->location = g_strdup (location);
+ data->info = g_strdup (info);
+ data->make_model = g_strdup (make_model);
+ data->browse_options = g_strdup (browse_options);
+ return data;
+}
+
+static void
+browse_data_free (gpointer data)
+{
+ browse_data_t *bdata = data;
+ debug_printf("browse_data_free() in THREAD %ld\n", pthread_self());
+ g_free (bdata->uri);
+ g_free (bdata->location);
+ g_free (bdata->info);
+ g_free (bdata->make_model);
+ g_free (bdata->browse_options);
+ g_free (bdata);
+}
+
+static void
+prepare_browse_data (void)
+{
+ static const char * const rattrs[] = { "printer-type",
+ "printer-state",
+ "printer-uri-supported",
+ "printer-info",
+ "printer-location",
+ "printer-make-and-model",
+ "auth-info-required",
+ "printer-uuid",
+ "job-template" };
+ ipp_t *request, *response = NULL;
+ ipp_attribute_t *attr;
+ http_t *conn = NULL;
+
+ conn = http_connect_local ();
+
+ if (conn == NULL) {
+ debug_printf("Browse send failed to connect to localhost\n");
+ goto fail;
+ }
+
+ request = ippNewRequest(CUPS_GET_PRINTERS);
+ ippAddStrings (request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", sizeof (rattrs) / sizeof (rattrs[0]),
+ NULL, rattrs);
+ ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser ());
+
+ debug_printf("preparing browse data\n");
+ response = cupsDoRequest (conn, request, "/");
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE) {
+ debug_printf("browse send failed for localhost: %s\n",
+ cupsLastErrorString ());
+ goto fail;
+ }
+
+ g_list_free_full (browse_data, browse_data_free);
+ browse_data = NULL;
+ for (attr = ippFirstAttribute(response); attr;
+ attr = ippNextAttribute(response)) {
+ int type = -1, state = -1;
+ const char *uri = NULL;
+ gchar *location = NULL;
+ gchar *info = NULL;
+ gchar *make_model = NULL;
+ GString *browse_options = g_string_new ("");
+
+ /* Skip any non-printer attributes */
+ while (attr && ippGetGroupTag(attr) != IPP_TAG_PRINTER)
+ attr = ippNextAttribute(response);
+
+ if (!attr)
+ break;
+
+ while (attr && ippGetGroupTag(attr) == IPP_TAG_PRINTER) {
+ const char *attrname = ippGetName(attr);
+ int value_tag = ippGetValueTag(attr);
+
+ if (!strcasecmp(attrname, "printer-type") &&
+ value_tag == IPP_TAG_ENUM) {
+ type = ippGetInteger(attr, 0);
+ if (type & CUPS_PRINTER_NOT_SHARED) {
+ /* Skip CUPS queues not marked as shared */
+ state = -1;
+ type = -1;
+ break;
+ }
+ } else if (!strcasecmp(attrname, "printer-state") &&
+ value_tag == IPP_TAG_ENUM)
+ state = ippGetInteger(attr, 0);
+ else if (!strcasecmp(attrname, "printer-uri-supported") &&
+ value_tag == IPP_TAG_URI)
+ uri = ippGetString(attr, 0, NULL);
+ else if (!strcasecmp(attrname, "printer-location") &&
+ value_tag == IPP_TAG_TEXT) {
+ /* Remove quotes */
+ gchar **tokens = g_strsplit (ippGetString(attr, 0, NULL), "\"", -1);
+ location = g_strjoinv ("", tokens);
+ g_strfreev (tokens);
+ } else if (!strcasecmp(attrname, "printer-info") &&
+ value_tag == IPP_TAG_TEXT) {
+ /* Remove quotes */
+ gchar **tokens = g_strsplit (ippGetString(attr, 0, NULL), "\"", -1);
+ info = g_strjoinv ("", tokens);
+ g_strfreev (tokens);
+ } else if (!strcasecmp(attrname, "printer-make-and-model") &&
+ value_tag == IPP_TAG_TEXT) {
+ /* Remove quotes */
+ gchar **tokens = g_strsplit (ippGetString(attr, 0, NULL), "\"", -1);
+ make_model = g_strjoinv ("", tokens);
+ g_strfreev (tokens);
+ } else if (!strcasecmp(attrname, "auth-info-required") &&
+ value_tag == IPP_TAG_KEYWORD) {
+ if (strcasecmp (ippGetString(attr, 0, NULL), "none"))
+ g_string_append_printf (browse_options, "auth-info-required=%s ",
+ ippGetString(attr, 0, NULL));
+ } else if (!strcasecmp(attrname, "printer-uuid") &&
+ value_tag == IPP_TAG_URI)
+ g_string_append_printf (browse_options, "uuid=%s ",
+ ippGetString(attr, 0, NULL));
+ else if (!strcasecmp(attrname, "job-sheets-default") &&
+ value_tag == IPP_TAG_NAME &&
+ ippGetCount(attr) == 2)
+ g_string_append_printf (browse_options, "job-sheets=%s,%s ",
+ ippGetString(attr, 0, NULL),
+ ippGetString(attr, 1, NULL));
+ else if (strstr(attrname, "-default")) {
+ gchar *name = g_strdup (attrname);
+ gchar *value = NULL;
+ *strstr (name, "-default") = '\0';
+
+ switch (value_tag) {
+ gchar **tokens;
+
+ case IPP_TAG_KEYWORD:
+ case IPP_TAG_STRING:
+ case IPP_TAG_NAME:
+ /* Escape value */
+ tokens = g_strsplit_set (ippGetString(attr, 0, NULL),
+ " \"\'\\", -1);
+ value = g_strjoinv ("\\", tokens);
+ g_strfreev (tokens);
+ break;
+
+ default:
+ /* other values aren't needed? */
+ debug_printf("skipping %s (%d)\n", name, value_tag);
+ break;
+ }
+
+ if (value) {
+ g_string_append_printf (browse_options, "%s=%s ", name, value);
+ g_free (value);
+ }
+
+ g_free (name);
+ }
+
+ attr = ippNextAttribute(response);
+ }
+
+ if (type != -1 && state != -1 && uri && location && info && make_model) {
+ gchar *browse_options_str = g_string_free (browse_options, FALSE);
+ browse_data_t *data;
+ browse_options = NULL;
+ g_strchomp (browse_options_str);
+ data = new_browse_data (type, state, uri, location,
+ info, make_model, browse_options_str);
+ browse_data = g_list_insert (browse_data, data, 0);
+ g_free (browse_options_str);
+ }
+
+ if (make_model)
+ g_free (make_model);
+
+ if (info)
+ g_free (info);
+
+ if (location)
+ g_free (location);
+
+ if (browse_options)
+ g_string_free (browse_options, TRUE);
+
+ if (!attr)
+ break;
+ }
+
+ fail:
+ if (response)
+ ippDelete(response);
+}
+
+static void
+update_local_printers (void)
+{
+ gboolean get_printers = FALSE;
+ http_t *conn;
+
+ if (inhibit_local_printers_update)
+ return;
+
+ conn = http_connect_local ();
+ if (conn &&
+ (!local_printers_context || local_printers_context->can_subscribe)) {
+ if (!local_printers_context ||
+ local_printers_context->subscription_id == -1) {
+ /* No subscription yet. First, create the subscription. */
+ local_printers_create_subscription (conn);
+ get_printers = TRUE;
+ } else
+ /* We already have a subscription, so use it. */
+
+ /* Note: for the moment, browse_poll_get_notifications() just
+ * tells us whether we should re-fetch the printer list, so it
+ * is safe to use here. */
+ get_printers = browse_poll_get_notifications (local_printers_context,
+ conn);
+ } else
+ get_printers = TRUE;
+
+ if (get_printers) {
+ get_local_printers ();
+
+ if (BrowseLocalProtocols & BROWSE_CUPS)
+ prepare_browse_data ();
+ }
+}
+
+int
+check_jobs () {
+ int num_jobs = 0;
+ cups_job_t *jobs = NULL;
+ remote_printer_t *p;
+ http_t *conn = NULL;
+
+ conn = http_connect_local ();
+ if (conn == NULL) {
+ debug_printf("Cannot connect to local CUPS to check whether there are still jobs.\n");
+ return 0;
+ }
+
+ if (cupsArrayCount(remote_printers) > 0)
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p;
+ p = (remote_printer_t *)cupsArrayNext(remote_printers))
+ if (!p->slave_of) {
+ num_jobs = cupsGetJobs2(conn, &jobs, p->queue_name, 0,
+ CUPS_WHICHJOBS_ACTIVE);
+ if (num_jobs > 0) {
+ debug_printf("Queue %s still has jobs!\n", p->queue_name);
+ cupsFreeJobs(num_jobs, jobs);
+ return 1;
+ }
+ }
+
+ debug_printf("All our remote printers are without jobs.\n");
+ return 0;
+}
+
+gboolean
+autoshutdown_execute (gpointer data)
+{
+ debug_printf("autoshutdown_execute() in THREAD %ld\n", pthread_self());
+ /* Are we still in auto shutdown mode and are we still without queues or
+ jobs*/
+ if (autoshutdown &&
+ (cupsArrayCount(remote_printers) == 0 ||
+ (autoshutdown_on == NO_JOBS && check_jobs() == 0))) {
+ debug_printf("Automatic shutdown as there are no print queues maintained by us or no jobs on them for %d sec.\n",
+ autoshutdown_timeout);
+ g_main_loop_quit(gmainloop);
+ g_main_context_wakeup(NULL);
+ }
+
+ /* Stop this timeout handler, we needed it only once */
+ return FALSE;
+}
+
+int
+color_space_score(const char *color_space)
+{
+ int score = 0;
+ const char *p = color_space;
+
+ if (!p) return -1;
+ if (!strncasecmp(p, "s", 1)) {
+ p += 1;
+ score += 2;
+ } else if (!strncasecmp(p, "adobe", 5)) {
+ p += 5;
+ score += 1;
+ } else
+ score += 3;
+ if (!strncasecmp(p, "black", 5)) {
+ p += 5;
+ score += 1000;
+ } else if (!strncasecmp(p, "gray", 4)) {
+ p += 4;
+ score += 2000;
+ } else if (!strncasecmp(p, "cmyk", 4)) {
+ p += 4;
+ score += 4000;
+ } else if (!strncasecmp(p, "cmy", 3)) {
+ p += 3;
+ score += 3000;
+ } else if (!strncasecmp(p, "rgb", 3)) {
+ p += 3;
+ score += 5000;
+ }
+ if (!strncasecmp(p, "-", 1) || !strncasecmp(p, "_", 1)) {
+ p += 1;
+ }
+ score += strtol(p, (char **)&p, 10) * 10;
+ debug_printf("Score for color space %s: %d\n", color_space, score);
+ return score;
+}
+
+
+#ifdef HAVE_LDAP_REBIND_PROC
+# if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+/*
+ * 'ldap_rebind_proc()' - Callback function for LDAP rebind
+ */
+
+static int /* O - Result code */
+ldap_rebind_proc(
+ LDAP *RebindLDAPHandle, /* I - LDAP handle */
+ LDAP_CONST char *refsp, /* I - ??? */
+ ber_tag_t request, /* I - ??? */
+ ber_int_t msgid, /* I - ??? */
+ void *params) /* I - ??? */
+{
+ int rc; /* Result code */
+# if LDAP_API_VERSION > 3000
+ struct berval bval; /* Bind value */
+# endif /* LDAP_API_VERSION > 3000 */
+
+
+ (void)request;
+ (void)msgid;
+ (void)params;
+
+ /*
+ * Bind to new LDAP server...
+ */
+
+ debug_printf("ldap_rebind_proc: Rebind to %s\n", refsp);
+
+# if LDAP_API_VERSION > 3000
+ bval.bv_val = BrowseLDAPPassword;
+ bval.bv_len = (BrowseLDAPPassword == NULL) ? 0 : strlen(BrowseLDAPPassword);
+
+ rc = ldap_sasl_bind_s(RebindLDAPHandle, BrowseLDAPBindDN, LDAP_SASL_SIMPLE,
+ &bval, NULL, NULL, NULL);
+# else
+ rc = ldap_bind_s(RebindLDAPHandle, BrowseLDAPBindDN, BrowseLDAPPassword,
+ LDAP_AUTH_SIMPLE);
+# endif /* LDAP_API_VERSION > 3000 */
+
+ return (rc);
+}
+
+
+# else /* defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) */
+/*
+ * 'ldap_rebind_proc()' - Callback function for LDAP rebind
+ */
+
+static int /* O - Result code */
+ldap_rebind_proc(
+ LDAP *RebindLDAPHandle, /* I - LDAP handle */
+ char **dnp, /* I - ??? */
+ char **passwdp, /* I - ??? */
+ int *authmethodp, /* I - ??? */
+ int freeit, /* I - ??? */
+ void *arg) /* I - ??? */
+{
+ switch (freeit)
+ {
+ case 1:
+ /*
+ * Free current values...
+ */
+
+ debug_printf("ldap_rebind_proc: Free values...\n");
+
+ if (dnp && *dnp)
+ free(*dnp);
+
+ if (passwdp && *passwdp)
+ free(*passwdp);
+ break;
+
+ case 0:
+ /*
+ * Return credentials for LDAP referal...
+ */
+
+ debug_printf("ldap_rebind_proc: Return necessary values...\n");
+
+ *dnp = strdup(BrowseLDAPBindDN);
+ *passwdp = strdup(BrowseLDAPPassword);
+ *authmethodp = LDAP_AUTH_SIMPLE;
+ break;
+
+ default:
+ /*
+ * Should never happen...
+ */
+
+ debug_printf("LDAP rebind has been called with wrong freeit value!\n");
+ break;
+ }
+
+ return (LDAP_SUCCESS);
+}
+# endif /* defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) */
+#endif /* HAVE_LDAP_REBIND_PROC */
+
+
+#ifdef HAVE_LDAP
+/*
+ * 'ldap_connect()' - Start new LDAP connection
+ */
+
+static LDAP * /* O - LDAP handle */
+ldap_connect(void)
+{
+ int rc; /* LDAP API status */
+ int version = 3; /* LDAP version */
+ struct berval bv = {0, ""}; /* SASL bind value */
+ LDAP *TempBrowseLDAPHandle=NULL;
+ /* Temporary LDAP Handle */
+# if defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP)
+ int ldap_ssl = 0; /* LDAP SSL indicator */
+ int ssl_err = 0; /* LDAP SSL error value */
+# endif /* defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP) */
+
+
+# ifdef HAVE_OPENLDAP
+# ifdef HAVE_LDAP_SSL
+ /*
+ * Set the certificate file to use for encrypted LDAP sessions...
+ */
+
+ if (BrowseLDAPCACertFile)
+ {
+ debug_printf("ldap_connect: Setting CA certificate file \"%s\"\n",
+ BrowseLDAPCACertFile);
+
+ if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
+ (void *)BrowseLDAPCACertFile)) != LDAP_SUCCESS)
+ debug_printf("Unable to set CA certificate file for LDAP "
+ "connections: %d - %s\n", rc, ldap_err2string(rc));
+ }
+# endif /* HAVE_LDAP_SSL */
+
+ /*
+ * Initialize OPENLDAP connection...
+ * LDAP stuff currently only supports ldapi EXTERNAL SASL binds...
+ */
+
+ if (!BrowseLDAPServer || !strcasecmp(BrowseLDAPServer, "localhost"))
+ rc = ldap_initialize(&TempBrowseLDAPHandle, "ldapi:///");
+ else
+ rc = ldap_initialize(&TempBrowseLDAPHandle, BrowseLDAPServer);
+
+# else /* HAVE_OPENLDAP */
+
+ int ldap_port = 0; /* LDAP port */
+ char ldap_protocol[11], /* LDAP protocol */
+ ldap_host[255]; /* LDAP host */
+
+ /*
+ * Split LDAP URI into its components...
+ */
+
+ if (!BrowseLDAPServer)
+ {
+ debug_printf("BrowseLDAPServer not configured!\n");
+ debug_printf("Disabling LDAP browsing!\n");
+ /*BrowseLocalProtocols &= ~BROWSE_LDAP;*/
+ BrowseRemoteProtocols &= ~BROWSE_LDAP;
+ return (NULL);
+ }
+
+ sscanf(BrowseLDAPServer, "%10[^:]://%254[^:/]:%d", ldap_protocol, ldap_host,
+ &ldap_port);
+
+ if (!strcmp(ldap_protocol, "ldap"))
+ ldap_ssl = 0;
+ else if (!strcmp(ldap_protocol, "ldaps"))
+ ldap_ssl = 1;
+ else
+ {
+ debug_printf("Unrecognized LDAP protocol (%s)!\n",
+ ldap_protocol);
+ debug_printf("Disabling LDAP browsing!\n");
+ /*BrowseLocalProtocols &= ~BROWSE_LDAP;*/
+ BrowseRemoteProtocols &= ~BROWSE_LDAP;
+ return (NULL);
+ }
+
+ if (ldap_port == 0)
+ {
+ if (ldap_ssl)
+ ldap_port = LDAPS_PORT;
+ else
+ ldap_port = LDAP_PORT;
+ }
+
+ debug_printf("ldap_connect: PROT:%s HOST:%s PORT:%d\n",
+ ldap_protocol, ldap_host, ldap_port);
+
+ /*
+ * Initialize LDAP connection...
+ */
+
+ if (!ldap_ssl)
+ {
+ if ((TempBrowseLDAPHandle = ldap_init(ldap_host, ldap_port)) == NULL)
+ rc = LDAP_OPERATIONS_ERROR;
+ else
+ rc = LDAP_SUCCESS;
+
+# ifdef HAVE_LDAP_SSL
+ }
+ else
+ {
+ /*
+ * Initialize SSL LDAP connection...
+ */
+
+ if (BrowseLDAPCACertFile)
+ {
+ rc = ldapssl_client_init(BrowseLDAPCACertFile, (void *)NULL);
+ if (rc != LDAP_SUCCESS)
+ {
+ debug_printf("Failed to initialize LDAP SSL client!\n");
+ rc = LDAP_OPERATIONS_ERROR;
+ }
+ else
+ {
+ if ((TempBrowseLDAPHandle = ldapssl_init(ldap_host, ldap_port,
+ 1)) == NULL)
+ rc = LDAP_OPERATIONS_ERROR;
+ else
+ rc = LDAP_SUCCESS;
+ }
+ }
+ else
+ {
+ debug_printf("LDAP SSL certificate file/database not configured!\n");
+ rc = LDAP_OPERATIONS_ERROR;
+ }
+
+# else /* HAVE_LDAP_SSL */
+
+ /*
+ * Return error, because client libraries doesn't support SSL
+ */
+
+ debug_printf("LDAP client libraries do not support SSL\n");
+ rc = LDAP_OPERATIONS_ERROR;
+
+# endif /* HAVE_LDAP_SSL */
+ }
+# endif /* HAVE_OPENLDAP */
+
+ /*
+ * Check return code from LDAP initialize...
+ */
+
+ if (rc != LDAP_SUCCESS)
+ {
+ debug_printf("Unable to initialize LDAP!\n");
+
+ if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR)
+ debug_printf("Temporarily disabling LDAP browsing...\n");
+ else
+ {
+ debug_printf("Disabling LDAP browsing!\n");
+
+ /*BrowseLocalProtocols &= ~BROWSE_LDAP;*/
+ BrowseRemoteProtocols &= ~BROWSE_LDAP;
+ }
+
+ ldap_disconnect(TempBrowseLDAPHandle);
+
+ return (NULL);
+ }
+
+ /*
+ * Upgrade LDAP version...
+ */
+
+ if (ldap_set_option(TempBrowseLDAPHandle, LDAP_OPT_PROTOCOL_VERSION,
+ (const void *)&version) != LDAP_SUCCESS)
+ {
+ debug_printf("Unable to set LDAP protocol version %d!\n",
+ version);
+ debug_printf("Disabling LDAP browsing!\n");
+
+ /*BrowseLocalProtocols &= ~BROWSE_LDAP;*/
+ BrowseRemoteProtocols &= ~BROWSE_LDAP;
+ ldap_disconnect(TempBrowseLDAPHandle);
+
+ return (NULL);
+ }
+
+ /*
+ * Register LDAP rebind procedure...
+ */
+
+# ifdef HAVE_LDAP_REBIND_PROC
+# if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+
+ rc = ldap_set_rebind_proc(TempBrowseLDAPHandle, &ldap_rebind_proc,
+ (void *)NULL);
+ if (rc != LDAP_SUCCESS)
+ debug_printf("Setting LDAP rebind function failed with status %d: %s\n",
+ rc, ldap_err2string(rc));
+
+# else
+
+ ldap_set_rebind_proc(TempBrowseLDAPHandle, &ldap_rebind_proc, (void *)NULL);
+
+# endif /* defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) */
+# endif /* HAVE_LDAP_REBIND_PROC */
+
+ /*
+ * Start LDAP bind...
+ */
+
+# if LDAP_API_VERSION > 3000
+ struct berval bval;
+ bval.bv_val = BrowseLDAPPassword;
+ bval.bv_len = (BrowseLDAPPassword == NULL) ? 0 : strlen(BrowseLDAPPassword);
+
+ if (!BrowseLDAPServer || !strcasecmp(BrowseLDAPServer, "localhost"))
+ rc = ldap_sasl_bind_s(TempBrowseLDAPHandle, NULL, "EXTERNAL", &bv, NULL,
+ NULL, NULL);
+ else
+ rc = ldap_sasl_bind_s(TempBrowseLDAPHandle, BrowseLDAPBindDN, LDAP_SASL_SIMPLE, &bval, NULL, NULL, NULL);
+
+# else
+ rc = ldap_bind_s(TempBrowseLDAPHandle, BrowseLDAPBindDN,
+ BrowseLDAPPassword, LDAP_AUTH_SIMPLE);
+# endif /* LDAP_API_VERSION > 3000 */
+
+ if (rc != LDAP_SUCCESS)
+ {
+ debug_printf("LDAP bind failed with error %d: %s\n",
+ rc, ldap_err2string(rc));
+
+# if defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP)
+ if (ldap_ssl && (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR))
+ {
+ ssl_err = PORT_GetError();
+ if (ssl_err != 0)
+ debug_printf("LDAP SSL error %d: %s\n", ssl_err,
+ ldapssl_err2string(ssl_err));
+ }
+# endif /* defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP) */
+
+ ldap_disconnect(TempBrowseLDAPHandle);
+
+ return (NULL);
+ }
+
+ debug_printf("LDAP connection established\n");
+
+ return (TempBrowseLDAPHandle);
+}
+
+
+/*
+ * 'ldap_reconnect()' - Reconnect to LDAP Server
+ */
+
+static LDAP * /* O - New LDAP handle */
+ldap_reconnect(void)
+{
+ LDAP *TempBrowseLDAPHandle = NULL; /* Temp Handle to LDAP server */
+
+
+ /*
+ * Get a new LDAP Handle and replace the global Handle
+ * if the new connection was successful.
+ */
+
+ debug_printf("Try LDAP reconnect...\n");
+
+ TempBrowseLDAPHandle = ldap_connect();
+
+ if (TempBrowseLDAPHandle != NULL)
+ {
+ if (BrowseLDAPHandle != NULL)
+ ldap_disconnect(BrowseLDAPHandle);
+
+ BrowseLDAPHandle = TempBrowseLDAPHandle;
+ }
+
+ return (BrowseLDAPHandle);
+}
+
+
+/*
+ * 'ldap_disconnect()' - Disconnect from LDAP Server
+ */
+
+static void
+ldap_disconnect(LDAP *ld) /* I - LDAP handle */
+{
+ int rc; /* Return code */
+
+
+ /*
+ * Close LDAP handle...
+ */
+
+# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
+ rc = ldap_unbind_ext_s(ld, NULL, NULL);
+# else
+ rc = ldap_unbind_s(ld);
+# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
+
+ if (rc != LDAP_SUCCESS)
+ debug_printf("Unbind from LDAP server failed with status %d: %s\n",
+ rc, ldap_err2string(rc));
+}
+
+/*
+ * 'cupsdUpdateLDAPBrowse()' - Scan for new printers via LDAP...
+ */
+
+void
+cupsdUpdateLDAPBrowse(void)
+{
+ char uri[HTTP_MAX_URI], /* Printer URI */
+ host[HTTP_MAX_URI], /* Hostname */
+ resource[HTTP_MAX_URI], /* Resource path */
+ local_resource[HTTP_MAX_URI], /* Resource path */
+ service_name[HTTP_MAX_URI],
+ location[1024], /* Printer location */
+ info[1024], /* Printer information */
+ make_model[1024], /* Printer make and model */
+ type_num[30], /* Printer type number */
+ scheme[32], /* URI's scheme */
+ username[64]; /* URI's username */
+ int port; /* URI's port number */
+ char *c;
+ int hl;
+ int rc; /* LDAP status */
+ int limit; /* Size limit */
+ LDAPMessage *res, /* LDAP search results */
+ *e; /* Current entry from search */
+
+ debug_printf("UpdateLDAPBrowse\n");
+
+ /*
+ * Reconnect if LDAP Handle is invalid...
+ */
+
+ if (! BrowseLDAPHandle)
+ {
+ ldap_reconnect();
+ return;
+ }
+
+ /*
+ * Search for cups printers in LDAP directory...
+ */
+
+ rc = ldap_search_rec(BrowseLDAPHandle, BrowseLDAPDN, LDAP_SCOPE_SUBTREE,
+ BrowseLDAPFilter, (char **)ldap_attrs, 0, &res);
+
+ /*
+ * If ldap search was successfull then exit function
+ * and temporary disable LDAP updates...
+ */
+
+ if (rc != LDAP_SUCCESS)
+ {
+ if (BrowseLDAPUpdate && ((rc == LDAP_SERVER_DOWN) || (rc == LDAP_CONNECT_ERROR)))
+ {
+ BrowseLDAPUpdate = FALSE;
+ debug_printf("LDAP update temporary disabled\n");
+ }
+ return;
+ }
+
+ /*
+ * If LDAP updates were disabled, we will reenable them...
+ */
+
+ if (! BrowseLDAPUpdate)
+ {
+ BrowseLDAPUpdate = TRUE;
+ debug_printf("LDAP update enabled\n");
+ }
+
+ /*
+ * Count LDAP entries and return if no entry exist...
+ */
+
+ limit = ldap_count_entries(BrowseLDAPHandle, res);
+ debug_printf("LDAP search returned %d entries\n", limit);
+ if (limit < 1)
+ {
+ ldap_freeres(res);
+ return;
+ }
+
+ /*
+ * Loop through the available printers...
+ */
+
+ for (e = ldap_first_entry(BrowseLDAPHandle, res);
+ e;
+ e = ldap_next_entry(BrowseLDAPHandle, e))
+ {
+ /*
+ * Get the required values from this entry...
+ */
+
+ if (ldap_getval_firststring(BrowseLDAPHandle, e,
+ "printerDescription", info, sizeof(info)) == -1)
+ continue;
+
+ if (ldap_getval_firststring(BrowseLDAPHandle, e,
+ "printerLocation", location, sizeof(location)) == -1)
+ continue;
+
+ if (ldap_getval_firststring(BrowseLDAPHandle, e,
+ "printerMakeAndModel", make_model, sizeof(make_model)) == -1)
+ continue;
+
+ if (ldap_getval_firststring(BrowseLDAPHandle, e,
+ "printerType", type_num, sizeof(type_num)) == -1)
+ continue;
+
+ if (ldap_getval_firststring(BrowseLDAPHandle, e,
+ "printerURI", uri, sizeof(uri)) == -1)
+ continue;
+
+ /*
+ * Process the entry...
+ */
+
+ memset(scheme, 0, sizeof(scheme));
+ memset(username, 0, sizeof(username));
+ memset(host, 0, sizeof(host));
+ memset(resource, 0, sizeof(resource));
+ memset(local_resource, 0, sizeof(local_resource));
+
+ httpSeparateURI (HTTP_URI_CODING_ALL, uri,
+ scheme, sizeof(scheme) - 1,
+ username, sizeof(username) - 1,
+ host, sizeof(host) - 1,
+ &port,
+ resource, sizeof(resource)- 1);
+
+ if (strncasecmp (resource, "/printers/", 10) &&
+ strncasecmp (resource, "/classes/", 9)) {
+ debug_printf("don't understand URI: %s\n", uri);
+ return;
+ }
+
+ strncpy (local_resource, resource + 1, sizeof (local_resource) - 1);
+ local_resource[sizeof (local_resource) - 1] = '\0';
+ c = strchr (local_resource, '?');
+ if (c)
+ *c = '\0';
+
+ /* Build the DNS-SD service name which CUPS would give to this printer
+ when DNS-SD-broadcasting it */
+ snprintf(service_name, sizeof (service_name), "%s @ %s",
+ (strlen(info) > 0 ? info : strchr(local_resource, '/') + 1), host);
+ /* Cut off trailing ".local" of host name */
+ hl = strlen(service_name);
+ if (hl > 6 && !strcasecmp(service_name + hl - 6, ".local"))
+ service_name[hl - 6] = '\0';
+ if (hl > 7 && !strcasecmp(service_name + hl - 7, ".local."))
+ service_name[hl - 7] = '\0';
+ /* DNS-SD service name has max. 63 characters */
+ service_name[63] = '\0';
+
+ debug_printf("LDAP: Remote host: %s; Port: %d; Remote queue name: %s; Service Name: %s\n",
+ host, port, strchr(local_resource, '/') + 1, service_name);
+
+ examine_discovered_printer_record(host, NULL, port, local_resource,
+ service_name, location, info, "", "",
+ NULL);
+
+ }
+
+ ldap_freeres(res);
+}
+
+/*
+ * 'ldap_search_rec()' - LDAP Search with reconnect
+ */
+
+static int /* O - Return code */
+ldap_search_rec(LDAP *ld, /* I - LDAP handler */
+ char *base, /* I - Base dn */
+ int scope, /* I - LDAP search scope */
+ char *filter, /* I - Filter string */
+ char *attrs[], /* I - Requested attributes */
+ int attrsonly, /* I - Return only attributes? */
+ LDAPMessage **res) /* I - LDAP handler */
+{
+ int rc; /* Return code */
+ LDAP *ldr; /* LDAP handler after reconnect */
+
+
+# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
+ rc = ldap_search_ext_s(ld, base, scope, filter, attrs, attrsonly, NULL, NULL,
+ NULL, LDAP_NO_LIMIT, res);
+# else
+ rc = ldap_search_s(ld, base, scope, filter, attrs, attrsonly, res);
+# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
+
+ /*
+ * If we have a connection problem try again...
+ */
+
+ if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR)
+ {
+ debug_printf("LDAP search failed with status %d: %s\n",
+ rc, ldap_err2string(rc));
+ debug_printf("We try the LDAP search once again after reconnecting to "
+ "the server\n");
+ ldap_freeres(*res);
+ ldr = ldap_reconnect();
+
+# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
+ rc = ldap_search_ext_s(ldr, base, scope, filter, attrs, attrsonly, NULL,
+ NULL, NULL, LDAP_NO_LIMIT, res);
+# else
+ rc = ldap_search_s(ldr, base, scope, filter, attrs, attrsonly, res);
+# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
+ }
+
+ if (rc == LDAP_NO_SUCH_OBJECT)
+ debug_printf("ldap_search_rec: LDAP entry/object not found\n");
+ else if (rc != LDAP_SUCCESS)
+ debug_printf("ldap_search_rec: LDAP search failed with status %d: %s\n",
+ rc, ldap_err2string(rc));
+
+ if (rc != LDAP_SUCCESS)
+ ldap_freeres(*res);
+
+ return (rc);
+}
+
+
+/*
+ * 'ldap_freeres()' - Free LDAPMessage
+ */
+
+static void
+ldap_freeres(LDAPMessage *entry) /* I - LDAP handler */
+{
+ int rc; /* Return value */
+
+
+ rc = ldap_msgfree(entry);
+ if (rc == -1)
+ debug_printf("Can't free LDAPMessage!\n");
+ else if (rc == 0)
+ debug_printf("Freeing LDAPMessage was unnecessary\n");
+}
+
+
+/*
+ * 'ldap_getval_char()' - Get first LDAP value and convert to string
+ */
+
+static int /* O - Return code */
+ldap_getval_firststring(
+ LDAP *ld, /* I - LDAP handler */
+ LDAPMessage *entry, /* I - LDAP message or search result */
+ char *attr, /* I - the wanted attribute */
+ char *retval, /* O - String to return */
+ unsigned long maxsize) /* I - Max string size */
+{
+ char *dn; /* LDAP DN */
+ int rc = 0; /* Return code */
+# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
+ struct berval **bval; /* LDAP value array */
+ unsigned long size; /* String size */
+
+
+ /*
+ * Get value from LDAPMessage...
+ */
+
+ if ((bval = ldap_get_values_len(ld, entry, attr)) == NULL)
+ {
+ rc = -1;
+ dn = ldap_get_dn(ld, entry);
+ debug_printf("Failed to get LDAP value %s for %s!\n",
+ attr, dn);
+ ldap_memfree(dn);
+ }
+ else
+ {
+ /*
+ * Check size and copy value into our string...
+ */
+
+ size = maxsize;
+ if (size < (bval[0]->bv_len + 1))
+ {
+ rc = -1;
+ dn = ldap_get_dn(ld, entry);
+ debug_printf("Attribute %s is too big! (dn: %s)\n",
+ attr, dn);
+ ldap_memfree(dn);
+ }
+ else
+ size = bval[0]->bv_len + 1;
+
+ strncpy(retval, bval[0]->bv_val, size);
+ if (size > 0)
+ retval[size - 1] = '\0';
+ ldap_value_free_len(bval);
+ }
+# else
+ char **value; /* LDAP value */
+
+ /*
+ * Get value from LDAPMessage...
+ */
+
+ if ((value = (char **)ldap_get_values(ld, entry, attr)) == NULL)
+ {
+ rc = -1;
+ dn = ldap_get_dn(ld, entry);
+ debug_printf("Failed to get LDAP value %s for %s!\n",
+ attr, dn);
+ ldap_memfree(dn);
+ }
+ else
+ {
+ strncpy(retval, *value, maxsize);
+ if (maxsize > 0)
+ retval[maxsize - 1] = '\0';
+ ldap_value_free(value);
+ }
+# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
+
+ return (rc);
+}
+
+#endif /* HAVE_LDAP */
+
+
+static int
+create_subscription ()
+{
+ ipp_t *req;
+ ipp_t *resp;
+ ipp_attribute_t *attr;
+ int id = 0;
+ http_t *conn = NULL;
+
+ conn = http_connect_local ();
+ if (conn == NULL) {
+ debug_printf("Cannot connect to local CUPS to subscribe to notifications.\n");
+ return 0;
+ }
+
+ req = ippNewRequest (IPP_CREATE_PRINTER_SUBSCRIPTION);
+ ippAddString (req, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, "/");
+ ippAddString (req, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD,
+ "notify-events", NULL, "all");
+ ippAddString (req, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI,
+ "notify-recipient-uri", NULL, "dbus://");
+ ippAddInteger (req, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
+ "notify-lease-duration", NOTIFY_LEASE_DURATION);
+
+ resp = cupsDoRequest (conn, req, "/");
+ if (!resp || cupsLastError() != IPP_STATUS_OK) {
+ debug_printf ("Error subscribing to CUPS notifications: %s\n",
+ cupsLastErrorString ());
+ return 0;
+ }
+
+ attr = ippFindAttribute (resp, "notify-subscription-id", IPP_TAG_INTEGER);
+ if (attr)
+ id = ippGetInteger (attr, 0);
+ else
+ debug_printf (""
+ "ipp-create-printer-subscription response doesn't contain "
+ "subscription id.\n");
+
+ ippDelete (resp);
+ return id;
+}
+
+
+static gboolean
+renew_subscription (int id)
+{
+ ipp_t *req;
+ ipp_t *resp;
+ http_t *conn = NULL;
+
+ conn = http_connect_local ();
+ if (conn == NULL) {
+ debug_printf("Cannot connect to local CUPS to renew subscriptions.\n");
+ return FALSE;
+ }
+
+ req = ippNewRequest (IPP_RENEW_SUBSCRIPTION);
+ ippAddInteger (req, IPP_TAG_OPERATION, IPP_TAG_INTEGER,
+ "notify-subscription-id", id);
+ ippAddString (req, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, "/");
+ ippAddString (req, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI,
+ "notify-recipient-uri", NULL, "dbus://");
+ ippAddInteger (req, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
+ "notify-lease-duration", NOTIFY_LEASE_DURATION);
+
+ resp = cupsDoRequest (conn, req, "/");
+ if (!resp || cupsLastError() != IPP_STATUS_OK) {
+ debug_printf ("Error renewing CUPS subscription %d: %s\n",
+ id, cupsLastErrorString ());
+ return FALSE;
+ }
+
+ ippDelete (resp);
+ return TRUE;
+}
+
+
+static gboolean
+renew_subscription_timeout (gpointer userdata)
+{
+ int *subscription_id = userdata;
+
+ debug_printf("renew_subscription_timeout() in THREAD %ld\n", pthread_self());
+
+ if (*subscription_id <= 0 || !renew_subscription (*subscription_id))
+ *subscription_id = create_subscription ();
+
+ return TRUE;
+}
+
+
+void
+cancel_subscription (int id)
+{
+ ipp_t *req;
+ ipp_t *resp;
+ http_t *conn = NULL;
+
+ conn = http_connect_local ();
+ if (conn == NULL) {
+ debug_printf("Cannot connect to local CUPS to cancel subscriptions.\n");
+ return;
+ }
+
+ if (id <= 0)
+ return;
+
+ req = ippNewRequest (IPP_CANCEL_SUBSCRIPTION);
+ ippAddString (req, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, "/");
+ ippAddInteger (req, IPP_TAG_OPERATION, IPP_TAG_INTEGER,
+ "notify-subscription-id", id);
+
+ resp = cupsDoRequest (conn, req, "/");
+ if (!resp || cupsLastError() != IPP_STATUS_OK) {
+ debug_printf ("Error subscribing to CUPS notifications: %s\n",
+ cupsLastErrorString ());
+ return;
+ }
+
+ ippDelete (resp);
+}
+
+int
+is_created_by_cups_browsed (const char *printer) {
+ remote_printer_t *p;
+
+ if (printer == NULL)
+ return 0;
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers))
+ if (!p->slave_of && !strcasecmp(printer, p->queue_name))
+ return 1;
+
+ return 0;
+}
+
+remote_printer_t *
+printer_record (const char *printer) {
+ remote_printer_t *p;
+
+ if (printer == NULL)
+ return NULL;
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers))
+ if (!p->slave_of && !strcasecmp(printer, p->queue_name))
+ return p;
+
+ return NULL;
+}
+
+void
+log_cluster(remote_printer_t *p) {
+ remote_printer_t *q, *r;
+ int i;
+ if (p == NULL || (!debug_stderr && !debug_logfile))
+ return;
+ if (p->netprinter) {
+ debug_printf("Printer %s is not a remote CUPS printer, load-balanced clustering not supported.\n",
+ p->queue_name);
+ return;
+ }
+ if (p->slave_of)
+ q = p->slave_of;
+ else
+ q = p;
+ debug_printf("Remote CUPS printers clustered as queue %s:\n", q->queue_name);
+ for (r = (remote_printer_t *)cupsArrayFirst(remote_printers), i = 0;
+ r; r = (remote_printer_t *)cupsArrayNext(remote_printers), i ++)
+ if (r->status != STATUS_DISAPPEARED && r->status != STATUS_UNCONFIRMED &&
+ (r == q || r->slave_of == q))
+ debug_printf(" %s%s%s\n", r->uri,
+ (r == q ? "*" : ""),
+ (i == q->last_printer ? " (last job printed)" : ""));
+}
+
+void
+log_all_printers() {
+ remote_printer_t *p, *q;
+ if (!debug_stderr && !debug_logfile)
+ return;
+ debug_printf("=== Remote printer overview ===\n");
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers))
+ debug_printf("Printer %s: Local queue %s, %s, Slave of %s%s\n", p->uri,
+ p->queue_name,
+ (p->netprinter ? "IPP Printer" : "Remote CUPS Printer"),
+ ((q = p->slave_of) != NULL ? q->uri : "None"),
+ (p->status == STATUS_UNCONFIRMED ? " (Unconfirmed)" :
+ (p->status == STATUS_DISAPPEARED ? " (Disappeared)" :
+ (p->status == STATUS_TO_BE_CREATED ?
+ " (To be created/updated)" : ""))));
+ debug_printf("===============================\n");
+}
+
+char*
+is_disabled(const char *printer, const char *reason) {
+ ipp_t *request, *response;
+ ipp_attribute_t *attr;
+ const char *pname = NULL;
+ ipp_pstate_t pstate = IPP_PRINTER_IDLE;
+ const char *p;
+ char *pstatemsg = NULL;
+ static const char *pattrs[] =
+ {
+ "printer-name",
+ "printer-state",
+ "printer-state-message"
+ };
+ http_t *conn = NULL;
+
+ conn = http_connect_local ();
+ if (conn == NULL) {
+ debug_printf("Cannot connect to local CUPS to check whether the printer %s is disabled.\n",
+ printer);
+ return NULL;
+ }
+
+ request = ippNewRequest(CUPS_GET_PRINTERS);
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes",
+ sizeof(pattrs) / sizeof(pattrs[0]),
+ NULL, pattrs);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name",
+ NULL, cupsUser());
+ if ((response = cupsDoRequest(conn, request, "/")) != NULL) {
+ for (attr = ippFirstAttribute(response); attr != NULL;
+ attr = ippNextAttribute(response)) {
+ while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_PRINTER)
+ attr = ippNextAttribute(response);
+ if (attr == NULL)
+ break;
+ pname = NULL;
+ pstate = IPP_PRINTER_IDLE;
+ if (pstatemsg) {
+ free(pstatemsg);
+ pstatemsg = NULL;
+ }
+ while (attr != NULL && ippGetGroupTag(attr) ==
+ IPP_TAG_PRINTER) {
+ if (!strcmp(ippGetName(attr), "printer-name") &&
+ ippGetValueTag(attr) == IPP_TAG_NAME)
+ pname = ippGetString(attr, 0, NULL);
+ else if (!strcmp(ippGetName(attr), "printer-state") &&
+ ippGetValueTag(attr) == IPP_TAG_ENUM)
+ pstate = (ipp_pstate_t)ippGetInteger(attr, 0);
+ else if (!strcmp(ippGetName(attr), "printer-state-message") &&
+ ippGetValueTag(attr) == IPP_TAG_TEXT) {
+ free(pstatemsg);
+ p = ippGetString(attr, 0, NULL);
+ if (p != NULL) pstatemsg = strdup(p);
+ }
+ attr = ippNextAttribute(response);
+ }
+ if (pname == NULL) {
+ if (attr == NULL)
+ break;
+ else
+ continue;
+ }
+ if (!strcasecmp(pname, printer)) {
+ switch (pstate) {
+ case IPP_PRINTER_IDLE:
+ case IPP_PRINTER_PROCESSING:
+ ippDelete(response);
+ free(pstatemsg);
+ return NULL;
+ case IPP_PRINTER_STOPPED:
+ ippDelete(response);
+ if (reason == NULL)
+ return pstatemsg;
+ else if (strcasestr(pstatemsg, reason) != NULL)
+ return pstatemsg;
+ else {
+ free(pstatemsg);
+ return NULL;
+ }
+ }
+ }
+ }
+ debug_printf("No information regarding enabled/disabled found about the requested printer '%s'\n",
+ printer);
+ ippDelete(response);
+ free(pstatemsg);
+ return NULL;
+ }
+ debug_printf("ERROR: Request for printer info failed: %s\n",
+ cupsLastErrorString());
+ free(pstatemsg);
+ return NULL;
+}
+
+int
+enable_printer (const char *printer) {
+ ipp_t *request;
+ char uri[HTTP_MAX_URI];
+ http_t *conn = NULL;
+
+ conn = http_connect_local ();
+ if (conn == NULL) {
+ debug_printf("Cannot connect to local CUPS to enable printer %s.\n",
+ printer);
+ return -1;
+ }
+
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", ippPort(), "/printers/%s", printer);
+ request = ippNewRequest (IPP_RESUME_PRINTER);
+ ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+ ippDelete(cupsDoRequest (conn, request, "/admin/"));
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE) {
+ debug_printf("ERROR: Failed enabling printer '%s': %s\n",
+ printer, cupsLastErrorString());
+ return -1;
+ }
+ debug_printf("Enabled printer '%s'\n", printer);
+ return 0;
+}
+
+int
+disable_printer (const char *printer, const char *reason) {
+ ipp_t *request;
+ char uri[HTTP_MAX_URI];
+ http_t *conn = NULL;
+
+ conn = http_connect_local ();
+ if (conn == NULL) {
+ debug_printf("Cannot connect to local CUPS to disable printer %s.\n",
+ printer);
+ return -1;
+ }
+
+ if (reason == NULL)
+ reason = "Disabled by cups-browsed";
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", ippPort(), "/printers/%s", printer);
+ request = ippNewRequest (IPP_PAUSE_PRINTER);
+ ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+ ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_TEXT,
+ "printer-state-message", NULL, reason);
+ ippDelete(cupsDoRequest (conn, request, "/admin/"));
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE) {
+ debug_printf("ERROR: Failed disabling printer '%s': %s\n",
+ printer, cupsLastErrorString());
+ return -1;
+ }
+ debug_printf("Disabled printer '%s'\n", printer);
+ return 0;
+}
+
+int
+set_cups_default_printer(const char *printer) {
+ ipp_t *request;
+ char uri[HTTP_MAX_URI];
+ http_t *conn = NULL;
+
+ conn = http_connect_local ();
+ if (conn == NULL) {
+ debug_printf("Cannot connect to local CUPS to subscribe to set printer %s as default printer.\n",
+ printer);
+ return -1;
+ }
+
+ if (printer == NULL)
+ return 0;
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", ippPort(), "/printers/%s", printer);
+ request = ippNewRequest(IPP_OP_CUPS_SET_DEFAULT);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, cupsUser());
+ ippDelete(cupsDoRequest(conn, request, "/admin/"));
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE) {
+ debug_printf("ERROR: Failed setting CUPS default printer to '%s': %s\n",
+ printer, cupsLastErrorString());
+ return -1;
+ }
+ debug_printf("Successfully set CUPS default printer to '%s'\n",
+ printer);
+ return 0;
+}
+
+char*
+get_cups_default_printer() {
+ ipp_t *request, *response;
+ ipp_attribute_t *attr;
+ const char *default_printer_name = NULL;
+ char *name_string;
+ http_t *conn = NULL;
+
+ conn = http_connect_local ();
+ if (conn == NULL) {
+ debug_printf("Cannot connect to local CUPS to find out which is the default printer.\n");
+ return NULL;
+ }
+
+ request = ippNewRequest(CUPS_GET_DEFAULT);
+ /* Default user */
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser());
+ /* Do it */
+ response = cupsDoRequest(conn, request, "/");
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE || !response) {
+ debug_printf("Could not determine system default printer!\n");
+ } else {
+ for (attr = ippFirstAttribute(response); attr != NULL;
+ attr = ippNextAttribute(response)) {
+ while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_PRINTER)
+ attr = ippNextAttribute(response);
+ if (attr) {
+ for (; attr && ippGetGroupTag(attr) == IPP_TAG_PRINTER;
+ attr = ippNextAttribute(response)) {
+ if (!strcasecmp(ippGetName(attr), "printer-name") &&
+ ippGetValueTag(attr) == IPP_TAG_NAME) {
+ default_printer_name = ippGetString(attr, 0, NULL);
+ break;
+ }
+ }
+ }
+ if (default_printer_name)
+ break;
+ }
+ }
+
+ if (default_printer_name != NULL) {
+ name_string = strdup(default_printer_name);
+ } else {
+ name_string = NULL;
+ }
+
+ ippDelete(response);
+
+ return name_string;
+}
+
+int
+is_cups_default_printer(const char *printer) {
+ if (printer == NULL)
+ return 0;
+ char *cups_default = get_cups_default_printer();
+ if (cups_default == NULL)
+ return 0;
+ if (!strcasecmp(printer, cups_default)) {
+ free(cups_default);
+ return 1;
+ }
+ free(cups_default);
+ return 0;
+}
+
+int
+invalidate_default_printer(int local) {
+ const char *filename = local ? local_default_printer_file :
+ remote_default_printer_file;
+ unlink(filename);
+ return 0;
+}
+
+int
+record_default_printer(const char *printer, int local) {
+ FILE *fp = NULL;
+ const char *filename = local ? local_default_printer_file :
+ remote_default_printer_file;
+
+ if (printer == NULL || strlen(printer) == 0)
+ return invalidate_default_printer(local);
+
+ fp = fopen(filename, "w+");
+ if (fp == NULL) {
+ debug_printf("ERROR: Failed creating file %s\n",
+ filename);
+ invalidate_default_printer(local);
+ return -1;
+ }
+ fprintf(fp, "%s", printer);
+ fclose(fp);
+
+ return 0;
+}
+
+const char*
+retrieve_default_printer(int local) {
+ FILE *fp = NULL;
+ const char *filename = local ? local_default_printer_file :
+ remote_default_printer_file;
+ const char *printer = NULL;
+ char *p, buf[1024];
+ int n;
+
+ fp = fopen(filename, "r");
+ if (fp == NULL) {
+ debug_printf("Failed reading file %s\n",
+ filename);
+ return NULL;
+ }
+ p = buf;
+ n = fscanf(fp, "%s", p);
+ if (n == 1) {
+ if (strlen(p) > 0)
+ printer = p;
+ }
+ fclose(fp);
+
+ return printer;
+}
+
+int
+invalidate_printer_options(const char *printer) {
+ char filename[1024];
+
+ snprintf(filename, sizeof(filename), save_options_file,
+ printer);
+ unlink(filename);
+ return 0;
+}
+
+int
+record_printer_options(const char *printer) {
+ remote_printer_t *p;
+ char filename[1024];
+ FILE *fp = NULL;
+ char uri[HTTP_MAX_URI], *resource;
+ ipp_t *request, *response;
+ ipp_attribute_t *attr;
+ const char *key;
+ char buf[65536], *c;
+ const char *ppdname = NULL;
+ ppd_file_t *ppd;
+ ppd_option_t *ppd_opt;
+ cups_option_t *option;
+ int i;
+ /* List of IPP attributes to get recorded */
+ static const char *attrs_to_record[] =
+ {
+ "*-default",
+ "auth-info-required",
+ /*"device-uri",*/
+ "job-quota-period",
+ "job-k-limit",
+ "job-page-limit",
+ /*"port-monitor",*/
+ "printer-error-policy",
+ "printer-info",
+ "printer-is-accepting-jobs",
+ "printer-is-shared",
+ "printer-geo-location",
+ "printer-location",
+ "printer-op-policy",
+ "printer-organization",
+ "printer-organizational-unit",
+ /*"printer-state",
+ "printer-state-message",
+ "printer-state-reasons",*/
+ "requesting-user-name-allowed",
+ "requesting-user-name-denied",
+ NULL
+ };
+ const char **ptr;
+ http_t *conn = NULL;
+
+ if (printer == NULL || strlen(printer) == 0)
+ return 0;
+
+ /* Get our data about this printer */
+ p = printer_record(printer);
+
+ if (p == NULL) {
+ debug_printf("Not recording printer options for %s: Unkown printer!\n",
+ printer);
+ return 0;
+ }
+
+ snprintf(filename, sizeof(filename), save_options_file,
+ printer);
+
+ debug_printf("Recording printer options for %s to %s\n",
+ printer, filename);
+
+ /* If there is a PPD file for this printer, we save the local
+ settings for the PPD options. */
+ if (cups_notifier != NULL || (p && p->netprinter)) {
+ if ((ppdname = cupsGetPPD(printer)) == NULL) {
+ debug_printf("Unable to get PPD file for %s: %s\n",
+ printer, cupsLastErrorString());
+ } else if ((ppd = ppdOpenFile(ppdname)) == NULL) {
+ unlink(ppdname);
+ debug_printf("Unable to open PPD file for %s.\n",
+ printer);
+ } else {
+ ppdMarkDefaults(ppd);
+ for (ppd_opt = ppdFirstOption(ppd); ppd_opt; ppd_opt = ppdNextOption(ppd))
+ if (strcasecmp(ppd_opt->keyword, "PageRegion") != 0) {
+ strncpy(buf, ppd_opt->keyword, sizeof(buf));
+ p->num_options = cupsAddOption(buf, ppd_opt->defchoice,
+ p->num_options, &(p->options));
+ }
+ ppdClose(ppd);
+ unlink(ppdname);
+ }
+ }
+
+ conn = http_connect_local ();
+ if (conn) {
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", ippPort(), "/printers/%s", printer);
+ resource = uri + (strlen(uri) - strlen(printer) - 10);
+ request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
+ uri);
+ response = cupsDoRequest(conn, request, resource);
+
+ /* Write all supported printer attributes */
+ if (response) {
+ attr = ippFirstAttribute(response);
+ while (attr) {
+ key = ippGetName(attr);
+ for (ptr = attrs_to_record; *ptr; ptr++)
+ if (strcasecmp(key, *ptr) == 0 ||
+ (*ptr[0] == '*' &&
+ strcasecmp(key + strlen(key) - strlen(*ptr) + 1, *ptr + 1) == 0))
+ break;
+ if (*ptr != NULL) {
+ if (strcasecmp(key, CUPS_BROWSED_DEST_PRINTER "-default") != 0 &&
+ (ppdname == NULL ||
+ strncasecmp(key + strlen(key) - 8, "-default", 8))) {
+ ippAttributeString(attr, buf, sizeof(buf));
+ buf[sizeof(buf) - 1] = '\0';
+ c = buf;
+ while (*c) {
+ if (*c == '\\')
+ memmove(c, c + 1, strlen(c));
+ if (*c) c ++;
+ }
+ p->num_options = cupsAddOption(key, buf, p->num_options,
+ &(p->options));
+ }
+ }
+ attr = ippNextAttribute(response);
+ }
+ ippDelete(response);
+ }
+ } else {
+ debug_printf("Cannot connect to local CUPS to read out the IPP attributes for printer %s.\n",
+ printer);
+ }
+
+ if (p->num_options > 0) {
+ fp = fopen(filename, "w+");
+ if (fp == NULL) {
+ debug_printf("ERROR: Failed creating file %s: %s\n",
+ filename, strerror(errno));
+ return -1;
+ }
+
+ for (i = p->num_options, option = p->options; i > 0; i --, option ++)
+ if (fprintf (fp, "%s=%s\n", option->name, option->value) < 0) {
+ debug_printf("ERROR: Failed to write into file %s: %s\n",
+ filename, strerror(errno));
+ fclose(fp);
+ return -1;
+ }
+
+ fclose(fp);
+
+ return 0;
+ } else
+ return -1;
+}
+
+int
+load_printer_options(const char *printer, int num_options,
+ cups_option_t **options) {
+ char filename[1024];
+ FILE *fp = NULL;
+ char *opt = NULL, *val;
+ size_t optlen = 0;
+
+ if (printer == NULL || strlen(printer) == 0 || options == NULL)
+ return 0;
+
+ /* Prepare reading file with saved option settings */
+ snprintf(filename, sizeof(filename), save_options_file,
+ printer);
+
+ debug_printf("Loading saved printer options for %s from %s\n",
+ printer, filename);
+
+ /* Open the file with the saved option settings for this print queue */
+ fp = fopen(filename, "r");
+ if (fp == NULL) {
+ debug_printf("Failed reading file %s, probably no options recorded yet\n",
+ filename);
+ } else {
+ /* Now read the lines of the file and add each setting to our request */
+ errno = 0;
+ debug_printf("Loading following option settings for printer %s:\n",
+ printer);
+ while (getline(&opt, &optlen, fp) != -1) {
+ if (strlen(opt) > 1 && (val = strchr(opt, '=')) != NULL) {
+ *val = '\0';
+ val ++;
+ val[strlen(val)-1] = '\0';
+ debug_printf(" %s=%s\n", opt, val);
+ num_options = cupsAddOption(opt, val, num_options, options);
+ }
+ }
+ debug_printf("\n");
+ if (errno != 0)
+ debug_printf("Failed reading saved options file %s: %s\n",
+ filename, strerror(errno));
+ free(opt);
+ fclose(fp);
+ }
+ return (num_options);
+}
+
+int
+queue_creation_handle_default(const char *printer) {
+ /* No default printer management if we cannot get D-Bus notifications
+ from CUPS */
+ if (cups_notifier == NULL)
+ return 0;
+ /* If this queue is recorded as the former default queue (and the current
+ default is local), set it as default (the CUPS notification handler
+ will record the local default printer then) */
+ const char *recorded_default = retrieve_default_printer(0);
+ if (recorded_default == NULL || strcasecmp(recorded_default, printer))
+ return 0;
+ char *current_default = get_cups_default_printer();
+ if (current_default == NULL || !is_created_by_cups_browsed(current_default)) {
+ if (set_cups_default_printer(printer) < 0) {
+ debug_printf("ERROR: Could not set former default printer %s as default again.\n",
+ printer);
+ free(current_default);
+ return -1;
+ } else {
+ debug_printf("Former default printer %s re-appeared, set as default again.\n",
+ printer);
+ invalidate_default_printer(0);
+ }
+ }
+ free(current_default);
+ return 0;
+}
+
+int
+queue_removal_handle_default(const char *printer) {
+ /* No default printer management if we cannot get D-Bus notifications
+ from CUPS */
+ if (cups_notifier == NULL)
+ return 0;
+ /* If the queue is the default printer, get back
+ to the recorded local default printer, record this queue for getting the
+ default set to this queue again if it re-appears. */
+ /* We call this also if a queue is only conserved because on cups-browsed
+ shutdown it still has jobs */
+ if (!is_cups_default_printer(printer))
+ return 0;
+ /* Record the fact that this printer was default */
+ if (record_default_printer(default_printer, 0) < 0) {
+ /* Delete record file if recording failed */
+ debug_printf("ERROR: Failed recording remote default printer (%s). Removing the file with possible old recording.\n",
+ printer);
+ invalidate_default_printer(0);
+ } else
+ debug_printf("Recorded the fact that the current printer (%s) is the default printer before deleting the queue and returning to the local default printer.\n",
+ printer);
+ /* Switch back to a recorded local printer, if available */
+ const char *local_default = retrieve_default_printer(1);
+ if (local_default != NULL) {
+ if (set_cups_default_printer(local_default) >= 0)
+ debug_printf("Switching back to %s as default printer.\n",
+ local_default);
+ else {
+ debug_printf("ERROR: Unable to switch back to %s as default printer.\n",
+ local_default);
+ return -1;
+ }
+ }
+ invalidate_default_printer(1);
+ return 0;
+}
+
+static void
+on_printer_state_changed (CupsNotifier *object,
+ const gchar *text,
+ const gchar *printer_uri,
+ const gchar *printer,
+ guint printer_state,
+ const gchar *printer_state_reasons,
+ gboolean printer_is_accepting_jobs,
+ gpointer user_data)
+{
+ int i;
+ char *ptr, buf[1024];
+ remote_printer_t *p, *q;
+ http_t *http = NULL;
+ ipp_t *request, *response;
+ ipp_attribute_t *attr;
+ const char *pname = NULL;
+ char *remote_cups_queue;
+ ipp_pstate_t pstate = IPP_PRINTER_IDLE;
+ int paccept = 0;
+ int num_jobs, min_jobs = 99999999;
+ cups_job_t *jobs = NULL;
+ const char *dest_host = NULL;
+ int dest_port = 0;
+ char dest_name[1024];
+ int dest_index = 0;
+ int valid_dest_found = 0;
+ char uri[HTTP_MAX_URI];
+ int job_id = 0;
+ int num_options;
+ cups_option_t *options;
+ static const char *pattrs[] =
+ {
+ "printer-name",
+ "printer-state",
+ "printer-is-accepting-jobs"
+ };
+ static const char *jattrs[] =
+ {
+ "job-id",
+ "job-state"
+ };
+ http_t *conn = NULL;
+
+ debug_printf("on_printer_state_changed() in THREAD %ld\n", pthread_self());
+
+ debug_printf("[CUPS Notification] Printer state change on printer %s: %s\n",
+ printer, text);
+ debug_printf("[CUPS Notification] Printer state reasons: %s\n",
+ printer_state_reasons);
+
+ if (terminating) {
+ debug_printf("[CUPS Notification]: Ignoring because cups-browsed is terminating.\n");
+ return;
+ }
+
+ if (autoshutdown && autoshutdown_on == NO_JOBS) {
+ if (check_jobs() == 0) {
+ /* If auto shutdown is active for triggering on no jobs being left, we
+ schedule the shutdown in autoshutdown_timeout seconds */
+ if (!autoshutdown_exec_id) {
+ debug_printf ("No jobs there any more on printers made available by us, shutting down in %d sec...\n", autoshutdown_timeout);
+ autoshutdown_exec_id =
+ g_timeout_add_seconds (autoshutdown_timeout, autoshutdown_execute,
+ NULL);
+ }
+ } else {
+ /* If auto shutdown is active for triggering on no jobs being left, we
+ cancel a shutdown in autoshutdown_timeout seconds as there are jobs
+ again. */
+ if (autoshutdown_exec_id) {
+ debug_printf ("New jobs there on the printers made available by us, killing auto shutdown timer.\n");
+ g_source_remove(autoshutdown_exec_id);
+ autoshutdown_exec_id = 0;
+ }
+ }
+ }
+
+ if ((ptr = strstr(text, " is now the default printer")) != NULL) {
+ /* Default printer has changed, we are triggered by the new default
+ printer */
+ strncpy(buf, text, ptr - text);
+ buf[ptr - text] = '\0';
+ debug_printf("[CUPS Notification] Default printer changed from %s to %s.\n",
+ default_printer, buf);
+ if (is_created_by_cups_browsed(default_printer)) {
+ /* Previous default printer created by cups-browsed */
+ if (!is_created_by_cups_browsed(buf)) {
+ /* New default printer local */
+ /* Removed backed-up local default printer as we do not have a
+ remote printer as default any more */
+ invalidate_default_printer(1);
+ debug_printf("Manually switched default printer from a cups-browsed-generated one to a local printer.\n");
+ }
+ } else {
+ /* Previous default printer local */
+ if (is_created_by_cups_browsed(buf)) {
+ /* New default printer created by cups-browsed */
+ /* Back up the local default printer to be able to return to it
+ if the remote printer disappears */
+ if (record_default_printer(default_printer, 1) < 0) {
+ /* Delete record file if recording failed */
+ debug_printf("ERROR: Failed recording local default printer. Removing the file with possible old recording.\n");
+ invalidate_default_printer(1);
+ } else
+ debug_printf("Recorded previous default printer so that if the currently selected cups-browsed-generated one disappears, we can return to the old local one.\n");
+ /* Remove a recorded remote printer as after manually selecting
+ another one as default this one is not relevant any more */
+ invalidate_default_printer(0);
+ }
+ }
+ if (default_printer != NULL)
+ free((void *)default_printer);
+ default_printer = strdup(buf);
+ } else if ((ptr = strstr(text, " is no longer the default printer"))
+ != NULL) {
+ /* Default printer has changed, we are triggered by the former default
+ printer */
+ strncpy(buf, text, ptr - text);
+ buf[ptr - text] = '\0';
+ debug_printf("[CUPS Notification] %s not default printer any more.\n", buf);
+ } else if ((ptr = strstr(text, " state changed to processing")) != NULL) {
+ /* Printer started processing a job, check if it uses the implicitclass
+ backend and if so, we select the remote queue to which to send the job
+ in a way so that we get load balancing between all remote queues
+ associated with this queue.
+
+ There are two methods to do that (configurable in cups-browsed.conf):
+
+ Queuing of jobs on the client (LoadBalancingType = QUEUE_ON_CLIENT):
+
+ Here we check all remote printers assigned to this printer and to its
+ slaves which is currently accepting jobs and idle. If all are busy,
+ we send a failure message and the backend will close with an error code
+ after some seconds of delay, to make the job getting retried making us
+ checking again here. If we find a destination, we tell the backend
+ which remote queue this destination is, making the backend printing the
+ job there immediately.
+
+ With this all waiting jobs get queued up on the client, on the servers
+ there will only be the jobs which are actually printing, as we do not
+ send jobs to a server which is already printing. This is also the
+ method which CUPS uses for classes. Advantage is a more even
+ distribution of the job workload on the servers, and if a server fails,
+ there are not several jobs stuck or lost. Disadvantage is that if one
+ takes the client (laptop, mobile phone, ...) out of the local network,
+ printing stops with the jobs waiting in the local queue.
+
+ Queuing of jobs on the servers (LoadBalancingType = QUEUE_ON_SERVERS):
+
+ Here we check all remote printers assigned to this printer and to its
+ slaves which is currently accepting jobs and find the one with the
+ lowest amount of jobs waiting and send the job to there. So on the
+ local queue we have never jobs waiting if at least one remote printer
+ accepts jobs.
+
+ Not having jobs waiting locally has the advantage that we can take the
+ local machine from the network and all jobs get printed. Disadvantage
+ is that if a server with a full queue of jobs goes away, the jobs go
+ away, too.
+
+ Default is queuing the jobs on the client as this is what CUPS does
+ with classes. */
+
+ debug_printf("[CUPS Notification] %s starts processing a job.\n", printer);
+ conn = http_connect_local ();
+ if (conn == NULL) {
+ debug_printf("Cannot connect to local CUPS to set destination for job in the load-balanced cluster %s.\n",
+ printer);
+ return;
+ }
+ q = printer_record(printer);
+ /* If we hit a slave and not the master, switch to the master */
+ if (q && q->slave_of)
+ q = q->slave_of;
+ if (q && q->netprinter == 0) {
+ /* We have remote CUPS queue(s) and so are using the implicitclass
+ backend */
+ debug_printf("[CUPS Notification] %s is using the \"implicitclass\" CUPS backend, so let us search for a destination for this job.\n", printer);
+ /* We keep track of the printer which we used last time and start
+ checking with the next printer this time, to get a "round robin"
+ type of printer usage instead of having most jobs going to the first
+ printer in the list. Method taken from the cupsdFindAvailablePrinter()
+ function of the scheduler/classes.c file of CUPS. */
+ if (q->last_printer < 0 ||
+ q->last_printer >= cupsArrayCount(remote_printers))
+ q->last_printer = 0;
+ log_cluster(q);
+ for (i = q->last_printer + 1; ; i++) {
+ if (i >= cupsArrayCount(remote_printers))
+ i = 0;
+ p = (remote_printer_t *)cupsArrayIndex(remote_printers, i);
+ if (!strcasecmp(p->queue_name, printer) &&
+ p->status == STATUS_CONFIRMED) {
+ remote_cups_queue = strrchr(p->uri, '/') + 1;
+ debug_printf("Checking state of remote printer %s on host %s, IP %s, port %d.\n", remote_cups_queue, p->host, p->ip, p->port);
+ http = httpConnectEncryptShortTimeout (p->ip ? p->ip : p->host,
+ p->port,
+ HTTP_ENCRYPT_IF_REQUESTED);
+ debug_printf("HTTP connection to %s:%d established.\n", p->host,
+ p->port);
+ if (http) {
+ /* Check whether the printer is idle, processing, or disabled */
+ httpSetTimeout(http, HttpRemoteTimeout, http_timeout_cb, NULL);
+ request = ippNewRequest(CUPS_GET_PRINTERS);
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes",
+ sizeof(pattrs) / sizeof(pattrs[0]),
+ NULL, pattrs);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name",
+ NULL, cupsUser());
+ if ((response = cupsDoRequest(http, request, "/")) !=
+ NULL) {
+ debug_printf("IPP request to %s:%d successful.\n", p->host,
+ p->port);
+ pname = NULL;
+ pstate = IPP_PRINTER_IDLE;
+ paccept = 0;
+ for (attr = ippFirstAttribute(response); attr != NULL;
+ attr = ippNextAttribute(response)) {
+ while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_PRINTER)
+ attr = ippNextAttribute(response);
+ if (attr == NULL)
+ break;
+ pname = NULL;
+ pstate = IPP_PRINTER_IDLE;
+ paccept = 0;
+ while (attr != NULL && ippGetGroupTag(attr) ==
+ IPP_TAG_PRINTER) {
+ if (!strcmp(ippGetName(attr), "printer-name") &&
+ ippGetValueTag(attr) == IPP_TAG_NAME)
+ pname = ippGetString(attr, 0, NULL);
+ else if (!strcmp(ippGetName(attr), "printer-state") &&
+ ippGetValueTag(attr) == IPP_TAG_ENUM)
+ pstate = (ipp_pstate_t)ippGetInteger(attr, 0);
+ else if (!strcmp(ippGetName(attr),
+ "printer-is-accepting-jobs") &&
+ ippGetValueTag(attr) == IPP_TAG_BOOLEAN)
+ paccept = ippGetBoolean(attr, 0);
+ attr = ippNextAttribute(response);
+ }
+ if (pname == NULL) {
+ if (attr == NULL)
+ break;
+ else
+ continue;
+ }
+ if (!strcasecmp(pname, remote_cups_queue)) {
+ if (paccept) {
+ debug_printf("Printer %s on host %s, port %d is accepting jobs.\n", remote_cups_queue, p->host, p->port);
+ switch (pstate) {
+ case IPP_PRINTER_IDLE:
+ valid_dest_found = 1;
+ dest_host = p->ip ? p->ip : p->host;
+ dest_port = p->port;
+ strncpy(dest_name, remote_cups_queue, sizeof(dest_name));
+ dest_index = i;
+ debug_printf("Printer %s on host %s, port %d is idle, take this as destination and stop searching.\n",
+ remote_cups_queue, p->host, p->port);
+ break;
+ case IPP_PRINTER_PROCESSING:
+ valid_dest_found = 1;
+ if (LoadBalancingType == QUEUE_ON_SERVERS) {
+ num_jobs = 0;
+ jobs = NULL;
+ num_jobs =
+ cupsGetJobs2(http, &jobs, remote_cups_queue, 0,
+ CUPS_WHICHJOBS_ACTIVE);
+ if (num_jobs >= 0 && num_jobs < min_jobs) {
+ min_jobs = num_jobs;
+ dest_host = p->ip ? p->ip : p->host;
+ dest_port = p->port;
+ strncpy(dest_name, remote_cups_queue,
+ sizeof(dest_name));
+ dest_index = i;
+ }
+ debug_printf("Printer %s on host %s, port %d is printing and it has %d jobs.\n",
+ remote_cups_queue, p->host, p->port,
+ num_jobs);
+ } else
+ debug_printf("Printer %s on host %s, port %d is printing.\n", remote_cups_queue, p->host, p->port);
+ break;
+ case IPP_PRINTER_STOPPED:
+ debug_printf("Printer %s on host %s, port %d is disabled, skip it.\n", remote_cups_queue, p->host, p->port);
+ break;
+ }
+ } else {
+ debug_printf("Printer %s on host %s, port %d is not accepting jobs, skip it.\n", remote_cups_queue, p->host, p->port);
+ }
+ break;
+ }
+ }
+ if (pstate == IPP_PRINTER_IDLE && paccept) {
+ q->last_printer = i;
+ break;
+ }
+ } else
+ debug_printf("IPP request to %s:%d failed.\n", p->host,
+ p->port);
+ httpClose(http);
+ http = NULL;
+ }
+ }
+ if (i == q->last_printer)
+ break;
+ }
+ /* Find the ID of the current job */
+ request = ippNewRequest(IPP_GET_JOBS);
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", ippPort(), "/printers/%s", printer);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes",
+ sizeof(jattrs) / sizeof(jattrs[0]), NULL, jattrs);
+ job_id = 0;
+ if ((response = cupsDoRequest(conn, request, "/")) != NULL) {
+ /* Get the current active job on this queue... */
+ ipp_jstate_t jobstate = IPP_JOB_PENDING;
+ for (attr = ippFirstAttribute(response); attr != NULL;
+ attr = ippNextAttribute(response)) {
+ if (!ippGetName(attr)) {
+ if (jobstate == IPP_JOB_PROCESSING)
+ break;
+ else
+ continue;
+ }
+ if (!strcmp(ippGetName(attr), "job-id") &&
+ ippGetValueTag(attr) == IPP_TAG_INTEGER)
+ job_id = ippGetInteger(attr, 0);
+ else if (!strcmp(ippGetName(attr), "job-state") &&
+ ippGetValueTag(attr) == IPP_TAG_ENUM)
+ jobstate = (ipp_jstate_t)ippGetInteger(attr, 0);
+ }
+ if (jobstate != IPP_JOB_PROCESSING)
+ job_id = 0;
+ ippDelete(response);
+ }
+ if (job_id == 0)
+ debug_printf("ERROR: could not determine ID of curremt job on %s\n",
+ printer);
+
+ /* Write the selected destination host into an option of our implicit
+ class queue (cups-browsed-dest-printer="<dest>") so that the
+ implicitclass backend will pick it up */
+ request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser());
+ if (dest_host) {
+ q->last_printer = dest_index;
+ snprintf(buf, sizeof(buf), "\"%d %s:%d/%s\"", job_id, dest_host,
+ dest_port, dest_name);
+ debug_printf("Destination for job %d to %s: %s:%d, queue %s\n",
+ job_id, printer, dest_host, dest_port, dest_name);
+ } else if (valid_dest_found == 1) {
+ snprintf(buf, sizeof(buf), "\"%d ALL_DESTS_BUSY\"", job_id);
+ debug_printf("All destinations busy for job %d to %s\n",
+ job_id, printer);
+ } else {
+ snprintf(buf, sizeof(buf), "\"%d NO_DEST_FOUND\"", job_id);
+ debug_printf("No destination found for job %d to %s\n",
+ job_id, printer);
+ }
+ num_options = 0;
+ options = NULL;
+ num_options = cupsAddOption(CUPS_BROWSED_DEST_PRINTER "-default", buf,
+ num_options, &options);
+ cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION);
+ cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER);
+ ippDelete(cupsDoRequest(conn, request, "/admin/"));
+ cupsFreeOptions(num_options, options);
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE) {
+ debug_printf("ERROR: Unable to set \"" CUPS_BROWSED_DEST_PRINTER
+ "-default\" option to communicate the destination server for this job (%s)!\n",
+ cupsLastErrorString());
+ return;
+ }
+ }
+ }
+}
+
+static void
+on_printer_deleted (CupsNotifier *object,
+ const gchar *text,
+ const gchar *printer_uri,
+ const gchar *printer,
+ guint printer_state,
+ const gchar *printer_state_reasons,
+ gboolean printer_is_accepting_jobs,
+ gpointer user_data)
+{
+ remote_printer_t *p;
+ const char* r;
+
+ debug_printf("on_printer_deleted() in THREAD %ld\n", pthread_self());
+
+ debug_printf("[CUPS Notification] Printer deleted: %s\n",
+ text);
+
+ if (terminating) {
+ debug_printf("[CUPS Notification]: Ignoring because cups-browsed is terminating.\n");
+ return;
+ }
+
+ if (is_created_by_cups_browsed(printer)) {
+ /* a cups-browsed-generated printer got deleted, re-create it */
+ debug_printf("Printer %s got deleted, re-creating it.\n",
+ printer);
+ /* If the deleted printer was the default printer, make sure it gets the
+ default printer again */
+ if (default_printer && !strcasecmp(printer, default_printer)) {
+ if (record_default_printer(printer, 0) < 0) {
+ /* Delete record file if recording failed */
+ debug_printf("ERROR: Failed recording remote default printer. Removing the file with possible old recording.\n");
+ invalidate_default_printer(0);
+ } else
+ debug_printf("Recorded %s as remote default printer so that it gets set as default after re-creating.\n");
+ /* Make sure that a recorded local default printer does not get lost
+ during the recovery operation */
+ if ((r = retrieve_default_printer(1)) != NULL) {
+ if (default_printer != NULL)
+ free((void *)default_printer);
+ default_printer = strdup(r);
+ }
+ }
+ /* Schedule for immediate creation of the CUPS queue */
+ p = printer_record(printer);
+ if (p && p->status != STATUS_DISAPPEARED &&
+ p->status != STATUS_UNCONFIRMED) {
+ p->status = STATUS_TO_BE_CREATED;
+ p->timeout = time(NULL) + TIMEOUT_IMMEDIATELY;
+ if (in_shutdown == 0)
+ recheck_timer();
+ }
+ }
+}
+
+static void
+on_printer_modified (CupsNotifier *object,
+ const gchar *text,
+ const gchar *printer_uri,
+ const gchar *printer,
+ guint printer_state,
+ const gchar *printer_state_reasons,
+ gboolean printer_is_accepting_jobs,
+ gpointer user_data)
+{
+ remote_printer_t *p;
+
+ debug_printf("on_printer_modified() in THREAD %ld\n", pthread_self());
+
+ debug_printf("[CUPS Notification] Printer modified: %s\n",
+ text);
+
+ if (terminating) {
+ debug_printf("[CUPS Notification]: Ignoring because cups-browsed is terminating.\n");
+ return;
+ }
+
+ if (is_created_by_cups_browsed(printer)) {
+ /* The user has changed settings of a printer which we have generated,
+ backup the changes for the case of a crash or unclean shutdown of
+ cups-browsed. */
+ p = printer_record(printer);
+ if (!p->no_autosave) {
+ debug_printf("Settings of printer %s got modified, doing backup.\n",
+ printer);
+ p->no_autosave = 1; /* Avoid infinite recursion */
+ record_printer_options(printer);
+ p->no_autosave = 0;
+ }
+ }
+}
+
+
+static remote_printer_t *
+create_remote_printer_entry (const char *queue_name,
+ const char *location,
+ const char *info,
+ const char *uri,
+ const char *host,
+ const char *ip,
+ int port,
+ const char *service_name,
+ const char *type,
+ const char *domain,
+ const char *pdl,
+ int color,
+ int duplex,
+ const char *make_model,
+ int is_cups_queue)
+{
+ remote_printer_t *p;
+ remote_printer_t *q;
+ int fd = 0; /* Script file descriptor */
+ char tempfile[1024]; /* Temporary file */
+ char buffer[8192]; /* Buffer for creating script */
+ int bytes;
+ const char *cups_serverbin; /* CUPS_SERVERBIN environment variable */
+ int uri_status, host_port;
+ http_t *http = NULL;
+ char scheme[10], userpass[1024], host_name[1024], resource[1024];
+ ipp_t *request, *response = NULL;
+#ifdef HAVE_CUPS_1_6
+ ipp_attribute_t *attr;
+ char valuebuffer[65536];
+ int i, count, left, right, bottom, top;
+ const char *default_page_size = NULL, *best_color_space = NULL, *color_space;
+ int is_pwgraster = 0;
+ int is_appleraster = 0;
+ int is_pclm = 0;
+ int is_pdf = 0;
+#endif /* HAVE_CUPS_1_6 */
+
+ if (!queue_name || !location || !info || !uri || !host || !service_name ||
+ !type || !domain) {
+ debug_printf("ERROR: create_remote_printer_entry(): Input value missing!\n");
+ return NULL;
+ }
+
+ /* Mark this as a queue to be created locally pointing to the printer */
+ if ((p = (remote_printer_t *)calloc(1, sizeof(remote_printer_t))) == NULL) {
+ debug_printf("ERROR: Unable to allocate memory.\n");
+ return NULL;
+ }
+
+ /* Assure that, if we have forgotten to set a field in the printer
+ record, that it is set to zero */
+ memset(p, 0, sizeof(remote_printer_t));
+
+ /* Queue name */
+ p->queue_name = strdup(queue_name);
+ if (!p->queue_name)
+ goto fail;
+
+ p->location = strdup(location);
+ if (!p->location)
+ goto fail;
+
+ p->info = strdup(info);
+ if (!p->info)
+ goto fail;
+
+ p->uri = strdup(uri);
+ if (!p->uri)
+ goto fail;
+
+ p->slave_of = NULL;
+ p->last_printer = -1;
+
+ p->num_options = 0;
+ p->options = NULL;
+
+ p->host = strdup (host);
+ if (!p->host)
+ goto fail;
+
+ p->ip = (ip != NULL ? strdup (ip) : NULL);
+
+ p->port = (port != 0 ? port : ippPort());
+
+ p->service_name = strdup (service_name);
+ if (!p->service_name)
+ goto fail;
+
+ /* Record DNS-SD service parameters to identify print queue
+ entry for removal when service disappears */
+ p->type = strdup (type);
+ if (!p->type)
+ goto fail;
+
+ p->domain = strdup (domain);
+ if (!p->domain)
+ goto fail;
+
+ /* Schedule for immediate creation of the CUPS queue */
+ p->status = STATUS_TO_BE_CREATED;
+ p->timeout = time(NULL) + TIMEOUT_IMMEDIATELY;
+
+ /* Flag which can be set to inhibit automatic saving of option settings
+ by the on_printer_modified() notification handler function */
+ p->no_autosave = 0;
+
+ /* Flag to mark whether this printer was discovered through a legacy
+ CUPS broadcast (1) or through DNS-SD (0) */
+ p->is_legacy = 0;
+
+ /* Remote CUPS printer or local queue remaining from previous cups-browsed
+ session */
+ /* is_cups_queue: -1: Unknown, 0: IPP printer, 1: Remote CUPS queue,
+ 2: Remote CUPS queue in user-defined cluster */
+ if (is_cups_queue != 0) {
+ if (is_cups_queue > 0 && CreateRemoteCUPSPrinterQueues == 0) {
+ debug_printf("Printer %s (%s) is a remote CUPS printer and cups-browsed is not configured to set up such printers automatically, ignoring this printer.\n",
+ p->queue_name, p->uri);
+ goto fail;
+ }
+ /* For a remote CUPS printer our local queue will be raw or get a
+ PPD file from the remote CUPS server, so that the driver on the
+ remote CUPS server gets used. So we will not generate a PPD file
+ or interface script at this point. */
+ p->netprinter = 0;
+ p->ppd = NULL;
+ p->model = NULL;
+ p->ifscript = NULL;
+ /* Check whether we have an equally named queue already from another
+ server */
+ for (q = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ q;
+ q = (remote_printer_t *)cupsArrayNext(remote_printers))
+ if (!strcasecmp(q->queue_name, p->queue_name) && /* Queue with same name
+ on server */
+ !q->slave_of) /* Find the master of the queues with this name,
+ to avoid "daisy chaining" */
+ break;
+ if (q && AutoClustering == 0 && is_cups_queue == 1) {
+ debug_printf("We have already created a queue with the name %s for another remote CUPS printer but automatic clustering of equally named printers is turned off nor did we find a manually defined cluster this printer belongs to. Skipping this printer.\n", p->queue_name);
+ debug_printf("In cups-browsed.conf try setting \"AutoClustering On\" to cluster equally-named remote CUPS printers, \"LocalQueueNamingRemoteCUPS DNS-SD\" to avoid queue name clashes, or define clusters with the \"Cluster\" directive.\n");
+ goto fail;
+ }
+ if (q && q->netprinter == 1) {
+ debug_printf("We have already created a queue with the name %s for another printer which is not a remote CUPS printer. Skipping this printer.\n", p->queue_name);
+ debug_printf("Try setting \"LocalQueueNamingRemoteCUPS DNS-SD\" or \"LocalQueueNamingRemoteCUPS RemoteName\" in cups-browsed.conf.\n");
+ goto fail;
+ }
+ p->slave_of = (q && q->status != STATUS_DISAPPEARED &&
+ q->status != STATUS_UNCONFIRMED) ? q : NULL;
+ if (p->slave_of) {
+ debug_printf("Printer %s already available through host %s, port %d.\n",
+ p->queue_name, q->host, q->port);
+ /* Update q */
+ q->status = STATUS_TO_BE_CREATED;
+ q->timeout = time(NULL) + TIMEOUT_IMMEDIATELY;
+ log_cluster(p);
+ } else if (q) {
+ q->slave_of = p;
+ debug_printf("Unconfirmed/disappeared printer %s already available through host %s, port %d, marking that printer a slave of the newly found one.\n",
+ p->queue_name, q->host, q->port);
+ log_cluster(p);
+ }
+ } else {
+#ifndef HAVE_CUPS_1_6
+ /* The following code uses a lot of CUPS >= 1.6 specific stuff.
+ For older CUPS <= 1.5.4 the following functionality is skipped
+ which means for CUPS <= 1.5.4 only for CUPS printer broadcasts
+ there are local queues created which should be sufficient
+ on systems where traditional CUPS <= 1.5.4 is used. */
+ goto fail;
+#else /* HAVE_CUPS_1_6 */
+ /* Non-CUPS printer broadcasts are most probably from printers
+ directly connected to the network and using the IPP protocol.
+ We check whether we can set them up without a device-specific
+ driver, only using page description languages which the
+ operating system provides: PCL 5c/5e/6/XL, PostScript, PDF, PWG
+ Raster, Apple Raster, PCLm. Especially printers designed for
+ driverless printing (DNS-SD + IPP 2.x + at least one of PWG
+ Raster, Apple Raster, PCLm, PDF) will work this way. Making
+ only driverless queues we can get an easy, configuration-less
+ way to print from mobile devices, even if there is no CUPS
+ server with shared printers around. */
+
+ if (CreateIPPPrinterQueues == IPP_PRINTERS_NO) {
+ debug_printf("Printer %s (%s) is an IPP network printer and cups-browsed is not configured to set up such printers automatically, ignoring this printer.\n",
+ p->queue_name, p->uri);
+ goto fail;
+ }
+
+ if (!pdl || pdl[0] == '\0' ||
+ (!strcasestr(pdl, "application/postscript") &&
+ !strcasestr(pdl, "application/pdf") &&
+ !strcasestr(pdl, "image/pwg-raster") &&
+#ifdef CUPS_RASTER_HAVE_APPLERASTER
+ !strcasestr(pdl, "image/urf") &&
+#endif
+#ifdef QPDF_HAVE_PCLM
+ !strcasestr(pdl, "application/PCLm") &&
+#endif
+ ((!strcasestr(pdl, "application/vnd.hp-PCL") &&
+ !strcasestr(pdl, "application/PCL") &&
+ !strcasestr(pdl, "application/x-pcl")) ||
+ ((!strncasecmp(make_model, "HP", 2) || /* HP inkjets not supported */
+ !strncasecmp(make_model, "Hewlett Packard", 15) ||
+ !strncasecmp(make_model, "Hewlett-Packard", 15)) &&
+ !strcasestr(make_model, "LaserJet") &&
+ !strcasestr(make_model, "Mopier"))) &&
+ !strcasestr(pdl, "application/vnd.hp-PCLXL"))) {
+ debug_printf("Cannot create remote printer %s (URI: %s, Model: %s, Accepted data formats: %s) as its PDLs are not known, ignoring this printer.\n",
+ p->queue_name, p->uri, make_model, pdl);
+ debug_printf("Supported PDLs: PWG Raster, %s%sPostScript, PDF, PCL XL, PCL 5c/e (HP inkjets report themselves as PCL printers but their PCL is not supported)\n",
+#ifdef CUPS_RASTER_HAVE_APPLERASTER
+ "Apple Raster, ",
+#else
+ "",
+#endif
+#ifdef QPDF_HAVE_PCLM
+ "PCLm, "
+#else
+ ""
+#endif
+ );
+ goto fail;
+ }
+
+ /* Check whether we have an equally named queue already */
+ for (q = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ q;
+ q = (remote_printer_t *)cupsArrayNext(remote_printers))
+ if (!strcasecmp(q->queue_name, p->queue_name)) {/* Queue with same name */
+ debug_printf("We have already created a queue with the name %s for another printer. Skipping this printer.\n", p->queue_name);
+ debug_printf("Try setting \"LocalQueueNamingIPPPrinter DNS-SD\" in cups-browsed.conf.\n");
+ goto fail;
+ }
+
+ p->slave_of = NULL;
+ p->model = NULL;
+ p->netprinter = 1;
+
+ /* Request printer properties via IPP to generate a PPD file for the
+ printer (mainly driverless-capable printers)
+ If we work with Systen V interface scripts use this info to set
+ option defaults. */
+ uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, uri,
+ scheme, sizeof(scheme),
+ userpass, sizeof(userpass),
+ host_name, sizeof(host_name),
+ &(host_port),
+ resource, sizeof(resource));
+ if (uri_status != HTTP_URI_OK)
+ goto fail;
+ if ((http = httpConnect(host_name, host_port)) ==
+ NULL) {
+ debug_printf("Cannot connect to remote printer %s (%s:%d), ignoring this printer.\n",
+ p->uri, host_name, host_port);
+ goto fail;
+ }
+ request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
+ response = cupsDoRequest(http, request, resource);
+
+ /* Log all printer attributes for debugging */
+ if (debug_stderr || debug_logfile) {
+ attr = ippFirstAttribute(response);
+ while (attr) {
+ debug_printf("Attr: %s\n",
+ ippGetName(attr));
+ ippAttributeString(attr, valuebuffer, sizeof(valuebuffer));
+ debug_printf("Value: %s\n", valuebuffer);
+ for (i = 0; i < ippGetCount(attr); i ++)
+ debug_printf("Keyword: %s\n",
+ ippGetString(attr, i, NULL));
+ attr = ippNextAttribute(response);
+ }
+ }
+
+ /* If we have opted for only printers designed for driverless use (PWG
+ Raster + Apple Raster + PCLm + PDF) being set up automatically, we check
+ first, whether our printer supports IPP 2.0 or newer. If not, we
+ skip this printer */
+ if (CreateIPPPrinterQueues == IPP_PRINTERS_DRIVERLESS) {
+ valuebuffer[0] = '\0';
+ if ((attr = ippFindAttribute(response,
+ "ipp-versions-supported",
+ IPP_TAG_KEYWORD)) != NULL) {
+ debug_printf("Checking whether printer %s supports IPP 2.x or newer: Attr: %s\n",
+ p->queue_name, ippGetName(attr));
+ for (i = 0; i < ippGetCount(attr); i ++) {
+ strncpy(valuebuffer, ippGetString(attr, i, NULL),
+ sizeof(valuebuffer));
+ debug_printf("Checking whether printer %s supports IPP 2.x or newer: Keyword: %s\n",
+ p->queue_name, valuebuffer);
+ if (valuebuffer[0] > '1')
+ break;
+ }
+ }
+ if (!attr || valuebuffer[0] == '\0' || valuebuffer[0] <= '1') {
+ debug_printf("cups-browsed is configured to auto-setup only printers which are designed for driverless printing. These printers require IPP 2.x or newer, but this printer only supports IPP 1.x or older. Skipping.\n");
+ goto fail;
+ } else
+ debug_printf("--> Printer supports IPP 2.x or newer.\n");
+ }
+
+ /* If we have opted for only PWG Raster printers or for only printers
+ designed for driverless use (PWG Raster + Apple Raster + PCLm + PDF)
+ being set up automatically, we check whether the printer has a non-empty
+ string in its "pwg-raster-document-resolution-supported" IPP attribute
+ to see whether we have a PWG Raster printer. */
+ if (CreateIPPPrinterQueues == IPP_PRINTERS_PWGRASTER ||
+ CreateIPPPrinterQueues == IPP_PRINTERS_DRIVERLESS) {
+ valuebuffer[0] = '\0';
+ if ((attr = ippFindAttribute(response,
+ "pwg-raster-document-resolution-supported",
+ IPP_TAG_KEYWORD)) != NULL) {
+ debug_printf("Checking whether printer %s is PWG Raster: Attr: %s\n",
+ p->queue_name, ippGetName(attr));
+ ippAttributeString(attr, valuebuffer, sizeof(valuebuffer));
+ debug_printf("Checking whether printer %s is PWG Raster: Value: %s\n",
+ p->queue_name, valuebuffer);
+ if (valuebuffer[0] == '\0') {
+ for (i = 0; i < ippGetCount(attr); i ++) {
+ strncpy(valuebuffer, ippGetString(attr, i, NULL),
+ sizeof(valuebuffer));
+ debug_printf("Checking whether printer %s is PWG Raster: Keyword: %s\n",
+ p->queue_name, valuebuffer);
+ if (valuebuffer[0] != '\0')
+ break;
+ }
+ }
+ }
+ if (attr && valuebuffer[0] != '\0')
+ is_pwgraster = 1;
+ debug_printf("--> Printer %s PWG Raster.\n",
+ is_pwgraster ? "supports" : "does not support");
+ }
+
+#ifdef CUPS_RASTER_HAVE_APPLERASTER
+ /* If we have opted for only Apple Raster printers or for only printers
+ designed for driverless use (PWG Raster + Apple Raster + PCLm + PDF)
+ being set up automatically, we check whether the printer has a non-empty
+ string in its "urf-supported" IPP attribute to see whether we have an
+ Apple Raster printer. */
+ if (CreateIPPPrinterQueues == IPP_PRINTERS_APPLERASTER ||
+ CreateIPPPrinterQueues == IPP_PRINTERS_DRIVERLESS) {
+ valuebuffer[0] = '\0';
+ if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL) {
+ debug_printf("Checking whether printer %s understands Apple Raster: Attr: %s\n",
+ p->queue_name, ippGetName(attr));
+ ippAttributeString(attr, valuebuffer, sizeof(valuebuffer));
+ debug_printf("Checking whether printer %s understands Apple Raster: Value: %s\n",
+ p->queue_name, valuebuffer);
+ if (valuebuffer[0] == '\0') {
+ for (i = 0; i < ippGetCount(attr); i ++) {
+ strncpy(valuebuffer, ippGetString(attr, i, NULL),
+ sizeof(valuebuffer));
+ debug_printf("Checking whether printer %s understands Apple Raster: Keyword: %s\n",
+ p->queue_name, valuebuffer);
+ if (valuebuffer[0] != '\0')
+ break;
+ }
+ }
+ }
+ if (attr && valuebuffer[0] != '\0')
+ is_appleraster = 1;
+ debug_printf("--> Printer %s Apple Raster.\n",
+ is_appleraster ? "supports" : "does not support");
+ }
+#endif
+
+#ifdef QPDF_HAVE_PCLM
+ /* If we have opted for only PCLm printers or for only printers
+ designed for driverless use (PWG Raster + Apple Raster + PCLm + PDF)
+ being set up automatically, we check whether the printer has a non-empty
+ string in its "pclm-compression-method-preferred" IPP attribute to see
+ whether we have a PCLm printer. */
+ if (CreateIPPPrinterQueues == IPP_PRINTERS_PCLM ||
+ CreateIPPPrinterQueues == IPP_PRINTERS_DRIVERLESS) {
+ valuebuffer[0] = '\0';
+ if ((attr = ippFindAttribute(response,
+ "pclm-compression-method-preferred",
+ IPP_TAG_KEYWORD)) != NULL) {
+ debug_printf("Checking whether printer %s understands PCLm: Attr: %s\n",
+ p->queue_name, ippGetName(attr));
+ ippAttributeString(attr, valuebuffer, sizeof(valuebuffer));
+ debug_printf("Checking whether printer %s understands PCLm: Value: %s\n",
+ p->queue_name, valuebuffer);
+ if (valuebuffer[0] == '\0') {
+ for (i = 0; i < ippGetCount(attr); i ++) {
+ strncpy(valuebuffer, ippGetString(attr, i, NULL),
+ sizeof(valuebuffer));
+ debug_printf("Checking whether printer %s understands PCLm: Keyword: %s\n",
+ p->queue_name, valuebuffer);
+ if (valuebuffer[0] != '\0')
+ break;
+ }
+ }
+ }
+ if (attr && valuebuffer[0] != '\0')
+ is_pclm = 1;
+ debug_printf("--> Printer %s PCLm.\n",
+ is_pclm ? "supports" : "does not support");
+ }
+#endif
+
+ /* If we have opted for only PDF printers or for only printers
+ designed for driverless use (PWG Raster + Apple Raster + PCLm + PDF)
+ being set up automatically, we check whether the printer has
+ "application/pdf" under its PDLs. */
+ if (CreateIPPPrinterQueues == IPP_PRINTERS_PDF ||
+ CreateIPPPrinterQueues == IPP_PRINTERS_DRIVERLESS) {
+ debug_printf("Checking whether printer %s understands PDF: PDLs: %s\n",
+ p->queue_name, pdl);
+ if(strcasestr(pdl, "application/pdf"))
+ is_pdf = 1;
+ debug_printf("--> Printer %s PDF.\n",
+ is_pdf ? "supports" : "does not support");
+ }
+
+ /* If the printer is not the driverless printer we opted for, we skip
+ this printer. */
+ if ((CreateIPPPrinterQueues == IPP_PRINTERS_DRIVERLESS &&
+ is_pwgraster == 0 && is_appleraster == 0 && is_pclm == 0 &&
+ is_pdf == 0) ||
+ (CreateIPPPrinterQueues == IPP_PRINTERS_PWGRASTER &&
+ is_pwgraster == 0) ||
+ (CreateIPPPrinterQueues == IPP_PRINTERS_APPLERASTER &&
+ is_appleraster == 0) ||
+ (CreateIPPPrinterQueues == IPP_PRINTERS_PCLM &&
+ is_pclm == 0) ||
+ (CreateIPPPrinterQueues == IPP_PRINTERS_PDF &&
+ is_pdf == 0)) {
+ debug_printf("Printer %s (%s%s%s%s%s%s%s%s%s%s%s%s%s) does not support the driverless printing protocol cups-browsed is configured to accept for setting up such printers automatically, ignoring this printer.\n",
+ p->queue_name, p->uri,
+ (CreateIPPPrinterQueues == IPP_PRINTERS_PWGRASTER ||
+ CreateIPPPrinterQueues == IPP_PRINTERS_DRIVERLESS ?
+ ", " : ""),
+ (CreateIPPPrinterQueues == IPP_PRINTERS_PWGRASTER ||
+ CreateIPPPrinterQueues == IPP_PRINTERS_DRIVERLESS ?
+ (is_pwgraster ? "" : "not ") : ""),
+ (CreateIPPPrinterQueues == IPP_PRINTERS_PWGRASTER ||
+ CreateIPPPrinterQueues == IPP_PRINTERS_DRIVERLESS ?
+ "PWG Raster" : ""),
+ (CreateIPPPrinterQueues == IPP_PRINTERS_APPLERASTER ||
+ CreateIPPPrinterQueues == IPP_PRINTERS_DRIVERLESS ?
+ ", " : ""),
+ (CreateIPPPrinterQueues == IPP_PRINTERS_APPLERASTER ||
+ CreateIPPPrinterQueues == IPP_PRINTERS_DRIVERLESS ?
+ (is_appleraster ? "" : "not ") : ""),
+ (CreateIPPPrinterQueues == IPP_PRINTERS_APPLERASTER ||
+ CreateIPPPrinterQueues == IPP_PRINTERS_DRIVERLESS ?
+ "Apple Raster" : ""),
+ (CreateIPPPrinterQueues == IPP_PRINTERS_PCLM ||
+ CreateIPPPrinterQueues == IPP_PRINTERS_DRIVERLESS ?
+ ", " : ""),
+ (CreateIPPPrinterQueues == IPP_PRINTERS_PCLM ||
+ CreateIPPPrinterQueues == IPP_PRINTERS_DRIVERLESS ?
+ (is_pclm ? "" : "not ") : ""),
+ (CreateIPPPrinterQueues == IPP_PRINTERS_PCLM ||
+ CreateIPPPrinterQueues == IPP_PRINTERS_DRIVERLESS ?
+ "PCLm" : ""),
+ (CreateIPPPrinterQueues == IPP_PRINTERS_PDF ||
+ CreateIPPPrinterQueues == IPP_PRINTERS_DRIVERLESS ?
+ ", " : ""),
+ (CreateIPPPrinterQueues == IPP_PRINTERS_PDF ||
+ CreateIPPPrinterQueues == IPP_PRINTERS_DRIVERLESS ?
+ (is_pdf ? "" : "not ") : ""),
+ (CreateIPPPrinterQueues == IPP_PRINTERS_PDF ||
+ CreateIPPPrinterQueues == IPP_PRINTERS_DRIVERLESS ?
+ "PDF" : ""));
+ goto fail;
+ }
+
+ if (IPPPrinterQueueType == PPD_YES) {
+ if (!ppdCreateFromIPP(buffer, sizeof(buffer), response, make_model,
+ pdl, color, duplex)) {
+ if (errno != 0)
+ debug_printf("Unable to create PPD file: %s\n", strerror(errno));
+ else
+ debug_printf("Unable to create PPD file: %s\n", ppdgenerator_msg);
+ goto fail;
+ } else {
+ debug_printf("PPD generation successful: %s\n", ppdgenerator_msg);
+ debug_printf("Created temporary PPD file: %s\n", buffer);
+ p->ppd = strdup(buffer);
+ p->ifscript = NULL;
+ }
+ } else if (IPPPrinterQueueType == PPD_NO) {
+ p->ppd = NULL;
+
+ /* Find default page size of the printer */
+ attr = ippFindAttribute(response,
+ "media-default",
+ IPP_TAG_ZERO);
+ if (attr) {
+ default_page_size = ippGetString(attr, 0, NULL);
+ debug_printf("Default page size: %s\n",
+ default_page_size);
+ p->num_options = cupsAddOption("media-default",
+ strdup(default_page_size),
+ p->num_options, &(p->options));
+ } else {
+ attr = ippFindAttribute(response,
+ "media-ready",
+ IPP_TAG_ZERO);
+ if (attr) {
+ default_page_size = ippGetString(attr, 0, NULL);
+ debug_printf("Default page size: %s\n",
+ default_page_size);
+ p->num_options = cupsAddOption("media-default",
+ strdup(default_page_size),
+ p->num_options, &(p->options));
+ } else
+ debug_printf("No default page size found!\n");
+ }
+
+ /* Find maximum unprintable margins of the printer */
+ if ((attr = ippFindAttribute(response, "media-bottom-margin-supported", IPP_TAG_INTEGER)) != NULL) {
+ for (i = 1, bottom = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
+ if (ippGetInteger(attr, i) > bottom)
+ bottom = ippGetInteger(attr, i);
+ } else
+ bottom = 1270;
+ snprintf(buffer, sizeof(buffer), "%d", bottom);
+ p->num_options = cupsAddOption("media-bottom-margin-default",
+ strdup(buffer),
+ p->num_options, &(p->options));
+
+ if ((attr = ippFindAttribute(response, "media-left-margin-supported", IPP_TAG_INTEGER)) != NULL) {
+ for (i = 1, left = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
+ if (ippGetInteger(attr, i) > left)
+ left = ippGetInteger(attr, i);
+ } else
+ left = 635;
+ snprintf(buffer, sizeof(buffer), "%d", left);
+ p->num_options = cupsAddOption("media-left-margin-default",
+ strdup(buffer),
+ p->num_options, &(p->options));
+
+ if ((attr = ippFindAttribute(response, "media-right-margin-supported", IPP_TAG_INTEGER)) != NULL) {
+ for (i = 1, right = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
+ if (ippGetInteger(attr, i) > right)
+ right = ippGetInteger(attr, i);
+ } else
+ right = 635;
+ snprintf(buffer, sizeof(buffer), "%d", right);
+ p->num_options = cupsAddOption("media-right-margin-default",
+ strdup(buffer),
+ p->num_options, &(p->options));
+
+ if ((attr = ippFindAttribute(response, "media-top-margin-supported", IPP_TAG_INTEGER)) != NULL) {
+ for (i = 1, top = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
+ if (ippGetInteger(attr, i) > top)
+ top = ippGetInteger(attr, i);
+ } else
+ top = 1270;
+ snprintf(buffer, sizeof(buffer), "%d", top);
+ p->num_options = cupsAddOption("media-top-margin-default",
+ strdup(buffer),
+ p->num_options, &(p->options));
+
+ debug_printf("Margins: Left: %d, Right: %d, Top: %d, Bottom: %d\n",
+ left, right, top, bottom);
+
+ /* Find best color space of the printer */
+ attr = ippFindAttribute(response,
+ "pwg-raster-document-type-supported",
+ IPP_TAG_ZERO);
+ if (attr) {
+ for (i = 0; i < ippGetCount(attr); i ++) {
+ color_space = ippGetString(attr, i, NULL);
+ debug_printf("Supported color space: %s\n", color_space);
+ if (color_space_score(color_space) >
+ color_space_score(best_color_space))
+ best_color_space = color_space;
+ }
+ debug_printf("Best color space: %s\n",
+ best_color_space);
+ p->num_options = cupsAddOption("print-color-mode-default",
+ strdup(best_color_space),
+ p->num_options, &(p->options));
+ } else {
+ debug_printf("No info about supported color spaces found!\n");
+ p->num_options = cupsAddOption("print-color-mode-default",
+ color == 1 ? "rgb" : "black",
+ p->num_options, &(p->options));
+ }
+
+ if (duplex)
+ p->num_options = cupsAddOption("sides-default", "two-sided-long-edge",
+ p->num_options, &(p->options));
+
+ p->num_options = cupsAddOption("output-format-default", strdup(pdl),
+ p->num_options, &(p->options));
+ p->num_options = cupsAddOption("make-and-model-default",
+ remove_bad_chars(make_model, 0),
+ p->num_options, &(p->options));
+
+ if ((cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL)
+ cups_serverbin = CUPS_SERVERBIN;
+
+ if ((fd = cupsTempFd(tempfile, sizeof(tempfile))) < 0) {
+ debug_printf("Unable to create interface script file\n");
+ goto fail;
+ }
+
+ debug_printf("Creating temp script file \"%s\"\n", tempfile);
+
+ snprintf(buffer, sizeof(buffer),
+ "#!/bin/sh\n"
+ "# System V interface script for printer %s generated by cups-browsed\n"
+ "\n"
+ "if [ $# -lt 5 -o $# -gt 6 ]; then\n"
+ " echo \"ERROR: $0 job-id user title copies options [file]\" >&2\n"
+ " exit 1\n"
+ "fi\n"
+ "\n"
+ "# Read from given file\n"
+ "if [ -n \"$6\" ]; then\n"
+ " exec \"$0\" \"$1\" \"$2\" \"$3\" \"$4\" \"$5\" < \"$6\"\n"
+ "fi\n"
+ "\n"
+ "%s/filter/sys5ippprinter \"$1\" \"$2\" \"$3\" \"$4\" \"$5\"\n",
+ p->queue_name, cups_serverbin);
+
+ bytes = write(fd, buffer, strlen(buffer));
+ if (bytes != strlen(buffer)) {
+ debug_printf("Unable to write interface script into the file\n");
+ goto fail;
+ }
+
+ close(fd);
+
+ p->ifscript = strdup(tempfile);
+ }
+
+ /*p->model = "drv:///sample.drv/laserjet.ppd";
+ debug_printf("PPD from system for %s: %s\n", p->queue_name, p->model);*/
+
+ /*p->ppd = "/usr/share/ppd/cupsfilters/pxlcolor.ppd";
+ debug_printf("PPD from file for %s: %s\n", p->queue_name, p->ppd);*/
+
+ /*p->ifscript = "/usr/lib/cups/filter/sys5ippprinter";
+ debug_printf("System V Interface script for %s: %s\n", p->queue_name, p->ifscript);*/
+
+#endif /* HAVE_CUPS_1_6 */
+ }
+
+ /* Add the new remote printer entry */
+ log_all_printers();
+ cupsArrayAdd(remote_printers, p);
+ log_all_printers();
+
+ /* If auto shutdown is active we have perhaps scheduled a timer to shut down
+ due to not having queues any more to maintain, kill the timer now */
+ if (autoshutdown && autoshutdown_exec_id &&
+ autoshutdown_on == NO_QUEUES &&
+ cupsArrayCount(remote_printers) > 0) {
+ debug_printf ("New printers there to make available, killing auto shutdown timer.\n");
+ g_source_remove(autoshutdown_exec_id);
+ autoshutdown_exec_id = 0;
+ }
+
+ ippDelete(response);
+ if (http)
+ httpClose(http);
+ return p;
+
+ fail:
+ debug_printf("ERROR: Unable to create print queue, ignoring printer.\n");
+ if (response) ippDelete(response);
+ if (http)
+ httpClose(http);
+ if (p->type) free (p->type);
+ if (p->service_name) free (p->service_name);
+ if (p->host) free (p->host);
+ if (p->domain) free (p->domain);
+ if (p->ip) free (p->ip);
+ cupsFreeOptions(p->num_options, p->options);
+ if (p->uri) free (p->uri);
+ if (p->location) free (p->location);
+ if (p->info) free (p->info);
+ if (p->queue_name) free (p->queue_name);
+ if (p->ppd) free (p->ppd);
+ if (p->model) free (p->model);
+ if (p->ifscript) free (p->ifscript);
+ free (p);
+ return NULL;
+}
+
+void
+remove_printer_entry(remote_printer_t *p) {
+ remote_printer_t *q = NULL, *r;
+
+ if (p == NULL) {
+ debug_printf ("ERROR: remove_printer_entry(): Supplied printer entry is NULL");
+ return;
+ }
+
+ if (!p->slave_of) {
+ /* Check whether this queue has a slave from another server and
+ find it */
+ for (q = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ q;
+ q = (remote_printer_t *)cupsArrayNext(remote_printers))
+ if (q != p && q->slave_of == p &&
+ q->status != STATUS_DISAPPEARED && q->status != STATUS_UNCONFIRMED)
+ break;
+ }
+ if (q) {
+ /* Make q the master of the cluster and p a slave of q. This way
+ removal of p does not delete the cluster's CUPS queue and update
+ of q makes sure the cluster's queue gets back into working state */
+ for (r = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ r;
+ r = (remote_printer_t *)cupsArrayNext(remote_printers))
+ if (r != q && r->slave_of == p &&
+ r->status != STATUS_DISAPPEARED && r->status != STATUS_UNCONFIRMED)
+ r->slave_of = q;
+ q->slave_of = NULL;
+ p->slave_of = q;
+ q->num_options = p->num_options;
+ q->options = p->options;
+ p->num_options = 0;
+ p->options = NULL;
+ /* Schedule this printer for updating the CUPS queue */
+ q->status = STATUS_TO_BE_CREATED;
+ q->timeout = time(NULL) + TIMEOUT_IMMEDIATELY;
+ debug_printf("Printer %s (%s) diasappeared, replacing by backup on host %s, port %d with URI %s.\n",
+ p->queue_name, p->uri, q->host, q->port, q->uri);
+ } else
+ debug_printf("Printer %s (Host: %s, Port: %d, URI: %s) disappeared and no slave available (or it is a slave of another printer), removing entry.\n",
+ p->queue_name, p->host, p->port, p->uri);
+
+ /* Schedule entry and its CUPS queue for removal */
+ p->status = STATUS_DISAPPEARED;
+ p->timeout = time(NULL) + TIMEOUT_REMOVE;
+}
+
+gboolean update_cups_queues(gpointer unused) {
+ remote_printer_t *p, *q, *r;
+ http_t *http, *remote_http;
+ char uri[HTTP_MAX_URI], device_uri[HTTP_MAX_URI], buf[1024], line[1024];
+ char *remote_cups_queue;
+ int num_options;
+ cups_option_t *options;
+ int num_jobs;
+ cups_job_t *jobs;
+ ipp_t *request;
+ time_t current_time = time(NULL);
+ int i, new_cupsfilter_line_inserted, ap_remote_queue_id_line_inserted,
+ cont_line_read, want_raw;
+ char *disabled_str, *ptr, *prefix;
+ const char *loadedppd = NULL;
+ int pass_through_ppd;
+ ppd_file_t *ppd;
+ ppd_choice_t *choice;
+ cups_file_t *in, *out;
+ char keyword[1024], *keyptr;
+ const char *customval;
+ const char *val = NULL;
+ cups_dest_t *dest = NULL;
+ int is_temporary;
+
+ debug_printf("update_cups_queues() in THREAD %ld\n", pthread_self());
+
+ /* Create dummy entry to point slaves at when their master is about to
+ get removed now (if we point them to NULL, we would try to remove
+ the already removed CUPS queue again when it comes to the removal
+ of the slave. */
+ if ((r = (remote_printer_t *)calloc(1, sizeof(remote_printer_t))) == NULL) {
+ debug_printf("ERROR: Unable to allocate memory.\n");
+ if (in_shutdown == 0)
+ recheck_timer ();
+ return FALSE;
+ }
+ memset(r, 0, sizeof(remote_printer_t));
+ r->uri = "<DELETED>";
+ /* Now redirect the slave_of pointers of the masters which get deleted now
+ to this dummy entry */
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers))
+ if (p->status == STATUS_DISAPPEARED &&
+ (q = p->slave_of) != NULL && q->status == STATUS_DISAPPEARED)
+ p->slave_of = r;
+
+ debug_printf("Processing printer list ...\n");
+ log_all_printers();
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+
+ /* terminating means we have received a signal and should shut down.
+ in_shutdown means we have exited the main loop.
+ update_cups_queues() is called after having exited the main loop
+ in order to remove any queues we have set up */
+ if (terminating && !in_shutdown) {
+ debug_printf("Stopping processing printer list because cups-browsed is terminating.\n");
+ break;
+ }
+
+ switch (p->status) {
+
+ /* Print queue generated by us in a previous session */
+ case STATUS_UNCONFIRMED:
+
+ /* Only act if the timeout has passed */
+ if (p->timeout > current_time)
+ break;
+
+ /* Queue not reported again by DNS-SD, remove it */
+ debug_printf("No remote printer named %s available, removing entry from previous session.\n",
+ p->queue_name);
+ remove_printer_entry(p);
+
+ /* DNS-SD has reported this printer as disappeared or we have replaced
+ this printer by another one */
+ case STATUS_DISAPPEARED:
+
+ /* Only act if the timeout has passed */
+ if (p->timeout > current_time)
+ break;
+
+ debug_printf("Removing entry %s (%s)%s.\n", p->queue_name, p->uri,
+ (p->slave_of ? "" : " and its CUPS queue"));
+
+ /* Remove the CUPS queue */
+ /* Slaves do not have a CUPS queue */
+ if ((q = p->slave_of) == NULL) {
+
+ if ((http = http_connect_local ()) == NULL) {
+ debug_printf("Unable to connect to CUPS!\n");
+ if (in_shutdown == 0)
+ p->timeout = current_time + TIMEOUT_RETRY;
+ break;
+ }
+
+ /* Do not auto-save option settings due to the print queue removal
+ process */
+ p->no_autosave = 1;
+
+ /* Record the option settings to retrieve them when the remote
+ queue re-appears later or when cups-browsed gets started again */
+ record_printer_options(p->queue_name);
+
+ /* Check whether there are still jobs and do not remove the queue
+ then */
+ num_jobs = 0;
+ jobs = NULL;
+ num_jobs = cupsGetJobs2(http, &jobs, p->queue_name, 0, CUPS_WHICHJOBS_ACTIVE);
+ if (num_jobs != 0) { /* error or jobs */
+ debug_printf("Queue has still jobs or CUPS error!\n");
+ cupsFreeJobs(num_jobs, jobs);
+ /* Disable the queue */
+#ifdef HAVE_AVAHI
+ if (avahi_present || p->domain == NULL || p->domain[0] == '\0')
+ /* If avahi has got shut down, do not disable queues which are,
+ created based on DNS-SD broadcasts as the server has most
+ probably not gone away */
+#endif /* HAVE_AVAHI */
+ disable_printer(p->queue_name,
+ "Printer disappeared or cups-browsed shutdown");
+ /* Schedule the removal of the queue for later */
+ if (in_shutdown == 0) {
+ p->timeout = current_time + TIMEOUT_RETRY;
+ p->no_autosave = 0;
+ break;
+ }
+ }
+
+ /* If this queue was the default printer, note that fact so that
+ it gets the default printer again when it re-appears, also switch
+ back to the last local default printer */
+ queue_removal_handle_default(p->queue_name);
+
+ /* If we do not have a subscription to CUPS' D-Bus notifications and
+ so no default printer management, we simply do not remove this
+ CUPS queue if it is the default printer, to not cause a change
+ of the default printer or the loss of the information that this
+ printer is the default printer. */
+ if (cups_notifier == NULL && is_cups_default_printer(p->queue_name)) {
+ /* Schedule the removal of the queue for later */
+ if (in_shutdown == 0) {
+ p->timeout = current_time + TIMEOUT_RETRY;
+ p->no_autosave = 0;
+ break;
+ }
+ }
+
+ /* No jobs, remove the CUPS queue */
+ debug_printf("Removing local CUPS queue %s (%s).\n", p->queue_name,
+ p->uri);
+ request = ippNewRequest(CUPS_DELETE_PRINTER);
+ /* Printer URI: ipp://localhost:631/printers/<queue name> */
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", ippPort(), "/printers/%s", p->queue_name);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+ /* Default user */
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser());
+ /* Do it */
+ ippDelete(cupsDoRequest(http, request, "/admin/"));
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE) {
+ debug_printf("Unable to remove CUPS queue!\n");
+ if (in_shutdown == 0) {
+ p->timeout = current_time + TIMEOUT_RETRY;
+ p->no_autosave = 0;
+ break;
+ }
+ }
+ }
+
+ /* CUPS queue removed, remove the list entry */
+ /* Note that we do not need to break out of the loop passing through
+ all elements of a CUPS array when we remove an element via the
+ cupsArrayRemove() function, as the function decreases the array-
+ internal index by one and so the cupsArrayNext() call gives us
+ the element right after the deleted element. So no skipping
+ of an element and especially no reading beyond the end of the
+ array. */
+ cupsArrayRemove(remote_printers, p);
+ if (p->queue_name) free (p->queue_name);
+ if (p->location) free (p->location);
+ if (p->info) free (p->info);
+ if (p->uri) free (p->uri);
+ cupsFreeOptions(p->num_options, p->options);
+ if (p->host) free (p->host);
+ if (p->ip) free (p->ip);
+ if (p->service_name) free (p->service_name);
+ if (p->type) free (p->type);
+ if (p->domain) free (p->domain);
+ if (p->ppd) free (p->ppd);
+ if (p->model) free (p->model);
+ if (p->ifscript) free (p->ifscript);
+ free(p);
+ p = NULL;
+
+ /* If auto shutdown is active and all printers we have set up got removed
+ again, schedule the shutdown in autoshutdown_timeout seconds
+ Note that in this case we also do not have jobs any more so if we
+ auto shutdown on running out of jobs, trigger it here, too. */
+ if (in_shutdown == 0 && autoshutdown && !autoshutdown_exec_id &&
+ (cupsArrayCount(remote_printers) == 0 ||
+ (autoshutdown_on == NO_JOBS && check_jobs() == 0))) {
+ debug_printf ("No printers there any more to make available or no jobs, shutting down in %d sec...\n", autoshutdown_timeout);
+ autoshutdown_exec_id =
+ g_timeout_add_seconds (autoshutdown_timeout, autoshutdown_execute,
+ NULL);
+ }
+
+ break;
+
+ /* DNS-SD has reported a new remote printer, create a CUPS queue for it,
+ or upgrade an existing queue, or update a queue to use a backup host
+ when it has disappeared on the currently used host */
+ /* (...or, we've just received a CUPS Browsing packet for this queue) */
+ case STATUS_TO_BE_CREATED:
+
+ /* Do not create a queue for slaves */
+ if (p->slave_of) {
+ p->status = STATUS_CONFIRMED;
+ if (p->is_legacy) {
+ p->timeout = time(NULL) + BrowseTimeout;
+ debug_printf("starting BrowseTimeout timer for %s (%ds)\n",
+ p->queue_name, BrowseTimeout);
+ } else
+ p->timeout = (time_t) -1;
+ break;
+ }
+
+ /* Only act if the timeout has passed */
+ if (p->timeout > current_time)
+ break;
+
+ debug_printf("Creating/Updating CUPS queue %s\n",
+ p->queue_name);
+
+ /* Make sure to have a connection to the local CUPS daemon */
+ if ((http = http_connect_local ()) == NULL) {
+ debug_printf("Unable to connect to CUPS!\n");
+ p->timeout = current_time + TIMEOUT_RETRY;
+ break;
+ }
+ httpSetTimeout(http, HttpLocalTimeout, http_timeout_cb, NULL);
+
+ /* Do not auto-save option settings due to the print queue creation
+ process */
+ p->no_autosave = 1;
+
+ /* Printer URI: ipp://localhost:631/printers/<queue name> */
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", ippPort(), "/printers/%s", p->queue_name);
+
+ /* If we have already a temporary CUPS queue our local queue we
+ are creating would overwrite the temporary queue, and so the
+ resulting queue will still be considered temporary by CUPS and
+ removed after one minute of inactivity. To avoid this we need
+ to convertthe queue into a permanent one and CUPS does this
+ only by sharing the queue (setting its boolean printer-is-shared
+ option. We unset the bit right after that to not actually share
+ the queue (if we want to share the queue we take care about this
+ later).
+ If the temporary queue is pointing to a remote CUPS printer
+ we cannot modify its printer-is-shared option as CUPS prevents
+ this. In this case we remove the temporary queue so that we
+ create a fresh one which will always be permanent.
+ If the temporary queue has still jobs we will not remove it to
+ not loose the jobs and wait with creating our new queue until
+ the jobs are done. */
+
+ /* Check whether there is a temporary CUPS queue which we would
+ overwrite */
+ dest = cupsGetNamedDest(http, p->queue_name, NULL);
+ if (dest) {
+ val = cupsGetOption ("printer-is-temporary",
+ dest->num_options,
+ dest->options);
+ is_temporary = val && (!strcasecmp (val, "yes") ||
+ !strcasecmp (val, "on") ||
+ !strcasecmp (val, "true"));
+ cupsFreeDests(1, dest);
+ if (is_temporary) {
+ debug_printf("Our new queue overwrites the temporary CUPS queue %s, so we need to make the queue permanent.\n",
+ p->queue_name);
+ /* We need to modify the printer-is-shared bit twice if we need to
+ make a temporary queue permanent but not share this queue */
+ for (i = 0; i <= 1; i ++) {
+ if (i == 0)
+ debug_printf("Setting printer-is-shared bit to make this queue permanent.\n");
+ else
+ debug_printf("Unsetting printer-is-shared bit.\n");
+ request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser());
+ num_options = 0;
+ options = NULL;
+ num_options = cupsAddOption("printer-is-shared",
+ (i == 0 ? "true" : "false"),
+ num_options, &options);
+ cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION);
+ cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER);
+ ippDelete(cupsDoRequest(http, request, "/admin/"));
+ cupsFreeOptions(num_options, options);
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE) {
+ debug_printf("Unable change printer-is-shared bit to %s (%s)!\n",
+ (i == 0 ? "true" : "false"),
+ cupsLastErrorString());
+ break;
+ }
+ }
+ /* Error on modifying printer-is-shared bit, removing temporary
+ queue */
+ if (i <= 1) {
+ debug_printf("Removing the temporary CUPS queue.\n");
+ /* Check whether there are still jobs and do not remove the queue
+ then */
+ num_jobs = 0;
+ jobs = NULL;
+ num_jobs = cupsGetJobs2(http, &jobs, p->queue_name, 0,
+ CUPS_WHICHJOBS_ACTIVE);
+ if (num_jobs != 0) { /* error or jobs */
+ debug_printf("Temporary queue has still jobs or CUPS error, retrying later.\n");
+ cupsFreeJobs(num_jobs, jobs);
+ /* Schedule the removal of the queue for later */
+ if (in_shutdown == 0) {
+ p->timeout = current_time + TIMEOUT_RETRY;
+ p->no_autosave = 0;
+ break;
+ }
+ }
+ /* No jobs, remove the CUPS queue */
+ request = ippNewRequest(CUPS_DELETE_PRINTER);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser());
+ ippDelete(cupsDoRequest(http, request, "/admin/"));
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE) {
+ debug_printf("Unable to remove temporary CUPS queue, retrying later\n");
+ if (in_shutdown == 0) {
+ p->timeout = current_time + TIMEOUT_RETRY;
+ p->no_autosave = 0;
+ break;
+ }
+ }
+ }
+ } else
+ debug_printf("Creating/Updating permanent CUPS queue %s.\n",
+ p ->queue_name);
+ } else
+ debug_printf("Creating permanent CUPS queue %s.\n",
+ p->queue_name);
+
+ /* Do we have default option settings in cups-browsed.conf? */
+ if (DefaultOptions) {
+ debug_printf("Applying default option settings to printer %s: %s\n",
+ p->queue_name, DefaultOptions);
+ p->num_options = cupsParseOptions(DefaultOptions, p->num_options,
+ &p->options);
+ }
+
+ /* Loading saved option settings from last session */
+ p->num_options = load_printer_options(p->queue_name, p->num_options,
+ &p->options);
+
+ /* If we create a queue to a remote CUPS printer we need the queue
+ name on the remote server */
+ if (p->netprinter == 0)
+ remote_cups_queue = strrchr(p->uri, '/') + 1;
+
+ /* Determine whether we have an IPP network printer. If not we
+ have remote CUPS queue(s) and so we use an implicit class for
+ load balancing. In this case we will assign an
+ implicitclass:... device URI, which makes cups-browsed find
+ the best destination for each job. */
+ loadedppd = NULL;
+ pass_through_ppd = 0;
+ if (cups_notifier != NULL && p->netprinter == 0) {
+ /* We are not an IPP network printer, so we use the device URI
+ implicitclass:<queue name>
+ We never use the implicitclass backend if we do not have D-Bus
+ notification from CUPS as we cannot assign a destination printer
+ to an incoming job then. */
+ snprintf(device_uri, sizeof(device_uri), "implicitclass:%s",
+ p->queue_name);
+ debug_printf("Print queue %s is for remote CUPS queue(s) and we get notifications from CUPS, using implicit class device URI %s\n",
+ p->queue_name, device_uri);
+ if (!p->ppd && !p->model && !p->ifscript) {
+ /* Having another backend than the CUPS "ipp" backend the
+ options from the PPD of the queue on the server are not
+ automatically used on the client any more, so we have to
+ explicitly load the PPD from one of the servers, apply it
+ to our local queue, and replace its "*cupsFilter(2): ..."
+ lines by one line making the print data get passed through
+ to the server without filtering on the client (where not
+ necessarily the right filters/drivers are installed) so
+ that it gets filtered on the server. In addition, we prefix
+ the PPD's NickName, so that automatic PPD updating by the
+ distribution's package installation/update infrastructure
+ is suppressed. */
+ /* Load the PPD file from one of the servers */
+ if ((remote_http =
+ httpConnectEncryptShortTimeout(p->ip ? p->ip : p->host,
+ p->port ? p->port :
+ ippPort(),
+ cupsEncryption()))
+ == NULL) {
+ debug_printf("Could not connect to the server %s:%d for %s!\n",
+ p->host, p->port, p->queue_name);
+ p->timeout = current_time + TIMEOUT_RETRY;
+ p->no_autosave = 0;
+ break;
+ }
+ httpSetTimeout(remote_http, HttpRemoteTimeout, http_timeout_cb, NULL);
+ if ((loadedppd = cupsGetPPD2(remote_http, remote_cups_queue))
+ == NULL &&
+ CreateRemoteRawPrinterQueues == 0) {
+ debug_printf("Unable to load PPD file for %s from the server %s:%d!\n",
+ p->queue_name, p->host, p->port);
+ p->timeout = current_time + TIMEOUT_RETRY;
+ p->no_autosave = 0;
+ httpClose(remote_http);
+ break;
+ } else if (loadedppd) {
+ debug_printf("Loaded PPD file %s for printer %s from server %s:%d!\n",
+ loadedppd, p->queue_name, p->host, p->port);
+ /* Modify PPD to not filter the job */
+ pass_through_ppd = 1;
+ }
+ httpClose(remote_http);
+ }
+ } else {
+ /* Device URI: ipp(s)://<remote host>:631/printers/<remote queue> */
+ strncpy(device_uri, p->uri, sizeof(device_uri));
+ debug_printf("Print queue %s is for an IPP network printer, or we do not get notifications from CUPS, using direct device URI %s\n",
+ p->queue_name, device_uri);
+ }
+ /* PPD from system's CUPS installation */
+ if (p->model) {
+ debug_printf("Loading system PPD %s for queue %s.\n",
+ p->model, p->queue_name);
+ loadedppd = cupsGetServerPPD(http, p->model);
+ }
+ /* PPD readily available */
+ if (p->ppd) {
+ debug_printf("Using PPD %s for queue %s.\n",
+ p->ppd, p->queue_name);
+ loadedppd = p->ppd;
+ }
+ if (loadedppd) {
+ if ((ppd = ppdOpenFile(loadedppd)) == NULL) {
+ int linenum; /* Line number of error */
+ ppd_status_t status = ppdLastError(&linenum);
+ debug_printf("Unable to open PPD \"%s\": %s on line %d.",
+ loadedppd, ppdErrorString(status), linenum);
+ p->timeout = current_time + TIMEOUT_RETRY;
+ p->no_autosave = 0;
+ unlink(loadedppd);
+ break;
+ }
+ ppdMarkDefaults(ppd);
+ cupsMarkOptions(ppd, p->num_options, p->options);
+ if ((out = cupsTempFile2(buf, sizeof(buf))) == NULL) {
+ debug_printf("Unable to create temporary file!\n");
+ p->timeout = current_time + TIMEOUT_RETRY;
+ p->no_autosave = 0;
+ ppdClose(ppd);
+ unlink(loadedppd);
+ break;
+ }
+ if ((in = cupsFileOpen(loadedppd, "r")) == NULL) {
+ debug_printf("Unable to open the downloaded PPD file!\n");
+ p->timeout = current_time + TIMEOUT_RETRY;
+ p->no_autosave = 0;
+ cupsFileClose(out);
+ ppdClose(ppd);
+ unlink(loadedppd);
+ break;
+ }
+ debug_printf("Editing PPD file %s for printer %s, setting the option defaults of the previous cups-browsed session%s, saving the resulting PPD in %s.\n",
+ loadedppd, p->queue_name,
+ (pass_through_ppd == 1 ?
+ " and inhibiting client-side filtering of the job" : ""),
+ buf);
+ new_cupsfilter_line_inserted = 0;
+ ap_remote_queue_id_line_inserted = 0;
+ cont_line_read = 0;
+ while (cupsFileGets(in, line, sizeof(line))) {
+ if (pass_through_ppd == 1 &&
+ (!strncmp(line, "*cupsFilter:", 12) ||
+ !strncmp(line, "*cupsFilter2:", 13))) {
+ cont_line_read = 0;
+ /* "*cupfFilter(2): ..." line: Remove it and replace the
+ first one by a line which passes through the data
+ unfiltered */
+ if (new_cupsfilter_line_inserted == 0) {
+ cupsFilePrintf(out, "*cupsFilter: \"*/* 0 -\"\n");
+ new_cupsfilter_line_inserted = 1;
+ }
+ /* Find the end of the "*cupsFilter(2): ..." entry in the
+ case it spans more than one line */
+ do {
+ if (strlen(line) != 0) {
+ ptr = line + strlen(line) - 1;
+ while(isspace(*ptr) && ptr > line)
+ ptr --;
+ if (*ptr == '"')
+ break;
+ }
+ cont_line_read = 1;
+ } while (cupsFileGets(in, line, sizeof(line)));
+ } else if (pass_through_ppd == 1 &&
+ !strncmp(line, "*NickName:", 10)) {
+ cont_line_read = 0;
+ /* Prefix the "NickName" of the printer so that automatic
+ PPD updaters skip this PPD */
+ ptr = strchr(line, '"');
+ if (ptr) {
+ ptr ++;
+ prefix = "Remote printer: ";
+ line[sizeof(line) - strlen(prefix) - 1] = '\0';
+ memmove(ptr + strlen(prefix), ptr, strlen(ptr) + 1);
+ memmove(ptr, prefix, strlen(prefix));
+ ptr = line + strlen(line) - 1;
+ while(isspace(*ptr) && ptr > line) {
+ ptr --;
+ *ptr = '\0';
+ }
+ if (*ptr != '"') {
+ if (ptr < line + sizeof(line) - 2) {
+ *(ptr + 1) = '"';
+ *(ptr + 2) = '\0';
+ } else {
+ line[sizeof(line) - 2] = '"';
+ line[sizeof(line) - 1] = '\0';
+ }
+ }
+ }
+ cupsFilePrintf(out, "%s\n", line);
+ } else if (!strncmp(line, "*Default", 8)) {
+ cont_line_read = 0;
+ strncpy(keyword, line + 8, sizeof(keyword));
+ for (keyptr = keyword; *keyptr; keyptr ++)
+ if (*keyptr == ':' || isspace(*keyptr & 255))
+ break;
+ *keyptr++ = '\0';
+ while (isspace(*keyptr & 255))
+ keyptr ++;
+ if (!strcmp(keyword, "PageRegion") ||
+ !strcmp(keyword, "PageSize") ||
+ !strcmp(keyword, "PaperDimension") ||
+ !strcmp(keyword, "ImageableArea")) {
+ if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) == NULL)
+ choice = ppdFindMarkedChoice(ppd, "PageRegion");
+ } else
+ choice = ppdFindMarkedChoice(ppd, keyword);
+ if (choice && strcmp(choice->choice, keyptr)) {
+ if (strcmp(choice->choice, "Custom"))
+ cupsFilePrintf(out, "*Default%s: %s\n", keyword,
+ choice->choice);
+ else if ((customval = cupsGetOption(keyword, p->num_options,
+ p->options)) != NULL)
+ cupsFilePrintf(out, "*Default%s: %s\n", keyword, customval);
+ else
+ cupsFilePrintf(out, "%s\n", line);
+ } else
+ cupsFilePrintf(out, "%s\n", line);
+ } else if (cont_line_read == 0 || strncmp(line, "*End", 4)) {
+ cont_line_read = 0;
+ /* Write an "APRemoteQueueID" line to make this queue marked
+ as remote printer by CUPS */
+ if (p->netprinter == 0 &&
+ strncmp(line, "*%", 2) &&
+ strncmp(line, "*PPD-Adobe:", 11) &&
+ ap_remote_queue_id_line_inserted == 0) {
+ ap_remote_queue_id_line_inserted = 1;
+ cupsFilePrintf(out, "*APRemoteQueueID: \"\"\n");
+ }
+ /* Simply write out the line as we read it */
+ cupsFilePrintf(out, "%s\n", line);
+ }
+ }
+ if (pass_through_ppd == 1 && new_cupsfilter_line_inserted == 0)
+ cupsFilePrintf(out, "*cupsFilter: \"*/* 0 -\"\n");
+ cupsFileClose(in);
+ cupsFileClose(out);
+ ppdClose(ppd);
+ unlink(loadedppd);
+ loadedppd = NULL;
+ if (p->ppd)
+ free(p->ppd);
+ p->ppd = strdup(buf);
+ }
+
+ /* Create a new CUPS queue or modify the existing queue */
+ request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+ /* Default user */
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser());
+ /* Queue should be enabled ... */
+ ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
+ IPP_PRINTER_IDLE);
+ /* ... and accepting jobs */
+ ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1);
+ num_options = 0;
+ options = NULL;
+ /* Device URI: ipp(s)://<remote host>:631/printers/<remote queue>
+ OR implicitclass:<queue name> */
+ num_options = cupsAddOption("device-uri", device_uri,
+ num_options, &options);
+ /* Option cups-browsed=true, marking that we have created this queue */
+ num_options = cupsAddOption(CUPS_BROWSED_MARK "-default", "true",
+ num_options, &options);
+ /* Description */
+ num_options = cupsAddOption("printer-info", p->info,
+ num_options, &options);
+ /* Location */
+ num_options = cupsAddOption("printer-location", p->location,
+ num_options, &options);
+ /* Default option settings from printer entry */
+ for (i = 0; i < p->num_options; i ++)
+ if (strcasecmp(p->options[i].name, "printer-is-shared"))
+ num_options = cupsAddOption(strdup(p->options[i].name),
+ strdup(p->options[i].value),
+ num_options, &options);
+ /* Encode option list into IPP attributes */
+ cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION);
+ cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER);
+ /* Do it */
+ if (p->ppd) {
+ debug_printf("Non-raw queue %s with PPD file: %s\n", p->queue_name, p->ppd);
+ ippDelete(cupsDoFileRequest(http, request, "/admin/", p->ppd));
+ want_raw = 0;
+ unlink(p->ppd);
+ free(p->ppd);
+ p->ppd = NULL;
+ } else if (p->ifscript) {
+ debug_printf("Non-raw queue %s with interface script: %s\n", p->queue_name, p->ifscript);
+ ippDelete(cupsDoFileRequest(http, request, "/admin/", p->ifscript));
+ want_raw = 0;
+ unlink(p->ifscript);
+ free(p->ifscript);
+ p->ifscript = NULL;
+ } else {
+ if (p->netprinter == 0) {
+ debug_printf("Raw queue %s\n", p->queue_name);
+ want_raw = 1;
+ } else {
+ debug_printf("Queue %s keeping its current PPD file/interface script\n", p->queue_name);
+ want_raw = 0;
+ }
+ ippDelete(cupsDoRequest(http, request, "/admin/"));
+ }
+ cupsFreeOptions(num_options, options);
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE) {
+ debug_printf("Unable to create/modify CUPS queue (%s)!\n",
+ cupsLastErrorString());
+ p->timeout = current_time + TIMEOUT_RETRY;
+ p->no_autosave = 0;
+ break;
+ }
+
+ /* Do not share a queue which serves only to point to a remote CUPS
+ printer
+
+ We do this in a seperate IPP request as on newer CUPS versions we
+ get an error when changing the printer-is-shared bit on a queue
+ pointing to a remote CUPS printer, this way we assure all other
+ settings be applied amd when setting the printer-is-shared to
+ false amd this errors, we can safely ignore the error as on queues
+ pointing to remote CUPS printers the bit is set to false by default
+ (these printers are never shared)
+
+ If our printer is an IPP network printer and not a CUPS queue, we
+ keep track of whether the user has changed the printer-is-shared
+ bit and recover this setting. The default setting for a new
+ queue is configurable via the NewIPPPrinterQueuesShared directive
+ in cups-browsed.conf */
+
+ request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser());
+ num_options = 0;
+ options = NULL;
+ if (p->netprinter == 1 &&
+ (val = cupsGetOption("printer-is-shared", p->num_options,
+ p->options)) != NULL) {
+ num_options = cupsAddOption("printer-is-shared", val,
+ num_options, &options);
+ debug_printf("Setting printer-is-shared bit to %s.\n", val);
+ } else if (p->netprinter == 1 && NewIPPPrinterQueuesShared) {
+ num_options = cupsAddOption("printer-is-shared", "true",
+ num_options, &options);
+ debug_printf("Setting printer-is-shared bit.\n");
+ } else {
+ num_options = cupsAddOption("printer-is-shared", "false",
+ num_options, &options);
+ debug_printf("Unsetting printer-is-shared bit.\n");
+ }
+ cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION);
+ cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER);
+ ippDelete(cupsDoRequest(http, request, "/admin/"));
+ cupsFreeOptions(num_options, options);
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE)
+ debug_printf("Unable to set printer-is-shared bit to false (%s)!\n",
+ cupsLastErrorString());
+
+ /* If we are about to create a raw queue or turn a non-raw queue
+ into a raw one, we apply the "ppd-name=raw" option to remove any
+ existing PPD file assigned to the queue.
+
+ Also here we do a separate IPP request as it errors in some
+ cases. */
+ if (want_raw) {
+ debug_printf("Removing local PPD file for printer %s\n", p->queue_name);
+ request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser());
+ num_options = 0;
+ options = NULL;
+ num_options = cupsAddOption("ppd-name", "raw",
+ num_options, &options);
+ cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION);
+ cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER);
+ ippDelete(cupsDoRequest(http, request, "/admin/"));
+ cupsFreeOptions(num_options, options);
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE)
+ debug_printf("Unable to remove PPD file from the print queue (%s)!\n",
+ cupsLastErrorString());
+ }
+
+ /* If this queue was the default printer in its previous life, make
+ it the default printer again. */
+ queue_creation_handle_default(p->queue_name);
+
+ /* If cups-browsed or a failed backend has disabled this
+ queue, re-enable it. */
+ if ((disabled_str = is_disabled(p->queue_name, "cups-browsed")) != NULL) {
+ enable_printer(p->queue_name);
+ free(disabled_str);
+ } else if ((disabled_str = is_disabled(p->queue_name, "Printer stopped due to backend errors")) != NULL) {
+ enable_printer(p->queue_name);
+ free(disabled_str);
+ }
+
+ p->status = STATUS_CONFIRMED;
+ if (p->is_legacy) {
+ p->timeout = time(NULL) + BrowseTimeout;
+ debug_printf("starting BrowseTimeout timer for %s (%ds)\n",
+ p->queue_name, BrowseTimeout);
+ } else
+ p->timeout = (time_t) -1;
+
+ p->no_autosave = 0;
+ break;
+
+ case STATUS_CONFIRMED:
+ /* Only act if the timeout has passed */
+ if (p->timeout > current_time)
+ break;
+
+ if (p->is_legacy) {
+ /* Remove a queue based on a legacy CUPS broadcast when the
+ broadcast timeout expires without a new broadcast of this
+ queue from the server */
+ remove_printer_entry(p);
+ } else
+ p->timeout = (time_t) -1;
+
+ break;
+
+ }
+ }
+ log_all_printers();
+
+ free(r);
+
+ if (in_shutdown == 0)
+ recheck_timer ();
+
+ /* Don't run this callback again */
+ return FALSE;
+}
+
+static void
+recheck_timer (void)
+{
+ remote_printer_t *p;
+ time_t timeout = (time_t) -1;
+ time_t now = time(NULL);
+
+ if (!gmainloop)
+ return;
+
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p;
+ p = (remote_printer_t *)cupsArrayNext(remote_printers))
+ if (p->timeout == (time_t) -1)
+ continue;
+ else if (now > p->timeout) {
+ timeout = 0;
+ break;
+ } else if (timeout == (time_t) -1 || p->timeout - now < timeout)
+ timeout = p->timeout - now;
+
+ if (queues_timer_id)
+ g_source_remove (queues_timer_id);
+
+ if (timeout != (time_t) -1) {
+ debug_printf("checking queues in %ds\n", timeout);
+ queues_timer_id = g_timeout_add_seconds (timeout, update_cups_queues, NULL);
+ } else {
+ debug_printf("listening\n");
+ queues_timer_id = 0;
+ }
+}
+
+static gboolean
+matched_filters (const char *queue_name,
+ const char *host,
+ uint16_t port,
+ const char *service_name,
+ const char *domain,
+ void *txt) {
+ browse_filter_t *filter;
+ const char *property = NULL;
+ char buf[10];
+#ifdef HAVE_AVAHI
+ AvahiStringList *entry = NULL;
+ char *key = NULL, *value = NULL;
+#endif /* HAVE_AVAHI */
+
+ debug_printf("Matching printer \"%s\" with properties Host = \"%s\", Port = %d, Service Name = \"%s\", Domain = \"%s\" with the BrowseFilter lines in cups-browsed.conf\n", queue_name, host, port, service_name, domain);
+ /* Go through all BrowseFilter lines and stop if one line does not match,
+ rejecting this printer */
+ for (filter = cupsArrayFirst (browsefilter);
+ filter;
+ filter = cupsArrayNext (browsefilter)) {
+ debug_printf("Matching with line \"BrowseFilter %s%s%s %s\"",
+ (filter->sense == FILTER_NOT_MATCH ? "NOT " : ""),
+ (filter->regexp && !filter->cregexp ? "EXACT " : ""),
+ filter->field, (filter->regexp ? filter->regexp : ""));
+#ifdef HAVE_AVAHI
+ /* Go through the TXT record to see whether this rule applies to a field
+ in there */
+ if (txt) {
+ entry = avahi_string_list_find((AvahiStringList *)txt, filter->field);
+ if (entry) {
+ avahi_string_list_get_pair(entry, &key, &value, NULL);
+ if (key) {
+ debug_printf(", TXT record entry: %s = %s",
+ key, (value ? value : ""));
+ if (filter->regexp) {
+ /* match regexp */
+ if (!value)
+ value = "";
+ if ((filter->cregexp &&
+ regexec(filter->cregexp, value, 0, NULL, 0) == 0) ||
+ (!filter->cregexp && !strcasecmp(filter->regexp, value))) {
+ avahi_free(key);
+ avahi_free(value);
+ if (filter->sense == FILTER_NOT_MATCH)
+ goto filter_failed;
+ } else {
+ avahi_free(key);
+ avahi_free(value);
+ if (filter->sense == FILTER_MATCH)
+ goto filter_failed;
+ }
+ } else {
+ /* match boolean value */
+ if (filter->sense == FILTER_MATCH) {
+ if (!value || strcasecmp(value, "T")) {
+ avahi_free(key);
+ avahi_free(value);
+ goto filter_failed;
+ }
+ } else {
+ if (value && !strcasecmp(value, "T")) {
+ avahi_free(key);
+ avahi_free(value);
+ goto filter_failed;
+ }
+ }
+ }
+ }
+ avahi_free(key);
+ avahi_free(value);
+ goto filter_matched;
+ }
+ }
+#endif /* HAVE_AVAHI */
+
+ /* Does one of the properties outside the TXT record match? */
+ property = buf;
+ buf[0] = '\0';
+ if (!strcasecmp(filter->field, "Name") ||
+ !strcasecmp(filter->field, "Printer") ||
+ !strcasecmp(filter->field, "PrinterName") ||
+ !strcasecmp(filter->field, "Queue") ||
+ !strcasecmp(filter->field, "QueueName")) {
+ if (queue_name)
+ property = queue_name;
+ } else if (!strcasecmp(filter->field, "Host") ||
+ !strcasecmp(filter->field, "HostName") ||
+ !strcasecmp(filter->field, "RemoteHost") ||
+ !strcasecmp(filter->field, "RemoteHostName") ||
+ !strcasecmp(filter->field, "Server") ||
+ !strcasecmp(filter->field, "ServerName")) {
+ if (host)
+ property = host;
+ } else if (!strcasecmp(filter->field, "Port")) {
+ if (port)
+ snprintf(buf, sizeof(buf), "%d", port);
+ } else if (!strcasecmp(filter->field, "Service") ||
+ !strcasecmp(filter->field, "ServiceName")) {
+ if (service_name)
+ property = service_name;
+ } else if (!strcasecmp(filter->field, "Domain")) {
+ if (domain)
+ property = domain;
+ } else
+ property = NULL;
+ if (property) {
+ if (!filter->regexp)
+ filter->regexp = "";
+ if ((filter->cregexp &&
+ regexec(filter->cregexp, property, 0, NULL, 0) == 0) ||
+ (!filter->cregexp && !strcasecmp(filter->regexp, property))) {
+ if (filter->sense == FILTER_NOT_MATCH)
+ goto filter_failed;
+ } else {
+ if (filter->sense == FILTER_MATCH)
+ goto filter_failed;
+ }
+ goto filter_matched;
+ }
+
+ debug_printf(": Field not found --> SKIPPED\n");
+ continue;
+
+ filter_matched:
+ debug_printf(" --> MATCHED\n");
+ }
+
+ /* All BrowseFilter lines matching, accept this printer */
+ debug_printf("All BrowseFilter lines matched or skipped, accepting printer %s\n",
+ queue_name);
+ return TRUE;
+
+ filter_failed:
+ debug_printf(" --> FAILED\n");
+ debug_printf("One BrowseFilter line did not match, ignoring printer %s\n",
+ queue_name);
+ return FALSE;
+}
+
+static remote_printer_t *
+examine_discovered_printer_record(const char *host,
+ const char *ip,
+ uint16_t port,
+ char *resource,
+ const char *service_name,
+ const char *location,
+ const char *info,
+ const char *type,
+ const char *domain,
+ void *txt) {
+
+ char uri[HTTP_MAX_URI];
+ char *queue_name = NULL, *remote_host = NULL, *pdl = NULL,
+ *make_model = NULL;
+ int color = 1, duplex = 1;
+#ifdef HAVE_AVAHI
+ char *fields[] = { "product", "usb_MDL", "ty", NULL }, **f;
+ AvahiStringList *entry = NULL;
+ char *key = NULL, *value = NULL;
+ char *note_value = NULL;
+#endif /* HAVE_AVAHI */
+ cluster_t *cluster = NULL;
+ char *member = NULL, *str = NULL;
+ remote_printer_t *p = NULL;
+ local_printer_t *local_printer = NULL;
+ char *backup_queue_name = NULL, *local_queue_name = NULL,
+ *local_queue_name_lower = NULL;
+ int is_cups_queue;
+
+ if (!host || !resource || !service_name || !location || !info || !type ||
+ !domain) {
+ debug_printf("ERROR: examine_discovered_printer_record(): Input value missing!\n");
+ return NULL;
+ }
+
+
+ is_cups_queue = 0;
+ memset(uri, 0, sizeof(uri));
+
+ /* Determine the device URI of the remote printer */
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri) - 1,
+ (strcasestr(type, "_ipps") ? "ipps" : "ipp"), NULL,
+ (ip != NULL ? ip : host), port, "/%s", resource);
+ /* Find the remote host name.
+ * Used in constructing backup_queue_name, so need to sanitize.
+ * strdup() is called inside remove_bad_chars() and result is free()-able.
+ */
+ remote_host = remove_bad_chars(host, 1);
+ /*hl = strlen(remote_host);
+ if (hl > 6 && !strcasecmp(remote_host + hl - 6, ".local"))
+ remote_host[hl - 6] = '\0';
+ if (hl > 7 && !strcasecmp(remote_host + hl - 7, ".local."))
+ remote_host[hl - 7] = '\0';*/
+
+#ifdef HAVE_AVAHI
+ if (txt) {
+ for (f = fields; *f; f ++) {
+ entry = avahi_string_list_find((AvahiStringList *)txt, *f);
+ if (entry) {
+ avahi_string_list_get_pair(entry, &key, &value, NULL);
+ if (key && value && !strcasecmp(key, *f) && strlen(value) >= 3) {
+ if (!strcasecmp(key, "product")) {
+ make_model = strdup(value + 1);
+ make_model[strlen(make_model) - 1] = '\0';
+ } else
+ make_model = strdup(value);
+ avahi_free(key);
+ avahi_free(value);
+ break;
+ }
+ avahi_free(key);
+ avahi_free(value);
+ }
+ }
+ }
+#endif /* HAVE_AVAHI */
+ /* Check by the resource whether the discovered printer is a CUPS queue */
+ if (!strncasecmp(resource, "printers/", 9) ||
+ !strncasecmp(resource, "classes/", 8)) {
+ /* This is a remote CUPS queue or class */
+ is_cups_queue = 1;
+ debug_printf("Found CUPS queue/class: %s on host %s.\n",
+ strchr(resource, '/') + 1, remote_host);
+#ifdef HAVE_AVAHI
+ /* If the remote queue has a PPD file, the "product" field of the
+ TXT record is populated. If it has no PPD file the remote queue
+ is a raw queue and so we do not know enough about the printer
+ behind it for auto-creating a local queue pointing to it. */
+ int raw_queue = 0;
+ if (txt) {
+ entry = avahi_string_list_find((AvahiStringList *)txt, "product");
+ if (entry) {
+ avahi_string_list_get_pair(entry, &key, &value, NULL);
+ if (!key || !value || strcasecmp(key, "product") || value[0] != '(' ||
+ value[strlen(value) - 1] != ')') {
+ raw_queue = 1;
+ }
+ avahi_free(key);
+ avahi_free(value);
+ } else
+ raw_queue = 1;
+ } else if (domain && domain[0] != '\0')
+ raw_queue = 1;
+ if (raw_queue && CreateRemoteRawPrinterQueues == 0) {
+ /* The remote CUPS queue is raw, ignore it */
+ debug_printf("Remote DNS-SD-advertised CUPS queue %s on host %s is raw, ignored.\n",
+ strchr(resource, '/') + 1, remote_host);
+ free (remote_host);
+ if (make_model) free (make_model);
+ return NULL;
+ }
+#endif /* HAVE_AVAHI */
+ /* Determine the queue name */
+ if (LocalQueueNamingRemoteCUPS == LOCAL_QUEUE_NAMING_MAKE_MODEL &&
+ make_model)
+ /* Works only with DNS-SD-discovered queues as otherwise we have no
+ make/model info */
+ queue_name = remove_bad_chars(make_model, 0);
+ else if (LocalQueueNamingRemoteCUPS == LOCAL_QUEUE_NAMING_REMOTE_NAME)
+ /* Not directly used in script generation input later, but taken from
+ packet, so better safe than sorry. (consider second loop with
+ backup_queue_name) */
+ queue_name = remove_bad_chars(strchr(resource, '/') + 1, 0);
+ else
+ /* Convert DNS-SD service name into a CUPS queue name exactly
+ as CUPS would do it, to override CUPS' own temporary queue
+ generation mechanism */
+ queue_name = remove_bad_chars(service_name, 2);
+ } else {
+ /* This is an IPP-based network printer */
+ is_cups_queue = 0;
+ /* Determine the queue name */
+ if (LocalQueueNamingIPPPrinter == LOCAL_QUEUE_NAMING_MAKE_MODEL &&
+ make_model)
+ /* Works only if we actually have make/model info in the DNS-SD record*/
+ queue_name = remove_bad_chars(make_model, 0);
+ else
+ /* Convert DNS-SD service name into a CUPS queue name exactly
+ as CUPS would do it, to override CUPS' own temporary queue
+ generation mechanism */
+ queue_name = remove_bad_chars(service_name, 2);
+#ifdef HAVE_AVAHI
+ if (txt) {
+ /* Find out which PDLs the printer understands */
+ entry = avahi_string_list_find((AvahiStringList *)txt, "pdl");
+ if (entry) {
+ avahi_string_list_get_pair(entry, &key, &value, NULL);
+ if (key && value && !strcasecmp(key, "pdl") && strlen(value) >= 3) {
+ pdl = remove_bad_chars(value, 1);
+ }
+ avahi_free(key);
+ avahi_free(value);
+ }
+ /* Find out if we have a color printer */
+ entry = avahi_string_list_find((AvahiStringList *)txt, "Color");
+ if (entry) {
+ avahi_string_list_get_pair(entry, &key, &value, NULL);
+ if (key && value && !strcasecmp(key, "Color")) {
+ if (!strcasecmp(value, "T")) color = 1;
+ if (!strcasecmp(value, "F")) color = 0;
+ }
+ avahi_free(key);
+ avahi_free(value);
+ }
+ /* Find out if we have a duplex printer */
+ entry = avahi_string_list_find((AvahiStringList *)txt, "Duplex");
+ if (entry) {
+ avahi_string_list_get_pair(entry, &key, &value, NULL);
+ if (key && value && !strcasecmp(key, "Duplex")) {
+ if (!strcasecmp(value, "T")) duplex = 1;
+ if (!strcasecmp(value, "F")) duplex = 0;
+ }
+ avahi_free(key);
+ avahi_free(value);
+ }
+ }
+#endif /* HAVE_AVAHI */
+ }
+ /* Extract location from DNS-SD TXT record's "note" field */
+#ifdef HAVE_AVAHI
+ if (!location) {
+ if (txt) {
+ entry = avahi_string_list_find((AvahiStringList *)txt, "note");
+ if (entry) {
+ avahi_string_list_get_pair(entry, &key, &note_value, NULL);
+ if (key && note_value && !strcasecmp(key, "note")) {
+ debug_printf("examine_discovered_printer_record: TXT.note: |%s|\n", note_value); /* !! */
+ location = note_value;
+ }
+ avahi_free(key);
+ /* don't avahi_free(note_value) here! */
+ }
+ }
+ if (!location)
+ location = "";
+ }
+ /* A NULL location is only passed in from resolve_callback(), which is HAVE_AVAHI */
+#endif /* HAVE_AVAHI */
+ /* Check if there exists already a CUPS queue with the
+ requested name Try name@host in such a case and if
+ this is also taken, ignore the printer */
+ if ((backup_queue_name = malloc((strlen(queue_name) +
+ strlen(remote_host) + 2) *
+ sizeof(char))) == NULL) {
+ debug_printf("ERROR: Unable to allocate memory.\n");
+ exit(1);
+ }
+ sprintf(backup_queue_name, "%s@%s", queue_name, remote_host);
+
+ /* Get available CUPS queues */
+ update_local_printers ();
+
+ /* We skip trying to use the queue name purely derived from the
+ remote CUPS queue name or make and model for remote CUPS queues
+ when automatic clustering of remote cUPS queues is turned off,
+ to directly create queues with names containing the server name
+ to avoid name clashes and with this remote queues skipped by
+ cups-browsed. */
+ if (!is_cups_queue ||
+ AutoClustering == 1 ||
+ LocalQueueNamingRemoteCUPS == LOCAL_QUEUE_NAMING_DNSSD) {
+ local_queue_name = queue_name;
+ /* Is there a local queue with the name of the remote queue? */
+ local_queue_name_lower = g_ascii_strdown(local_queue_name, -1);
+ local_printer = g_hash_table_lookup (local_printers,
+ local_queue_name_lower);
+ free(local_queue_name_lower);
+ }
+ /* Use the originally chosen queue name plus the server name if
+ the original name is already taken or if we had skipped using
+ it. To decide on whether the queue name is already taken, only
+ consider CUPS queues not created by us */
+ if ((is_cups_queue &&
+ AutoClustering == 0 &&
+ LocalQueueNamingRemoteCUPS != LOCAL_QUEUE_NAMING_DNSSD) ||
+ (local_printer && !local_printer->cups_browsed_controlled)) {
+ /* Found local queue with same name as remote queue */
+ /* Is there a local queue with the name <queue>@<host>? */
+ local_queue_name = backup_queue_name;
+ debug_printf("%s already taken, using fallback name: %s\n",
+ queue_name, local_queue_name);
+ local_queue_name_lower = g_ascii_strdown(local_queue_name, -1);
+ local_printer = g_hash_table_lookup (local_printers,
+ local_queue_name_lower);
+ free(local_queue_name_lower);
+ if (local_printer && !local_printer->cups_browsed_controlled) {
+ /* Found also a local queue with name <queue>@<host>, so
+ ignore this remote printer */
+ debug_printf("%s also taken, printer ignored.\n",
+ local_queue_name);
+ goto fail;
+ }
+ }
+
+ /* If we only want to create queues for printers for which CUPS does
+ not already auto-create queues, we check here whether we can skip
+ this printer */
+ if (OnlyUnsupportedByCUPS) {
+ if (g_hash_table_find (cups_supported_remote_printers,
+ local_printer_service_name_matches,
+ (gpointer *)service_name)) {
+ /* Found a DNS-SD-discovered CUPS-supported printer whose URI matches
+ our discovered printer */
+ debug_printf("Printer %s (DNS-SD service name \"%s\") does not need to be covered by us as it is already supported by CUPS, skipping.\n",
+ local_queue_name, service_name);
+ goto fail;
+ }
+ }
+
+ if (is_cups_queue) {
+ /* Check whether our new printer matches one of the user-defined
+ printer clusters */
+ for (cluster = cupsArrayFirst(clusters);
+ cluster;
+ cluster = cupsArrayNext(clusters)) {
+ for (member = cupsArrayFirst(cluster->members);
+ member;
+ member = cupsArrayNext(cluster->members)) {
+ /* Match remote CUPS queue name */
+ if ((str = strrchr(resource, '/')) != NULL && strlen(str) > 1) {
+ str = remove_bad_chars(str + 1, 2);
+ if (strcasecmp(member, str) == 0) /* Match */
+ break;
+ free(str);
+ }
+ /* Match make and model */
+ if (make_model) {
+ str = remove_bad_chars(make_model, 2);
+ if (strcasecmp(member, str) == 0) /* Match */
+ break;
+ free(str);
+ }
+ /* Match DNS-SD service name */
+ if (service_name) {
+ str = remove_bad_chars(service_name, 2);
+ if (strcasecmp(member, str) == 0) /* Match */
+ break;
+ free(str);
+ }
+ }
+ if (member)
+ break;
+ }
+ if (cluster) {
+ local_queue_name = cluster->local_queue_name;
+ is_cups_queue = 2;
+ free(str);
+ } else if (AutoClustering) {
+ /* If we do automatic clustering by matching queue names, do not
+ add a queue to a manually defined cluster because it matches
+ the cluster's local queue name. Manually defined clusters can
+ only be joined by printers which match one of the cluster's
+ member names */
+ for (cluster = cupsArrayFirst(clusters);
+ cluster;
+ cluster = cupsArrayNext(clusters)) {
+ if (strcasecmp(local_queue_name, cluster->local_queue_name) == 0) {
+ debug_printf("We have already a manually defined printer cluster with the name %s. Automatic clustering does not add this printer to this cluster as it does not match any of the cluster's member names. Skipping this printer.\n", local_queue_name);
+ debug_printf("In cups-browsed.conf try \"LocalQueueNamingRemoteCUPS DNS-SD\" or give another name to your manually defined cluster (\"Cluster\" directive) to avoid name clashes.\n");
+ goto fail;
+ }
+ }
+ }
+ }
+
+ if (!matched_filters (local_queue_name, remote_host, port, service_name, domain,
+ txt)) {
+ debug_printf("Printer %s does not match BrowseFilter lines in cups-browsed.conf, printer ignored.\n",
+ local_queue_name);
+ goto fail;
+ }
+
+ /* Check if we have already created a queue for the discovered
+ printer */
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers))
+ if (!strcasecmp(p->queue_name, local_queue_name) &&
+ (p->host[0] == '\0' ||
+ p->status == STATUS_UNCONFIRMED ||
+ p->status == STATUS_DISAPPEARED ||
+ (!strcasecmp(p->host, remote_host) && p->port == port &&
+ strlen(p->uri) - strlen(resource) > 0 &&
+ !strcasecmp(p->uri + strlen(p->uri) - strlen(resource), resource))))
+ break;
+
+ /* Is there a local queue with the same URI as the remote queue? */
+ if (!p && g_hash_table_find (local_printers,
+ local_printer_has_uri,
+ uri)) {
+ /* Found a local queue with the same URI as our discovered printer
+ would get, so ignore this remote printer */
+ debug_printf("Printer with URI %s already exists, printer ignored.\n",
+ uri);
+ goto fail;
+ }
+
+ if (p) {
+ debug_printf("Entry for %s (URI: %s) already exists.\n",
+ p->queue_name, p->uri);
+ /* We have already created a local queue, check whether the
+ discovered service allows us to upgrade the queue to IPPS
+ or whether the URI part after ipp(s):// has changed, or
+ whether the discovered queue is discovered via DNS-SD
+ having more info in contrary to the existing being
+ discovered by legacy CUPS or LDAP */
+ if ((strcasestr(type, "_ipps") &&
+ !strncasecmp(p->uri, "ipp:", 4)) ||
+ strcasecmp(strchr(p->uri, ':'), strchr(uri, ':')) ||
+ ((p->domain == NULL || p->domain[0] == '\0') &&
+ domain != NULL && domain[0] != '\0' &&
+ (p->type == NULL || p->type[0] == '\0') &&
+ type != NULL && type[0] != '\0')) {
+
+ /* Schedule local queue for upgrade to ipps: or for URI change */
+ if (strcasestr(type, "_ipps") &&
+ !strncasecmp(p->uri, "ipp:", 4))
+ debug_printf("Upgrading printer %s (Host: %s, Port :%d) to IPPS. New URI: %s\n",
+ p->queue_name, remote_host, port, uri);
+ if (strcasecmp(strchr(p->uri, ':'), strchr(uri, ':')))
+ debug_printf("Changing URI of printer %s (Host: %s, Port: %d) to %s.\n",
+ p->queue_name, remote_host, port, uri);
+ if ((p->domain == NULL || p->domain[0] == '\0') &&
+ domain != NULL && domain[0] != '\0' &&
+ (p->type == NULL || p->type[0] == '\0') &&
+ type != NULL && type[0] != '\0') {
+ debug_printf("Discovered printer %s (Host: %s, Port: %d, URI: %s) by DNS-SD now.\n",
+ p->queue_name, remote_host, port, uri);
+ if (p->is_legacy) {
+ p->is_legacy = 0;
+ if (p->status == STATUS_CONFIRMED)
+ p->timeout = (time_t) -1;
+ }
+ }
+ free(p->location);
+ free(p->info);
+ free(p->uri);
+ free(p->host);
+ free(p->ip);
+ free(p->service_name);
+ free(p->type);
+ free(p->domain);
+ p->location = strdup(location);
+ p->info = strdup(info);
+ p->uri = strdup(uri);
+ p->status = STATUS_TO_BE_CREATED;
+ p->timeout = time(NULL) + TIMEOUT_IMMEDIATELY;
+ p->host = strdup(remote_host);
+ p->ip = (ip != NULL ? strdup(ip) : NULL);
+ p->port = port;
+ p->service_name = strdup(service_name);
+ p->type = strdup(type);
+ p->domain = strdup(domain);
+
+ }
+
+ /* Mark queue entry as confirmed if the entry
+ is unconfirmed */
+ if (p->status == STATUS_UNCONFIRMED ||
+ p->status == STATUS_DISAPPEARED) {
+ debug_printf("Marking entry for %s (URI: %s) as confirmed.\n",
+ p->queue_name, p->uri);
+ p->status = STATUS_CONFIRMED;
+ if (p->is_legacy) {
+ p->timeout = time(NULL) + BrowseTimeout;
+ debug_printf("starting BrowseTimeout timer for %s (%ds)\n",
+ p->queue_name, BrowseTimeout);
+ } else
+ p->timeout = (time_t) -1;
+ /* If this queue was the default printer in its previous life, make
+ it the default printer again. */
+ queue_creation_handle_default(p->queue_name);
+ /* If this queue is disabled, re-enable it. */
+ enable_printer(p->queue_name);
+ /* Record the options, to record any changes which happened
+ while cups-browsed was not running */
+ record_printer_options(p->queue_name);
+ }
+
+ if (p->location[0] == '\0') {
+ free (p->location);
+ p->location = strdup(location);
+ }
+ if (p->info[0] == '\0') {
+ free (p->info);
+ p->info = strdup(info);
+ }
+ if (p->host[0] == '\0') {
+ free (p->host);
+ p->host = strdup(remote_host);
+ }
+ if (p->ip == NULL || p->ip[0] == '\0') {
+ if (p->ip) free (p->ip);
+ p->ip = (ip != NULL ? strdup(ip) : NULL);
+ }
+ if (p->port == 0)
+ p->port = port;
+ if (p->service_name[0] == '\0' && service_name) {
+ free (p->service_name);
+ p->service_name = strdup(service_name);
+ }
+ if (p->type[0] == '\0' && type) {
+ free (p->type);
+ p->type = strdup(type);
+ }
+ if (p->domain[0] == '\0' && domain) {
+ free (p->domain);
+ p->domain = strdup(domain);
+ }
+ p->netprinter = is_cups_queue ? 0 : 1;
+ } else {
+
+ /* We need to create a local queue pointing to the
+ discovered printer */
+ p = create_remote_printer_entry (local_queue_name, location, info, uri,
+ remote_host, ip, port,
+ service_name ? service_name : "", type,
+ domain, pdl, color, duplex, make_model,
+ is_cups_queue);
+ }
+
+ fail:
+ free (backup_queue_name);
+ free (remote_host);
+ free (pdl);
+ free (queue_name);
+ free (make_model);
+#ifdef HAVE_AVAHI
+ if (note_value) avahi_free(note_value);
+#endif /* HAVE_AVAHI */
+
+ if (p)
+ debug_printf("DNS-SD IDs: Service name: \"%s\", "
+ "Service type: \"%s\", Domain: \"%s\"\n",
+ p->service_name, p->type, p->domain);
+
+ return p;
+}
+
+static gboolean
+allowed (struct sockaddr *srcaddr)
+{
+ allow_t *allow;
+ int i;
+ gboolean server_allowed;
+ allow_sense_t sense;
+
+ if (browse_order == ORDER_DENY_ALLOW)
+ /* BrowseOrder Deny,Allow: Allow server, then apply BrowseDeny lines,
+ after that BrowseAllow lines */
+ server_allowed = TRUE;
+ else
+ /* BrowseOrder Allow,Deny: Deny server, then apply BrowseAllow lines,
+ after that BrowseDeny lines */
+ server_allowed = FALSE;
+
+ for (i = 0; i <= 1; i ++) {
+ if (browse_order == ORDER_DENY_ALLOW)
+ /* Treat BrowseDeny lines first, then BrowseAllow lines */
+ sense = (i == 0 ? ALLOW_DENY : ALLOW_ALLOW);
+ else
+ /* Treat BrowseAllow lines first, then BrowseDeny lines */
+ sense = (i == 0 ? ALLOW_ALLOW : ALLOW_DENY);
+
+ if (server_allowed == (sense == ALLOW_ALLOW ? TRUE : FALSE))
+ continue;
+
+ if (browseallow_all && sense == ALLOW_ALLOW) {
+ server_allowed = TRUE;
+ continue;
+ }
+ if (browsedeny_all && sense == ALLOW_DENY) {
+ server_allowed = FALSE;
+ continue;
+ }
+
+ for (allow = cupsArrayFirst (browseallow);
+ allow;
+ allow = cupsArrayNext (browseallow)) {
+ if (allow->sense != sense)
+ continue;
+
+ switch (allow->type) {
+ case ALLOW_INVALID:
+ break;
+
+ case ALLOW_IP:
+ switch (srcaddr->sa_family) {
+ case AF_INET:
+ if (((struct sockaddr_in *) srcaddr)->sin_addr.s_addr ==
+ allow->addr.ipv4.sin_addr.s_addr) {
+ server_allowed = (sense == ALLOW_ALLOW ? TRUE : FALSE);
+ goto match;
+ }
+ break;
+
+ case AF_INET6:
+ if (!memcmp (&((struct sockaddr_in6 *) srcaddr)->sin6_addr,
+ &allow->addr.ipv6.sin6_addr,
+ sizeof (allow->addr.ipv6.sin6_addr))) {
+ server_allowed = (sense == ALLOW_ALLOW ? TRUE : FALSE);
+ goto match;
+ }
+ break;
+ }
+ break;
+
+ case ALLOW_NET:
+ switch (srcaddr->sa_family) {
+ struct sockaddr_in6 *src6addr;
+
+ case AF_INET:
+ if ((((struct sockaddr_in *) srcaddr)->sin_addr.s_addr &
+ allow->mask.ipv4.sin_addr.s_addr) ==
+ allow->addr.ipv4.sin_addr.s_addr) {
+ server_allowed = (sense == ALLOW_ALLOW ? TRUE : FALSE);
+ goto match;
+ }
+ break;
+
+ case AF_INET6:
+ src6addr = (struct sockaddr_in6 *) srcaddr;
+ if (((src6addr->sin6_addr.s6_addr[0] &
+ allow->mask.ipv6.sin6_addr.s6_addr[0]) ==
+ allow->addr.ipv6.sin6_addr.s6_addr[0]) &&
+ ((src6addr->sin6_addr.s6_addr[1] &
+ allow->mask.ipv6.sin6_addr.s6_addr[1]) ==
+ allow->addr.ipv6.sin6_addr.s6_addr[1]) &&
+ ((src6addr->sin6_addr.s6_addr[2] &
+ allow->mask.ipv6.sin6_addr.s6_addr[2]) ==
+ allow->addr.ipv6.sin6_addr.s6_addr[2]) &&
+ ((src6addr->sin6_addr.s6_addr[3] &
+ allow->mask.ipv6.sin6_addr.s6_addr[3]) ==
+ allow->addr.ipv6.sin6_addr.s6_addr[3])) {
+ server_allowed = (sense == ALLOW_ALLOW ? TRUE : FALSE);
+ goto match;
+ }
+ break;
+ }
+ }
+ }
+ match:
+ continue;
+ }
+
+ return server_allowed;
+}
+
+#ifdef HAVE_AVAHI
+static void resolve_callback(
+ AvahiServiceResolver *r,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
+ AvahiResolverEvent event,
+ const char *name,
+ const char *type,
+ const char *domain,
+ const char *host_name,
+ const AvahiAddress *address,
+ uint16_t port,
+ AvahiStringList *txt,
+ AvahiLookupResultFlags flags,
+ AVAHI_GCC_UNUSED void* userdata) {
+ char ifname[IF_NAMESIZE];
+
+ debug_printf("resolve_callback() in THREAD %ld\n", pthread_self());
+
+ if (r == NULL || name == NULL || type == NULL || domain == NULL)
+ return;
+
+ /* Ignore local queues on the port of the cupsd we are serving for */
+ if (flags & AVAHI_LOOKUP_RESULT_LOCAL && port == ippPort())
+ goto ignore;
+
+ /* Get the interface name */
+ if (!if_indextoname(interface, ifname)) {
+ debug_printf("Unable to find interface name for interface %d: %s\n",
+ interface, strerror(errno));
+ strncpy(ifname, "Unknown", sizeof(ifname));
+ }
+
+ /* Called whenever a service has been resolved successfully or timed out */
+
+ switch (event) {
+
+ /* Resolver error */
+ case AVAHI_RESOLVER_FAILURE:
+ debug_printf("Avahi-Resolver: Failed to resolve service '%s' of type '%s' in domain '%s' on interface '%s' (%s): %s\n",
+ name, type, domain, ifname,
+ (address ?
+ (address->proto == AVAHI_PROTO_INET ? "IPv4" :
+ address->proto == AVAHI_PROTO_INET6 ? "IPv6" :
+ "IPv4/IPv6 Unknown") :
+ "IPv4/IPv6 Unknown"),
+ avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))));
+ break;
+
+ /* New remote printer found */
+ case AVAHI_RESOLVER_FOUND: {
+ AvahiStringList *rp_entry, *adminurl_entry;
+ char *rp_key, *rp_value, *adminurl_key, *adminurl_value;
+
+ debug_printf("Avahi Resolver: Service '%s' of type '%s' in domain '%s' on interface '%s' (%s).\n",
+ name, type, domain, ifname,
+ (address ?
+ (address->proto == AVAHI_PROTO_INET ? "IPv4" :
+ address->proto == AVAHI_PROTO_INET6 ? "IPv6" :
+ "IPv4/IPv6 Unknown") :
+ "IPv4/IPv6 Unknown"));
+
+ /* Ignore if terminated (by SIGTERM) */
+ if (terminating) {
+ debug_printf("Avahi Resolver: Ignoring because cups-browsed is terminating.\n");
+ break;
+ }
+
+ if (txt && (rp_entry = avahi_string_list_find(txt, "rp")))
+ avahi_string_list_get_pair(rp_entry, &rp_key, &rp_value, NULL);
+ else {
+ rp_key = strdup("rp");
+ rp_value = strdup("");
+ }
+ if (txt && (adminurl_entry = avahi_string_list_find(txt, "adminurl")))
+ avahi_string_list_get_pair(adminurl_entry, &adminurl_key,
+ &adminurl_value, NULL);
+ else {
+ adminurl_key = strdup("adminurl");
+ if (host_name && (adminurl_value = malloc(strlen(host_name) + 8)) != NULL)
+ sprintf(adminurl_value, "http://%s", host_name);
+ else
+ adminurl_value = strdup("");
+ }
+
+ if (CreateIPPPrinterQueues == IPP_PRINTERS_LOCAL_ONLY &&
+ strcasecmp(ifname, "lo")) {
+ debug_printf("Avahi Resolver: Service '%s' of type '%s' in domain '%s' skipped, not a local service.\n",
+ name, type, domain);
+ goto clean_up;
+ }
+
+ if (txt && rp_key && rp_value && adminurl_key && adminurl_value &&
+ !strcasecmp(rp_key, "rp") && !strcasecmp(adminurl_key, "adminurl")) {
+ char *p, instance[64];
+ /* Extract instance from DNSSD service name (to serve as info field) */
+ p = strstr(name, " @ ");
+ if (p) {
+ int n;
+ n = p - name;
+ if (n >= sizeof(instance))
+ n = sizeof(instance) - 1;
+ strncpy(instance, name, n);
+ instance[n] = '\0';
+ debug_printf("Avahi-Resolver: instance: |%s|\n", instance); /* !! */
+ } else {
+ instance[0] = '\0';
+ }
+ /* Determine the remote printer's IP */
+ if (IPBasedDeviceURIs != IP_BASED_URIS_NO || !strcasecmp(ifname, "lo") ||
+ (!browseallow_all && cupsArrayCount(browseallow) > 0)) {
+ struct sockaddr saddr;
+ struct sockaddr *addr = &saddr;
+ char *addrstr;
+ int addrlen;
+ int addrfound = 0;
+ if ((addrstr = calloc(256, sizeof(char))) == NULL) {
+ debug_printf("Avahi Resolver: Service '%s' of type '%s' in domain '%s' skipped, could not allocate memory to determine IP address.\n",
+ name, type, domain);
+ goto clean_up;
+ }
+ if (address &&
+ address->proto == AVAHI_PROTO_INET &&
+ IPBasedDeviceURIs != IP_BASED_URIS_IPV6_ONLY) {
+ avahi_address_snprint(addrstr, 256, address);
+ addr->sa_family = AF_INET;
+ if (inet_aton(addrstr,
+ &((struct sockaddr_in *) addr)->sin_addr) &&
+ allowed(addr))
+ addrfound = 1;
+ } else if (address &&
+ address->proto == AVAHI_PROTO_INET6 &&
+ interface != AVAHI_IF_UNSPEC &&
+ IPBasedDeviceURIs != IP_BASED_URIS_IPV4_ONLY) {
+ strncpy(addrstr, "[v1.", 256);
+ avahi_address_snprint(addrstr + 4, 256 - 6, address);
+ addrlen = strlen(addrstr + 4);
+ addr->sa_family = AF_INET6;
+ if (inet_pton(AF_INET6, addrstr + 4,
+ &((struct sockaddr_in6 *) addr)->sin6_addr) &&
+ allowed(addr)) {
+ if (!strncasecmp(addrstr + 4, "fe", 2) &&
+ (addrstr[6] == '8' || addrstr[6] == '9' ||
+ addrstr[6] == 'A' || addrstr[6] == 'B' ||
+ addrstr[6] == 'a' || addrstr[6] == 'B'))
+ /* Link-local address, needs specification of interface */
+ snprintf(addrstr + addrlen + 4, 256 -
+ addrlen - 4, "%%%s]",
+ ifname);
+ else {
+ addrstr[addrlen + 4] = ']';
+ addrstr[addrlen + 5] = '\0';
+ }
+ addrfound = 1;
+ }
+ } else
+ debug_printf("Avahi Resolver: Service '%s' of type '%s' in domain '%s': No IP address information available.\n",
+ name, type, domain);
+ if (addrfound == 1) {
+ /* Check remote printer type and create appropriate local queue to
+ point to it */
+ if (IPBasedDeviceURIs != IP_BASED_URIS_NO ||
+ !strcasecmp(ifname, "lo") ||
+ !host_name) {
+ debug_printf("Avahi Resolver: Service '%s' of type '%s' in domain '%s' with IP address %s.\n",
+ name, type, domain, addrstr);
+ examine_discovered_printer_record((strcasecmp(ifname, "lo") &&
+ host_name ? host_name : addrstr),
+ addrstr, port, rp_value, name,
+ "", instance, type, domain,
+ txt);
+ } else
+ examine_discovered_printer_record(host_name, NULL, port, rp_value,
+ name, "", instance, type,
+ domain, txt);
+ } else
+ debug_printf("Avahi Resolver: Service '%s' of type '%s' in domain '%s' skipped, could not determine IP address.\n",
+ name, type, domain);
+ free(addrstr);
+ } else {
+ /* Check remote printer type and create appropriate local queue to
+ point to it */
+ if (host_name)
+ examine_discovered_printer_record(host_name, NULL, port, rp_value,
+ name, "", instance, type, domain,
+ txt);
+ else
+ debug_printf("Avahi Resolver: Service '%s' of type '%s' in domain '%s' skipped, host name not supplied.\n",
+ name, type, domain);
+ }
+ }
+
+ clean_up:
+
+ /* Clean up */
+
+ if (rp_entry) {
+ avahi_free(rp_key);
+ avahi_free(rp_value);
+ } else {
+ free(rp_key);
+ free(rp_value);
+ }
+ if (adminurl_entry) {
+ avahi_free(adminurl_key);
+ avahi_free(adminurl_value);
+ } else {
+ free(adminurl_key);
+ free(adminurl_value);
+ }
+ break;
+ }
+ }
+
+ ignore:
+ avahi_service_resolver_free(r);
+
+ if (in_shutdown == 0)
+ recheck_timer ();
+}
+
+static void browse_callback(
+ AvahiServiceBrowser *b,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
+ AvahiBrowserEvent event,
+ const char *name,
+ const char *type,
+ const char *domain,
+ AvahiLookupResultFlags flags,
+ void* userdata) {
+
+ AvahiClient *c = userdata;
+ char ifname[IF_NAMESIZE];
+
+ debug_printf("browse_callback() in THREAD %ld\n", pthread_self());
+
+ if (b == NULL)
+ return;
+
+ /* Get the interface name */
+ if (!if_indextoname(interface, ifname)) {
+ debug_printf("Unable to find interface name for interface %d: %s\n",
+ interface, strerror(errno));
+ strncpy(ifname, "Unknown", sizeof(ifname));
+ }
+
+ /* Called whenever a new services becomes available on the LAN or
+ is removed from the LAN */
+
+ switch (event) {
+
+ /* Avahi browser error */
+ case AVAHI_BROWSER_FAILURE:
+
+ debug_printf("Avahi Browser: ERROR: %s\n",
+ avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b))));
+ g_main_loop_quit(gmainloop);
+ g_main_context_wakeup(NULL);
+ return;
+
+ /* New service (remote printer) */
+ case AVAHI_BROWSER_NEW:
+
+ if (c == NULL || name == NULL || type == NULL || domain == NULL)
+ return;
+
+ debug_printf("Avahi Browser: NEW: service '%s' of type '%s' in domain '%s' on interface '%s'\n",
+ name, type, domain, ifname);
+
+ /* Ignore if terminated (by SIGTERM) */
+ if (terminating) {
+ debug_printf("Avahi Browser: Ignoring because cups-browsed is terminating.\n");
+ break;
+ }
+
+ /* We ignore the returned resolver object. In the callback
+ function we free it. If the server is terminated before
+ the callback function is called the server will free
+ the resolver for us. */
+
+ if (!(avahi_service_resolver_new(c, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback, c)))
+ debug_printf("Failed to resolve service '%s': %s\n",
+ name, avahi_strerror(avahi_client_errno(c)));
+ break;
+
+ /* A service (remote printer) has disappeared */
+ case AVAHI_BROWSER_REMOVE: {
+ remote_printer_t *p;
+
+ if (name == NULL || type == NULL || domain == NULL)
+ return;
+
+ debug_printf("Avahi Browser: REMOVE: service '%s' of type '%s' in domain '%s' on interface '%s'\n",
+ name, type, domain, ifname);
+
+ /* Ignore if terminated (by SIGTERM) */
+ if (terminating) {
+ debug_printf("Avahi Browser: Ignoring because cups-browsed is terminating.\n");
+ break;
+ }
+
+ /* Check whether we have listed this printer */
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers))
+ if (p->status != STATUS_DISAPPEARED &&
+ !strcasecmp(p->service_name, name) &&
+ !strcasecmp(p->type, type) &&
+ !strcasecmp(p->domain, domain))
+ break;
+ if (p) {
+ remove_printer_entry(p);
+ debug_printf("DNS-SD IDs: Service name: \"%s\", Service type: \"%s\", Domain: \"%s\"\n",
+ p->service_name, p->type, p->domain);
+
+ if (in_shutdown == 0)
+ recheck_timer ();
+ }
+ break;
+ }
+
+ /* All cached Avahi events are treated now */
+ case AVAHI_BROWSER_ALL_FOR_NOW:
+ case AVAHI_BROWSER_CACHE_EXHAUSTED:
+ debug_printf("Avahi Browser: %s\n",
+ event == AVAHI_BROWSER_CACHE_EXHAUSTED ?
+ "CACHE_EXHAUSTED" : "ALL_FOR_NOW");
+ break;
+ }
+
+}
+
+void avahi_browser_shutdown() {
+ remote_printer_t *p;
+
+ avahi_present = 0;
+
+ /* Remove all queues which we have set up based on DNS-SD discovery*/
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ if (p->type && p->type[0]) {
+ p->status = STATUS_DISAPPEARED;
+ p->timeout = time(NULL) + TIMEOUT_IMMEDIATELY;
+ }
+ }
+ if (in_shutdown == 0)
+ recheck_timer();
+ else
+ update_cups_queues(NULL);
+
+ /* Free the data structures for DNS-SD browsing */
+ if (sb1) {
+ avahi_service_browser_free(sb1);
+ sb1 = NULL;
+ }
+ if (sb2) {
+ avahi_service_browser_free(sb2);
+ sb2 = NULL;
+ }
+
+ /* Switch on auto shutdown mode */
+ if (autoshutdown_avahi && in_shutdown == 0) {
+ autoshutdown = 1;
+ debug_printf("Avahi server disappeared, switching to auto shutdown mode ...\n");
+ /* If there are no printers or no jobs schedule the shutdown in
+ autoshutdown_timeout seconds */
+ if (!autoshutdown_exec_id &&
+ (cupsArrayCount(remote_printers) == 0 ||
+ (autoshutdown_on == NO_JOBS && check_jobs() == 0))) {
+ debug_printf ("We entered auto shutdown mode and no printers are there to make available or no jobs on them, shutting down in %d sec...\n", autoshutdown_timeout);
+ autoshutdown_exec_id =
+ g_timeout_add_seconds (autoshutdown_timeout, autoshutdown_execute,
+ NULL);
+ }
+ }
+}
+
+void avahi_shutdown() {
+ avahi_browser_shutdown();
+ if (client) {
+ avahi_client_free(client);
+ client = NULL;
+ }
+ if (glib_poll) {
+ avahi_glib_poll_free(glib_poll);
+ glib_poll = NULL;
+ }
+}
+
+static void client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void * userdata) {
+ int error;
+
+ if (c == NULL)
+ return;
+
+ /* Called whenever the client or server state changes */
+ switch (state) {
+
+ /* avahi-daemon available */
+ case AVAHI_CLIENT_S_REGISTERING:
+ case AVAHI_CLIENT_S_RUNNING:
+ case AVAHI_CLIENT_S_COLLISION:
+
+ debug_printf("Avahi server connection got available, setting up service browsers.\n");
+
+ /* Create the service browsers */
+ if (!sb1)
+ if (!(sb1 =
+ avahi_service_browser_new(c, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
+ "_ipp._tcp", NULL, 0, browse_callback,
+ c))) {
+ debug_printf("ERROR: Failed to create service browser for IPP: %s\n",
+ avahi_strerror(avahi_client_errno(c)));
+ }
+ if (!sb2)
+ if (!(sb2 =
+ avahi_service_browser_new(c, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
+ "_ipps._tcp", NULL, 0, browse_callback,
+ c))) {
+ debug_printf("ERROR: Failed to create service browser for IPPS: %s\n",
+ avahi_strerror(avahi_client_errno(c)));
+ }
+
+ avahi_present = 1;
+
+ /* switch off auto shutdown mode */
+ if (autoshutdown_avahi) {
+ autoshutdown = 0;
+ debug_printf("Avahi server available, switching to permanent mode ...\n");
+ /* If there is still an active auto shutdown timer, kill it */
+ if (autoshutdown_exec_id) {
+ debug_printf ("We have left auto shutdown mode, killing auto shutdown timer.\n");
+ g_source_remove(autoshutdown_exec_id);
+ autoshutdown_exec_id = 0;
+ }
+ }
+
+ break;
+
+ /* Avahi client error */
+ case AVAHI_CLIENT_FAILURE:
+
+ if (avahi_client_errno(c) == AVAHI_ERR_DISCONNECTED) {
+ debug_printf("Avahi server disappeared, shutting down service browsers, removing DNS-SD-discovered print queues.\n");
+ avahi_browser_shutdown();
+ /* Renewing client */
+ avahi_client_free(client);
+ client = avahi_client_new(avahi_glib_poll_get(glib_poll),
+ AVAHI_CLIENT_NO_FAIL,
+ client_callback, NULL, &error);
+ if (!client) {
+ debug_printf("ERROR: Failed to create client: %s\n",
+ avahi_strerror(error));
+ BrowseRemoteProtocols &= ~BROWSE_DNSSD;
+ avahi_shutdown();
+ }
+ } else {
+ debug_printf("ERROR: Avahi server connection failure: %s\n",
+ avahi_strerror(avahi_client_errno(c)));
+ g_main_loop_quit(gmainloop);
+ g_main_context_wakeup(NULL);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void avahi_init() {
+ int error;
+
+ if (BrowseRemoteProtocols & BROWSE_DNSSD) {
+ /* Allocate main loop object */
+ if (!glib_poll)
+ if (!(glib_poll = avahi_glib_poll_new(NULL, G_PRIORITY_DEFAULT))) {
+ debug_printf("ERROR: Failed to create glib poll object.\n");
+ goto avahi_init_fail;
+ }
+
+ /* Allocate a new client */
+ if (!client)
+ client = avahi_client_new(avahi_glib_poll_get(glib_poll),
+ AVAHI_CLIENT_NO_FAIL,
+ client_callback, NULL, &error);
+
+ /* Check wether creating the client object succeeded */
+ if (!client) {
+ debug_printf("ERROR: Failed to create client: %s\n",
+ avahi_strerror(error));
+ goto avahi_init_fail;
+ }
+
+ return;
+
+ avahi_init_fail:
+ BrowseRemoteProtocols &= ~BROWSE_DNSSD;
+ avahi_shutdown();
+ }
+}
+#endif /* HAVE_AVAHI */
+
+/*
+ * A CUPS printer has been discovered via CUPS Browsing
+ * or with BrowsePoll
+ */
+void
+found_cups_printer (const char *remote_host, const char *uri,
+ const char *location, const char *info)
+{
+ char scheme[32];
+ char username[64];
+ char host[HTTP_MAX_HOST];
+ char resource[HTTP_MAX_URI];
+ int port;
+ netif_t *iface;
+ char local_resource[HTTP_MAX_URI];
+ char service_name[HTTP_MAX_URI];
+ char *c;
+ int hl;
+ remote_printer_t *printer;
+
+ memset(scheme, 0, sizeof(scheme));
+ memset(username, 0, sizeof(username));
+ memset(host, 0, sizeof(host));
+ memset(resource, 0, sizeof(resource));
+ memset(local_resource, 0, sizeof(local_resource));
+
+ httpSeparateURI (HTTP_URI_CODING_ALL, uri,
+ scheme, sizeof(scheme) - 1,
+ username, sizeof(username) - 1,
+ host, sizeof(host) - 1,
+ &port,
+ resource, sizeof(resource)- 1);
+
+ /* Check this isn't one of our own broadcasts */
+ for (iface = cupsArrayFirst (netifs);
+ iface;
+ iface = cupsArrayNext (netifs))
+ if (!strcasecmp (host, iface->address))
+ break;
+ if (iface) {
+ debug_printf("ignoring own broadcast on %s\n",
+ iface->address);
+ return;
+ }
+
+ if (strncasecmp (resource, "/printers/", 10) &&
+ strncasecmp (resource, "/classes/", 9)) {
+ debug_printf("Don't understand URI: %s\n", uri);
+ return;
+ }
+
+ strncpy (local_resource, resource + 1, sizeof (local_resource) - 1);
+ local_resource[sizeof (local_resource) - 1] = '\0';
+ c = strchr (local_resource, '?');
+ if (c)
+ *c = '\0';
+
+ /* Build the DNS-SD service name which CUPS would give to this printer
+ when DNS-SD-broadcasting it */
+ snprintf(service_name, sizeof (service_name), "%s @ %s",
+ (info ? info : strchr(local_resource, '/') + 1), host);
+ /* Cut off trailing ".local" of host name */
+ hl = strlen(service_name);
+ if (hl > 6 && !strcasecmp(service_name + hl - 6, ".local"))
+ service_name[hl - 6] = '\0';
+ if (hl > 7 && !strcasecmp(service_name + hl - 7, ".local."))
+ service_name[hl - 7] = '\0';
+ /* DNS-SD service name has max. 63 characters */
+ service_name[63] = '\0';
+
+ debug_printf("CUPS browsing: Remote host: %s; Port: %d; Remote queue name: %s; Service Name: %s\n",
+ host, port, strchr(local_resource, '/') + 1, service_name);
+
+ printer = examine_discovered_printer_record(host, NULL, port, local_resource,
+ service_name,
+ location ? location : "",
+ info ? info : "", "", "", NULL);
+
+ if (printer &&
+ (printer->domain == NULL || printer->domain[0] == '\0' ||
+ printer->type == NULL || printer->type[0] == '\0')) {
+ printer->is_legacy = 1;
+ if (printer->status != STATUS_TO_BE_CREATED) {
+ printer->timeout = time(NULL) + BrowseTimeout;
+ debug_printf("starting BrowseTimeout timer for %s (%ds)\n",
+ printer->queue_name, BrowseTimeout);
+ }
+ }
+}
+
+gboolean
+process_browse_data (GIOChannel *source,
+ GIOCondition condition,
+ gpointer data)
+{
+ char packet[2048];
+ http_addr_t srcaddr;
+ socklen_t srclen;
+ ssize_t got;
+ unsigned int type;
+ unsigned int state;
+ char remote_host[256];
+ char uri[1024];
+ char location[1024];
+ char info[1024];
+ char *c = NULL, *end = NULL;
+
+ debug_printf("process_browse_data() in THREAD %ld\n", pthread_self());
+
+ memset(packet, 0, sizeof(packet));
+ memset(remote_host, 0, sizeof(remote_host));
+ memset(uri, 0, sizeof(uri));
+ memset(info, 0, sizeof(info));
+
+ srclen = sizeof (srcaddr);
+ got = recvfrom (browsesocket, packet, sizeof (packet) - 1, 0,
+ &srcaddr.addr, &srclen);
+ if (got == -1) {
+ debug_printf ("cupsd-browsed: error receiving browse packet: %s\n",
+ strerror (errno));
+ /* Remove this I/O source */
+ return FALSE;
+ }
+
+ packet[got] = '\0';
+ httpAddrString (&srcaddr, remote_host, sizeof (remote_host) - 1);
+
+ /* Check this packet is allowed */
+ if (!allowed ((struct sockaddr *) &srcaddr)) {
+ debug_printf("browse packet from %s disallowed\n",
+ remote_host);
+ return TRUE;
+ }
+
+ debug_printf("browse packet received from %s\n",
+ remote_host);
+
+ if (sscanf (packet, "%x%x%1023s", &type, &state, uri) < 3) {
+ debug_printf("incorrect browse packet format\n");
+ return TRUE;
+ }
+
+ info[0] = '\0';
+
+ /* do not read OOB */
+ end = packet + sizeof(packet);
+ c = strchr (packet, '\"');
+ if (c >= end)
+ return TRUE;
+
+ if (c) {
+ /* Extract location field */
+ {
+ int i;
+ c++;
+ for (i = 0;
+ i < sizeof (location) - 1 && *c != '\"' && c < end;
+ i++, c++)
+ location[i] = *c;
+ location[i] = '\0';
+ debug_printf("process_browse_data: location: |%s|\n", location); /* !! */
+ }
+ for (; c < end && *c != '\"'; c++)
+ ;
+
+ if (c >= end)
+ return TRUE;
+
+ if (*c == '\"') {
+ for (c++; c < end && isspace(*c); c++)
+ ;
+ }
+
+ if (c >= end)
+ return TRUE;
+
+ /* Is there an info field? */
+ if (*c == '\"') {
+ int i;
+ c++;
+ for (i = 0;
+ i < sizeof (info) - 1 && *c != '\"' && c < end;
+ i++, c++)
+ info[i] = *c;
+ info[i] = '\0';
+ debug_printf("process_browse_data: info: |%s|\n", info); /* !! */
+ }
+ }
+ if (c >= end)
+ return TRUE;
+
+ if (!(type & CUPS_PRINTER_DELETE))
+ found_cups_printer (remote_host, uri, location, info);
+
+ if (in_shutdown == 0)
+ recheck_timer ();
+
+ /* Don't remove this I/O source */
+ return TRUE;
+}
+
+static gboolean
+update_netifs (gpointer data)
+{
+ struct ifaddrs *ifaddr, *ifa;
+ netif_t *iface, *iface2;
+ int dupe;
+
+ debug_printf("update_netifs() in THREAD %ld\n", pthread_self());
+
+ update_netifs_sourceid = 0;
+ if (getifaddrs (&ifaddr) == -1) {
+ debug_printf("unable to get interface addresses: %s\n",
+ strerror (errno));
+ return FALSE;
+ }
+
+ while ((iface = cupsArrayFirst (netifs)) != NULL) {
+ cupsArrayRemove (netifs, iface);
+ free (iface->address);
+ free (iface);
+ }
+
+ for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
+ netif_t *iface;
+
+ if (ifa->ifa_addr == NULL)
+ continue;
+
+ if (ifa->ifa_broadaddr == NULL)
+ continue;
+
+ if (ifa->ifa_flags & IFF_LOOPBACK)
+ continue;
+
+ if (!(ifa->ifa_flags & IFF_BROADCAST))
+ continue;
+
+ iface = malloc (sizeof (netif_t));
+ if (iface == NULL) {
+ debug_printf ("malloc failure\n");
+ exit (1);
+ }
+
+ iface->address = malloc (HTTP_MAX_HOST);
+ if (iface->address == NULL) {
+ free (iface);
+ debug_printf ("malloc failure\n");
+ exit (1);
+ }
+
+ iface->address[0] = '\0';
+ switch (ifa->ifa_addr->sa_family) {
+ case AF_INET:
+ /* copy broadcast addr/fill in port first to faciliate dupe compares */
+ memcpy (&iface->broadcast, ifa->ifa_broadaddr,
+ sizeof (struct sockaddr_in));
+ iface->broadcast.ipv4.sin_port = htons (BrowsePort);
+ /* discard if we already have an interface sharing the broadcast address */
+ dupe = 0;
+ for (iface2 = (netif_t *)cupsArrayFirst (netifs);
+ iface2 != NULL;
+ iface2 = (netif_t *)cupsArrayNext (netifs)) {
+ if (memcmp(&iface2->broadcast, &iface->broadcast,
+ sizeof(struct sockaddr_in)) == 0) {
+ dupe = 1;
+ break;
+ }
+ }
+ if (dupe) break;
+ getnameinfo (ifa->ifa_addr, sizeof (struct sockaddr_in),
+ iface->address, HTTP_MAX_HOST,
+ NULL, 0, NI_NUMERICHOST);
+ break;
+
+ case AF_INET6:
+ if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *)(ifa->ifa_addr))
+ ->sin6_addr))
+ break;
+
+ /* see above for order */
+ memcpy (&iface->broadcast, ifa->ifa_broadaddr,
+ sizeof (struct sockaddr_in6));
+ iface->broadcast.ipv6.sin6_port = htons (BrowsePort);
+ /* discard alias addresses (identical broadcast) */
+ dupe = 0;
+ for (iface2 = (netif_t *)cupsArrayFirst (netifs);
+ iface2 != NULL;
+ iface2 = (netif_t *)cupsArrayNext (netifs)) {
+ if (memcmp(&iface2->broadcast, ifa->ifa_broadaddr,
+ sizeof(struct sockaddr_in6)) == 0) {
+ dupe = 1;
+ break;
+ }
+ }
+ if (dupe) break;
+ getnameinfo (ifa->ifa_addr, sizeof (struct sockaddr_in6),
+ iface->address, HTTP_MAX_HOST, NULL, 0, NI_NUMERICHOST);
+ break;
+ }
+
+ if (iface->address[0]) {
+ cupsArrayAdd (netifs, iface);
+ debug_printf("network interface at %s\n", iface->address);
+ } else {
+ free (iface->address);
+ free (iface);
+ }
+ }
+
+ freeifaddrs (ifaddr);
+
+ /* If run as a timeout, don't run it again. */
+ return FALSE;
+}
+
+static void
+broadcast_browse_packets (gpointer data, gpointer user_data)
+{
+ browse_data_t *bdata = data;
+ netif_t *browse;
+ char packet[2048];
+ char uri[HTTP_MAX_URI];
+ char scheme[32];
+ char username[64];
+ char host[HTTP_MAX_HOST];
+ int port;
+ char resource[HTTP_MAX_URI];
+
+ debug_printf("broadcast_browse_packets() in THREAD %ld\n", pthread_self());
+
+ for (browse = (netif_t *)cupsArrayFirst (netifs);
+ browse != NULL;
+ browse = (netif_t *)cupsArrayNext (netifs)) {
+ /* Replace 'localhost' with our IP address on this interface */
+ httpSeparateURI(HTTP_URI_CODING_ALL, bdata->uri,
+ scheme, sizeof(scheme),
+ username, sizeof(username),
+ host, sizeof(host),
+ &port,
+ resource, sizeof(resource));
+ httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof (uri),
+ scheme, username, browse->address, port, resource);
+
+ if (snprintf (packet, sizeof (packet),
+ "%x " /* type */
+ "%x " /* state */
+ "%s " /* uri */
+ "\"%s\" " /* location */
+ "\"%s\" " /* info */
+ "\"%s\" " /* make-and-model */
+ "lease-duration=%d" /* BrowseTimeout */
+ "%s%s" /* other browse options */
+ "\n",
+ bdata->type,
+ bdata->state,
+ uri,
+ bdata->location,
+ bdata->info,
+ bdata->make_model,
+ BrowseTimeout,
+ bdata->browse_options ? " " : "",
+ bdata->browse_options ? bdata->browse_options : "")
+ >= sizeof (packet)) {
+ debug_printf ("oversize packet not sent\n");
+ continue;
+ }
+
+ debug_printf("packet to send:\n%s", packet);
+
+ int err = sendto (browsesocket, packet,
+ strlen (packet), 0,
+ &browse->broadcast.addr,
+ httpAddrLength (&browse->broadcast));
+ if (err == -1)
+ debug_printf("cupsd-browsed: sendto returned %d: %s\n",
+ err, strerror (errno));
+ }
+}
+
+gboolean
+send_browse_data (gpointer data)
+{
+ debug_printf("send_browse_data() in THREAD %ld\n", pthread_self());
+ update_netifs (NULL);
+ res_init ();
+ update_local_printers ();
+ g_list_foreach (browse_data, broadcast_browse_packets, NULL);
+ g_timeout_add_seconds (BrowseInterval, send_browse_data, NULL);
+
+ /* Stop this timeout handler, we called a new one */
+ return FALSE;
+}
+
+static browsepoll_printer_t *
+new_browsepoll_printer (const char *uri_supported,
+ const char *location,
+ const char *info)
+{
+ browsepoll_printer_t *printer = g_malloc (sizeof (browsepoll_printer_t));
+ printer->uri_supported = g_strdup (uri_supported);
+ printer->location = g_strdup (location);
+ printer->info = g_strdup (info);
+ return printer;
+}
+
+static void
+browsepoll_printer_free (gpointer data)
+{
+ browsepoll_printer_t *printer = data;
+ debug_printf("browsepoll_printer_free() in THREAD %ld\n", pthread_self());
+ free (printer->uri_supported);
+ free (printer->location);
+ free (printer->info);
+ free (printer);
+}
+
+static void
+browse_poll_get_printers (browsepoll_t *context, http_t *conn)
+{
+ static const char * const rattrs[] = { "printer-uri-supported",
+ "printer-location",
+ "printer-info"};
+ ipp_t *request, *response = NULL;
+ ipp_attribute_t *attr;
+ GList *printers = NULL;
+
+ debug_printf ("cups-browsed [BrowsePoll %s:%d]: CUPS-Get-Printers\n",
+ context->server, context->port);
+
+ request = ippNewRequest(CUPS_GET_PRINTERS);
+ if (context->major > 0) {
+ debug_printf("cups-browsed [BrowsePoll %s:%d]: setting IPP version %d.%d\n",
+ context->server, context->port, context->major,
+ context->minor);
+ ippSetVersion (request, context->major, context->minor);
+ }
+
+ ippAddStrings (request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", sizeof (rattrs) / sizeof (rattrs[0]),
+ NULL,
+ rattrs);
+
+ /* Ask the server to exclude printers that are remote or not shared,
+ or implicit classes. */
+ ippAddInteger (request, IPP_TAG_OPERATION, IPP_TAG_ENUM,
+ "printer-type-mask",
+ CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
+ CUPS_PRINTER_NOT_SHARED);
+ ippAddInteger (request, IPP_TAG_OPERATION, IPP_TAG_ENUM,
+ "printer-type", 0);
+
+ ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser ());
+
+ response = cupsDoRequest(conn, request, "/");
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE) {
+ debug_printf("cups-browsed [BrowsePoll %s:%d]: failed: %s\n",
+ context->server, context->port, cupsLastErrorString ());
+ goto fail;
+ }
+
+ for (attr = ippFirstAttribute(response); attr;
+ attr = ippNextAttribute(response)) {
+ browsepoll_printer_t *printer;
+ const char *uri, *location, *info;
+
+ while (attr && ippGetGroupTag(attr) != IPP_TAG_PRINTER)
+ attr = ippNextAttribute(response);
+
+ if (!attr)
+ break;
+
+ uri = NULL;
+ info = NULL;
+ location = NULL;
+ while (attr && ippGetGroupTag(attr) == IPP_TAG_PRINTER) {
+
+ if (!strcasecmp (ippGetName(attr), "printer-uri-supported") &&
+ ippGetValueTag(attr) == IPP_TAG_URI)
+ uri = ippGetString(attr, 0, NULL);
+ else if (!strcasecmp (ippGetName(attr), "printer-location") &&
+ ippGetValueTag(attr) == IPP_TAG_TEXT)
+ location = ippGetString(attr, 0, NULL);
+ else if (!strcasecmp (ippGetName(attr), "printer-info") &&
+ ippGetValueTag(attr) == IPP_TAG_TEXT)
+ info = ippGetString(attr, 0, NULL);
+
+ attr = ippNextAttribute(response);
+ }
+
+ if (uri) {
+ found_cups_printer (context->server, uri, location, info);
+ printer = new_browsepoll_printer (uri, location, info);
+ printers = g_list_insert (printers, printer, 0);
+ }
+
+ if (!attr)
+ break;
+ }
+
+ g_list_free_full (context->printers, browsepoll_printer_free);
+ context->printers = printers;
+
+fail:
+ if (response)
+ ippDelete(response);
+}
+
+static void
+browse_poll_create_subscription (browsepoll_t *context, http_t *conn)
+{
+ static const char * const events[] = { "printer-added",
+ "printer-changed",
+ "printer-config-changed",
+ "printer-modified",
+ "printer-deleted",
+ "printer-state-changed" };
+ ipp_t *request, *response = NULL;
+ ipp_attribute_t *attr;
+
+ debug_printf ("cups-browsed [BrowsePoll %s:%d]: IPP-Create-Subscription\n",
+ context->server, context->port);
+
+ request = ippNewRequest(IPP_CREATE_PRINTER_SUBSCRIPTION);
+ if (context->major > 0) {
+ debug_printf("cups-browsed [BrowsePoll %s:%d]: setting IPP version %d.%d\n",
+ context->server, context->port, context->major,
+ context->minor);
+ ippSetVersion (request, context->major, context->minor);
+ }
+
+ ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, "/");
+ ippAddString (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD,
+ "notify-pull-method", NULL, "ippget");
+ ippAddString (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_CHARSET,
+ "notify-charset", NULL, "utf-8");
+ ippAddString (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser ());
+ ippAddStrings (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD,
+ "notify-events", sizeof (events) / sizeof (events[0]),
+ NULL, events);
+ ippAddInteger (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
+ "notify-time-interval", BrowseInterval);
+
+ response = cupsDoRequest (conn, request, "/");
+ if (!response ||
+ ippGetStatusCode (response) > IPP_STATUS_OK_EVENTS_COMPLETE) {
+ debug_printf("cupsd-browsed [BrowsePoll %s:%d]: failed: %s\n",
+ context->server, context->port, cupsLastErrorString ());
+ context->subscription_id = -1;
+ context->can_subscribe = FALSE;
+ goto fail;
+ }
+
+ for (attr = ippFirstAttribute(response); attr;
+ attr = ippNextAttribute(response)) {
+ if (ippGetGroupTag (attr) == IPP_TAG_SUBSCRIPTION) {
+ if (ippGetValueTag (attr) == IPP_TAG_INTEGER &&
+ !strcasecmp (ippGetName (attr), "notify-subscription-id")) {
+ context->subscription_id = ippGetInteger (attr, 0);
+ debug_printf("cups-browsed [BrowsePoll %s:%d]: subscription ID=%d\n",
+ context->server, context->port, context->subscription_id);
+ break;
+ }
+ }
+ }
+
+ if (!attr) {
+ debug_printf("cups-browsed [BrowsePoll %s:%d]: no ID returned\n",
+ context->server, context->port);
+ context->subscription_id = -1;
+ context->can_subscribe = FALSE;
+ }
+
+fail:
+ if (response)
+ ippDelete(response);
+}
+
+static void
+browse_poll_cancel_subscription (browsepoll_t *context)
+{
+ ipp_t *request, *response = NULL;
+ http_t *conn = httpConnectEncryptShortTimeout (context->server, context->port,
+ HTTP_ENCRYPT_IF_REQUESTED);
+
+ if (conn == NULL) {
+ debug_printf("cups-browsed [BrowsePoll %s:%d]: connection failure "
+ "attempting to cancel\n", context->server, context->port);
+ return;
+ }
+
+ httpSetTimeout(conn, HttpRemoteTimeout, http_timeout_cb, NULL);
+
+ debug_printf ("cups-browsed [BrowsePoll %s:%d]: IPP-Cancel-Subscription\n",
+ context->server, context->port);
+
+ request = ippNewRequest(IPP_CANCEL_SUBSCRIPTION);
+ if (context->major > 0) {
+ debug_printf("cups-browsed [BrowsePoll %s:%d]: setting IPP version %d.%d\n",
+ context->server, context->port, context->major,
+ context->minor);
+ ippSetVersion (request, context->major, context->minor);
+ }
+
+ ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, "/");
+ ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser ());
+ ippAddInteger (request, IPP_TAG_OPERATION, IPP_TAG_INTEGER,
+ "notify-subscription-id", context->subscription_id);
+
+ response = cupsDoRequest (conn, request, "/");
+ if (!response ||
+ ippGetStatusCode (response) > IPP_STATUS_OK_EVENTS_COMPLETE)
+ debug_printf("cupsd-browsed [BrowsePoll %s:%d]: failed: %s\n",
+ context->server, context->port, cupsLastErrorString ());
+
+ if (response)
+ ippDelete(response);
+
+ httpClose (conn);
+}
+
+static gboolean
+browse_poll_get_notifications (browsepoll_t *context, http_t *conn)
+{
+ ipp_t *request, *response = NULL;
+ ipp_status_t status;
+ gboolean get_printers = FALSE;
+
+ debug_printf ("cups-browsed [BrowsePoll %s:%d]: IPP-Get-Notifications\n",
+ context->server, context->port);
+
+ request = ippNewRequest(IPP_GET_NOTIFICATIONS);
+ if (context->major > 0) {
+ debug_printf("cups-browsed [BrowsePoll %s:%d]: setting IPP version %d.%d\n",
+ context->server, context->port, context->major,
+ context->minor);
+ ippSetVersion (request, context->major, context->minor);
+ }
+
+ ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, "/");
+ ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser ());
+ ippAddInteger (request, IPP_TAG_OPERATION, IPP_TAG_INTEGER,
+ "notify-subscription-ids", context->subscription_id);
+ ippAddInteger (request, IPP_TAG_OPERATION, IPP_TAG_INTEGER,
+ "notify-sequence-numbers", context->sequence_number + 1);
+
+ response = cupsDoRequest (conn, request, "/");
+ if (!response)
+ status = cupsLastError ();
+ else
+ status = ippGetStatusCode (response);
+
+ if (status == IPP_STATUS_ERROR_NOT_FOUND) {
+ /* Subscription lease has expired. */
+ debug_printf ("cups-browsed [BrowsePoll %s:%d]: Lease expired\n",
+ context->server, context->port);
+ browse_poll_create_subscription (context, conn);
+ get_printers = TRUE;
+ } else if (status > IPP_STATUS_OK_EVENTS_COMPLETE) {
+ debug_printf("cups-browsed [BrowsePoll %s:%d]: failed: %s\n",
+ context->server, context->port, cupsLastErrorString ());
+ context->can_subscribe = FALSE;
+ browse_poll_cancel_subscription (context);
+ context->subscription_id = -1;
+ context->sequence_number = 0;
+ get_printers = TRUE;
+ }
+
+ if (!get_printers) {
+ ipp_attribute_t *attr;
+ gboolean seen_event = FALSE;
+ int last_seq = context->sequence_number;
+ if (response == NULL)
+ return FALSE;
+ for (attr = ippFirstAttribute(response); attr;
+ attr = ippNextAttribute(response))
+ if (ippGetGroupTag (attr) == IPP_TAG_EVENT_NOTIFICATION) {
+ /* There is a printer-* event here. */
+ seen_event = TRUE;
+
+ if (!strcmp (ippGetName (attr), "notify-sequence-number") &&
+ ippGetValueTag (attr) == IPP_TAG_INTEGER)
+ last_seq = ippGetInteger (attr, 0);
+ }
+
+ if (seen_event) {
+ debug_printf("cups-browsed [BrowsePoll %s:%d]: printer-* event\n",
+ context->server, context->port);
+ context->sequence_number = last_seq;
+ get_printers = TRUE;
+ } else
+ debug_printf("cups-browsed [BrowsePoll %s:%d]: no events\n",
+ context->server, context->port);
+ }
+
+ if (response)
+ ippDelete (response);
+
+ return get_printers;
+}
+
+static void
+browsepoll_printer_keepalive (gpointer data, gpointer user_data)
+{
+ browsepoll_printer_t *printer = data;
+ const char *server = user_data;
+ debug_printf("browsepoll_printer_keepalive() in THREAD %ld\n", pthread_self());
+ found_cups_printer (server, printer->uri_supported, printer->location,
+ printer->info);
+}
+
+gboolean
+browse_poll (gpointer data)
+{
+ browsepoll_t *context = data;
+ http_t *conn = NULL;
+ gboolean get_printers = FALSE;
+
+ debug_printf("browse_poll() in THREAD %ld\n", pthread_self());
+
+ debug_printf ("browse polling %s:%d\n",
+ context->server, context->port);
+
+ res_init ();
+
+ conn = httpConnectEncryptShortTimeout (context->server, context->port,
+ HTTP_ENCRYPT_IF_REQUESTED);
+ if (conn == NULL) {
+ debug_printf("cups-browsed [BrowsePoll %s:%d]: failed to connect\n",
+ context->server, context->port);
+ goto fail;
+ }
+
+ httpSetTimeout(conn, HttpRemoteTimeout, http_timeout_cb, NULL);
+
+ if (context->can_subscribe) {
+ if (context->subscription_id == -1) {
+ /* The first time this callback is run we need to create the IPP
+ * subscription to watch to printer-* events. */
+ browse_poll_create_subscription (context, conn);
+ get_printers = TRUE;
+ } else
+ /* On subsequent runs, check for notifications using our
+ * subscription. */
+ get_printers = browse_poll_get_notifications (context, conn);
+ }
+ else
+ get_printers = TRUE;
+
+ update_local_printers ();
+ inhibit_local_printers_update = TRUE;
+ if (get_printers)
+ browse_poll_get_printers (context, conn);
+ else
+ g_list_foreach (context->printers, browsepoll_printer_keepalive,
+ context->server);
+
+ inhibit_local_printers_update = FALSE;
+
+ if (in_shutdown == 0)
+ recheck_timer ();
+
+ fail:
+
+ if (conn)
+ httpClose (conn);
+
+ /* Call a new timeout handler so that we run again */
+ g_timeout_add_seconds (BrowseInterval, browse_poll, data);
+
+ /* Stop this timeout handler, we called a new one */
+ return FALSE;
+}
+
+#ifdef HAVE_LDAP
+gboolean
+browse_ldap_poll (gpointer data)
+{
+ char *tmpFilter; /* Query filter */
+ int filterLen;
+
+ debug_printf("browse_ldap_poll() in THREAD %ld\n", pthread_self());
+
+ /* do real stuff here */
+ if (!BrowseLDAPDN)
+ {
+ debug_printf("Need to set BrowseLDAPDN to use LDAP browsing!\n");
+ BrowseLocalProtocols &= ~BROWSE_LDAP;
+ BrowseRemoteProtocols &= ~BROWSE_LDAP;
+
+ return FALSE;
+ }
+ else
+ {
+ if (!BrowseLDAPInitialised)
+ {
+ BrowseLDAPInitialised = TRUE;
+ /*
+ * Query filter string
+ */
+ if (BrowseLDAPFilter)
+ filterLen = snprintf(NULL, 0, "(&%s%s)", LDAP_BROWSE_FILTER, BrowseLDAPFilter);
+ else
+ filterLen = strlen(LDAP_BROWSE_FILTER);
+
+ tmpFilter = (char *)malloc(filterLen + 1);
+ if (!tmpFilter)
+ {
+ debug_printf("Could not allocate memory for LDAP browse query filter!\n");
+ BrowseLocalProtocols &= ~BROWSE_LDAP;
+ BrowseRemoteProtocols &= ~BROWSE_LDAP;
+
+ return FALSE;
+ }
+
+ if (BrowseLDAPFilter)
+ {
+ snprintf(tmpFilter, filterLen + 1, "(&%s%s)", LDAP_BROWSE_FILTER, BrowseLDAPFilter);
+ free(BrowseLDAPFilter);
+ BrowseLDAPFilter = NULL;
+ }
+ else
+ strcpy(tmpFilter, LDAP_BROWSE_FILTER);
+
+ BrowseLDAPFilter = tmpFilter;
+
+ /*
+ * Open LDAP handle...
+ */
+
+ BrowseLDAPHandle = ldap_connect();
+ }
+
+ cupsdUpdateLDAPBrowse();
+ if (in_shutdown == 0)
+ recheck_timer();
+ }
+
+ /* Call a new timeout handler so that we run again */
+ g_timeout_add_seconds (BrowseInterval, browse_ldap_poll, data);
+
+ /* Stop this timeout handler, we called a new one */
+ return FALSE;
+}
+#endif /* HAVE_LDAP */
+
+static void
+sigterm_handler(int sig) {
+ (void)sig; /* remove compiler warnings... */
+
+ if (terminating) {
+ debug_printf("Caught signal %d while already terminating.\n", sig);
+ return;
+ }
+ terminating = 1; /* ignore any further callbacks and break loops */
+ /* Flag that we should stop and return... */
+ g_main_loop_quit(gmainloop);
+ g_main_context_wakeup(NULL);
+ debug_printf("Caught signal %d, shutting down ...\n", sig);
+}
+
+static void
+sigusr1_handler(int sig) {
+ (void)sig; /* remove compiler warnings... */
+
+ /* Turn off auto shutdown mode... */
+ autoshutdown = 0;
+ debug_printf("Caught signal %d, switching to permanent mode ...\n", sig);
+ /* If there is still an active auto shutdown timer, kill it */
+ if (autoshutdown_exec_id) {
+ debug_printf ("We have left auto shutdown mode, killing auto shutdown timer.\n");
+ g_source_remove(autoshutdown_exec_id);
+ autoshutdown_exec_id = 0;
+ }
+}
+
+static void
+sigusr2_handler(int sig) {
+ (void)sig; /* remove compiler warnings... */
+
+ /* Turn on auto shutdown mode... */
+ autoshutdown = 1;
+ debug_printf("Caught signal %d, switching to auto shutdown mode ...\n", sig);
+ /* If there are no printers or no jobs schedule the shutdown in
+ autoshutdown_timeout seconds */
+ if (!autoshutdown_exec_id &&
+ (cupsArrayCount(remote_printers) == 0 ||
+ (autoshutdown_on == NO_JOBS && check_jobs() == 0))) {
+ debug_printf ("We entered auto shutdown mode and no printers are there to make available or no jobs on them, shutting down in %d sec...\n", autoshutdown_timeout);
+ autoshutdown_exec_id =
+ g_timeout_add_seconds (autoshutdown_timeout, autoshutdown_execute,
+ NULL);
+ }
+}
+
+static int
+read_browseallow_value (const char *value, allow_sense_t sense)
+{
+ char *p;
+ struct in_addr addr;
+ allow_t *allow;
+
+ if (value && !strcasecmp (value, "all")) {
+ if (sense == ALLOW_ALLOW) {
+ browseallow_all = TRUE;
+ return 0;
+ } else if (sense == ALLOW_DENY) {
+ browsedeny_all = TRUE;
+ return 0;
+ } else
+ return 1;
+ }
+
+ allow = calloc (1, sizeof (allow_t));
+ allow->sense = sense;
+ if (value == NULL)
+ goto fail;
+ p = strchr (value, '/');
+ if (p) {
+ char *s = strdup (value);
+ s[p - value] = '\0';
+
+ if (!inet_aton (s, &addr)) {
+ free (s);
+ goto fail;
+ }
+
+ free (s);
+ allow->type = ALLOW_NET;
+ allow->addr.ipv4.sin_addr.s_addr = addr.s_addr;
+
+ p++;
+ if (strchr (p, '.')) {
+ if (inet_aton (p, &addr))
+ allow->mask.ipv4.sin_addr.s_addr = addr.s_addr;
+ else
+ goto fail;
+ } else {
+ char *endptr;
+ unsigned long bits = strtoul (p, &endptr, 10);
+ if (p == endptr)
+ goto fail;
+
+ if (bits > 32)
+ goto fail;
+
+ allow->mask.ipv4.sin_addr.s_addr = htonl (((0xffffffff << (32 - bits)) &
+ 0xffffffff));
+ }
+ } else if (inet_aton (value, &addr)) {
+ allow->type = ALLOW_IP;
+ allow->addr.ipv4.sin_addr.s_addr = addr.s_addr;
+ } else
+ goto fail;
+
+ cupsArrayAdd (browseallow, allow);
+ return 0;
+
+fail:
+ allow->type = ALLOW_INVALID;
+ cupsArrayAdd (browseallow, allow);
+ return 1;
+}
+
+void
+read_configuration (const char *filename)
+{
+ cups_file_t *fp;
+ int i, linenum = 0;
+ char line[HTTP_MAX_BUFFER];
+ char *value = NULL, *ptr, *start;
+ const char *delim = " \t,";
+ int browse_allow_line_found = 0;
+ int browse_deny_line_found = 0;
+ int browse_order_line_found = 0;
+ int browse_line_found = 0;
+ browse_filter_t *filter = NULL;
+ int browse_filter_options, exact_match, err;
+ char errbuf[1024];
+ cluster_t *cluster = NULL;
+
+ if (!filename)
+ filename = CUPS_SERVERROOT "/cups-browsed.conf";
+
+ if ((fp = cupsFileOpen(filename, "r")) == NULL) {
+ debug_printf("unable to open configuration file; "
+ "using defaults\n");
+ return;
+ }
+
+ i = 0;
+ linenum = -1;
+ /* First, we read the option settings supplied on the command line via
+ "-o ..." in the order given on the command line, then we read the lines
+ of the configuration file. This means that if there are contradicting
+ settings on the command line and in the configuration file, the setting
+ in the configuration file is used. */
+ while ((i < cupsArrayCount(command_line_config) &&
+ (value = cupsArrayIndex(command_line_config, i++)) &&
+ strncpy(line, value, sizeof(line))) ||
+ cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) {
+ if (linenum < 0) {
+ /* We are still reading options from the command line ("-o ..."),
+ separate key (line) and value (value) */
+ value = line;
+ while (*value && !isspace(*value) && !(*value == '='))
+ value ++;
+ if (*value) {
+ *value = '\0';
+ value ++;
+ while (*value && (isspace(*value) || (*value == '=')))
+ value ++;
+ }
+ }
+
+ debug_printf("Reading config%s: %s %s\n",
+ (linenum < 0 ? " (from command line)" : ""), line, value);
+ if (!strcasecmp(line, "DebugLogging") && value) {
+ char *p, *saveptr;
+ p = strtok_r (value, delim, &saveptr);
+ while (p) {
+ if (!strcasecmp(p, "file")) {
+ if (debug_logfile == 0) {
+ debug_logfile = 1;
+ start_debug_logging();
+ }
+ } else if (!strcasecmp(p, "stderr"))
+ debug_stderr = 1;
+ else if (strcasecmp(p, "none"))
+ debug_printf("Unknown debug logging mode '%s'\n", p);
+
+ p = strtok_r (NULL, delim, &saveptr);
+ }
+ } else if (!strcasecmp(line, "CacheDir") && value) {
+ if (value[0] != '\0')
+ strncpy(cachedir, value, sizeof(cachedir) - 1);
+ } else if (!strcasecmp(line, "LogDir") && value) {
+ if (value[0] != '\0')
+ strncpy(logdir, value, sizeof(logdir) - 1);
+ } else if ((!strcasecmp(line, "BrowseProtocols") ||
+ !strcasecmp(line, "BrowseLocalProtocols") ||
+ !strcasecmp(line, "BrowseRemoteProtocols")) && value) {
+ int protocols = 0;
+ char *p, *saveptr;
+ p = strtok_r (value, delim, &saveptr);
+ while (p) {
+ if (!strcasecmp(p, "dnssd"))
+ protocols |= BROWSE_DNSSD;
+ else if (!strcasecmp(p, "cups"))
+ protocols |= BROWSE_CUPS;
+ else if (!strcasecmp(p, "ldap"))
+ protocols |= BROWSE_LDAP;
+ else if (strcasecmp(p, "none"))
+ debug_printf("Unknown protocol '%s'\n", p);
+
+ p = strtok_r (NULL, delim, &saveptr);
+ }
+
+ if (!strcasecmp(line, "BrowseLocalProtocols"))
+ BrowseLocalProtocols = protocols;
+ else if (!strcasecmp(line, "BrowseRemoteProtocols"))
+ BrowseRemoteProtocols = protocols;
+ else
+ BrowseLocalProtocols = BrowseRemoteProtocols = protocols;
+ } else if (!strcasecmp(line, "BrowsePoll") && value) {
+ browsepoll_t **old = BrowsePoll;
+ BrowsePoll = realloc (BrowsePoll,
+ (NumBrowsePoll + 1) *
+ sizeof (browsepoll_t *));
+ if (!BrowsePoll) {
+ debug_printf("unable to realloc: ignoring BrowsePoll line\n");
+ BrowsePoll = old;
+ } else {
+ char *colon, *slash;
+ browsepoll_t *b = g_malloc0 (sizeof (browsepoll_t));
+ debug_printf("Adding BrowsePoll server: %s\n", value);
+ b->server = strdup (value);
+ b->port = BrowsePort;
+ b->can_subscribe = TRUE; /* first assume subscriptions work */
+ b->subscription_id = -1;
+ slash = strchr (b->server, '/');
+ if (slash) {
+ *slash++ = '\0';
+ if (!strcasecmp (slash, "version=1.0")) {
+ b->major = 1;
+ b->minor = 0;
+ } else if (!strcasecmp (slash, "version=1.1")) {
+ b->major = 1;
+ b->minor = 1;
+ } else if (!strcasecmp (slash, "version=2.0")) {
+ b->major = 2;
+ b->minor = 0;
+ } else if (!strcasecmp (slash, "version=2.1")) {
+ b->major = 2;
+ b->minor = 1;
+ } else if (!strcasecmp (slash, "version=2.2")) {
+ b->major = 2;
+ b->minor = 2;
+ } else {
+ debug_printf ("ignoring unknown server option: %s\n", slash);
+ }
+ } else
+ b->major = 0;
+
+ colon = strchr (b->server, ':');
+ if (colon) {
+ char *endptr;
+ unsigned long n;
+ *colon++ = '\0';
+ n = strtoul (colon, &endptr, 10);
+ if (endptr != colon && n < INT_MAX)
+ b->port = (int) n;
+ }
+
+ BrowsePoll[NumBrowsePoll++] = b;
+ }
+ } else if (!strcasecmp(line, "BrowseAllow")) {
+ if (read_browseallow_value (value, ALLOW_ALLOW))
+ debug_printf ("BrowseAllow value \"%s\" not understood\n",
+ value);
+ else {
+ browse_allow_line_found = 1;
+ browse_line_found = 1;
+ }
+ } else if (!strcasecmp(line, "BrowseDeny")) {
+ if (read_browseallow_value (value, ALLOW_DENY))
+ debug_printf ("BrowseDeny value \"%s\" not understood\n",
+ value);
+ else {
+ browse_deny_line_found = 1;
+ browse_line_found = 1;
+ }
+ } else if (!strcasecmp(line, "BrowseOrder") && value) {
+ if (!strncasecmp(value, "Allow", 5) &&
+ strcasestr(value, "Deny")) { /* Allow,Deny */
+ browse_order = ORDER_ALLOW_DENY;
+ browse_order_line_found = 1;
+ browse_line_found = 1;
+ } else if (!strncasecmp(value, "Deny", 4) &&
+ strcasestr(value, "Allow")) { /* Deny,Allow */
+ browse_order = ORDER_DENY_ALLOW;
+ browse_order_line_found = 1;
+ browse_line_found = 1;
+ } else
+ debug_printf ("BrowseOrder value \"%s\" not understood\n",
+ value);
+ } else if (!strcasecmp(line, "BrowseFilter") && value) {
+ ptr = value;
+ /* Skip white space */
+ while (*ptr && isspace(*ptr)) ptr ++;
+ /* Premature line end */
+ if (!*ptr) goto browse_filter_fail;
+ filter = calloc (1, sizeof (browse_filter_t));
+ if (!filter) goto browse_filter_fail;
+ browse_filter_options = 1;
+ filter->sense = FILTER_MATCH;
+ exact_match = 0;
+ while (browse_filter_options) {
+ if (!strncasecmp(ptr, "NOT", 3) && *(ptr + 3) &&
+ isspace(*(ptr + 3))) {
+ /* Accept remote printers where regexp does NOT match or where
+ the boolean field is false */
+ filter->sense = FILTER_NOT_MATCH;
+ ptr += 4;
+ /* Skip white space until next word */
+ while (*ptr && isspace(*ptr)) ptr ++;
+ /* Premature line end without field name */
+ if (!*ptr) goto browse_filter_fail;
+ } else if (!strncasecmp(ptr, "EXACT", 5) && *(ptr + 5) &&
+ isspace(*(ptr + 5))) {
+ /* Consider the rest of the line after the field name a string which
+ has to match the field exactly */
+ exact_match = 1;
+ ptr += 6;
+ /* Skip white space until next word */
+ while (*ptr && isspace(*ptr)) ptr ++;
+ /* Premature line end without field name */
+ if (!*ptr) goto browse_filter_fail;
+ } else
+ /* No more options, consider next word the name of the field which
+ should match the regexp */
+ browse_filter_options = 0;
+ }
+ start = ptr;
+ while (*ptr && !isspace(*ptr)) ptr ++;
+ if (*ptr) {
+ /* Mark end of the field name */
+ *ptr = '\0';
+ /* Skip white space until regexp or line end */
+ ptr ++;
+ while (*ptr && isspace(*ptr)) ptr ++;
+ }
+ filter->field = strdup(start);
+ if (!*ptr) {
+ /* Only field name and no regexp is given, so this rule is
+ about matching a boolean value */
+ filter->regexp = NULL;
+ filter->cregexp = NULL;
+ } else {
+ /* The rest of the line is the regexp, store and compile it */
+ filter->regexp = strdup(ptr);
+ if (!exact_match) {
+ /* Compile the regexp only if the line does not require an exact
+ match (using the EXACT option */
+ filter->cregexp = calloc(1, sizeof (regex_t));
+ if ((err = regcomp(filter->cregexp, filter->regexp,
+ REG_EXTENDED | REG_ICASE)) != 0) {
+ regerror(err, filter->cregexp, errbuf, sizeof(errbuf));
+ debug_printf ("BrowseFilter line with error in regular expression \"%s\": %s\n",
+ filter->regexp, errbuf);
+ goto browse_filter_fail;
+ }
+ } else
+ filter->cregexp = NULL;
+ }
+ cupsArrayAdd (browsefilter, filter);
+ continue;
+ browse_filter_fail:
+ if (filter) {
+ if (filter->field)
+ free(filter->field);
+ if (filter->regexp)
+ free(filter->regexp);
+ if (filter->cregexp)
+ regfree(filter->cregexp);
+ free(filter);
+ }
+ } else if ((!strcasecmp(line, "BrowseInterval") || !strcasecmp(line, "BrowseTimeout")) && value) {
+ int t = atoi(value);
+ if (t >= 0) {
+ if (!strcasecmp(line, "BrowseInterval"))
+ BrowseInterval = t;
+ else if (!strcasecmp(line, "BrowseTimeout"))
+ BrowseTimeout = t;
+
+ debug_printf("Set %s to %d sec.\n",
+ line, t);
+ } else
+ debug_printf("Invalid %s value: %d\n",
+ line, t);
+ } else if (!strcasecmp(line, "DomainSocket") && value) {
+ if (value[0] != '\0')
+ DomainSocket = strdup(value);
+ } else if ((!strcasecmp(line, "HttpLocalTimeout") || !strcasecmp(line, "HttpRemoteTimeout")) && value) {
+ int t = atoi(value);
+ if (t >= 0) {
+ if (!strcasecmp(line, "HttpLocalTimeout"))
+ HttpLocalTimeout = t;
+ else if (!strcasecmp(line, "HttpRemoteTimeout"))
+ HttpRemoteTimeout = t;
+
+ debug_printf("Set %s to %d sec.\n",
+ line, t);
+ } else
+ debug_printf("Invalid %s value: %d\n",
+ line, t);
+ } else if (!strcasecmp(line, "IPBasedDeviceURIs") && value) {
+ if (!strcasecmp(value, "IPv4") || !strcasecmp(value, "IPv4Only"))
+ IPBasedDeviceURIs = IP_BASED_URIS_IPV4_ONLY;
+ else if (!strcasecmp(value, "IPv6") || !strcasecmp(value, "IPv6Only"))
+ IPBasedDeviceURIs = IP_BASED_URIS_IPV6_ONLY;
+ else if (!strcasecmp(value, "yes") || !strcasecmp(value, "true") ||
+ !strcasecmp(value, "on") || !strcasecmp(value, "1") ||
+ !strcasecmp(value, "IP") || !strcasecmp(value, "IPAddress"))
+ IPBasedDeviceURIs = IP_BASED_URIS_ANY;
+ else if (!strcasecmp(value, "no") || !strcasecmp(value, "false") ||
+ !strcasecmp(value, "off") || !strcasecmp(value, "0") ||
+ !strcasecmp(value, "Name") || !strcasecmp(value, "HostName"))
+ IPBasedDeviceURIs = IP_BASED_URIS_NO;
+ } else if (!strcasecmp(line, "LocalQueueNamingRemoteCUPS") && value) {
+ if (strcasestr(value, "DNSSD") || strcasestr(value, "DNS-SD"))
+ LocalQueueNamingRemoteCUPS = LOCAL_QUEUE_NAMING_DNSSD;
+ else if (strcasestr(value, "Make") && strcasestr(value, "Model"))
+ LocalQueueNamingRemoteCUPS = LOCAL_QUEUE_NAMING_MAKE_MODEL;
+ else if (strcasestr(value, "Remote") || strcasestr(value, "Name"))
+ LocalQueueNamingRemoteCUPS = LOCAL_QUEUE_NAMING_REMOTE_NAME;
+ } else if (!strcasecmp(line, "LocalQueueNamingIPPPrinter") && value) {
+ if (strcasestr(value, "DNSSD") || strcasestr(value, "DNS-SD"))
+ LocalQueueNamingIPPPrinter = LOCAL_QUEUE_NAMING_DNSSD;
+ else if (strcasestr(value, "Make") && strcasestr(value, "Model"))
+ LocalQueueNamingIPPPrinter = LOCAL_QUEUE_NAMING_MAKE_MODEL;
+ } else if (!strcasecmp(line, "OnlyUnsupportedByCUPS") && value) {
+ if (!strcasecmp(value, "yes") || !strcasecmp(value, "true") ||
+ !strcasecmp(value, "on") || !strcasecmp(value, "1"))
+ OnlyUnsupportedByCUPS = 1;
+ else if (!strcasecmp(value, "no") || !strcasecmp(value, "false") ||
+ !strcasecmp(value, "off") || !strcasecmp(value, "0"))
+ OnlyUnsupportedByCUPS = 0;
+ } else if (!strcasecmp(line, "CreateRemoteRawPrinterQueues") && value) {
+ if (!strcasecmp(value, "yes") || !strcasecmp(value, "true") ||
+ !strcasecmp(value, "on") || !strcasecmp(value, "1"))
+ CreateRemoteRawPrinterQueues = 1;
+ else if (!strcasecmp(value, "no") || !strcasecmp(value, "false") ||
+ !strcasecmp(value, "off") || !strcasecmp(value, "0"))
+ CreateRemoteRawPrinterQueues = 0;
+ } else if (!strcasecmp(line, "CreateRemoteCUPSPrinterQueues") && value) {
+ if (!strcasecmp(value, "yes") || !strcasecmp(value, "true") ||
+ !strcasecmp(value, "on") || !strcasecmp(value, "1"))
+ CreateRemoteCUPSPrinterQueues = 1;
+ else if (!strcasecmp(value, "no") || !strcasecmp(value, "false") ||
+ !strcasecmp(value, "off") || !strcasecmp(value, "0"))
+ CreateRemoteCUPSPrinterQueues = 0;
+ } else if (!strcasecmp(line, "CreateIPPPrinterQueues") && value) {
+ if (!strcasecmp(value, "all") ||
+ !strcasecmp(value, "yes") || !strcasecmp(value, "true") ||
+ !strcasecmp(value, "on") || !strcasecmp(value, "1"))
+ CreateIPPPrinterQueues = IPP_PRINTERS_ALL;
+ else if (!strcasecmp(value, "no") || !strcasecmp(value, "false") ||
+ !strcasecmp(value, "off") || !strcasecmp(value, "0"))
+ CreateIPPPrinterQueues = IPP_PRINTERS_NO;
+ else if (strcasestr(value, "local") || strcasestr(value, "usb"))
+ CreateIPPPrinterQueues = IPP_PRINTERS_LOCAL_ONLY;
+ else if (strcasestr(value, "driver") && strcasestr(value, "less"))
+ CreateIPPPrinterQueues = IPP_PRINTERS_DRIVERLESS;
+ else if (strcasestr(value, "every") || strcasestr(value, "pwg"))
+ CreateIPPPrinterQueues = IPP_PRINTERS_PWGRASTER;
+ else if (strcasestr(value, "apple") || strcasestr(value, "air"))
+ CreateIPPPrinterQueues = IPP_PRINTERS_APPLERASTER;
+ else if (strcasestr(value, "pclm") || strcasestr(value, "pcl-m"))
+ CreateIPPPrinterQueues = IPP_PRINTERS_PCLM;
+ else if (strcasestr(value, "pdf"))
+ CreateIPPPrinterQueues = IPP_PRINTERS_PDF;
+ } else if (!strcasecmp(line, "IPPPrinterQueueType") && value) {
+ if (!strncasecmp(value, "Auto", 4))
+ IPPPrinterQueueType = PPD_YES;
+ else if (!strncasecmp(value, "PPD", 3))
+ IPPPrinterQueueType = PPD_YES;
+ else if (!strncasecmp(value, "NoPPD", 5))
+ IPPPrinterQueueType = PPD_NO;
+ else if (!strncasecmp(value, "Interface", 9))
+ IPPPrinterQueueType = PPD_NO;
+ } else if (!strcasecmp(line, "NewIPPPrinterQueuesShared") && value) {
+ if (!strcasecmp(value, "yes") || !strcasecmp(value, "true") ||
+ !strcasecmp(value, "on") || !strcasecmp(value, "1"))
+ NewIPPPrinterQueuesShared = 1;
+ else if (!strcasecmp(value, "no") || !strcasecmp(value, "false") ||
+ !strcasecmp(value, "off") || !strcasecmp(value, "0"))
+ NewIPPPrinterQueuesShared = 0;
+ } else if (!strcasecmp(line, "AutoClustering") && value) {
+ if (!strcasecmp(value, "yes") || !strcasecmp(value, "true") ||
+ !strcasecmp(value, "on") || !strcasecmp(value, "1"))
+ AutoClustering = 1;
+ else if (!strcasecmp(value, "no") || !strcasecmp(value, "false") ||
+ !strcasecmp(value, "off") || !strcasecmp(value, "0"))
+ AutoClustering = 0;
+ } else if (!strcasecmp(line, "Cluster") && value) {
+ ptr = value;
+ /* Skip white space */
+ while (*ptr && isspace(*ptr)) ptr ++;
+ /* Premature line end */
+ if (!*ptr) goto cluster_fail;
+ /* Find the local queue name for the cluster */
+ start = ptr;
+ while (*ptr && !isspace(*ptr) && *ptr != ':') ptr ++;
+ if (*ptr) {
+ /* Mark end of the local queue name */
+ *ptr = '\0';
+ /* Skip colon and white space until next word or line end */
+ ptr ++;
+ while (*ptr && (isspace(*ptr) || *ptr == ':')) ptr ++;
+ }
+ /* Empty queue name */
+ if (strlen(start) <= 0)
+ goto cluster_fail;
+ /* Clean queue name */
+ start = remove_bad_chars(start, 0);
+ /* Check whether we have already a cluster with this name */
+ for (cluster = cupsArrayFirst(clusters);
+ cluster;
+ cluster = cupsArrayNext(clusters))
+ if (!strcasecmp(start, cluster->local_queue_name)) {
+ debug_printf("Duplicate cluster with queue name \"%s\".\n",
+ start);
+ cluster = NULL;
+ goto cluster_fail;
+ }
+ /* Create the new cluster definition */
+ cluster = calloc (1, sizeof (cluster_t));
+ if (!cluster) goto cluster_fail;
+ cluster->local_queue_name = start;
+ cluster->members = cupsArrayNew(NULL, NULL);
+ if (!*ptr) {
+ /* Only local queue name given, so assume this name as the only
+ member name (only remote queues with this name match) */
+ cupsArrayAdd(cluster->members, remove_bad_chars(start, 2));
+ } else {
+ /* The rest of the line lists one or more member queue names */
+ while (*ptr) {
+ start = ptr;
+ while (*ptr && !isspace(*ptr)) ptr ++;
+ if (*ptr) {
+ /* Mark end of the current word */
+ *ptr = '\0';
+ /* Skip white space until next word or line end */
+ ptr ++;
+ while (*ptr && isspace(*ptr)) ptr ++;
+ }
+ /* Add member queue name to the list */
+ if (strlen(start) > 0)
+ cupsArrayAdd(cluster->members, remove_bad_chars(start, 2));
+ }
+ }
+ cupsArrayAdd (clusters, cluster);
+ continue;
+ cluster_fail:
+ if (cluster) {
+ if (cluster->local_queue_name)
+ free(cluster->local_queue_name);
+ if (cluster->members) {
+ while ((ptr = cupsArrayFirst (cluster->members)) != NULL) {
+ cupsArrayRemove (cluster->members, ptr);
+ free (ptr);
+ }
+ cupsArrayDelete (cluster->members);
+ }
+ free(cluster);
+ }
+ } else if (!strcasecmp(line, "LoadBalancing") && value) {
+ if (!strncasecmp(value, "QueueOnClient", 13))
+ LoadBalancingType = QUEUE_ON_CLIENT;
+ else if (!strncasecmp(value, "QueueOnServers", 14))
+ LoadBalancingType = QUEUE_ON_SERVERS;
+ } else if (!strcasecmp(line, "DefaultOptions") && value) {
+ if (strlen(value) > 0)
+ DefaultOptions = strdup(value);
+ } else if (!strcasecmp(line, "AutoShutdown") && value) {
+ char *p, *saveptr;
+ p = strtok_r (value, delim, &saveptr);
+ while (p) {
+ if (!strcasecmp(p, "On") || !strcasecmp(p, "Yes") ||
+ !strcasecmp(p, "True") || !strcasecmp(p, "1")) {
+ autoshutdown = 1;
+ debug_printf("Turning on auto shutdown mode.\n");
+ } else if (!strcasecmp(p, "Off") || !strcasecmp(p, "No") ||
+ !strcasecmp(p, "False") || !strcasecmp(p, "0")) {
+ autoshutdown = 0;
+ debug_printf("Turning off auto shutdown mode (permanent mode).\n");
+ } else if (!strcasecmp(p, "avahi")) {
+ autoshutdown_avahi = 1;
+ debug_printf("Turning on auto shutdown control by appearing and disappearing of the Avahi server.\n");
+ } else if (strcasecmp(p, "none"))
+ debug_printf("Unknown mode '%s'\n", p);
+ p = strtok_r (NULL, delim, &saveptr);
+ }
+ } else if (!strcasecmp(line, "AutoShutdownTimeout") && value) {
+ int t = atoi(value);
+ if (t >= 0) {
+ autoshutdown_timeout = t;
+ debug_printf("Set auto shutdown timeout to %d sec.\n",
+ t);
+ } else
+ debug_printf("Invalid auto shutdown timeout value: %d\n",
+ t);
+ } else if (!strcasecmp(line, "AutoShutdownOn") && value) {
+ int success = 0;
+ if (!strncasecmp(value, "no", 2)) {
+ if (strcasestr(value + 2, "queue")) {
+ autoshutdown_on = NO_QUEUES;
+ success = 1;
+ } else if (strcasestr(value + 2, "job")) {
+ autoshutdown_on = NO_JOBS;
+ success = 1;
+ }
+ }
+ if (success)
+ debug_printf("Set auto shutdown inactivity type to no %s.\n",
+ autoshutdown_on == NO_QUEUES ? "queues" : "jobs");
+ else
+ debug_printf("Invalid auto shutdown inactivity type value: %s\n",
+ value);
+ }
+#ifdef HAVE_LDAP
+ else if (!strcasecmp(line, "BrowseLDAPBindDN") && value) {
+ if (value[0] != '\0')
+ BrowseLDAPBindDN = strdup(value);
+ }
+# ifdef HAVE_LDAP_SSL
+ else if (!strcasecmp(line, "BrowseLDAPCACertFile") && value) {
+ if (value[0] != '\0')
+ BrowseLDAPCACertFile = strdup(value);
+ }
+# endif /* HAVE_LDAP_SSL */
+ else if (!strcasecmp(line, "BrowseLDAPDN") && value) {
+ if (value[0] != '\0')
+ BrowseLDAPDN = strdup(value);
+ } else if (!strcasecmp(line, "BrowseLDAPPassword") && value) {
+ if (value[0] != '\0')
+ BrowseLDAPPassword = strdup(value);
+ } else if (!strcasecmp(line, "BrowseLDAPServer") && value) {
+ if (value[0] != '\0')
+ BrowseLDAPServer = strdup(value);
+ } else if (!strcasecmp(line, "BrowseLDAPFilter") && value) {
+ if (value[0] != '\0')
+ BrowseLDAPFilter = strdup(value);
+ }
+#endif /* HAVE_LDAP */
+ }
+
+ if (browse_line_found == 0) {
+ /* No "Browse..." lines at all */
+ browseallow_all = 1;
+ browse_order = ORDER_DENY_ALLOW;
+ debug_printf("No \"Browse...\" line at all, accept all servers (\"BrowseOrder Deny,Allow\").\n");
+ } else if (browse_order_line_found == 0) {
+ /* No "BrowseOrder" line */
+ if (browse_allow_line_found == 0) {
+ /* Only "BrowseDeny" lines */
+ browse_order = ORDER_DENY_ALLOW;
+ debug_printf("No \"BrowseOrder\" line and only \"BrowseDeny\" lines, accept all except what matches the \"BrowseDeny\" lines (\"BrowseOrder Deny,Allow\").\n");
+ } else if (browse_deny_line_found == 0) {
+ /* Only "BrowseAllow" lines */
+ browse_order = ORDER_ALLOW_DENY;
+ debug_printf("No \"BrowseOrder\" line and only \"BrowseAllow\" lines, deny all except what matches the \"BrowseAllow\" lines (\"BrowseOrder Allow,Deny\").\n");
+ } else {
+ /* Default for "BrowseOrder" */
+ browse_order = ORDER_DENY_ALLOW;
+ debug_printf("No \"BrowseOrder\" line, use \"BrowseOrder Deny,Allow\" as default.\n");
+ }
+ }
+
+ cupsFileClose(fp);
+}
+
+static void
+defer_update_netifs (void)
+{
+ if (update_netifs_sourceid)
+ g_source_remove (update_netifs_sourceid);
+
+ update_netifs_sourceid = g_timeout_add_seconds (10, update_netifs, NULL);
+}
+
+static void
+nm_properties_changed (GDBusProxy *proxy,
+ GVariant *changed_properties,
+ const gchar *const *invalidated_properties,
+ gpointer user_data)
+{
+ GVariantIter *iter;
+ const gchar *key;
+ GVariant *value;
+ debug_printf("nm_properties_changed() in THREAD %ld\n", pthread_self());
+ g_variant_get (changed_properties, "a{sv}", &iter);
+ while (g_variant_iter_loop (iter, "{&sv}", &key, &value)) {
+ if (!strcmp (key, "ActiveConnections")) {
+ debug_printf ("NetworkManager ActiveConnections changed\n");
+ defer_update_netifs ();
+ break;
+ }
+ }
+
+ g_variant_iter_free (iter);
+}
+
+static void
+find_previous_queue (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ const char *name = key;
+ const local_printer_t *printer = value;
+ remote_printer_t *p;
+ debug_printf("find_previous_queue() in THREAD %ld\n", pthread_self());
+ if (printer->cups_browsed_controlled) {
+ /* Queue found, add to our list */
+ p = create_remote_printer_entry (name, "", "", printer->device_uri, "", "",
+ 0, "", "", "", NULL, 0, 0, NULL, -1);
+ if (p) {
+ /* Mark as unconfirmed, if no Avahi report of this queue appears
+ in a certain time frame, we will remove the queue */
+ p->status = STATUS_UNCONFIRMED;
+
+ if (BrowseRemoteProtocols & BROWSE_CUPS)
+ p->timeout = time(NULL) + BrowseTimeout;
+ else
+ p->timeout = time(NULL) + TIMEOUT_CONFIRM;
+
+ p->slave_of = NULL;
+ debug_printf("Found CUPS queue %s (URI: %s) from previous session.\n",
+ p->queue_name, p->uri);
+ } else {
+ debug_printf("ERROR: Unable to allocate memory.\n");
+ exit(1);
+ }
+ }
+}
+
+int main(int argc, char*argv[]) {
+ int ret = 1;
+ http_t *http;
+ int i;
+ char *val;
+ remote_printer_t *p;
+ GDBusProxy *proxy = NULL;
+ GError *error = NULL;
+ int subscription_id = 0;
+
+ /* Initialise the command_line_config array */
+ command_line_config = cupsArrayNew(NULL, NULL);
+
+ /* Initialise the browseallow array */
+ browseallow = cupsArrayNew(NULL, NULL);
+
+ /* Initialise the browsefilter array */
+ browsefilter = cupsArrayNew(NULL, NULL);
+
+ /* Initialise the clusters array */
+ clusters = cupsArrayNew(NULL, NULL);
+
+ /* Read command line options */
+ if (argc >= 2) {
+ for (i = 1; i < argc; i++)
+ if (!strcasecmp(argv[i], "--debug") || !strcasecmp(argv[i], "-d") ||
+ !strncasecmp(argv[i], "-v", 2)) {
+ /* Turn on debug output mode if requested */
+ debug_stderr = 1;
+ debug_printf("Reading command line option %s, turning on debug mode (Log on standard error).\n",
+ argv[i]);
+ } else if (!strcasecmp(argv[i], "--logfile") ||
+ !strcasecmp(argv[i], "-l")) {
+ /* Turn on debug log file mode if requested */
+ if (debug_logfile == 0) {
+ debug_logfile = 1;
+ start_debug_logging();
+ debug_printf("Reading command line option %s, turning on debug mode (Log into log file %s).\n",
+ argv[i], debug_log_file);
+ }
+ } else if (!strncasecmp(argv[i], "-c", 2)) {
+ /* Alternative configuration file */
+ val = argv[i] + 2;
+ if (strlen(val) == 0) {
+ i ++;
+ if (i < argc && *argv[i] != '-')
+ val = argv[i];
+ else
+ val = NULL;
+ }
+ if (val) {
+ alt_config_file = strdup(val);
+ debug_printf("Reading command line option -c %s, using alternative configuration file.\n",
+ alt_config_file);
+ } else {
+ fprintf(stderr,
+ "Reading command line option -c, no alternative configuration file name supplied.\n\n");
+ goto help;
+ }
+ } else if (!strncasecmp(argv[i], "-o", 2)) {
+ /* Configuration option via command line */
+ val = argv[i] + 2;
+ if (strlen(val) == 0) {
+ i ++;
+ if (i < argc && *argv[i] != '-')
+ val = argv[i];
+ else
+ val = NULL;
+ }
+ if (val) {
+ cupsArrayAdd (command_line_config, strdup(val));
+ debug_printf("Reading command line option -o %s, applying extra configuration option.\n",
+ val);
+ } else {
+ fprintf(stderr,
+ "Reading command line option -o, no extra configuration option supplied.\n\n");
+ goto help;
+ }
+ } else if (!strncasecmp(argv[i], "--autoshutdown-timeout", 22)) {
+ debug_printf("Reading command line: %s\n", argv[i]);
+ if (argv[i][22] == '=' && argv[i][23])
+ val = argv[i] + 23;
+ else if (!argv[i][22] && i < argc -1) {
+ i++;
+ debug_printf("Reading command line: %s\n", argv[i]);
+ val = argv[i];
+ } else {
+ fprintf(stderr, "Expected auto shutdown timeout setting after \"--autoshutdown-timeout\" option.\n\n");
+ goto help;
+ }
+ int t = atoi(val);
+ if (t >= 0) {
+ autoshutdown_timeout = t;
+ debug_printf("Set auto shutdown timeout to %d sec.\n",
+ t);
+ } else {
+ fprintf(stderr, "Invalid auto shutdown timeout value: %d\n\n",
+ t);
+ goto help;
+ }
+ } else if (!strncasecmp(argv[i], "--autoshutdown-on", 17)) {
+ debug_printf("Reading command line: %s\n", argv[i]);
+ if (argv[i][17] == '=' && argv[i][18])
+ val = argv[i] + 18;
+ else if (!argv[i][17] && i < argc - 1) {
+ i++;
+ debug_printf("Reading command line: %s\n", argv[i]);
+ val = argv[i];
+ } else {
+ fprintf(stderr, "Expected auto shutdown inactivity type (\"no-queues\" or \"no-jobs\") after \"--autoshutdown-on\" option.\n\n");
+ goto help;
+ }
+ int success = 0;
+ if (!strncasecmp(val, "no", 2)) {
+ if (strcasestr(val + 2, "queue")) {
+ autoshutdown_on = NO_QUEUES;
+ success = 1;
+ } else if (strcasestr(val + 2, "job")) {
+ autoshutdown_on = NO_JOBS;
+ success = 1;
+ }
+ }
+ if (success)
+ debug_printf("Set auto shutdown inactivity type to no %s.\n",
+ autoshutdown_on == NO_QUEUES ? "queues" : "jobs");
+ else
+ debug_printf("Invalid auto shutdown inactivity type value: %s\n",
+ val);
+ } else if (!strncasecmp(argv[i], "--autoshutdown", 14)) {
+ debug_printf("Reading command line: %s\n", argv[i]);
+ if (argv[i][14] == '=' && argv[i][15])
+ val = argv[i] + 15;
+ else if (!argv[i][14] && i < argc -1) {
+ i++;
+ debug_printf("Reading command line: %s\n", argv[i]);
+ val = argv[i];
+ } else {
+ fprintf(stderr, "Expected auto shutdown setting after \"--autoshutdown\" option.\n\n");
+ goto help;
+ }
+ if (!strcasecmp(val, "On") || !strcasecmp(val, "Yes") ||
+ !strcasecmp(val, "True") || !strcasecmp(val, "1")) {
+ autoshutdown = 1;
+ debug_printf("Turning on auto shutdown mode.\n");
+ } else if (!strcasecmp(val, "Off") || !strcasecmp(val, "No") ||
+ !strcasecmp(val, "False") || !strcasecmp(val, "0")) {
+ autoshutdown = 0;
+ debug_printf("Turning off auto shutdown mode (permanent mode).\n");
+ } else if (!strcasecmp(val, "avahi")) {
+ autoshutdown_avahi = 1;
+ debug_printf("Turning on auto shutdown control by appearing and disappearing of the Avahi server.\n");
+ } else if (strcasecmp(val, "none")) {
+ fprintf(stderr, "Unknown mode '%s'\n\n", val);
+ goto help;
+ }
+ } else if (!strcasecmp(argv[i], "--version") ||
+ !strcasecmp(argv[i], "--help") || !strcasecmp(argv[i], "-h")) {
+ /* Help!! */
+ goto help;
+ } else {
+ /* Unknown option */
+ fprintf(stderr,
+ "Reading command line option %s, unknown command line option.\n\n",
+ argv[i]);
+ goto help;
+ }
+ }
+
+ debug_printf("cups-browsed of cups-filters version "VERSION" starting.\n");
+
+ /* Read in cups-browsed.conf */
+ read_configuration (alt_config_file);
+
+ /* Set the paths of the auxiliary files */
+ if (cachedir[0] == '\0')
+ strncpy(cachedir, DEFAULT_CACHEDIR, sizeof(cachedir) - 1);
+ if (logdir[0] == '\0')
+ strncpy(logdir, DEFAULT_LOGDIR, sizeof(logdir) - 1);
+ strncpy(local_default_printer_file, cachedir,
+ sizeof(local_default_printer_file) - 1);
+ strncpy(local_default_printer_file + strlen(cachedir),
+ LOCAL_DEFAULT_PRINTER_FILE,
+ sizeof(local_default_printer_file) - strlen(cachedir) - 1);
+ strncpy(remote_default_printer_file, cachedir,
+ sizeof(remote_default_printer_file) - 1);
+ strncpy(remote_default_printer_file + strlen(cachedir),
+ REMOTE_DEFAULT_PRINTER_FILE,
+ sizeof(remote_default_printer_file) - strlen(cachedir) - 1);
+ strncpy(save_options_file, cachedir,
+ sizeof(save_options_file) - 1);
+ strncpy(save_options_file + strlen(cachedir),
+ SAVE_OPTIONS_FILE,
+ sizeof(save_options_file) - strlen(cachedir) - 1);
+ strncpy(debug_log_file, logdir,
+ sizeof(debug_log_file) - 1);
+ strncpy(debug_log_file + strlen(logdir),
+ DEBUG_LOG_FILE,
+ sizeof(debug_log_file) - strlen(logdir) - 1);
+ if (debug_logfile == 1)
+ start_debug_logging();
+
+ debug_printf("main() in THREAD %ld\n", pthread_self());
+
+ /* Point to selected CUPS server or domain socket via the CUPS_SERVER
+ environment variable or DomainSocket configuration file option.
+ Default to localhost:631 (and not to CUPS default to override
+ client.conf files as cups-browsed works only with a local CUPS
+ daemon, not with remote ones. */
+ if (getenv("CUPS_SERVER") != NULL) {
+ strncpy(local_server_str, getenv("CUPS_SERVER"), sizeof(local_server_str));
+ } else {
+#ifdef CUPS_DEFAULT_DOMAINSOCKET
+ if (DomainSocket == NULL)
+ DomainSocket = CUPS_DEFAULT_DOMAINSOCKET;
+#endif
+ if (DomainSocket != NULL) {
+ struct stat sockinfo; /* Domain socket information */
+ if (strcasecmp(DomainSocket, "None") != 0 &&
+ strcasecmp(DomainSocket, "Off") != 0 &&
+ !stat(DomainSocket, &sockinfo) &&
+ (sockinfo.st_mode & S_IROTH) != 0 &&
+ (sockinfo.st_mode & S_IWOTH) != 0)
+ strncpy(local_server_str, DomainSocket, sizeof(local_server_str));
+ else
+ strncpy(local_server_str, "localhost:631", sizeof(local_server_str));
+ } else
+ strncpy(local_server_str, "localhost:631", sizeof(local_server_str));
+ setenv("CUPS_SERVER", local_server_str, 1);
+ }
+ cupsSetServer(local_server_str);
+ BrowsePort = ippPort();
+
+ if (BrowseLocalProtocols & BROWSE_DNSSD) {
+ debug_printf("Local support for DNSSD not implemented\n");
+ BrowseLocalProtocols &= ~BROWSE_DNSSD;
+ }
+
+ if (BrowseLocalProtocols & BROWSE_LDAP) {
+ debug_printf("Local support for LDAP not implemented\n");
+ BrowseLocalProtocols &= ~BROWSE_LDAP;
+ }
+
+#ifndef HAVE_AVAHI
+ if (BrowseRemoteProtocols & BROWSE_DNSSD) {
+ debug_printf("Remote support for DNSSD not supported\n");
+ BrowseRemoteProtocols &= ~BROWSE_DNSSD;
+ }
+#endif /* HAVE_AVAHI */
+
+#ifndef HAVE_LDAP
+ if (BrowseRemoteProtocols & BROWSE_LDAP) {
+ debug_printf("Remote support for LDAP not supported\n");
+ BrowseRemoteProtocols &= ~BROWSE_LDAP;
+ }
+#endif /* HAVE_LDAP */
+
+ /* Wait for CUPS daemon to start */
+ while ((http = http_connect_local ()) == NULL)
+ sleep(1);
+
+ /* Initialise the array of network interfaces */
+ netifs = cupsArrayNew(NULL, NULL);
+ update_netifs (NULL);
+
+ local_printers = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ free_local_printer);
+ cups_supported_remote_printers = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ free_local_printer);
+
+ /* Read out the currently defined CUPS queues and find the ones which we
+ have added in an earlier session */
+ update_local_printers ();
+ if ((val = get_cups_default_printer()) != NULL) {
+ default_printer = strdup(val);
+ free(val);
+ }
+ remote_printers = cupsArrayNew(NULL, NULL);
+ g_hash_table_foreach (local_printers, find_previous_queue, NULL);
+
+ /* Redirect SIGINT and SIGTERM so that we do a proper shutdown, removing
+ the CUPS queues which we have created
+ Use SIGUSR1 and SIGUSR2 to turn off and turn on auto shutdown mode
+ resp. */
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, sigterm_handler);
+ sigset(SIGINT, sigterm_handler);
+ sigset(SIGUSR1, sigusr1_handler);
+ sigset(SIGUSR2, sigusr2_handler);
+ debug_printf("Using signal handler SIGSET\n");
+#elif defined(HAVE_SIGACTION)
+ struct sigaction action; /* Actions for POSIX signals */
+ memset(&action, 0, sizeof(action));
+ sigemptyset(&action.sa_mask);
+ sigaddset(&action.sa_mask, SIGTERM);
+ action.sa_handler = sigterm_handler;
+ sigaction(SIGTERM, &action, NULL);
+ sigemptyset(&action.sa_mask);
+ sigaddset(&action.sa_mask, SIGINT);
+ action.sa_handler = sigterm_handler;
+ sigaction(SIGINT, &action, NULL);
+ sigemptyset(&action.sa_mask);
+ sigaddset(&action.sa_mask, SIGUSR1);
+ action.sa_handler = sigusr1_handler;
+ sigaction(SIGUSR1, &action, NULL);
+ sigemptyset(&action.sa_mask);
+ sigaddset(&action.sa_mask, SIGUSR2);
+ action.sa_handler = sigusr2_handler;
+ sigaction(SIGUSR2, &action, NULL);
+ debug_printf("Using signal handler SIGACTION\n");
+#else
+ signal(SIGTERM, sigterm_handler);
+ signal(SIGINT, sigterm_handler);
+ signal(SIGUSR1, sigusr1_handler);
+ signal(SIGUSR2, sigusr2_handler);
+ debug_printf("Using signal handler SIGNAL\n");
+#endif /* HAVE_SIGSET */
+
+#ifdef HAVE_AVAHI
+ if (autoshutdown_avahi)
+ autoshutdown = 1;
+ avahi_init();
+#endif /* HAVE_AVAHI */
+
+ if (autoshutdown == 1) {
+ /* If there are no printers or no jobs schedule the shutdown in
+ autoshutdown_timeout seconds */
+ if (!autoshutdown_exec_id &&
+ (cupsArrayCount(remote_printers) == 0 ||
+ (autoshutdown_on == NO_JOBS && check_jobs() == 0))) {
+ debug_printf ("We set auto shutdown mode and no printers are there to make available or no jobs on them, shutting down in %d sec...\n", autoshutdown_timeout);
+ autoshutdown_exec_id =
+ g_timeout_add_seconds (autoshutdown_timeout, autoshutdown_execute,
+ NULL);
+ }
+ }
+
+ if (BrowseLocalProtocols & BROWSE_CUPS ||
+ BrowseRemoteProtocols & BROWSE_CUPS) {
+ /* Set up our CUPS Browsing socket */
+ browsesocket = socket (AF_INET, SOCK_DGRAM, 0);
+ if (browsesocket == -1) {
+ debug_printf("failed to create CUPS Browsing socket: %s\n",
+ strerror (errno));
+ } else {
+ struct sockaddr_in addr;
+ memset (&addr, 0, sizeof (addr));
+ addr.sin_addr.s_addr = htonl (INADDR_ANY);
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons (BrowsePort);
+ if (bind (browsesocket, (struct sockaddr *)&addr, sizeof (addr))) {
+ debug_printf("failed to bind CUPS Browsing socket: %s\n",
+ strerror (errno));
+ close (browsesocket);
+ browsesocket = -1;
+ } else {
+ int on = 1;
+ if (setsockopt (browsesocket, SOL_SOCKET, SO_BROADCAST,
+ &on, sizeof (on))) {
+ debug_printf("failed to allow broadcast: %s\n",
+ strerror (errno));
+ BrowseLocalProtocols &= ~BROWSE_CUPS;
+ }
+ }
+ }
+
+ if (browsesocket == -1) {
+ BrowseLocalProtocols &= ~BROWSE_CUPS;
+ BrowseRemoteProtocols &= ~BROWSE_CUPS;
+ }
+ }
+
+ if (BrowseLocalProtocols == 0 &&
+ BrowseRemoteProtocols == 0 &&
+ !BrowsePoll) {
+ debug_printf("nothing left to do\n");
+ ret = 0;
+ goto fail;
+ }
+
+ /* Override the default password callback so we don't end up
+ * prompting for it. */
+ cupsSetPasswordCB2 (password_callback, NULL);
+
+ /* Watch NetworkManager for network interface changes */
+ proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+ NULL, /* GDBusInterfaceInfo */
+ "org.freedesktop.NetworkManager",
+ "/org/freedesktop/NetworkManager",
+ "org.freedesktop.NetworkManager",
+ NULL, /* GCancellable */
+ NULL); /* GError */
+
+ if (proxy)
+ g_signal_connect (proxy,
+ "g-properties-changed",
+ G_CALLBACK (nm_properties_changed),
+ NULL);
+
+ /* Run the main loop */
+ gmainloop = g_main_loop_new (NULL, FALSE);
+ recheck_timer ();
+
+ if (BrowseRemoteProtocols & BROWSE_CUPS) {
+ GIOChannel *browse_channel = g_io_channel_unix_new (browsesocket);
+ g_io_channel_set_close_on_unref (browse_channel, FALSE);
+ g_io_add_watch (browse_channel, G_IO_IN, process_browse_data, NULL);
+ }
+
+ if (BrowseLocalProtocols & BROWSE_CUPS) {
+ debug_printf ("will send browse data every %ds\n",
+ BrowseInterval);
+ g_idle_add (send_browse_data, NULL);
+ }
+
+#ifdef HAVE_LDAP
+ if (BrowseRemoteProtocols & BROWSE_LDAP) {
+ debug_printf ("will browse poll LDAP every %ds\n",
+ BrowseInterval);
+ g_idle_add (browse_ldap_poll, NULL);
+ }
+#endif /* HAVE_LDAP */
+
+ if (BrowsePoll) {
+ size_t index;
+ for (index = 0;
+ index < NumBrowsePoll;
+ index++) {
+ debug_printf ("will browse poll %s every %ds\n",
+ BrowsePoll[index]->server, BrowseInterval);
+ g_idle_add (browse_poll, BrowsePoll[index]);
+ }
+ }
+
+ /* Subscribe to CUPS' D-Bus notifications and create a proxy to receive
+ the notifications */
+ subscription_id = create_subscription ();
+ g_timeout_add_seconds (NOTIFY_LEASE_DURATION - 60,
+ renew_subscription_timeout,
+ &subscription_id);
+ cups_notifier = cups_notifier_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ 0,
+ NULL,
+ CUPS_DBUS_PATH,
+ NULL,
+ &error);
+ if (error) {
+ fprintf (stderr, "Error creating cups notify handler: %s", error->message);
+ g_error_free (error);
+ cups_notifier = NULL;
+ }
+ if (cups_notifier != NULL) {
+ g_signal_connect (cups_notifier, "printer-state-changed",
+ G_CALLBACK (on_printer_state_changed), NULL);
+ g_signal_connect (cups_notifier, "printer-deleted",
+ G_CALLBACK (on_printer_deleted), NULL);
+ g_signal_connect (cups_notifier, "printer-modified",
+ G_CALLBACK (on_printer_modified), NULL);
+ }
+
+ /* If auto shutdown is active and we do not find any printers initially,
+ schedule the shutdown in autoshutdown_timeout seconds */
+ if (autoshutdown && !autoshutdown_exec_id &&
+ cupsArrayCount(remote_printers) == 0) {
+ debug_printf ("No printers found to make available, shutting down in %d sec...\n", autoshutdown_timeout);
+ autoshutdown_exec_id =
+ g_timeout_add_seconds (autoshutdown_timeout, autoshutdown_execute, NULL);
+ }
+
+ g_main_loop_run (gmainloop);
+
+ debug_printf("main loop exited\n");
+ g_main_loop_unref (gmainloop);
+ gmainloop = NULL;
+ ret = 0;
+
+fail:
+
+ /* Clean up things */
+
+ in_shutdown = 1;
+
+ if (proxy)
+ g_object_unref (proxy);
+
+ /* Remove all queues which we have set up */
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ p->status = STATUS_DISAPPEARED;
+ p->timeout = time(NULL) + TIMEOUT_IMMEDIATELY;
+ }
+ update_cups_queues(NULL);
+
+ cancel_subscription (subscription_id);
+ if (cups_notifier)
+ g_object_unref (cups_notifier);
+
+ if (BrowsePoll) {
+ size_t index;
+ for (index = 0;
+ index < NumBrowsePoll;
+ index++) {
+ if (BrowsePoll[index]->can_subscribe &&
+ BrowsePoll[index]->subscription_id != -1)
+ browse_poll_cancel_subscription (BrowsePoll[index]);
+
+ free (BrowsePoll[index]->server);
+ g_list_free_full (BrowsePoll[index]->printers,
+ browsepoll_printer_free);
+ free (BrowsePoll[index]);
+ }
+
+ free (BrowsePoll);
+ }
+
+ if (local_printers_context) {
+ browse_poll_cancel_subscription (local_printers_context);
+ g_list_free_full (local_printers_context->printers,
+ browsepoll_printer_free);
+ free (local_printers_context);
+ }
+
+ http_close_local ();
+
+#ifdef HAVE_AVAHI
+ avahi_shutdown();
+#endif /* HAVE_AVAHI */
+
+#ifdef HAVE_LDAP
+ if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_LDAP) &&
+ BrowseLDAPHandle)
+ {
+ ldap_disconnect(BrowseLDAPHandle);
+ BrowseLDAPHandle = NULL;
+ }
+#endif /* HAVE_LDAP */
+
+ if (browsesocket != -1)
+ close (browsesocket);
+
+ g_hash_table_destroy (local_printers);
+ g_hash_table_destroy (cups_supported_remote_printers);
+
+ if (BrowseLocalProtocols & BROWSE_CUPS)
+ g_list_free_full (browse_data, browse_data_free);
+
+ /* Close log file if we have one */
+ if (debug_logfile == 1)
+ stop_debug_logging();
+
+ return ret;
+
+ help:
+
+ fprintf(stderr,
+ "cups-browsed of cups-filters version "VERSION"\n\n"
+ "Usage: cups-browsed [options]\n"
+ "Options:\n"
+ " -c cups-browsed.conf Set alternative cups-browsed.conf file to use.\n"
+ " -d\n"
+ " -v\n"
+ " --debug Run in debug mode (logging to stderr).\n"
+ " -l\n"
+ " --logfile Run in debug mode (logging into file).\n"
+ " -h\n"
+ " --help\n"
+ " --version Show this usage message.\n"
+ " -o Option=Value Supply configuration option via command line,\n"
+ " options are the same as in cups-browsed.conf.\n"
+ " --autoshutdown=<mode> Automatically shut down cups-browsed when inactive:\n"
+ " <mode> can be set to Off, On, or avahi, where Off\n"
+ " means that cups-browsed stays running permanently\n"
+ " (default), On means that it shuts down after 30\n"
+ " seconds (or any given timeout) of inactivity, and\n"
+ " avahi means that cups-browsed shuts down when\n"
+ " avahi-daemon shuts down.\n"
+ " --autoshutdown-timout=<time> Timeout (in seconds) for auto-shutdown.\n"
+ " --autoshutdown-on=<type> Type of inactivity which leads to an auto-\n"
+ " shutdown: If <type> is \"no-queues\", the shutdown\n"
+ " is triggered by not having any cups-browsed-created\n"
+ " print queue any more. With <type> being \"no-jobs\"\n"
+ " shutdown is initiated by no job being printed\n"
+ " on any cups-browsed-generated print queue any more.\n"
+ " \"no-queues\" is the default.\n"
+ );
+
+ return 1;
+}
+
diff --git a/utils/cups-browsed.conf.5 b/utils/cups-browsed.conf.5
new file mode 100644
index 000000000..b8c5d68e8
--- /dev/null
+++ b/utils/cups-browsed.conf.5
@@ -0,0 +1,882 @@
+.\"Text automatically generated by txt2man
+.TH cups-browsed.conf 5 "29 June 2013" "" ""
+.SH NAME
+\fBcups-browsed.conf \fP- server configuration file for cups-browsed
+\fB
+.SH DESCRIPTION
+The cups-browsed.conf file configures the cups-browsed daemon. It is normally
+located in the /etc/cups directory. Each line in the file can be a
+configuration directive, a blank line, or a comment. Comment lines start
+with the # character.
+.SH DIRECTIVES
+The "CacheDir" directive determines where cups-browsed should save
+information about the print queues it had generated when shutting down,
+like whether one of these queues was the default printer, or default
+option settings of the queues.
+.PP
+.nf
+.fam C
+ CacheDir /var/cache/cups
+
+.fam T
+.fi
+With "LogDir" can be defined where cups-browsed creates its debug log file
+(if "DebugLogging file" is set).
+.PP
+.nf
+.fam C
+ LogDir /var/log/cups
+
+.fam T
+.fi
+The "DebugLogging" directive determines how should debug logging be done.
+Into the file /var/log/cups/cups-browsed_log ("file"), to stderr ("stderr"), or
+not at all ("none").
+.PP
+.nf
+.fam C
+ DebugLogging file
+ DebugLogging stderr
+ DebugLogging file stderr
+ DebugLogging none
+
+.fam T
+.fi
+Only browse remote printers (via DNS-SD or CUPS browsing) from
+selected servers using the "BrowseAllow", "BrowseDeny", and
+"BrowseOrder" directives
+.PP
+This serves for restricting the choice of printers in print dialogs
+to trusted servers or to reduce the number of listed printers in the
+print dialogs to a more user-friendly amount in large networks with
+very many shared printers.
+.PP
+This only filters the selection of remote printers for which
+cups-browsed creates local queues. If the print dialog uses other
+mechanisms to list remote printers as for example direct DNS-SD
+access, cups-browsed has no influence. cups-browsed also does not
+prevent the user from manually accessing non-listed printers.
+.PP
+"BrowseAllow": Accept printers from these hosts or networks. If there
+are only "BrowseAllow" lines and no "BrowseOrder" and/or "BrowseDeny"
+lines, only servers matching at last one "BrowseAllow" line are
+accepted.
+.PP
+"BrowseDeny": Deny printers from these hosts or networks. If there are
+only "BrowseDeny" lines and no "BrowseOrder" and/or "BrowseAllow"
+lines, all servers NOT matching any of the "BrowseDeny" lines are
+accepted.
+.PP
+"BrowseOrder": Determine the order in which "BrowseAllow" and
+"BrowseDeny" lines are applied. With "BrowseOrder Deny,Allow" in the
+beginning all servers are accepted, then the "BrowseDeny" lines are
+applied to exclude unwished servers or networks and after that the
+"BrowseAllow" lines to re-include servers or networks. With
+"BrowseOrder Allow,Deny" we start with denying all servers, then
+applying the "BrowseAllow" lines and afterwards the "BrowseDeny"
+lines.
+.PP
+Default for "BrowseOrder" is "Deny.Allow" if there are both
+"BrowseAllow" and "BrowseDeny" lines.
+.PP
+If there are no "Browse..." lines at all, all servers are accepted.
+.PP
+.nf
+.fam C
+ BrowseAllow All
+ BrowseAllow 192.168.7.20
+ BrowseAllow 192.168.7.0/24
+ BrowseAllow 192.168.7.0/255.255.255.0
+
+ BrowseDeny All
+ BrowseDeny 192.168.1.13
+ BrowseDeny 192.168.3.0/24
+ BrowseDeny 192.168.3.0/255.255.255.0
+
+ BrowseOrder Deny,Allow
+ BrowseOrder Allow,Deny
+
+.fam T
+.fi
+Filtering of remote printers by other properties than IP addresses of
+their servers
+.PP
+Often the desired selection of printers cannot be reached by only
+taking into account the IP addresses of the servers. For these cases
+there is the BrowseFilter directive to filter by most of the known
+properties of the printer.
+.PP
+By default there is no BrowseFilter line meaning that no filtering is
+applied.
+.PP
+To do filtering one can supply one or more BrowseFilter directives
+like this:
+.PP
+.nf
+.fam C
+ BrowseFilter [NOT] [EXACT] <FIELD> [<VALUE>]
+
+.fam T
+.fi
+The BrowseFilter directive always starts with the word "BrowseFilter"
+and it must at least contain the name of the data field (<FIELD>) of
+the printer's properties to which it should apply.
+.PP
+Available field names are:
+.PP
+.nf
+.fam C
+ name: Name of the local print queue to be created
+ host: Host name of the remote print server
+ port: Port through which the printer is accessed on the server
+ service: DNS/SD service name of the remote printer
+ domain: Domain of the remote print server
+
+.fam T
+.fi
+Also all field names in the TXT records of DNS-SD-advertised printers
+are valid, like "color", "duplex", "pdl", ... If the field name of the
+filter rule does not exist for the printer, the rule is skipped.
+.PP
+The optional <VALUE> field is either the exact value (when the option
+EXACT is supplied) or a regular expression (Run "man 7 regex" in a
+terminal window) to be matched with the data field.
+.PP
+If no <VALUE> filed is supplied, rules with field names of the TXT
+record are considered for boolean matching (true/false) of boolean
+field (like duplex, which can have the values "T" for true and "F" for
+false).
+.PP
+If the option NOT is supplied, the filter rule is fulfilled if the
+regular expression or the exact value DOES NOT match the content of
+the data field. In a boolean rule (without <VALUE>) the rule matches
+false.
+.PP
+Regular expressions are always considered case-insensitive and
+extended POSIX regular expressions. Field names and options (NOT,
+EXACT) are all evaluated case-insensitive. If there is an error in a
+regular expression, the BrowseFilter line gets ignored.
+.PP
+Especially to note is that supplying any simple string consisting of
+only letters, numbers, spaces, and some basic special characters as a
+regular expression matches if it is contained somewhere in the data
+field.
+.PP
+If there is more than one BrowseFilter directive, ALL the directives
+need to be fulfilled for the remote printer to be accepted. If one is
+not fulfilled, the printer will get ignored.
+.PP
+Examples:
+.PP
+Rules for standard data items which are supplied with any remote
+printer advertised via DNS-SD:
+.PP
+Print queue name must contain "hum_res_", this matches "hum_res_mono"
+or "hum_res_color" but also "old_hum_res_mono":
+.PP
+.nf
+.fam C
+ BrowseFilter name hum_res_
+
+.fam T
+.fi
+This matches if the remote host name contains "printserver", like
+"printserver.local", "printserver2.example.com", "newprintserver":
+.PP
+.nf
+.fam C
+ BrowseFilter host printserver
+
+.fam T
+.fi
+This matches all ports with 631 int its number, for example 631, 8631,
+10631,...:
+.PP
+.nf
+.fam C
+ BrowseFilter port 631
+
+.fam T
+.fi
+This rule matches if the DNS-SD service name contains "@ printserver":
+.PP
+.nf
+.fam C
+ Browsefilter service @ printserver
+
+.fam T
+.fi
+Matches all domains with "local" in their names, not only "local" but
+also things like "printlocally.com":
+.PP
+.nf
+.fam C
+ BrowseFilter domain local
+
+.fam T
+.fi
+Examples for rules applying to items of the TXT record:
+.PP
+This rule selects PostScript printers, as the "PDL" field in the TXT
+record contains "postscript" then. This includes also remote CUPS
+queues which accept PostScript, independent of whether the physical
+printer behind the CUPS queue accepts PostScript or not.
+.PP
+.nf
+.fam C
+ BrowseFilter pdl postscript
+
+.fam T
+.fi
+Color printers usually contain a "Color" entry set to "T" (for true)
+in the TXT record. This rule selects them:
+.PP
+.nf
+.fam C
+ BrowseFilter color
+
+.fam T
+.fi
+This is a similar rule to select only duplex (automatic double-sided
+printing) printers:
+.PP
+.nf
+.fam C
+ BrowseFilter duplex
+
+.fam T
+.fi
+Rules with the NOT option:
+.PP
+This rule EXCLUDES printers from all hosts containing "financial" in
+their names, nice to get rid of the 100s of printers of the financial
+department:
+.PP
+.nf
+.fam C
+ BrowseFilter NOT host financial
+
+.fam T
+.fi
+Get only monochrome printers ("Color" set to "F", meaning false, in
+the TXT record):
+.PP
+.nf
+.fam C
+ BrowseFilter NOT color
+
+.fam T
+.fi
+Rules with more advanced use of regular expressions:
+.PP
+Only queue names which BEGIN WITH "hum_res_" are accepted now, so we
+still get "hum_res_mono" or "hum_res_color" but not "old_hum_res_mono"
+any more:
+.PP
+.nf
+.fam C
+ BrowseFilter name ^hum_res_
+
+.fam T
+.fi
+Server names is accepted if it contains "print_server" OR
+"graphics_dep_server":
+.PP
+.nf
+.fam C
+ BrowseFilter host print_server|graphics_dep_server
+
+.fam T
+.fi
+"printserver1", "printserver2", and "printserver3", nothing else:
+.PP
+.nf
+.fam C
+ BrowseFilter host ^printserver[1-3]$
+
+.fam T
+.fi
+Printers understanding at least one of PostScript, PCL, or PDF:
+.PP
+.nf
+.fam C
+ BrowseFilter pdl postscript|pcl|pdf
+
+.fam T
+.fi
+Examples for the EXACT option:
+.PP
+Only printers from "printserver.local" are accepted:
+.PP
+.nf
+.fam C
+ BrowseFilter EXACT host printserver.local
+
+.fam T
+.fi
+Printers from all servers except "prinserver2.local" are accepted:
+.PP
+.nf
+.fam C
+ BrowseFilter NOT EXACT host prinserver2.local
+
+.fam T
+.fi
+The BrowsePoll directive polls a server for available printers once
+every 60 seconds. Multiple BrowsePoll directives can be specified
+to poll multiple servers. The default port to connect to is 631.
+BrowsePoll works independently of whether CUPS browsing is activated
+in BrowseRemoteProtocols.
+.PP
+.nf
+.fam C
+ BrowsePoll 192.168.7.20
+ BrowsePoll 192.168.7.65:631
+ BrowsePoll host.example.com:631
+
+
+.fam T
+.fi
+The BrowseLocalProtocols directive specifies the protocols to use
+when advertising local shared printers on the network. The default
+is "none". Control of advertising of local shared printers using
+dnssd is done in /etc/cups/cupsd.conf.
+.PP
+.nf
+.fam C
+ BrowseLocalProtocols none
+ BrowseLocalProtocols CUPS
+
+
+.fam T
+.fi
+The BrowseRemoteProtocols directive specifies the protocols to use
+when finding remote shared printers on the network. Multiple
+protocols can be specified by separating them with spaces.
+The default is "dnssd cups".
+.PP
+.nf
+.fam C
+ BrowseRemoteProtocols none
+ BrowseRemoteProtocols CUPS dnssd
+ BrowseRemoteProtocols CUPS
+ BrowseRemoteProtocols dnssd
+ BrowseRemoteProtocols ldap
+
+.fam T
+.fi
+The BrowseProtocols directive specifies the protocols to use when
+finding remote shared printers on the network and advertising local
+shared printers. "dnssd" and "ldap" are ignored for BrowseLocalProtocols.
+Multiple protocols can be specified by separating them with spaces. The
+default is "none" for BrowseLocalProtocols and "dnssd cups" for
+BrowseRemoteProtocols.
+.PP
+.nf
+.fam C
+ BrowseProtocols none
+ BrowseProtocols CUPS dnssd
+ BrowseProtocols CUPS
+ BrowseProtocols dnssd
+ BrowseProtocols ldap
+
+.fam T
+.fi
+The configuration for the LDAP browsing mode define where the LDAP search
+should be performed. If built with an LDAP library that supports TLS, the
+path to the server's certificate, or to a certificates store, can be
+specified.
+The optional filter allows the LDAP search to be more specific, and is used
+in addition to the hardcoded filter (objectclass=cupsPrinter).
+.PP
+.nf
+.fam C
+ BrowseLDAPBindDN cn=cups-browsed,dc=domain,dc=tld
+ BrowseLDAPCACertFile /path/to/server/certificate.pem
+ BrowseLDAPDN ou=printers,dc=domain,dc=tld
+ BrowseLDAPFilter (printerLocation=/Office 1/*)
+ BrowseLDAPPassword s3cret
+ BrowseLDAPServer ldaps://ldap.domain.tld
+
+.fam T
+.fi
+The DomainSocket directive specifies the domain socket through which
+the locally running CUPS daemon is accessed. If not specified the
+standard domain socket of CUPS is used. Use this if you have specified
+an alternative domain socket for CUPS via a Listen directive in
+/etc/cups/cupsd.conf. If cups-browsed is not able to access the local
+CUPS daemon via a domain socket it accesses it via localhost. "None"
+or "Off" lets cups-browsed not use CUPS' domain socket.
+.PP
+.nf
+.fam C
+ DomainSocket /var/run/cups/cups.sock
+ DomainSocket None
+ DomainSocket Off
+
+.fam T
+.fi
+Set HTTP timeout (in seconds) for requests sent to local/remote
+resources Note that too short timeouts can make services getting
+missed when they are present and operations be unneccesarily
+repeated and too long timeouts can make operations take too long
+when the server does not respond.
+.PP
+.nf
+.fam C
+ HttpLocalTimeout 5
+ HttpRemoteTimeout 10
+
+.fam T
+.fi
+The interval between browsing/broadcasting cycles, local and/or
+remote, can be adjusted with the BrowseInterval directive.
+.PP
+.nf
+.fam C
+ BrowseInterval 60
+
+.fam T
+.fi
+The BrowseTimeout directive determines the amount of time that
+browsing-related operations are allowed to take in seconds.
+Notably, adding or removing one printer queue is considered as one
+operation. The timeout applies to each one of those operations.
+Especially queues discovered by CUPS broadcasts will be removed after
+this timeout if no further broadcast from the server happens.
+.PP
+.nf
+.fam C
+ BrowseTimeout 300
+
+.fam T
+.fi
+Set OnlyUnsupportedByCUPS to "Yes" will make cups-browsed not create
+local queues for remote printers for which CUPS creates queues by
+itself. These printers are printers advertised via DNS-SD and doing
+CUPS-supported (currently PWG Raster and Apple Raster) driverless
+printing, including remote CUPS queues. Queues for other printers
+(like for legacy PostScript/PCL printers) are always created
+(depending on the other configuration settings of cups-browsed).
+
+With OnlyUnsupportedByCUPS set to "No", cups-browsed creates queues
+for all printers which it supports, including printers for which CUPS
+would create queues by itself. Temporary queues created by CUPS will
+get overwritten. This way it is assured that any extra functionality
+of cups-browsed will apply to these queues. As queues created by
+cups-browsed are permanent CUPS queues this setting is also
+recommended if applications/print dialogs which do not support
+temporary CUPS queues are installed. This setting is the default.
+.PP
+.nf
+.fam C
+ OnlyUnsupportedByCUPS Yes
+
+.fam T
+.fi
+With the directives LocalQueueNamingRemoteCUPS and
+LocalQueueNamingIPPPrinter you can determine how the names for local
+queues generated by cups-browsed are generated, separately for remote
+CUPS printers and IPP printers.
+
+"DNS-SD" (the default in both cases) bases the naming on the service
+name of the printer's advertised DNS-SD record. This is exactly the
+same naming scheme as CUPS uses for its temporary queues, so the local
+queue from cups-browsed prevents CUPS from listing and creating an
+additional queue. As DNS-SD service names have to be unique, queue
+names of printers from different servers will also be unique and so
+there is no automatic clustering for load-balanced printing.
+
+"MakeModel" bases the queue name on the printer's manufacturer and
+model names. This scheme cups-browsed used formerly for IPP printers.
+
+"RemoteName" is only available for remote CUPS queues and uses the
+name of the queue on the remote CUPS server as the local queue's
+name. This makes printers on different CUPS servers with equal queue
+names automatically forming a load-balancing cluster as CUPS did
+formerly (CUPS 1.5.x and older) with CUPS-broadcasted remote
+printers. This scheme cups-browsed used formerly for remote CUPS
+printers.
+.PP
+.nf
+.fam C
+ LocalQueueNamingRemoteCUPS DNS-SD
+ LocalQueueNamingRemoteCUPS MakeModel
+ LocalQueueNamingRemoteCUPS RemoteName
+ LocalQueueNamingIPPPrinter DNS-SD
+ LocalQueueNamingIPPPrinter MakeModel
+
+.fam T
+.fi
+Set IPBasedDeviceURIs to "Yes" if cups-browsed should create its local
+queues with device URIs with the IP addresses instead of the host
+names of the remote servers. This mode is there for any problems with
+host name resolution in the network, especially also if avahi-daemon
+is only run for printer discovery and already stopped while still
+printing. By default this mode is turned off, meaning that we use URIs
+with host names.
+.PP
+If you prefer IPv4 or IPv6 IP addresses in the URIs, you can set
+IPBasedDeviceURIs to "IPv4" to only get IPv4 IP addresses or
+IPBasedDeviceURIs to "IPv6" to only get IPv6 IP addresses.
+.PP
+.nf
+.fam C
+ IPBasedDeviceURIs No
+ IPBasedDeviceURIs Yes
+ IPBasedDeviceURIs IPv4
+ IPBasedDeviceURIs IPv6
+
+.fam T
+.fi
+Set CreateRemoteRawPrinterQueues to "Yes" to let cups-browsed also
+create local queues pointing to remote raw CUPS queues. Normally,
+only queues pointing to remote queues with PPD/driver are created
+as we do not use drivers on the client side, but in some cases
+accessing a remote raw queue can make sense, for example if the
+queue forwards the jobs by a special backend like Tea4CUPS.
+.PP
+.nf
+.fam C
+ CreateRemoteRawPrinterQueues Yes
+
+.fam T
+.fi
+cups-browsed by default creates local print queues for each shared
+CUPS print queue which it discovers on remote machines in the local
+network(s). Set CreateRemoteCUPSPrinterQueues to "No" if you do not
+want cups-browsed to do this. For example you can set cups-browsed
+to only create queues for IPP network printers setting
+CreateIPPPrinterQueues not to "No" and CreateRemoteCUPSPrinterQueues
+to "No".
+.PP
+.nf
+.fam C
+ CreateRemoteCUPSPrinterQueues No
+
+.fam T
+.fi
+Set CreateIPPPrinterQueues to "All" to let cups-browsed discover IPP
+network printers (native printers, not CUPS queues) with known page
+description languages (PWG Raster, PDF, PostScript, PCL XL, PCL
+5c/e) in the local network and auto-create print queues for them.
+
+Set CreateIPPPrinterQueues to "Everywhere" to let cups-browsed
+discover IPP Everywhere printers in the local network (native
+printers, not CUPS queues) and auto-create print queues for them.
+
+Set CreateIPPPrinterQueues to "AppleRaster" to let cups-browsed
+discover Apple Raster printers in the local network (native
+printers, not CUPS queues) and auto-create print queues for them.
+
+Set CreateIPPPrinterQueues to "Driverless" to let cups-browsed
+discover printers designed for driverless use (currently IPP
+Everywhere and Apple Raster) in the local network (native printers,
+not CUPS queues) and auto-create print queues for them.
+
+Set CreateIPPPrinterQueues to "LocalOnly" to auto-create print
+queues only for local printers made available as IPP printers. These
+are for example IPP-over-USB printers, made available via
+ippusbxd(8). This is the default.
+
+Set CreateIPPPrinterQueues to "No" to not auto-create print queues
+for IPP network printers.
+
+If queues with PPD file are created (see IPPPrinterQueueType
+directive below) the PPDs are auto-generated by cups-browsed based
+on properties of the printer polled via IPP. In case of missing
+information, info from the Bonjour record is used asd as last mean
+default values.
+
+If queues without PPD (see IPPPrinterQueueType directive below) are
+created clients have to IPP-poll the capabilities of the printer and
+send option settings as standard IPP attributes. Then we do not poll
+the capabilities by ourselves to not wake up the printer from
+power-saving mode when creating the queues. Jobs have to be sent in
+one of PDF, PWG Raster, or JPEG format. Other formats are not
+accepted.
+
+This functionality is primarily for mobile devices running
+CUPS to not need a printer setup tool nor a collection of printer
+drivers and PPDs.
+.PP
+.nf
+.fam C
+ CreateIPPPrinterQueues No
+ CreateIPPPrinterQueues LocalOnly
+ CreateIPPPrinterQueues Everywhere
+ CreateIPPPrinterQueues AppleRaster
+ CreateIPPPrinterQueues Everywhere AppleRaster
+ CreateIPPPrinterQueues Driverless
+ CreateIPPPrinterQueues All
+
+.fam T
+.fi
+If cups-browsed is automatically creating print queues for native
+IPP network printers ("CreateIPPPrinterQueues Yes"), the type of
+queue to be created can be selected by the "IPPPrinterQueueType"
+directive. The "PPD" (default) setting makes queues with PPD file
+being created. With "Interface" or "NoPPD" the queue is created with
+a System V interface script (Not supported with CUPS 2.2.x or
+later). "Auto" is for backward compatibility and also lets queues
+with PPD get created.
+.PP
+.nf
+.fam C
+ IPPPrinterQueueType PPD
+ IPPPrinterQueueType NoPPD
+ IPPPrinterQueueType Interface
+ IPPPrinterQueueType Auto
+
+.fam T
+.fi
+The NewIPPPrinterQueuesShared directive determines whether a print
+queue for a newly discovered IPP network printer (not remote CUPS
+queue) will be shared to the local network or not. This is only
+valid for newly discovered printers. For printers discovered in an
+earlier cups-browsed session, cups-browsed will remember whether the
+printer was shared, so changes by the user get conserved. Default is
+not to share newly discovered IPP printers.
+.PP
+.nf
+.fam C
+ NewIPPPrinterQueuesShared Yes
+
+.fam T
+.fi
+If there is more than one remote CUPS printer whose local queue
+would get the same name and AutoClustering is set to "Yes" (the
+default) only one local queue is created which makes up a
+load-balancing cluster of the remote printers which would get this
+queue name (implicit class). This means that when several jobs are
+sent to this queue they get distributed between the printers, using
+the method chosen by the LoadBalancing directive.
+.PP
+Note that the forming of clusters depends on the naming scheme for
+local queues created by cups-browsed. If you have set
+LocalQueueNamingRemoteCUPS to "DNSSD" you will not get automatic
+clustering as the DNS-SD service names are always unique. With
+LocalQueueNamingRemoteCUPS set to "RemoteName" local queues are
+named as the CUPS queues on the remote servers are named and so
+equally named queues on different servers get clustered (this is how
+CUPS did it in version 1.5.x or older). LocalQueueNamingRemoteCUPS
+set to "MakeModel" makes remote printers of the same model get
+clustered. Note that then a cluster can contain more than one queue
+of the same server.
+.PP
+With AutoClustering set to "No", for each remote CUPS printer an
+individual local queue is created, and to avoid name clashes when
+using the LocalQueueNamingRemoteCUPS settings "RemoteName" or
+"MakeModel" "@<server name>" is added to the local queue name.
+.PP
+Only remote CUPS printers get clustered, not IPP network printers or
+IPP-over-USB printers.
+.PP
+.nf
+.fam C
+ AutoClustering Yes
+ AutoClustering No
+
+.fam T
+.fi
+Load-balancing printer cluster formation can also be manually
+controlled by defining explicitly which remote CUPS printers should
+get clustered together.
+.PP
+This is done by the "Cluster" directive:
+.PP
+.nf
+.fam C
+ Cluster <QUEUENAME>: <EXPRESSION1> <EXPRESSION2> ...
+ Cluster <QUEUENAME>
+
+.fam T
+.fi
+If no expressions are given, <QUEUENAME> is used as the first and
+only expression for this cluster.
+.PP
+Discovered printers are matched against all the expressions of all
+defined clusters. The first expression which matches the discovered
+printer determines to which cluster it belongs. Note that this way a
+printer can only belong to one cluster. Once matched, further
+cluster definitions will not checked any more.
+.PP
+With the first printer matching a cluster's expression a local queue
+with the name <QUEUENAME> is created. If more printers are
+discovered and match this cluster, they join the cluster. Printing
+to this queue prints to all these printers in a load-balancing
+manner, according to to the setting of the LoadBalancing directive.
+.PP
+Each expression must be a string of characters without spaces. If
+spaces are needed, replace them by underscores ('_').
+.PP
+An expression can be matched in three ways:
+.PP
+.nf
+.fam C
+ 1. By the name of the CUPS queue on the remote server
+ 2. By make and model name of the remote printer
+ 3. By the DNS-SD service name of the remote printer
+
+.fam T
+.fi
+Note that the matching is done case-insensitively and any group of
+non-alphanumerical characters is replaced by a single underscore.
+.PP
+So if an expression is "HP_DeskJet_2540" and the remote server
+reports "hp Deskjet-2540" the printer gets matched to this cluster.
+.PP
+If "AutoClustering" is not set to "No" both your manual cluster
+definitions will be followed and automatic clustering of
+equally-named remote queues will be performed. If a printer matches
+in both categories the match to the manually defined cluster has
+priority. Automatic clustering of equally-named remote printers is
+not performed if there is a manually defined cluster with this name
+(at least as the printers do not match this cluster).
+.PP
+Examples:
+.PP
+To cluster all remote CUPS queues named "laserprinter" in your local
+network but not cluster any other equally-named remote CUPS printers
+use (Local queue will get named "laserprinter"):
+.PP
+.nf
+.fam C
+ AutoClustering No
+ Cluster laserprinter
+
+.fam T
+.fi
+To cluster all remote CUPS queues of HP LaserJet 4050 printers in a
+local queue named "LJ4050":
+.PP
+.nf
+.fam C
+ Cluster LJ4050: HP_LaserJet_4050
+
+.fam T
+.fi
+As DNS-SD service names are unique in a network you can create a
+cluster from exactly specified printers (spaces replaced by
+underscors):
+.PP
+.nf
+.fam C
+ Cluster hrdep: oldlaser_@_hr-server1 newlaser_@_hr-server2
+
+.fam T
+.fi
+The LoadBalancing directive switches between two methods of handling
+load balancing between equally-named remote queues which are
+represented by one local print queue making up a cluster of them
+(implicit class).
+.PP
+The two methods are:
+.PP
+Queuing of jobs on the client (LoadBalancing QueueOnClient):
+.PP
+Here we queue up the jobs on the client and regularly check the
+clustered remote print queues. If we find an idle queue, we pass
+on a job to it.
+.PP
+This is also the method which CUPS uses for classes. Advantage is a
+more even distribution of the job workload on the servers
+(especially if the printing speed of the servers is very different),
+and if a server fails, there are not several jobs stuck or
+lost. Disadvantage is that if one takes the client (laptop, mobile
+phone, ...) out of the local network, printing stops with the jobs
+waiting in the local queue.
+.PP
+Queuing of jobs on the servers (LoadBalancing QueueOnServers):
+.PP
+Here we check the number of jobs on each of the clustered remote
+printers and send an incoming job immediately to the remote printer
+with the lowest amount of jobs in its queue. This way no jobs queue
+up locally, all jobs which are waiting are waiting on one of the
+remote servers.
+.PP
+Not having jobs waiting locally has the advantage that we can take
+the local machine from the network and all jobs get printed.
+Disadvantage is that if a server with a full queue of jobs goes
+away, the jobs go away, too.
+.PP
+Default is queuing the jobs on the client as this is what CUPS does
+with classes.
+.PP
+.nf
+.fam C
+ LoadBalancing QueueOnClient
+ LoadBalancing QueueOnServers
+
+.fam T
+.fi
+With the DefaultOptions directive one or more option settings can be
+defined to be applied to every print queue newly created by
+cups-browsed. Each option is supplied as one supplies options with the
+"-o" command line argument to the "lpadmin" command (Run "man lpadmin"
+for more details). More than one option can be supplied separating the
+options by spaces. By default no option settings are pre-defined.
+.PP
+Note that print queues which cups-browsed already created before
+remember their previous settings and so these settings do not get
+applied.
+.PP
+.nf
+.fam C
+ DefaultOptions Option1=Value1 Option2=Value2 Option3 noOption4
+
+.fam T
+.fi
+The AutoShutdown directive specifies whether cups-browsed should
+automatically terminate when it has no local raw queues set up
+pointing to any discovered remote printers or no jobs on such queues
+depending on AutoShutdownOn setting (auto shutdown
+mode). Setting it to "On" activates the auto-shutdown mode, setting it
+to "Off" deactivates it (the default). The special mode "avahi" turns
+auto shutdown off while avahi-daemon is running and on when
+avahi-daemon stops. This allows running cups-browsed on-demand when
+avahi-daemon is run on-demand.
+.PP
+.nf
+.fam C
+ AutoShutdown Off
+ AutoShutdown On
+ AutoShutdown avahi
+
+.fam T
+.fi
+The AutoShutdownOn directive determines what event cups-browsed
+considers as inactivity in auto shutdown mode. "NoQueues" (the
+default) means that auto shutdown is initiated when there are no
+queues for discovered remote printers generated by cups-browsed any
+more. "NoJobs" means that all queues generated by cups-browsed are
+without jobs.
+.PP
+.nf
+.fam C
+ AutoShutdownOn NoQueues
+ AutoShutdownOn NoJobs
+
+.fam T
+.fi
+The AutoShutdownTimeout directive specifies after how many seconds
+without local raw queues set up pointing to any discovered remote
+printers or jobs on these queues cups-browsed should actually shut
+down in auto shutdown mode. Default is 30 seconds, 0 means immediate
+shutdown.
+.PP
+.nf
+.fam C
+ AutoShutdownTimeout 20
+
+.fam T
+.fi
+.SH SEE ALSO
+
+\fBcups-browsed\fP(8)
+.PP
+/usr/share/doc/cups-browsed/README.gz
+.SH AUTHOR
+The authors of cups-browsed are listed in /usr/share/doc/cups-browsed/AUTHORS.
+.PP
+This manual page was written for the Debian Project, but it may be used by others.
diff --git a/utils/cups-browsed.conf.in b/utils/cups-browsed.conf.in
new file mode 100644
index 000000000..978cec611
--- /dev/null
+++ b/utils/cups-browsed.conf.in
@@ -0,0 +1,673 @@
+# All configuration options described here can also be supplied on the
+# command line of cups-browsed via the "-o" option. In case of
+# contradicting settings the setting defined in the configuration file
+# will get used.
+
+# Unknown directives are ignored, also unknown values.
+
+
+# Where should cups-browsed save information about the print queues it had
+# generated when shutting down, like whether one of these queues was the
+# default printer, or default option settings of the queues?
+
+# CacheDir /var/cache/cups
+
+
+# Where should cups-browsed create its debug log file (if "DebugLogging file"
+# is set)?
+
+# LogDir /var/log/cups
+
+
+# How should debug logging be done? Into the file
+# /var/log/cups/cups-browsed_log ('file'), to stderr ('stderr'), or
+# not at all ('none')?
+
+# DebugLogging file
+# DebugLogging stderr
+# DebugLogging file stderr
+# DebugLogging none
+
+
+# Which protocols will we use to discover printers on the network?
+# Can use DNSSD and/or CUPS and/or LDAP, or 'none' for neither.
+
+BrowseRemoteProtocols @BROWSEREMOTEPROTOCOLS@
+
+
+# Which protocols will we use to broadcast shared local printers to the network?
+# Can use DNSSD and/or CUPS, or 'none' for neither.
+# Only CUPS is actually supported, as DNSSD is done by CUPS itself (we ignore
+# DNSSD in this directive).
+
+# BrowseLocalProtocols none
+
+
+# Settings of this directive apply to both BrowseRemoteProtocols and
+# BrowseLocalProtocols.
+# Can use DNSSD and/or CUPS and/or LDAP, or 'none' for neither.
+
+# BrowseProtocols none
+
+
+# Only browse remote printers (via DNS-SD or CUPS browsing) from
+# selected servers using the "BrowseAllow", "BrowseDeny", and
+# "BrowseOrder" directives
+
+# This serves for restricting the choice of printers in print dialogs
+# to trusted servers or to reduce the number of listed printers in the
+# print dialogs to a more user-friendly amount in large networks with
+# very many shared printers.
+
+# This only filters the selection of remote printers for which
+# cups-browsed creates local queues. If the print dialog uses other
+# mechanisms to list remote printers as for example direct DNS-SD
+# access, cups-browsed has no influence. cups-browsed also does not
+# prevent the user from manually accessing non-listed printers.
+
+# "BrowseAllow": Accept printers from these hosts or networks. If
+# there are only "BrowseAllow" lines and no "BrowseOrder" and/or
+# "BrowseDeny" lines, only servers matching at last one "BrowseAllow"
+# line are accepted.
+
+# "BrowseDeny": Deny printers from these hosts or networks. If there
+# are only "BrowseDeny" lines and no "BrowseOrder" and/or
+# "BrowseAllow" lines, all servers NOT matching any of the
+# "BrowseDeny" lines are accepted.
+
+# "BrowseOrder": Determine the order in which "BrowseAllow" and
+# "BrowseDeny" lines are applied. With "BrowseOrder Deny,Allow" in the
+# beginning all servers are accepted, then the "BrowseDeny" lines are
+# applied to exclude unwished servers or networks and after that the
+# "BrowseAllow" lines to re-include servers or networks. With
+# "BrowseOrder Allow,Deny" we start with denying all servers, then
+# applying the "BrowseAllow" lines and afterwards the "BrowseDeny"
+# lines.
+
+# Default for "BrowseOrder" is "Deny.Allow" if there are both
+# "BrowseAllow" and "BrowseDeny" lines.
+
+# If there are no "Browse..." lines at all, all servers are accepted.
+
+# BrowseAllow All
+# BrowseAllow cups.example.com
+# BrowseAllow 192.168.1.12
+# BrowseAllow 192.168.1.0/24
+# BrowseAllow 192.168.1.0/255.255.255.0
+
+# BrowseDeny All
+# BrowseDeny printserver.example.com
+# BrowseDeny 192.168.1.13
+# BrowseDeny 192.168.3.0/24
+# BrowseDeny 192.168.3.0/255.255.255.0
+
+# BrowseOrder Deny,Allow
+# BrowseOrder Allow,Deny
+
+
+# The interval between browsing/broadcasting cycles, local and/or
+# remote, can be adjusted with the BrowseInterval directive.
+
+# BrowseInterval 60
+
+
+# Browsing-related operations such as adding or removing printer queues
+# and broadcasting are each allowed to take up to a given amount of time.
+# It can be configured, in seconds, with the BrowseTimeout directive.
+# Especially queues discovered by CUPS broadcasts will be removed after
+# this timeout if no further broadcast from the server happens.
+
+# BrowseTimeout 300
+
+
+# Filtering of remote printers by other properties than IP addresses
+# of their servers
+
+# Often the desired selection of printers cannot be reached by only
+# taking into account the IP addresses of the servers. For these cases
+# there is the BrowseFilter directive to filter by most of the known
+# properties of the printer.
+
+# By default there is no BrowseFilter line meaning that no filtering
+# is applied.
+
+# To do filtering one can supply one or more BrowseFilter directives
+# like this:
+
+# BrowseFilter [NOT] [EXACT] <FIELD> [<VALUE>]
+
+# The BrowseFilter directive always starts with the word
+# "BrowseFilter" and it must at least contain the name of the data
+# field (<FIELD>) of the printer's properties to which it should
+# apply.
+
+# Available field names are:
+
+# name: Name of the local print queue to be created
+# host: Host name of the remote print server
+# port: Port through which the printer is accessed on the server
+# service: DNS/SD service name of the remote printer
+# domain: Domain of the remote print server
+
+# Also all field names in the TXT records of DNS-SD-advertised printers
+# are valid, like "color", "duplex", "pdl", ... If the field name of
+# the filter rule does not exist for the printer, the rule is skipped.
+
+# The optional <VALUE> field is either the exact value (when the
+# option EXACT is supplied) or a regular expression (Run "man 7 regex"
+# in a terminal window) to be matched with the data field.
+
+# If no <VALUE> filed is supplied, rules with field names of the TXT
+# record are considered for boolean matching (true/false) of boolean
+# field (like duplex, which can have the values "T" for true and "F"
+# for false).
+
+# If the option NOT is supplied, the filter rule is fulfilled if the
+# regular expression or the exact value DOES NOT match the content of
+# the data field. In a boolean rule (without <VALUE>) the rule matches
+# false.
+
+# Regular expressions are always considered case-insensitive and
+# extended POSIX regular expressions. Field names and options (NOT,
+# EXACT) are all evaluated case-insensitive. If there is an error in a
+# regular expression, the BrowseFilter line gets ignored.
+
+# Especially to note is that supplying any simple string consisting of
+# only letters, numbers, spaces, and some basic special characters as
+# a regular expression matches if it is contained somewhere in the
+# data field.
+
+# If there is more than one BrowseFilter directive, ALL the directives
+# need to be fulfilled for the remote printer to be accepted. If one
+# is not fulfilled, the printer will get ignored.
+
+# Examples:
+
+# Rules for standard data items which are supplied with any remote
+# printer advertised via DNS-SD:
+
+# Print queue name must contain "hum_res_", this matches
+# "hum_res_mono" or "hum_res_color" but also "old_hum_res_mono":
+
+# BrowseFilter name hum_res_
+
+# This matches if the remote host name contains "printserver", like
+# "printserver.local", "printserver2.example.com", "newprintserver":
+
+# BrowseFilter host printserver
+
+# This matches all ports with 631 int its number, for example 631,
+# 8631, 10631,...:
+
+# BrowseFilter port 631
+
+# This rule matches if the DNS-SD service name contains "@ printserver":
+
+# Browsefilter service @ printserver
+
+# Matches all domains with "local" in their names, not only "local" but
+# also things like "printlocally.com":
+
+# BrowseFilter domain local
+
+# Examples for rules applying to items of the TXT record:
+
+# This rule selects PostScript printers, as the "PDL" field in the TXT
+# record contains "postscript" then. This includes also remote CUPS
+# queues which accept PostScript, independent of whether the physical
+# printer behind the CUPS queue accepts PostScript or not.
+
+# BrowseFilter pdl postscript
+
+# Color printers usually contain a "Color" entry set to "T" (for true)
+# in the TXT record. This rule selects them:
+
+# BrowseFilter color
+
+# This is a similar rule to select only duplex (automatic double-sided
+# printing) printers:
+
+# BrowseFilter duplex
+
+# Rules with the NOT option:
+
+# This rule EXCLUDES printers from all hosts containing "financial" in
+# their names, nice to get rid of the 100s of printers of the
+# financial department:
+
+# BrowseFilter NOT host financial
+
+# Get only monochrome printers ("Color" set to "F", meaning false, in
+# the TXT record):
+
+# BrowseFilter NOT color
+
+# Rules with more advanced use of regular expressions:
+
+# Only queue names which BEGIN WITH "hum_res_" are accepted now, so we
+# still get "hum_res_mono" or "hum_res_color" but not
+# "old_hum_res_mono" any more:
+
+# BrowseFilter name ^hum_res_
+
+# Server names is accepted if it contains "print_server" OR
+# "graphics_dep_server":
+
+# BrowseFilter host print_server|graphics_dep_server
+
+# "printserver1", "printserver2", and "printserver3", nothing else:
+
+# BrowseFilter host ^printserver[1-3]$
+
+# Printers understanding at least one of PostScript, PCL, or PDF:
+
+# BrowseFilter pdl postscript|pcl|pdf
+
+# Examples for the EXACT option:
+
+# Only printers from "printserver.local" are accepted:
+
+# BrowseFilter EXACT host printserver.local
+
+# Printers from all servers except "prinserver2.local" are accepted:
+
+# BrowseFilter NOT EXACT host prinserver2.local
+
+
+# Use BrowsePoll to poll a particular CUPS server
+
+# BrowsePoll cups.example.com
+# BrowsePoll cups.example.com:631
+# BrowsePoll cups.example.com:631/version=1.1
+
+
+# LDAP browsing configuration
+# The default value for all options is an empty string. Example configuration:
+
+# BrowseLDAPBindDN cn=cups-browsed,dc=domain,dc=tld
+# BrowseLDAPCACertFile /path/to/server/certificate.pem
+# BrowseLDAPDN ou=printers,dc=domain,dc=tld
+# BrowseLDAPFilter (printerLocation=/Office 1/*)
+# BrowseLDAPPassword s3cret
+# BrowseLDAPServer ldaps://ldap.domain.tld
+
+
+# Use DomainSocket to access the local CUPS daemon via another than the
+# default domain socket. "None" or "Off" lets cups-browsed not use CUPS'
+# domain socket.
+
+# DomainSocket @CUPS_DEFAULT_DOMAINSOCKET@
+# DomainSocket None
+# DomainSocket Off
+
+
+# Set HTTP timeout (in seconds) for requests sent to local/remote
+# resources Note that too short timeouts can make services getting
+# missed when they are present and operations be unneccesarily
+# repeated and too long timeouts can make operations take too long
+# when the server does not respond.
+
+# HttpLocalTimeout 5
+# HttpRemoteTimeout 10
+
+
+# Set OnlyUnsupportedByCUPS to "Yes" will make cups-browsed not create
+# local queues for remote printers for which CUPS creates queues by
+# itself. These printers are printers advertised via DNS-SD and doing
+# CUPS-supported (currently PWG Raster and Apple Raster) driverless
+# printing, including remote CUPS queues. Queues for other printers
+# (like for legacy PostScript/PCL printers) are always created
+# (depending on the other configuration settings of cups-browsed).
+
+# With OnlyUnsupportedByCUPS set to "No", cups-browsed creates queues
+# for all printers which it supports, including printers for which
+# CUPS would create queues by itself. Temporary queues created by CUPS
+# will get overwritten. This way it is assured that any extra
+# functionality of cups-browsed will apply to these queues. As queues
+# created by cups-browsed are permanent CUPS queues this setting is
+# also recommended if applications/print dialogs which do not support
+# temporary CUPS queues are installed. This setting is the default.
+
+# OnlyUnsupportedByCUPS Yes
+
+
+# With the directives LocalQueueNamingRemoteCUPS and
+# LocalQueueNamingIPPPrinter you can determine how the names for local
+# queues generated by cups-browsed are generated, separately for
+# remote CUPS printers and IPP printers.
+
+# DNS-SD (the default in both cases) bases the naming on the service
+# name of the printer's advertised DNS-SD record. This is exactly the
+# same naming scheme as CUPS uses for its temporary queues, so the
+# local queue from cups-browsed prevents CUPS from listing and
+# creating an additional queue. As DNS-SD service names have to be
+# unique, queue names of printers from different servers will also be
+# unique and so there is no automatic clustering for load-balanced
+# printing.
+
+# MakeModel bases the queue name on the printer's manufacturer and
+# model names. This scheme cups-browsed used formerly for IPP
+# printers.
+
+# RemoteName is only available for remote CUPS queues and uses the
+# name of the queue on the remote CUPS server as the local queue's
+# name. This makes printers on different CUPS servers with equal queue
+# names automatically forming a load-balancing cluster as CUPS did
+# formerly (CUPS 1.5.x and older) with CUPS-broadcasted remote
+# printers. This scheme cups-browsed used formerly for remote CUPS
+# printers.
+
+# LocalQueueNamingRemoteCUPS DNS-SD
+# LocalQueueNamingRemoteCUPS MakeModel
+# LocalQueueNamingRemoteCUPS RemoteName
+# LocalQueueNamingIPPPrinter DNS-SD
+# LocalQueueNamingIPPPrinter MakeModel
+
+
+# Set IPBasedDeviceURIs to "Yes" if cups-browsed should create its
+# local queues with device URIs with the IP addresses instead of the
+# host names of the remote servers. This mode is there for any
+# problems with host name resolution in the network, especially also
+# if avahi-daemon is only run for printer discovery and already
+# stopped while still printing. By default this mode is turned off,
+# meaning that we use URIs with host names.
+
+# If you prefer IPv4 or IPv6 IP addresses in the URIs, you can set
+# IPBasedDeviceURIs to "IPv4" to only get IPv4 IP addresses or
+# IPBasedDeviceURIs to "IPv6" to only get IPv6 IP addresses.
+
+# IPBasedDeviceURIs No
+# IPBasedDeviceURIs Yes
+# IPBasedDeviceURIs IPv4
+# IPBasedDeviceURIs IPv6
+
+
+# Set CreateRemoteRawPrinterQueues to "Yes" to let cups-browsed also
+# create local queues pointing to remote raw CUPS queues. Normally,
+# only queues pointing to remote queues with PPD/driver are created
+# as we do not use drivers on the client side, but in some cases
+# accessing a remote raw queue can make sense, for example if the
+# queue forwards the jobs by a special backend like Tea4CUPS.
+
+# CreateRemoteRawPrinterQueues Yes
+
+
+# cups-browsed by default creates local print queues for each shared
+# CUPS print queue which it discovers on remote machines in the local
+# network(s). Set CreateRemoteCUPSPrinterQueues to "No" if you do not
+# want cups-browsed to do this. For example you can set cups-browsed
+# to only create queues for IPP network printers setting
+# CreateIPPPrinterQueues not to "No" and CreateRemoteCUPSPrinterQueues
+# to "No".
+
+# CreateRemoteCUPSPrinterQueues No
+
+
+# Set CreateIPPPrinterQueues to "All" to let cups-browsed discover IPP
+# network printers (native printers, not CUPS queues) with known page
+# description languages (PWG Raster, PDF, PostScript, PCL XL, PCL
+# 5c/e) in the local network and auto-create print queues for them.
+
+# Set CreateIPPPrinterQueues to "Everywhere" to let cups-browsed
+# discover IPP Everywhere printers in the local network (native
+# printers, not CUPS queues) and auto-create print queues for them.
+
+# Set CreateIPPPrinterQueues to "AppleRaster" to let cups-browsed
+# discover Apple Raster printers in the local network (native
+# printers, not CUPS queues) and auto-create print queues for them.
+
+# Set CreateIPPPrinterQueues to "Driverless" to let cups-browsed
+# discover printers designed for driverless use (currently IPP
+# Everywhere and Apple Raster) in the local network (native printers,
+# not CUPS queues) and auto-create print queues for them.
+
+# Set CreateIPPPrinterQueues to "LocalOnly" to auto-create print
+# queues only for local printers made available as IPP printers. These
+# are for example IPP-over-USB printers, made available via
+# ippusbxd. This is the default.
+
+# Set CreateIPPPrinterQueues to "No" to not auto-create print queues
+# for IPP network printers.
+
+# If queues with PPD file are created (see IPPPrinterQueueType
+# directive below) the PPDs are auto-generated by cups-browsed based
+# on properties of the printer polled via IPP. In case of missing
+# information, info from the Bonjour record is used asd as last mean
+# default values.
+
+# If queues without PPD (see IPPPrinterQueueType directive below) are
+# created clients have to IPP-poll the capabilities of the printer and
+# send option settings as standard IPP attributes. Then we do not poll
+# the capabilities by ourselves to not wake up the printer from
+# power-saving mode when creating the queues. Jobs have to be sent in
+# one of PDF, PWG Raster, or JPEG format. Other formats are not
+# accepted.
+
+# This functionality is primarily for mobile devices running
+# CUPS to not need a printer setup tool nor a collection of printer
+# drivers and PPDs.
+
+# CreateIPPPrinterQueues No
+# CreateIPPPrinterQueues LocalOnly
+# CreateIPPPrinterQueues Everywhere
+# CreateIPPPrinterQueues AppleRaster
+# CreateIPPPrinterQueues Everywhere AppleRaster
+# CreateIPPPrinterQueues Driverless
+# CreateIPPPrinterQueues All
+
+
+# If cups-browsed is automatically creating print queues for native
+# IPP network printers ("CreateIPPPrinterQueues Yes"), the type of
+# queue to be created can be selected by the "IPPPrinterQueueType"
+# directive. The "PPD" (default) setting makes queues with PPD file
+# being created. With "Interface" or "NoPPD" the queue is created with
+# a System V interface script (Not supported with CUPS 2.2.x or
+# later). "Auto" is for backward compatibility and also lets queues
+# with PPD get created.
+
+# IPPPrinterQueueType PPD
+# IPPPrinterQueueType NoPPD
+# IPPPrinterQueueType Interface
+# IPPPrinterQueueType Auto
+
+
+# The NewIPPPrinterQueuesShared directive determines whether a print
+# queue for a newly discovered IPP network printer (not remote CUPS
+# queue) will be shared to the local network or not. This is only
+# valid for newly discovered printers. For printers discovered in an
+# earlier cups-browsed session, cups-browsed will remember whether the
+# printer was shared, so changes by the user get conserved. Default is
+# not to share newly discovered IPP printers.
+
+# NewIPPPrinterQueuesShared Yes
+
+
+# If there is more than one remote CUPS printer whose local queue
+# would get the same name and AutoClustering is set to "Yes" (the
+# default) only one local queue is created which makes up a
+# load-balancing cluster of the remote printers which would get this
+# queue name (implicit class). This means that when several jobs are
+# sent to this queue they get distributed between the printers, using
+# the method chosen by the LoadBalancing directive.
+
+# Note that the forming of clusters depends on the naming scheme for
+# local queues created by cups-browsed. If you have set
+# LocalQueueNamingRemoteCUPS to "DNSSD" you will not get automatic
+# clustering as the DNS-SD service names are always unique. With
+# LocalQueueNamingRemoteCUPS set to "RemoteName" local queues are
+# named as the CUPS queues on the remote servers are named and so
+# equally named queues on different servers get clustered (this is how
+# CUPS did it in version 1.5.x or older). LocalQueueNamingRemoteCUPS
+# set to "MakeModel" makes remote printers of the same model get
+# clustered. Note that then a cluster can contain more than one queue
+# of the same server.
+
+# With AutoClustering set to "No", for each remote CUPS printer an
+# individual local queue is created, and to avoid name clashes when
+# using the LocalQueueNamingRemoteCUPS settings "RemoteName" or
+# "MakeModel" "@<server name>" is added to the local queue name.
+
+# Only remote CUPS printers get clustered, not IPP network printers or
+# IPP-over-USB printers.
+
+# AutoClustering Yes
+# AutoClustering No
+
+
+# Load-balancing printer cluster formation can also be manually
+# controlled by defining explicitly which remote CUPS printers should
+# get clustered together.
+
+# This is done by the "Cluster" directive:
+
+# Cluster <QUEUENAME>: <EXPRESSION1> <EXPRESSION2> ...
+# Cluster <QUEUENAME>
+
+# If no expressions are given, <QUEUENAME> is used as the first and
+# only expression for this cluster.
+
+# Discovered printers are matched against all the expressions of all
+# defined clusters. The first expression which matches the discovered
+# printer determines to which cluster it belongs. Note that this way a
+# printer can only belong to one cluster. Once matched, further
+# cluster definitions will not checked any more.
+
+# With the first printer matching a cluster's expression a local queue
+# with the name <QUEUENAME> is created. If more printers are
+# discovered and match this cluster, they join the cluster. Printing
+# to this queue prints to all these printers in a load-balancing
+# manner, according to to the setting of the LoadBalancing directive.
+
+# Each expression must be a string of characters without spaces. If
+# spaces are needed, replace them by underscores ('_').
+
+# An expression can be matched in three ways:
+
+# 1. By the name of the CUPS queue on the remote server
+# 2. By make and model name of the remote printer
+# 3. By the DNS-SD service name of the remote printer
+
+# Note that the matching is done case-insensitively and any group of
+# non-alphanumerical characters is replaced by a single underscore.
+
+# So if an expression is "HP_DeskJet_2540" and the remote server
+# reports "hp Deskjet-2540" the printer gets matched to this cluster.
+
+# If "AutoClustering" is not set to "No" both your manual cluster
+# definitions will be followed and automatic clustering of
+# equally-named remote queues will be performed. If a printer matches
+# in both categories the match to the manually defined cluster has
+# priority. Automatic clustering of equally-named remote printers is
+# not performed if there is a manually defined cluster with this name
+# (at least as the printers do not match this cluster).
+
+# Examples:
+
+# To cluster all remote CUPS queues named "laserprinter" in your local
+# network but not cluster any other equally-named remote CUPS printers
+# use (Local queue will get named "laserprinter"):
+
+# AutoClustering No
+# Cluster laserprinter
+
+# To cluster all remote CUPS queues of HP LaserJet 4050 printers in a
+# local queue named "LJ4050":
+
+# Cluster LJ4050: HP_LaserJet_4050
+
+# As DNS-SD service names are unique in a network you can create a
+# cluster from exactly specified printers (spaces replaced by
+# underscors):
+
+# Cluster hrdep: oldlaser_@_hr-server1 newlaser_@_hr-server2
+
+
+# The LoadBalancing directive switches between two methods of handling
+# load balancing between equally-named remote queues which are
+# represented by one local print queue making up a cluster of them
+# (implicit class).
+
+# The two methods are:
+
+# Queuing of jobs on the client (LoadBalancing QueueOnClient):
+
+# Here we queue up the jobs on the client and regularly check the
+# clustered remote print queues. If we find an idle queue, we pass
+# on a job to it.
+
+# This is also the method which CUPS uses for classes. Advantage is a
+# more even distribution of the job workload on the servers
+# (especially if the printing speed of the servers is very different),
+# and if a server fails, there are not several jobs stuck or
+# lost. Disadvantage is that if one takes the client (laptop, mobile
+# phone, ...) out of the local network, printing stops with the jobs
+# waiting in the local queue.
+
+# Queuing of jobs on the servers (LoadBalancing QueueOnServers):
+
+# Here we check the number of jobs on each of the clustered remote
+# printers and send an incoming job immediately to the remote printer
+# with the lowest amount of jobs in its queue. This way no jobs queue
+# up locally, all jobs which are waiting are waiting on one of the
+# remote servers.
+
+# Not having jobs waiting locally has the advantage that we can take
+# the local machine from the network and all jobs get printed.
+# Disadvantage is that if a server with a full queue of jobs goes
+# away, the jobs go away, too.
+
+# Default is queuing the jobs on the client as this is what CUPS does
+# with classes.
+
+# LoadBalancing QueueOnClient
+# LoadBalancing QueueOnServers
+
+
+# With the DefaultOptions directive one or more option settings can be
+# defined to be applied to every print queue newly created by
+# cups-browsed. Each option is supplied as one supplies options with
+# the "-o" command line argument to the "lpadmin" command (Run "man
+# lpadmin" for more details). More than one option can be supplied
+# separating the options by spaces. By default no option settings are
+# pre-defined.
+
+# Note that print queues which cups-browsed already created before
+# remember their previous settings and so these settings do not get
+# applied.
+
+# DefaultOptions Option1=Value1 Option2=Value2 Option3 noOption4
+
+
+# The AutoShutdown directive specifies whether cups-browsed should
+# automatically terminate when it has no local raw queues set up
+# pointing to any discovered remote printers or no jobs on such queues
+# depending on AutoShutdownOn setting (auto shutdown mode). Setting it
+# to "On" activates the auto-shutdown mode, setting it to "Off"
+# deactiivates it (the default). The special mode "avahi" turns auto
+# shutdown off while avahi-daemon is running and on when avahi-daemon
+# stops. This allows running cups-browsed on-demand when avahi-daemon
+# is run on-demand.
+
+# AutoShutdown Off
+# AutoShutdown On
+# AutoShutdown avahi
+
+
+# The AutoShutdownOn directive determines what event cups-browsed
+# considers as inactivity in auto shutdown mode. "NoQueues" (the
+# default) means that auto shutdown is initiated when there are no
+# queues for discovered remote printers generated by cups-browsed any
+# more. "NoJobs" means that all queues generated by cups-browsed are
+# without jobs.
+
+# AutoShutdownOn NoQueues
+# AutoShutdownOn NoJobs
+
+
+# The AutoShutdownTimeout directive specifies after how many seconds
+# without local raw queues set up pointing to any discovered remote
+# printers or jobs on these queues cups-browsed should actually shut
+# down in auto shutdown mode. Default is 30 seconds, 0 means immediate
+# shutdown.
+
+# AutoShutdownTimeout 30
diff --git a/utils/cups-browsed.in b/utils/cups-browsed.in
new file mode 100644
index 000000000..1f79152a5
--- /dev/null
+++ b/utils/cups-browsed.in
@@ -0,0 +1,156 @@
+#!/bin/sh
+# Provides: cups-browsed
+# Required-Start: $local_fs $remote_fs $network $named $time $cups
+# Required-Stop: $local_fs $remote_fs $network $named $time $cups
+# Should-Start: $avahi-daemon
+# Should-Stop: $avahi-daemon
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: cups-browsed - Make remote CUPS printers available locally
+# Description: This daemon browses Bonjour broadcasts of shared remote CUPS
+# printers and makes these printers available locally by creating
+# local CUPS queues pointing to the remote queues. This replaces
+# the CUPS browsing which was dropped in CUPS 1.6.1. For the end
+# the behavior is the same as with the old CUPS broadcasting/
+# browsing, but in the background the standard method for network
+# service announcement and discovery, Bonjour, is used.
+### END INIT INFO
+
+#
+# Linux chkconfig stuff:
+#
+# chkconfig: 235 99 00
+# description: Startup/shutdown script for cups-browsed.
+#
+
+#
+# NetBSD 1.5+ rcorder script lines. The format of the following two
+# lines is very strict -- please don't add additional spaces!
+#
+# PROVIDE: cups-browsed
+# REQUIRE: cups
+#
+
+
+#### OS-Dependent Configuration
+
+case "`uname`" in
+ *BSD*)
+ IS_ON=:
+ ECHO=echo
+ ECHO_OK=:
+ ECHO_ERROR=:
+ ;;
+
+ Darwin*)
+ . /etc/rc.common
+
+ if test "${CUPS_BROWSED:=-YES-}" = "-NO-"; then
+ exit 0
+ fi
+
+ IS_ON=:
+ ECHO=ConsoleMessage
+ ECHO_OK=:
+ ECHO_ERROR=:
+ ;;
+
+ Linux*)
+ IS_ON=/bin/true
+ if test -f /etc/init.d/functions; then
+ . /etc/init.d/functions
+ ECHO=echo
+ ECHO_OK="echo_success"
+ ECHO_ERROR="echo_failure"
+ else
+ ECHO=echo
+ ECHO_OK=:
+ ECHO_ERROR=:
+ fi
+ ;;
+
+ *)
+ IS_ON=/bin/true
+ ECHO=echo
+ ECHO_OK=:
+ ECHO_ERROR=:
+ ;;
+esac
+
+#
+# Make sure we have the standard program directories in the path
+# since some operating systems (this means YOU HP-UX!) don't
+# provide a standard path on boot-up...
+#
+
+if test "x$PATH" = x; then
+ PATH="/bin:/usr/bin:/sbin:/usr/sbin"
+else
+ PATH="/bin:/usr/bin:/sbin:/usr/sbin:$PATH"
+fi
+
+export PATH
+
+#
+# See if the CUPS server (cupsd) is running...
+#
+
+case "`uname`" in
+ Linux* | *BSD* | Darwin*)
+ pid=`ps ax | awk '{if (match($5, ".*/cups-browsed$") || $5 == "cups-browsed") print $1}'`
+ ;;
+ *)
+ pid=""
+ ;;
+esac
+
+#
+# Start or stop cups-browsed based upon the first argument to the script.
+#
+
+case $1 in
+ start | restart | reload)
+ if $IS_ON cups; then
+ if test "$pid" != ""; then
+ kill -TERM $pid
+ fi
+ prefix=@prefix@
+ exec_prefix=@exec_prefix@
+ @sbindir@/cups-browsed &
+ if test $? != 0; then
+ $ECHO_FAIL
+ $ECHO "cups-browsed: unable to $1."
+ exit 1
+ fi
+ $ECHO_OK
+ $ECHO "cups-browsed: ${1}ed."
+ fi
+ ;;
+
+ stop)
+ if test "$pid" != ""; then
+ kill -TERM $pid
+ $ECHO_OK
+ $ECHO "cups-browsed: stopped."
+ fi
+ ;;
+
+ status)
+ if test "$pid" != ""; then
+ echo "cups-browsed: running."
+ else
+ echo "cups-browsed: not running."
+ fi
+ ;;
+
+ *)
+ echo "Usage: cups-browsed {reload|restart|start|status|stop}"
+ exit 1
+ ;;
+esac
+
+#
+# Exit with no errors.
+#
+
+exit 0
diff --git a/utils/cups-browsed.service b/utils/cups-browsed.service
new file mode 100644
index 000000000..c0b8d0627
--- /dev/null
+++ b/utils/cups-browsed.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Make remote CUPS printers available locally
+Requires=cups.service
+After=cups.service avahi-daemon.service
+Wants=avahi-daemon.service
+
+[Service]
+ExecStart=/usr/sbin/cups-browsed
+
+[Install]
+WantedBy=multi-user.target
diff --git a/utils/driverless.1 b/utils/driverless.1
new file mode 100644
index 000000000..7dfa11bd5
--- /dev/null
+++ b/utils/driverless.1
@@ -0,0 +1,70 @@
+.TH driverless 1 "27 Dec 2016" "" ""
+.SH NAME
+\fBdriverless \fP- PPD generator utility for driverless printing
+\fB
+.SH SYNOPSIS
+.nf
+.fam C
+\fBdriverless\fP [\fB-h\fP | \fB--help\fP | \fB--version\fP] [\fB-d\fP | \fB-v\fP | \fB--debug\fP] [\fBlist\fP] | [\fBcat\fP \fIdriver URI\fP] | [\fIIPP printer URI\fP]
+
+.fam T
+.fi
+.fam T
+.fi
+.SH DESCRIPTION
+\fBdriverless\fP generates PPD files for printers which are designed
+for driverless printing (currently IPP Everywhere and AirPrint
+printers) by polling capability information from the printers via
+IPP. it can be either called for listing suitable printers in the
+network and for actually generating the PPD. It can also be called by
+CUPS when CUPS is listing available PPDs/drivers or creating print
+queues, making the setup of driverless printers with printer setup
+tools transparently working.
+.P
+driverless is placed in /usr/lib/cups/driver/ for listing available
+driverless-capable printers and generating PPDs for them. It should
+also be put in /usr/lib/cups/backend/ (preferably by a symbolic link)
+to list IPP device URIs for suitable printers. Printer setup tools
+like system-config-printer, the CUPS web interface at
+http://localhost:631/, and CUPS' command line utilities can use
+driverless with CUPS to list available driverless-capable printers,
+determine their IPP device URIs and generate PPDs for them. The
+printers will be automatically and correctly set up for driverless
+printing. Note that driverless printing requires IPP communication
+with the printer.
+.P
+A second symbolic link to /usr/lib/cups/driver/driverless from
+/usr/bin/ allows driverless to be called directly by a user.
+.SH OPTIONS
+.TP
+.B
+\fB-h\fP, \fB--help\fP, \fB--version\fP
+Show help page, including version number.
+.TP
+.B
+\fB-v\fP, \fB-d\fP, \fB--debug\fP
+Debug mode, verbose logging to stderr.
+.TP
+.B
+\fBlist\fP
+List the driver URIs and metadata for all available IPP printers suitable
+for driverless PPD file generation (to be used by CUPS).
+.TP
+.B
+\fBcat\fP \fIdriver URI\fP
+Generate the PPD file for the supplied \fIdriver URI\fP from the output of "list"
+(to be used by CUPS).
+.TP
+.B
+\fIIPP printer URI\fB
+Generate the PPD file for the supplied \fIIPP printer URI\fP (suitable URIs are listed when calling driverless without options).
+.TP
+When called without options, the IPP printer URIs of all available IPP printers will be listed.
+.P
+.SH SEE ALSO
+
+\fBcups-browsed\fP(8), \fBippfind\fP(1)
+.PP
+.SH AUTHOR
+The authors of \fBdriverless\fP are listed in /usr/share/doc/\fBcups-filters\fP/AUTHORS.
+.PP
diff --git a/utils/driverless.c b/utils/driverless.c
new file mode 100644
index 000000000..517fb9242
--- /dev/null
+++ b/utils/driverless.c
@@ -0,0 +1,674 @@
+/***
+ This file is part of cups-filters.
+
+ This file is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ This file is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+ Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with cups-filters; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#if defined(__OpenBSD__)
+#include <sys/socket.h>
+#endif /* __OpenBSD__ */
+#include <sys/types.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/wait.h>
+
+#include <cups/cups.h>
+#include <cups/ppd.h>
+#include <cups/raster.h>
+#include <cupsfilters/ppdgenerator.h>
+
+static int debug = 0;
+static int job_canceled = 0;
+static void cancel_job(int sig);
+
+int
+list_printers (int mode)
+{
+ int ippfind_pid, /* Process ID for ippfind */
+ post_proc_pid = 0, /* Process ID of post-processing */
+ post_proc_pipe[2], /* Pipe to post-processing */
+ wait_children, /* Number of child processes left */
+ wait_pid, /* Process ID from wait() */
+ wait_status, /* Status from child */
+ exit_status = 0, /* Exit status */
+ bytes, /* Bytes copied */
+ i;
+ char *ippfind_argv[100], /* Arguments for ippfind */
+ buffer[8192]; /* Copy buffer */
+ cups_file_t *fp; /* Post-processing input file */
+ char *ptr; /* Pointer into string */
+ char *service_uri = NULL,
+ *txt_usb_mfg = NULL,
+ *txt_usb_mdl = NULL,
+ *txt_product = NULL,
+ *txt_ty = NULL,
+ *txt_pdl = NULL,
+ value[256], /* Value string */
+ make_and_model[512], /* Manufacturer and model */
+ make[512], /* Manufacturer */
+ model[256], /* Model */
+ pdl[256], /* PDL */
+ device_id[2048]; /* 1284 device ID */
+
+ /*
+ * Use CUPS' ippfind utility to discover all printers designed for
+ * driverless use (IPP Everywhere or Apple Raster), and only IPP
+ * network printers, not CUPS queues, output all data elements needed
+ * for our desired output.
+ */
+
+ /* ippfind ! --txt printer-type --and \( --txt-pdl image/pwg-raster --or --txt-pdl image/urf \) -x echo -en '{service_uri}\t{txt_usb_MFG}\t{txt_usb_MDL}\t{txt_product}\t{txt_ty}\t{service_name}\t{txt_pdl}\n' \; */
+
+ i = 0;
+ ippfind_argv[i++] = "ippfind";
+ ippfind_argv[i++] = "-T"; /* Bonjour poll timeout */
+ ippfind_argv[i++] = "3"; /* 3 seconds */
+ ippfind_argv[i++] = "!"; /* ! --txt printer-type */
+ ippfind_argv[i++] = "--txt"; /* No remote CUPS queues */
+ ippfind_argv[i++] = "printer-type"; /* (no "printer-type" in TXT
+ record) */
+ ippfind_argv[i++] = "--and"; /* and */
+ ippfind_argv[i++] = "(";
+ ippfind_argv[i++] = "--txt-pdl"; /* PDL list in TXT record contains */
+ ippfind_argv[i++] = "image/pwg-raster"; /* PWG Raster (IPP Everywhere) */
+#ifdef QPDF_HAVE_PCLM
+ ippfind_argv[i++] = "--or"; /* or */
+ ippfind_argv[i++] = "--txt-pdl";
+ ippfind_argv[i++] = "application/PCLm"; /* PCLm */
+#endif
+#ifdef CUPS_RASTER_HAVE_APPLERASTER
+ ippfind_argv[i++] = "--or"; /* or */
+ ippfind_argv[i++] = "--txt-pdl";
+ ippfind_argv[i++] = "image/urf"; /* Apple Raster */
+#endif
+ ippfind_argv[i++] = "--or"; /* or */
+ ippfind_argv[i++] = "--txt-pdl";
+ ippfind_argv[i++] = "application/pdf"; /* PDF */
+ ippfind_argv[i++] = ")";
+ ippfind_argv[i++] = "-x";
+ ippfind_argv[i++] = "echo"; /* Output the needed data fields */
+ ippfind_argv[i++] = "-en"; /* separated by tab characters */
+ if (mode > 0)
+ ippfind_argv[i++] = "{service_uri}\t{txt_usb_MFG}\t{txt_usb_MDL}\t{txt_product}\t{txt_ty}\t{txt_pdl}\n";
+ else
+ ippfind_argv[i++] = "{service_uri}\n";
+ ippfind_argv[i++] = ";";
+ ippfind_argv[i++] = NULL;
+ /*for (i = 0; ippfind_argv[i]; i++) fprintf(stderr, "%s ", ippfind_argv[i]);
+ fprintf(stderr, "\n");*/
+
+ /*
+ * Create a pipe for passing the ippfind output to post-processing
+ */
+
+ if (pipe(post_proc_pipe))
+ {
+ perror("ERROR: Unable to create pipe to post-processing");
+
+ exit_status = 1;
+ goto error;
+ }
+
+ if ((ippfind_pid = fork()) == 0)
+ {
+ /*
+ * Child comes here...
+ */
+
+ dup2(post_proc_pipe[1], 1);
+ close(post_proc_pipe[0]);
+ close(post_proc_pipe[1]);
+
+ execvp(CUPS_IPPFIND, ippfind_argv);
+ perror("ERROR: Unable to execute ippfind utility");
+
+ exit(1);
+ }
+ else if (ippfind_pid < 0)
+ {
+ /*
+ * Unable to fork!
+ */
+
+ perror("ERROR: Unable to execute ippfind utility");
+
+ exit_status = 1;
+ goto error;
+ }
+
+ if (debug)
+ fprintf(stderr, "DEBUG: Started %s (PID %d)\n", ippfind_argv[0],
+ ippfind_pid);
+
+ if ((post_proc_pid = fork()) == 0)
+ {
+ /*
+ * Child comes here...
+ */
+
+ dup2(post_proc_pipe[0], 0);
+ close(post_proc_pipe[0]);
+ close(post_proc_pipe[1]);
+
+ fp = cupsFileStdin();
+
+ while ((bytes = cupsFileGetLine(fp, buffer, sizeof(buffer))) > 0)
+ {
+ if (strncasecmp(buffer, "ipp:", 4) && strncasecmp(buffer, "ipps:", 4)) {
+ /* Invalid IPP URI */
+ fprintf(stderr, "EROOR: Invalid IPP URI: %s\n", buffer);
+ continue;
+ }
+ if (mode == 0)
+ /* Manual call on the command line */
+ printf("%s", buffer);
+ else {
+ /* Call by CUPS, either as PPD generator
+ (/usr/lib/cups/driver/, with "list" command line argument)
+ or as backend in discovery mode (/usr/lib/cups/backend/,
+ env variable "SOFTWARE" starts with "CUPS") */
+ ptr = buffer;
+ service_uri = ptr;
+ ptr = memchr(ptr, '\t', sizeof(buffer) - (ptr - buffer));
+ if (!ptr) goto read_error;
+ *ptr = '\0';
+ ptr ++;
+ txt_usb_mfg = ptr;
+ ptr = memchr(ptr, '\t', sizeof(buffer) - (ptr - buffer));
+ if (!ptr) goto read_error;
+ *ptr = '\0';
+ ptr ++;
+ txt_usb_mdl = ptr;
+ ptr = memchr(ptr, '\t', sizeof(buffer) - (ptr - buffer));
+ if (!ptr) goto read_error;
+ *ptr = '\0';
+ ptr ++;
+ txt_product = ptr;
+ ptr = memchr(ptr, '\t', sizeof(buffer) - (ptr - buffer));
+ if (!ptr) goto read_error;
+ *ptr = '\0';
+ ptr ++;
+ txt_ty = ptr;
+ ptr = memchr(ptr, '\t', sizeof(buffer) - (ptr - buffer));
+ if (!ptr) goto read_error;
+ *ptr = '\0';
+ ptr ++;
+ txt_pdl = ptr;
+ ptr = memchr(ptr, '\n', sizeof(buffer) - (ptr - buffer));
+ if (!ptr) goto read_error;
+ *ptr = '\0';
+
+ make_and_model[0] = '\0';
+ make[0] = '\0';
+ pdl[0] = '\0';
+ device_id[0] = '\0';
+ strncpy(model, "Unknown", sizeof(model));
+
+ if (txt_usb_mfg[0] != '\0') {
+ strncpy(make, txt_usb_mfg, sizeof(make));
+ ptr = device_id + strlen(device_id);
+ snprintf(ptr, sizeof(device_id) - (size_t)(ptr - device_id),
+ "MFG:%s;", txt_usb_mfg);
+ }
+ if (txt_usb_mdl[0] != '\0') {
+ strncpy(model, txt_usb_mdl, sizeof(model));
+ ptr = device_id + strlen(device_id);
+ snprintf(ptr, sizeof(device_id) - (size_t)(ptr - device_id),
+ "MDL:%s;", txt_usb_mdl);
+ } else if (txt_product[0] != '\0') {
+ if (txt_product[0] == '(') {
+ /* Strip parenthesis... */
+ if ((ptr = txt_product + strlen(txt_product) - 1) > txt_product &&
+ *ptr == ')')
+ *ptr = '\0';
+ strncpy(model, txt_product + 1, sizeof(model));
+ } else
+ strncpy(model, txt_product, sizeof(model));
+ } else if (txt_ty[0] != '\0') {
+ strncpy(model, txt_ty, sizeof(model));
+ if ((ptr = strchr(model, ',')) != NULL)
+ *ptr = '\0';
+ }
+ if (txt_pdl[0] != '\0')
+ strncpy(pdl, txt_pdl, sizeof(pdl));
+
+ if (!device_id[0] && strcasecmp(model, "Unknown")) {
+ if (make[0])
+ snprintf(device_id, sizeof(device_id), "MFG:%s;MDL:%s;",
+ make, model);
+ else if (!strncasecmp(model, "designjet ", 10))
+ snprintf(device_id, sizeof(device_id), "MFG:HP;MDL:%s;",
+ model + 10);
+ else if (!strncasecmp(model, "stylus ", 7))
+ snprintf(device_id, sizeof(device_id), "MFG:EPSON;MDL:%s;",
+ model + 7);
+ else if ((ptr = strchr(model, ' ')) != NULL) {
+ /* Assume the first word is the make...*/
+ memcpy(make, model, (size_t)(ptr - model));
+ make[ptr - model] = '\0';
+ snprintf(device_id, sizeof(device_id), "MFG:%s;MDL:%s;",
+ make, ptr + 1);
+ }
+ }
+
+ if (device_id[0] &&
+ !strcasestr(device_id, "CMD:") &&
+ !strcasestr(device_id, "COMMAND SET:") &&
+ (strcasestr(pdl, "application/pdf") ||
+ strcasestr(pdl, "application/postscript") ||
+ strcasestr(pdl, "application/vnd.hp-PCL") ||
+ strcasestr(pdl, "application/PCLm") ||
+ strcasestr(pdl, "image/"))) {
+ value[0] = '\0';
+ if (strcasestr(pdl, "application/pdf"))
+ strncat(value, ",PDF", sizeof(value));
+ if (strcasestr(pdl, "application/PCLm"))
+ strncat(value, ",PCLM", sizeof(value));
+ if (strcasestr(pdl, "application/postscript"))
+ strncat(value, ",PS", sizeof(value));
+ if (strcasestr(pdl, "application/vnd.hp-PCL"))
+ strncat(value, ",PCL", sizeof(value));
+ if (strcasestr(pdl, "image/pwg-raster"))
+ strncat(value, ",PWGRaster", sizeof(value));
+ if (strcasestr(pdl, "image/urf"))
+ strncat(value, ",AppleRaster", sizeof(value));
+ for (ptr = strcasestr(pdl, "image/"); ptr;
+ ptr = strcasestr(ptr, "image/")) {
+ char *valptr = value + strlen(value);
+ if (valptr < (value + sizeof(value) - 1))
+ *valptr++ = ',';
+ ptr += 6;
+ while (isalnum(*ptr & 255) || *ptr == '-' || *ptr == '.') {
+ if (isalnum(*ptr & 255) && valptr < (value + sizeof(value) - 1))
+ *valptr++ = (char)toupper(*ptr++ & 255);
+ else
+ break;
+ }
+ *valptr = '\0';
+ }
+ ptr = device_id + strlen(device_id);
+ snprintf(ptr, sizeof(device_id) - (size_t)(ptr - device_id),
+ "CMD:%s;", value + 1);
+ }
+
+ if (make[0] &&
+ (strncasecmp(model, make, strlen(make)) ||
+ !isspace(model[strlen(make)])))
+ snprintf(make_and_model, sizeof(make_and_model), "%s %s",
+ make, model);
+ else
+ strncpy(make_and_model, model, sizeof(make_and_model));
+
+ if (mode == 1)
+ /* Call with "list" argument (PPD generator in list mode */
+ printf("\"driverless:%s\" en \"%s\" \"%s, driverless, cups-filters " VERSION
+ "\" \"%s\"\n", service_uri, make, make_and_model, device_id);
+ else
+ /* Call without arguments and env variable "SOFTWARE" starting
+ with "CUPS" (Backend in discovery mode) */
+ printf("network %s \"%s\" \"%s (driverless)\" \"%s\" \"\"\n", service_uri, make_and_model, make_and_model, device_id);
+
+ read_error:
+ continue;
+ }
+ }
+
+ /*
+ * Copy the rest of the file
+ */
+
+ while ((bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0)
+ fwrite(buffer, 1, bytes, stdout);
+
+ exit(0);
+ }
+ else if (post_proc_pid < 0)
+ {
+ /*
+ * Unable to fork!
+ */
+
+ perror("ERROR: Unable to execute post-processing process");
+
+ exit_status = 1;
+ goto error;
+ }
+
+ if (debug)
+ fprintf(stderr, "DEBUG: Started post-processing (PID %d)\n", post_proc_pid);
+
+ close(post_proc_pipe[0]);
+ close(post_proc_pipe[1]);
+
+ /*
+ * Wait for the child processes to exit...
+ */
+
+ wait_children = 2;
+
+ while (wait_children > 0)
+ {
+ /*
+ * Wait until we get a valid process ID or the job is canceled...
+ */
+
+ while ((wait_pid = wait(&wait_status)) < 0 && errno == EINTR)
+ {
+ if (job_canceled)
+ {
+ kill(ippfind_pid, SIGTERM);
+ kill(post_proc_pid, SIGTERM);
+
+ job_canceled = 0;
+ }
+ }
+
+ if (wait_pid < 0)
+ break;
+
+ wait_children --;
+
+ /*
+ * Report child status...
+ */
+
+ if (wait_status)
+ {
+ if (WIFEXITED(wait_status))
+ {
+ exit_status = WEXITSTATUS(wait_status);
+
+ if (debug)
+ fprintf(stderr, "DEBUG: PID %d (%s) stopped with status %d!\n",
+ wait_pid,
+ wait_pid == ippfind_pid ? "ippfind" :
+ (wait_pid == post_proc_pid ? "Post-processing" :
+ "Unknown process"),
+ exit_status);
+ /* When run by CUPS do not exit with an error status if there is
+ simply no driverless printer available or no Avahi present */
+ if (mode != 0 && wait_pid == ippfind_pid && exit_status <= 2)
+ exit_status = 0;
+ }
+ else if (WTERMSIG(wait_status) == SIGTERM)
+ {
+ if (debug)
+ fprintf(stderr,
+ "DEBUG: PID %d (%s) was terminated normally with signal %d!\n",
+ wait_pid,
+ wait_pid == ippfind_pid ? "ippfind" :
+ (wait_pid == post_proc_pid ? "Post-processing" :
+ "Unknown process"),
+ exit_status);
+ }
+ else
+ {
+ exit_status = WTERMSIG(wait_status);
+
+ if (debug)
+ fprintf(stderr, "DEBUG: PID %d (%s) crashed on signal %d!\n",
+ wait_pid,
+ wait_pid == ippfind_pid ? "ippfind" :
+ (wait_pid == post_proc_pid ? "Post-processing" :
+ "Unknown process"),
+ exit_status);
+ }
+ }
+ else
+ {
+ if (debug)
+ fprintf(stderr, "DEBUG: PID %d (%s) exited with no errors.\n",
+ wait_pid,
+ wait_pid == ippfind_pid ? "ippfind" :
+ (wait_pid == post_proc_pid ? "Post-processing" :
+ "Unknown process"));
+ }
+ }
+
+ /*
+ * Exit...
+ */
+
+ error:
+
+ return (exit_status);
+
+}
+
+int
+generate_ppd (const char *uri)
+{
+ int uri_status, host_port;
+ http_t *http = NULL;
+ char scheme[10], userpass[1024], host_name[1024], resource[1024];
+ ipp_t *request, *response = NULL;
+ ipp_attribute_t *attr;
+ char buffer[65536], ppdname[1024];
+ int i, fd, bytes;
+
+ /* Request printer properties via IPP to generate a PPD file for the
+ printer (mainly IPP Everywhere printers)
+ If we work with Systen V interface scripts use this info to set
+ option defaults. */
+ uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, uri,
+ scheme, sizeof(scheme),
+ userpass, sizeof(userpass),
+ host_name, sizeof(host_name),
+ &(host_port),
+ resource, sizeof(resource));
+ if (uri_status != HTTP_URI_OK) {
+ fprintf(stderr, "ERROR: Invalid URI: %s\n", uri);
+ goto fail;
+ }
+ if ((http = httpConnect(host_name, host_port)) ==
+ NULL) {
+ fprintf(stderr, "ERROR: Cannot connect to remote printer %s (%s:%d)\n",
+ uri, host_name, host_port);
+ goto fail;
+ }
+ request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+ response = cupsDoRequest(http, request, resource);
+
+ /* Log all printer attributes for debugging */
+ if (debug) {
+ attr = ippFirstAttribute(response);
+ while (attr) {
+ fprintf(stderr, "DEBUG2: Attr: %s\n", ippGetName(attr));
+ ippAttributeString(attr, buffer, sizeof(buffer));
+ fprintf(stderr, "DEBUG2: Value: %s\n", buffer);
+ for (i = 0; i < ippGetCount(attr); i ++)
+ fprintf(stderr, "DEBUG2: Keyword: %s\n",
+ ippGetString(attr, i, NULL));
+ attr = ippNextAttribute(response);
+ }
+ }
+
+ /* Generate the PPD file */
+ if (!ppdCreateFromIPP(ppdname, sizeof(ppdname), response, NULL, NULL, 0, 0)) {
+ if (strlen(ppdgenerator_msg) > 0)
+ fprintf(stderr, "ERROR: Unable to create PPD file: %s\n",
+ ppdgenerator_msg);
+ else if (errno != 0)
+ fprintf(stderr, "ERROR: Unable to create PPD file: %s\n",
+ strerror(errno));
+ else
+ fprintf(stderr, "ERROR: Unable to create PPD file: Unknown reason\n");
+ goto fail;
+ } else if (debug) {
+ fprintf(stderr, "DEBUG: PPD generation successful: %s\n", ppdgenerator_msg);
+ fprintf(stderr, "DEBUG: Created temporary PPD file: %s\n", ppdname);
+ }
+
+ ippDelete(response);
+ httpClose(http);
+
+ /* Output of PPD file to stdout */
+ fd = open(ppdname, O_RDONLY);
+ while ((bytes = read(fd, buffer, sizeof(buffer))) > 0)
+ bytes = fwrite(buffer, 1, bytes, stdout);
+ close(fd);
+ unlink(buffer);
+
+ return 0;
+
+ fail:
+ ippDelete(response);
+ if (http)
+ httpClose(http);
+
+ return 1;
+}
+
+
+int main(int argc, char*argv[]) {
+ int i;
+ char *val;
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Ignore broken pipe signals...
+ */
+
+ signal(SIGPIPE, SIG_IGN);
+
+ /*
+ * Register a signal handler to cleanly cancel a job.
+ */
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, cancel_job);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = cancel_job;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, cancel_job);
+#endif /* HAVE_SIGSET */
+
+ /* Read command line options */
+ if (argc >= 2) {
+ for (i = 1; i < argc; i++)
+ if (!strcasecmp(argv[i], "--debug") || !strcasecmp(argv[i], "-d") ||
+ !strncasecmp(argv[i], "-v", 2)) {
+ /* Output debug messages on stderr also when not running under CUPS
+ ("list" and "cat" options) */
+ debug = 1;
+ } else if (!strcasecmp(argv[i], "list")) {
+ /* List a driver URI and metadata for each printer suitable for
+ driverless printing */
+ debug = 1;
+ exit(list_printers(1));
+ } else if (!strncasecmp(argv[i], "cat", 3)) {
+ /* Generate the PPD file for the given driver URI */
+ debug = 1;
+ val = argv[i] + 3;
+ if (strlen(val) == 0) {
+ i ++;
+ if (i < argc && *argv[i] != '-')
+ val = argv[i];
+ else
+ val = NULL;
+ }
+ if (val) {
+ /* Generate PPD file */
+ if (!strncasecmp(val, "driverless:", 11))
+ val += 11;
+ exit(generate_ppd(val));
+ } else {
+ fprintf(stderr,
+ "Reading command line option \"cat\", no driver URI supplied.\n\n");
+ goto help;
+ }
+ } else if (!strcasecmp(argv[i], "--version") ||
+ !strcasecmp(argv[i], "--help") || !strcasecmp(argv[i], "-h")) {
+ /* Help!! */
+ goto help;
+ } else {
+ /* Unknown option, consider as IPP printer URI */
+ exit(generate_ppd(argv[i]));
+ }
+ }
+
+ /* Call without arguments, list printer URIs for all suitable printers
+ when started manually, list printer URIs and metadata like CUPS
+ backends do when started as CUPS backend (discovery mode only) */
+ if ((val = getenv("SOFTWARE")) != NULL &&
+ strncasecmp(val, "CUPS", 4) == 0) {
+ /* CUPS backend in discovery mode */
+ debug = 1;
+ exit(list_printers(2));
+ } else
+ /* Manual call */
+ exit(list_printers(0));
+
+ help:
+
+ fprintf(stderr,
+ "\ndriverless of cups-filters version "VERSION"\n\n"
+ "Usage: driverless [options]\n"
+ "Options:\n"
+ " -h\n"
+ " --help\n"
+ " --version Show this usage message.\n"
+ " -d\n"
+ " -v\n"
+ " --debug Debug/verbose mode.\n"
+ " list List the driver URIs and metadata for all available\n"
+ " IPP printers supporting driverless printing (to be\n"
+ " used by CUPS).\n"
+ " cat <driver URI> Generate the PPD file for the driver URI\n"
+ " <driver URI> (to be used by CUPS).\n"
+ " <printer URI> Generate the PPD file for the IPP printer URI\n"
+ " <printer URI>.\n"
+ "\n"
+ "When called without options, the IPP printer URIs of all available IPP printers\n"
+ "will be listed.\n\n"
+ );
+
+ return 1;
+}
+
+/*
+ * 'cancel_job()' - Flag the job as canceled.
+ */
+
+static void
+cancel_job(int sig) /* I - Signal number (unused) */
+{
+ (void)sig;
+
+ job_canceled = 1;
+}
diff --git a/utils/org.cups.cupsd.Notifier.xml b/utils/org.cups.cupsd.Notifier.xml
new file mode 100644
index 000000000..e70a5c31d
--- /dev/null
+++ b/utils/org.cups.cupsd.Notifier.xml
@@ -0,0 +1,147 @@
+<node>
+
+ <interface name="org.cups.cupsd.Notifier">
+
+ <signal name="ServerStarted">
+ <arg type="s" name="text" />
+ </signal>
+
+ <signal name="ServerRestarted">
+ <arg type="s" name="text" />
+ </signal>
+
+ <signal name="ServerStopped">
+ <arg type="s" name="text" />
+ </signal>
+
+ <signal name="ServerAudit">
+ <arg type="s" name="text" />
+ </signal>
+
+ <signal name="PrinterAdded">
+ <arg type="s" name="text" />
+ <arg type="s" name="printer_uri" />
+ <arg type="s" name="printer_name" />
+ <arg type="u" name="printer_state" />
+ <arg type="s" name="printer_state_reasons" />
+ <arg type="b" name="printer_is_accepting_jobs" />
+ </signal>
+
+ <signal name="PrinterDeleted">
+ <arg type="s" name="text" />
+ <arg type="s" name="printer_uri" />
+ <arg type="s" name="printer_name" />
+ <arg type="u" name="printer_state" />
+ <arg type="s" name="printer_state_reasons" />
+ <arg type="b" name="printer_is_accepting_jobs" />
+ </signal>
+
+ <signal name="PrinterModified">
+ <arg type="s" name="text" />
+ <arg type="s" name="printer_uri" />
+ <arg type="s" name="printer_name" />
+ <arg type="u" name="printer_state" />
+ <arg type="s" name="printer_state_reasons" />
+ <arg type="b" name="printer_is_accepting_jobs" />
+ </signal>
+
+ <signal name="PrinterRestarted">
+ <arg type="s" name="text" />
+ <arg type="s" name="printer_uri" />
+ <arg type="s" name="printer_name" />
+ <arg type="u" name="printer_state" />
+ <arg type="s" name="printer_state_reasons" />
+ <arg type="b" name="printer_is_accepting_jobs" />
+ </signal>
+
+ <signal name="PrinterStopped">
+ <arg type="s" name="text" />
+ <arg type="s" name="printer_uri" />
+ <arg type="s" name="printer_name" />
+ <arg type="u" name="printer_state" />
+ <arg type="s" name="printer_state_reasons" />
+ <arg type="b" name="printer_is_accepting_jobs" />
+ </signal>
+
+ <signal name="PrinterShutdown">
+ <arg type="s" name="text" />
+ <arg type="s" name="printer_uri" />
+ <arg type="s" name="printer_name" />
+ <arg type="u" name="printer_state" />
+ <arg type="s" name="printer_state_reasons" />
+ <arg type="b" name="printer_is_accepting_jobs" />
+ </signal>
+
+ <signal name="PrinterStateChanged">
+ <arg type="s" name="text" />
+ <arg type="s" name="printer_uri" />
+ <arg type="s" name="printer_name" />
+ <arg type="u" name="printer_state" />
+ <arg type="s" name="printer_state_reasons" />
+ <arg type="b" name="printer_is_accepting_jobs" />
+ </signal>
+
+ <signal name="PrinterFinishingsChanged">
+ <arg type="s" name="text" />
+ <arg type="s" name="printer_uri" />
+ <arg type="s" name="printer_name" />
+ <arg type="u" name="printer_state" />
+ <arg type="s" name="printer_state_reasons" />
+ <arg type="b" name="printer_is_accepting_jobs" />
+ </signal>
+
+ <signal name="PrinterMediaChanged">
+ <arg type="s" name="text" />
+ <arg type="s" name="printer_uri" />
+ <arg type="s" name="printer_name" />
+ <arg type="u" name="printer_state" />
+ <arg type="s" name="printer_state_reasons" />
+ <arg type="b" name="printer_is_accepting_jobs" />
+ </signal>
+
+ <signal name="JobCreated">
+ <arg type="s" name="text" />
+ <arg type="s" name="printer_uri" />
+ <arg type="s" name="printer_name" />
+ <arg type="u" name="printer_state" />
+ <arg type="s" name="printer_state_reasons" />
+ <arg type="b" name="printer_is_accepting_jobs" />
+ <arg type="u" name="job_id" />
+ <arg type="u" name="job_state" />
+ <arg type="s" name="job_state_reasons" />
+ <arg type="s" name="job_name" />
+ <arg type="u" name="job_impressions_completed" />
+ </signal>
+
+ <signal name="JobCompleted">
+ <arg type="s" name="text" />
+ <arg type="s" name="printer_uri" />
+ <arg type="s" name="printer_name" />
+ <arg type="u" name="printer_state" />
+ <arg type="s" name="printer_state_reasons" />
+ <arg type="b" name="printer_is_accepting_jobs" />
+ <arg type="u" name="job_id" />
+ <arg type="u" name="job_state" />
+ <arg type="s" name="job_state_reasons" />
+ <arg type="s" name="job_name" />
+ <arg type="u" name="job_impressions_completed" />
+ </signal>
+
+ <signal name="JobState">
+ <arg type="s" name="text" />
+ <arg type="s" name="printer_uri" />
+ <arg type="s" name="printer_name" />
+ <arg type="u" name="printer_state" />
+ <arg type="s" name="printer_state_reasons" />
+ <arg type="b" name="printer_is_accepting_jobs" />
+ <arg type="u" name="job_id" />
+ <arg type="u" name="job_state" />
+ <arg type="s" name="job_state_reasons" />
+ <arg type="s" name="job_name" />
+ <arg type="u" name="job_impressions_completed" />
+ </signal>
+
+ </interface>
+
+</node>
+