mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 10:58:58 +00:00
Remove PCRE
This commit is contained in:
parent
30f109e244
commit
9a96e233b0
@ -1,5 +1,7 @@
|
|||||||
2017-08-10 Jay Berkenbilt <ejb@ql.org>
|
2017-08-10 Jay Berkenbilt <ejb@ql.org>
|
||||||
|
|
||||||
|
* Remove dependency on libpcre.
|
||||||
|
|
||||||
* Be more forgiving of certain types of errors in the xref table
|
* Be more forgiving of certain types of errors in the xref table
|
||||||
that don't interfere with interpreting the table.
|
that don't interfere with interpreting the table.
|
||||||
|
|
||||||
|
27
README
27
README
@ -13,11 +13,11 @@ warranty.
|
|||||||
Prerequisites
|
Prerequisites
|
||||||
=============
|
=============
|
||||||
|
|
||||||
QPDF depends on external libraries "zlib" and "pcre". These are part
|
QPDF depends on the external library "zlib". This are part of every
|
||||||
of virtually all Linux distributions and are readily available;
|
Linux distribution and is readily available. Download information
|
||||||
download information appears in the documentation. For Windows, you
|
appears in the documentation. For Windows, you can download pre-built
|
||||||
can download pre-built binary versions of those libraries for some
|
binary versions of this libraries for some compilers; see
|
||||||
compilers; see README-windows.txt for additional details.
|
README-windows.txt for additional details.
|
||||||
|
|
||||||
QPDF requires a C++ compiler that works with STL. Your compiler must
|
QPDF requires a C++ compiler that works with STL. Your compiler must
|
||||||
also support "long long". Almost all modern compilers do. If you are
|
also support "long long". Almost all modern compilers do. If you are
|
||||||
@ -34,10 +34,9 @@ you had an otherwise working qpdf.
|
|||||||
Licensing terms of embedded software
|
Licensing terms of embedded software
|
||||||
====================================
|
====================================
|
||||||
|
|
||||||
QPDF makes use of zlib and pcre for its functionality. These packages
|
QPDF makes use of zlib for its functionality. This package can be
|
||||||
can be downloaded separately from their own download locations, or
|
downloaded separately from its own download location, or it can be
|
||||||
they can be downloaded in the external-libs area of the qpdf download
|
downloaded in the external-libs area of the qpdf download site.
|
||||||
site.
|
|
||||||
|
|
||||||
The Rijndael encryption implementation used as the basis for AES
|
The Rijndael encryption implementation used as the basis for AES
|
||||||
encryption and decryption support comes from Philip J. Erdelsky's
|
encryption and decryption support comes from Philip J. Erdelsky's
|
||||||
@ -147,11 +146,11 @@ user's manual can be found in the "doc" directory. The docbook
|
|||||||
sources to the user's manual can be found in the "manual" directory.
|
sources to the user's manual can be found in the "manual" directory.
|
||||||
|
|
||||||
The software library is just libqpdf, and all the header files are in
|
The software library is just libqpdf, and all the header files are in
|
||||||
the qpdf subdirectory. If you link statically with -lqpdf, then you
|
the qpdf subdirectory. If you link statically with -lqpdf, then you
|
||||||
will also need to link with -lpcre and -lz. The shared qpdf library
|
will also need to link with -lz. The shared qpdf library is linked
|
||||||
is linked with -lpcre and -lz, and none of qpdf's public header files
|
with -lz, and none of qpdf's public header files directly include
|
||||||
directly include files from pcre or libz, so in many cases, qpdf's
|
files from libz, so in many cases, qpdf's development files are self
|
||||||
development files are self contained.
|
contained.
|
||||||
|
|
||||||
To learn about using the library, please read comments in the header
|
To learn about using the library, please read comments in the header
|
||||||
files in include/qpdf, especially QPDF.hh, QPDFObjectHandle.hh, and
|
files in include/qpdf, especially QPDF.hh, QPDFObjectHandle.hh, and
|
||||||
|
@ -46,9 +46,8 @@ download.
|
|||||||
* qpdf-external-libs-src.zip
|
* qpdf-external-libs-src.zip
|
||||||
|
|
||||||
If you want to build the external libraries on your own (for
|
If you want to build the external libraries on your own (for
|
||||||
Windows or anything else), you can download this archive. In
|
Windows or anything else), you can download this archive. In
|
||||||
addition to including unmodified distributions of pcre and zlib, it
|
addition to including an unmodified distribution zlib, it includes
|
||||||
includes a README file and some scripts to help you build them for
|
a README file and some scripts to help you build it for Windows.
|
||||||
Windows.
|
|
||||||
|
|
||||||
If you want to build on Windows, please see also README-windows.txt.
|
If you want to build on Windows, please see also README-windows.txt.
|
||||||
|
@ -84,29 +84,32 @@ installers are provided, they might do that already by default.
|
|||||||
External Libraries
|
External Libraries
|
||||||
==================
|
==================
|
||||||
|
|
||||||
In order to build qpdf, you must have copies of zlib and pcre. The
|
In order to build qpdf, you must have a copy of zlib. The easy way to
|
||||||
easy way to get them is to download them from the qpdf download area.
|
get it is to download it from the qpdf download area. There are
|
||||||
There are packages called external-libs-bin.zip and
|
packages called external-libs-bin.zip and external-libs-src.zip. If
|
||||||
external-libs-src.zip. If you are building with MSVC 2010 or MINGW,
|
you are building with MSVC 2010 or MINGW, you can just extract the
|
||||||
you can just extract the qpdf-external-libs-bin.zip zip file into the
|
qpdf-external-libs-bin.zip zip file into the top-level qpdf source
|
||||||
top-level qpdf source tree. Note that you need the 2012-06-20 version
|
tree. Note that you need the 2012-06-20 version (at least) to build
|
||||||
(at least) to build qpdf 3.0 or greater since this includes 64-bit
|
qpdf 3.0 or greater since this includes 64-bit libraries. The
|
||||||
libraries. It will create a directory called external-libs which
|
2017-08-10 version includes libraries built with MSVC 2015 and
|
||||||
contains header files and precompiled libraries. Passing
|
contains only zlib. Older versions also contain pcre, which is no
|
||||||
--enable-external-libs to ./configure (which is done automatically if
|
longer required as of qpdf 7.0.0. Extracting the zip will create a
|
||||||
you follow the instructions below) is sufficient to find them.
|
directory called external-libs which contains header files and
|
||||||
|
precompiled libraries. Passing --enable-external-libs to ./configure
|
||||||
|
(which is done automatically if you follow the instructions below) is
|
||||||
|
sufficient to find them.
|
||||||
|
|
||||||
You can also obtain pcre and zlib directly on your own and install
|
You can also obtain zlib directly on your own and install it. If you
|
||||||
them. If you are using mingw, you can just set CPPFLAGS, LDFLAGS, and
|
are using mingw, you can just set CPPFLAGS, LDFLAGS, and LIBS when you
|
||||||
LIBS when you run ./configure so that it can find the header files and
|
run ./configure so that it can find the header files and libraries. If
|
||||||
libraries. If you are building with msvc and you want to do this, it
|
you are building with msvc and you want to do this, it probably won't
|
||||||
probably won't work because ./configure doesn't know how to interpret
|
work because ./configure doesn't know how to interpret LDFLAGS and
|
||||||
LDFLAGS and LIBS properly for MSVC (though qpdf's own build system
|
LIBS properly for MSVC (though qpdf's own build system does). In this
|
||||||
does). In this case, you can probably get away with cheating by
|
case, you can probably get away with cheating by passing
|
||||||
passing --enable-external-libs to ./configure and then just editing
|
--enable-external-libs to ./configure and then just editing CPPFLAGS,
|
||||||
CPPFLAGS, LDFLAGS, LIBS in the generated autoconf.mk file. Note that
|
LDFLAGS, LIBS in the generated autoconf.mk file. Note that you should
|
||||||
you should use UNIX-like syntax (-I, -L, -l) even though this is not
|
use UNIX-like syntax (-I, -L, -l) even though this is not what cl
|
||||||
what cl takes on the command line. qpdf's build rules will fix it.
|
takes on the command line. qpdf's build rules will fix it.
|
||||||
|
|
||||||
You can also download qpdf-external-libs-src.zip and follow the
|
You can also download qpdf-external-libs-src.zip and follow the
|
||||||
instructions in the README.txt there for how to build external libs.
|
instructions in the README.txt there for how to build external libs.
|
||||||
|
@ -113,7 +113,12 @@ Release Reminders
|
|||||||
version control system into a directory called qpdf-external-libs
|
version control system into a directory called qpdf-external-libs
|
||||||
and just make a zip file of the result called
|
and just make a zip file of the result called
|
||||||
qpdf-external-libs-src.zip. See the README.txt file there for
|
qpdf-external-libs-src.zip. See the README.txt file there for
|
||||||
information on creating binary external libs releases.
|
information on creating binary external libs releases. Run this
|
||||||
|
from the external-libs repository:
|
||||||
|
|
||||||
|
git archive --prefix=external-libs/ HEAD . | (cd /tmp; tar xf -)
|
||||||
|
cd /tmp
|
||||||
|
zip -r qpdf-external-libs-src.zip external-libs
|
||||||
|
|
||||||
* To create Windows binary releases, extract the qpdf source
|
* To create Windows binary releases, extract the qpdf source
|
||||||
distribution in Windows (MSYS + MINGW, MSVC). From the extracted
|
distribution in Windows (MSYS + MINGW, MSVC). From the extracted
|
||||||
|
3
TODO
3
TODO
@ -7,9 +7,6 @@ version if needed.
|
|||||||
Soon
|
Soon
|
||||||
====
|
====
|
||||||
|
|
||||||
* Eliminate dependency on PCRE. There aren't that many regular
|
|
||||||
expressions, and they are used only for internal purposes.
|
|
||||||
|
|
||||||
* Consider whether there should be a mode in which QPDFObjectHandle
|
* Consider whether there should be a mode in which QPDFObjectHandle
|
||||||
returns nulls for operations on the wrong type instead of asserting
|
returns nulls for operations on the wrong type instead of asserting
|
||||||
the type. The way things are wired up now, this would have to be a
|
the type. The way things are wired up now, this would have to be a
|
||||||
|
12
configure.ac
12
configure.ac
@ -82,8 +82,6 @@ fi
|
|||||||
if test "$BUILD_INTERNAL_LIBS" = "0"; then
|
if test "$BUILD_INTERNAL_LIBS" = "0"; then
|
||||||
AC_CHECK_HEADER(zlib.h,,[MISSING_ZLIB_H=1; MISSING_ANY=1])
|
AC_CHECK_HEADER(zlib.h,,[MISSING_ZLIB_H=1; MISSING_ANY=1])
|
||||||
AC_SEARCH_LIBS(deflate,z zlib,,[MISSING_ZLIB=1; MISSING_ANY=1])
|
AC_SEARCH_LIBS(deflate,z zlib,,[MISSING_ZLIB=1; MISSING_ANY=1])
|
||||||
AC_CHECK_HEADER(pcre.h,,[MISSING_PCRE_H=1; MISSING_ANY=1])
|
|
||||||
AC_SEARCH_LIBS(pcre_compile,pcre,,[MISSING_PCRE=1; MISSING_ANY=1])
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "x$qpdf_OS_SECURE_RANDOM" = "x1"; then
|
if test "x$qpdf_OS_SECURE_RANDOM" = "x1"; then
|
||||||
@ -453,14 +451,6 @@ if test "$MISSING_ZLIB" = "1"; then
|
|||||||
AC_MSG_WARN(unable to find required library z (or zlib))
|
AC_MSG_WARN(unable to find required library z (or zlib))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$MISSING_PCRE_H" = "1"; then
|
|
||||||
AC_MSG_WARN(unable to find required header pcre.h)
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "$MISSING_PCRE" = "1"; then
|
|
||||||
AC_MSG_WARN(unable to find required library pcre)
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "$MISSING_DOCBOOK_FO" = "1"; then
|
if test "$MISSING_DOCBOOK_FO" = "1"; then
|
||||||
AC_MSG_WARN(docbook fo stylesheets are required to build PDF documentation)
|
AC_MSG_WARN(docbook fo stylesheets are required to build PDF documentation)
|
||||||
fi
|
fi
|
||||||
@ -497,7 +487,7 @@ if test "$USE_EXTERNAL_LIBS" = "1"; then
|
|||||||
# much trouble getting it to work with a different compiler.
|
# much trouble getting it to work with a different compiler.
|
||||||
CPPFLAGS="$CPPFLAGS -Iexternal-libs/include"
|
CPPFLAGS="$CPPFLAGS -Iexternal-libs/include"
|
||||||
LDFLAGS="$LDFLAGS -Lexternal-libs/lib-$BUILDRULES$WINDOWS_WORDSIZE"
|
LDFLAGS="$LDFLAGS -Lexternal-libs/lib-$BUILDRULES$WINDOWS_WORDSIZE"
|
||||||
LIBS="$LIBS -lz -lpcre"
|
LIBS="$LIBS -lz"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
@ -727,7 +727,6 @@ lld
|
|||||||
lookup
|
lookup
|
||||||
lossy
|
lossy
|
||||||
LowPart
|
LowPart
|
||||||
lpcre
|
|
||||||
lqpdf
|
lqpdf
|
||||||
lsb
|
lsb
|
||||||
lt
|
lt
|
||||||
@ -914,7 +913,6 @@ pb
|
|||||||
pbytes
|
pbytes
|
||||||
pc
|
pc
|
||||||
pcre
|
pcre
|
||||||
pcreapi
|
|
||||||
pdf
|
pdf
|
||||||
PDFâ
|
PDFâ
|
||||||
PDFContext
|
PDFContext
|
||||||
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||||||
Name: libqpdf
|
Name: libqpdf
|
||||||
Description: PDF transformation library
|
Description: PDF transformation library
|
||||||
Version: @PACKAGE_VERSION@
|
Version: @PACKAGE_VERSION@
|
||||||
Requires.private: zlib, libpcre
|
Requires.private: zlib
|
||||||
Libs: -L${libdir} -lqpdf
|
Libs: -L${libdir} -lqpdf
|
||||||
Cflags: -I${includedir}
|
Cflags: -I${includedir}
|
||||||
|
354
libqpdf/PCRE.cc
354
libqpdf/PCRE.cc
@ -1,354 +0,0 @@
|
|||||||
#include <qpdf/PCRE.hh>
|
|
||||||
#include <qpdf/QUtil.hh>
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
PCRE::NoBackref::NoBackref() :
|
|
||||||
std::logic_error("PCRE error: no match")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PCRE::Match::Match(int nbackrefs, char const* subject)
|
|
||||||
{
|
|
||||||
this->init(-1, nbackrefs, subject);
|
|
||||||
}
|
|
||||||
|
|
||||||
PCRE::Match::~Match()
|
|
||||||
{
|
|
||||||
this->destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
PCRE::Match::Match(Match const& rhs)
|
|
||||||
{
|
|
||||||
this->copy(rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
PCRE::Match&
|
|
||||||
PCRE::Match::operator=(Match const& rhs)
|
|
||||||
{
|
|
||||||
if (this != &rhs)
|
|
||||||
{
|
|
||||||
this->destroy();
|
|
||||||
this->copy(rhs);
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PCRE::Match::init(int nmatches, int nbackrefs, char const* subject)
|
|
||||||
{
|
|
||||||
this->nmatches = nmatches;
|
|
||||||
this->nbackrefs = nbackrefs;
|
|
||||||
this->subject = subject;
|
|
||||||
this->ovecsize = 3 * (1 + nbackrefs);
|
|
||||||
this->ovector = 0;
|
|
||||||
if (this->ovecsize)
|
|
||||||
{
|
|
||||||
this->ovector = new int[this->ovecsize];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PCRE::Match::copy(Match const& rhs)
|
|
||||||
{
|
|
||||||
this->init(rhs.nmatches, rhs.nbackrefs, rhs.subject);
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < this->ovecsize; ++i)
|
|
||||||
{
|
|
||||||
this->ovector[i] = rhs.ovector[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PCRE::Match::destroy()
|
|
||||||
{
|
|
||||||
delete [] this->ovector;
|
|
||||||
}
|
|
||||||
|
|
||||||
PCRE::Match::operator bool()
|
|
||||||
{
|
|
||||||
return (this->nmatches >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
PCRE::Match::getMatch(int n, int flags)
|
|
||||||
{
|
|
||||||
// This method used to be implemented in terms of
|
|
||||||
// pcre_get_substring, but that function gives you an empty string
|
|
||||||
// for an unmatched backreference that is in range.
|
|
||||||
|
|
||||||
int offset;
|
|
||||||
int length;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
getOffsetLength(n, offset, length);
|
|
||||||
}
|
|
||||||
catch (NoBackref&)
|
|
||||||
{
|
|
||||||
if (flags & gm_no_substring_returns_empty)
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string(this->subject).substr(offset, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PCRE::Match::getOffsetLength(int n, int& offset, int& length)
|
|
||||||
{
|
|
||||||
if ((this->nmatches < 0) ||
|
|
||||||
(n > this->nmatches - 1) ||
|
|
||||||
(this->ovector[n * 2] == -1))
|
|
||||||
{
|
|
||||||
throw NoBackref();
|
|
||||||
}
|
|
||||||
offset = this->ovector[n * 2];
|
|
||||||
length = this->ovector[n * 2 + 1] - offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
PCRE::Match::getOffset(int n)
|
|
||||||
{
|
|
||||||
int offset;
|
|
||||||
int length;
|
|
||||||
this->getOffsetLength(n, offset, length);
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
PCRE::Match::getLength(int n)
|
|
||||||
{
|
|
||||||
int offset;
|
|
||||||
int length;
|
|
||||||
this->getOffsetLength(n, offset, length);
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
PCRE::Match::nMatches() const
|
|
||||||
{
|
|
||||||
return this->nmatches;
|
|
||||||
}
|
|
||||||
|
|
||||||
PCRE::PCRE(char const* pattern, int options)
|
|
||||||
{
|
|
||||||
char const *errptr;
|
|
||||||
int erroffset;
|
|
||||||
this->code = pcre_compile(pattern, options, &errptr, &erroffset, 0);
|
|
||||||
if (this->code)
|
|
||||||
{
|
|
||||||
pcre_fullinfo(this->code, 0, PCRE_INFO_CAPTURECOUNT, &(this->nbackrefs));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::string message = (std::string("compilation of ") + pattern +
|
|
||||||
" failed at offset " +
|
|
||||||
QUtil::int_to_string(erroffset) + ": " +
|
|
||||||
errptr);
|
|
||||||
throw std::runtime_error("PCRE error: " + message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PCRE::~PCRE()
|
|
||||||
{
|
|
||||||
pcre_free(this->code);
|
|
||||||
}
|
|
||||||
|
|
||||||
PCRE::Match
|
|
||||||
PCRE::match(char const* subject, int options, int startoffset, int size)
|
|
||||||
{
|
|
||||||
if (size == -1)
|
|
||||||
{
|
|
||||||
size = strlen(subject);
|
|
||||||
}
|
|
||||||
|
|
||||||
Match result(this->nbackrefs, subject);
|
|
||||||
int status = pcre_exec(this->code, 0, subject, size,
|
|
||||||
startoffset, options,
|
|
||||||
result.ovector, result.ovecsize);
|
|
||||||
if (status >= 0)
|
|
||||||
{
|
|
||||||
result.nmatches = status;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::string message;
|
|
||||||
|
|
||||||
switch (status)
|
|
||||||
{
|
|
||||||
case PCRE_ERROR_NOMATCH:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PCRE_ERROR_BADOPTION:
|
|
||||||
message = "bad option passed to PCRE::match()";
|
|
||||||
throw std::logic_error(message);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PCRE_ERROR_NOMEMORY:
|
|
||||||
message = "insufficient memory";
|
|
||||||
throw std::runtime_error(message);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PCRE_ERROR_NULL:
|
|
||||||
case PCRE_ERROR_BADMAGIC:
|
|
||||||
case PCRE_ERROR_UNKNOWN_NODE:
|
|
||||||
default:
|
|
||||||
message = "pcre_exec returned " + QUtil::int_to_string(status);
|
|
||||||
throw std::logic_error(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PCRE::test(int n)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (n == 1)
|
|
||||||
{
|
|
||||||
static char const* utf8 = "abπdefq";
|
|
||||||
PCRE u1("^([[:alpha:]]+)");
|
|
||||||
PCRE u2("^([\\p{L}]+)", PCRE_UTF8);
|
|
||||||
PCRE::Match m1 = u1.match(utf8);
|
|
||||||
if (m1)
|
|
||||||
{
|
|
||||||
std::cout << "no utf8: " << m1.getMatch(1) << std::endl;
|
|
||||||
}
|
|
||||||
PCRE::Match m2 = u2.match(utf8);
|
|
||||||
if (m2)
|
|
||||||
{
|
|
||||||
std::cout << "utf8: " << m2.getMatch(1) << std::endl;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
PCRE pcre1("a**");
|
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
|
||||||
{
|
|
||||||
std::cout << e.what() << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
PCRE pcre2("^([^\\s:]*)\\s*:\\s*(.*?)\\s*$");
|
|
||||||
PCRE::Match m2 = pcre2.match("key: value one two three ");
|
|
||||||
if (m2)
|
|
||||||
{
|
|
||||||
std::cout << m2.nMatches() << std::endl;
|
|
||||||
std::cout << m2.getMatch(0) << std::endl;
|
|
||||||
std::cout << m2.getOffset(0) << std::endl;
|
|
||||||
std::cout << m2.getLength(0) << std::endl;
|
|
||||||
std::cout << m2.getMatch(1) << std::endl;
|
|
||||||
std::cout << m2.getOffset(1) << std::endl;
|
|
||||||
std::cout << m2.getLength(1) << std::endl;
|
|
||||||
std::cout << m2.getMatch(2) << std::endl;
|
|
||||||
std::cout << m2.getOffset(2) << std::endl;
|
|
||||||
std::cout << m2.getLength(2) << std::endl;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
std::cout << m2.getMatch(3) << std::endl;
|
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
|
||||||
{
|
|
||||||
std::cout << e.what() << std::endl;
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
std::cout << m2.getOffset(3) << std::endl;
|
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
|
||||||
{
|
|
||||||
std::cout << e.what() << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PCRE pcre3("^(a+)(b+)?$");
|
|
||||||
PCRE::Match m3 = pcre3.match("aaa");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (m3)
|
|
||||||
{
|
|
||||||
std::cout << m3.nMatches() << std::endl;
|
|
||||||
std::cout << m3.getMatch(0) << std::endl;
|
|
||||||
std::cout << m3.getMatch(1) << std::endl;
|
|
||||||
std::cout << "-"
|
|
||||||
<< m3.getMatch(
|
|
||||||
2, Match::gm_no_substring_returns_empty)
|
|
||||||
<< "-" << std::endl;
|
|
||||||
std::cout << "hello" << std::endl;
|
|
||||||
std::cout << m3.getMatch(2) << std::endl;
|
|
||||||
std::cout << "can't see this" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
|
||||||
{
|
|
||||||
std::cout << e.what() << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// backref: 1 2 3 4 5
|
|
||||||
PCRE pcre4("^((?:(a(b)?)(?:,(c))?)|(c))?$");
|
|
||||||
static char const* candidates[] = {
|
|
||||||
"qqqcqqq", // no match
|
|
||||||
"ab,c", // backrefs: 0, 1, 2, 3, 4
|
|
||||||
"ab", // backrefs: 0, 1, 2, 3
|
|
||||||
"a", // backrefs: 0, 1, 2
|
|
||||||
"a,c", // backrefs: 0, 1, 2, 4
|
|
||||||
"c", // backrefs: 0, 1, 5
|
|
||||||
"", // backrefs: 0
|
|
||||||
0
|
|
||||||
};
|
|
||||||
for (char const** p = candidates; *p; ++p)
|
|
||||||
{
|
|
||||||
PCRE::Match m(pcre4.match(*p));
|
|
||||||
if (m)
|
|
||||||
{
|
|
||||||
int nmatches = m.nMatches();
|
|
||||||
for (int i = 0; i < nmatches; ++i)
|
|
||||||
{
|
|
||||||
std::cout << *p << ": " << i << ": ";
|
|
||||||
try
|
|
||||||
{
|
|
||||||
std::string match = m.getMatch(i);
|
|
||||||
std::cout << match;
|
|
||||||
}
|
|
||||||
catch (NoBackref&)
|
|
||||||
{
|
|
||||||
std::cout << "no backref (getMatch)";
|
|
||||||
}
|
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
std::cout << *p << ": " << i << ": ";
|
|
||||||
try
|
|
||||||
{
|
|
||||||
int offset;
|
|
||||||
int length;
|
|
||||||
m.getOffsetLength(i, offset, length);
|
|
||||||
std::cout << offset << ", " << length;
|
|
||||||
}
|
|
||||||
catch (NoBackref&)
|
|
||||||
{
|
|
||||||
std::cout << "no backref (getOffsetLength)";
|
|
||||||
}
|
|
||||||
std:: cout << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << *p << ": no match" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
|
||||||
{
|
|
||||||
std::cout << "unexpected exception: " << e.what() << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
@ -14,7 +14,6 @@ SRCS_libqpdf = \
|
|||||||
libqpdf/InsecureRandomDataProvider.cc \
|
libqpdf/InsecureRandomDataProvider.cc \
|
||||||
libqpdf/MD5.cc \
|
libqpdf/MD5.cc \
|
||||||
libqpdf/OffsetInputSource.cc \
|
libqpdf/OffsetInputSource.cc \
|
||||||
libqpdf/PCRE.cc \
|
|
||||||
libqpdf/Pipeline.cc \
|
libqpdf/Pipeline.cc \
|
||||||
libqpdf/Pl_AES_PDF.cc \
|
libqpdf/Pl_AES_PDF.cc \
|
||||||
libqpdf/Pl_ASCII85Decoder.cc \
|
libqpdf/Pl_ASCII85Decoder.cc \
|
||||||
|
@ -1,117 +0,0 @@
|
|||||||
// This is a C++ wrapper class around Philip Hazel's perl-compatible
|
|
||||||
// regular expressions library.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef __PCRE_HH__
|
|
||||||
#define __PCRE_HH__
|
|
||||||
|
|
||||||
#include <qpdf/DLL.h>
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
# define PCRE_STATIC
|
|
||||||
#endif
|
|
||||||
#include <pcre.h>
|
|
||||||
#include <string>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
// Note: this class does not encapsulate all features of the PCRE
|
|
||||||
// package -- only those that I actually need right now are here.
|
|
||||||
|
|
||||||
class PCRE
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// This is thrown when an attempt is made to access a non-existent
|
|
||||||
// back reference.
|
|
||||||
class NoBackref: public std::logic_error
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QPDF_DLL
|
|
||||||
NoBackref();
|
|
||||||
virtual ~NoBackref() throw() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Match
|
|
||||||
{
|
|
||||||
friend class PCRE;
|
|
||||||
public:
|
|
||||||
QPDF_DLL
|
|
||||||
Match(int nbackrefs, char const* subject);
|
|
||||||
QPDF_DLL
|
|
||||||
Match(Match const&);
|
|
||||||
QPDF_DLL
|
|
||||||
Match& operator=(Match const&);
|
|
||||||
QPDF_DLL
|
|
||||||
~Match();
|
|
||||||
QPDF_DLL
|
|
||||||
operator bool();
|
|
||||||
|
|
||||||
// All the back reference accessing routines may throw the
|
|
||||||
// special exception NoBackref (derived from Exception) if the
|
|
||||||
// back reference does not exist. Exception will be thrown
|
|
||||||
// for other error conditions. This allows callers to trap
|
|
||||||
// this condition explicitly when they care about the
|
|
||||||
// difference between a backreference matching an empty string
|
|
||||||
// and not matching at all.
|
|
||||||
|
|
||||||
// see getMatch flags below
|
|
||||||
QPDF_DLL
|
|
||||||
std::string getMatch(int n, int flags = 0);
|
|
||||||
QPDF_DLL
|
|
||||||
void getOffsetLength(int n, int& offset, int& length);
|
|
||||||
QPDF_DLL
|
|
||||||
int getOffset(int n);
|
|
||||||
QPDF_DLL
|
|
||||||
int getLength(int n);
|
|
||||||
|
|
||||||
// nMatches returns the number of available matches including
|
|
||||||
// match 0 which is the whole string. In other words, if you
|
|
||||||
// have one backreference in your expression and the
|
|
||||||
// expression matches, nMatches() will return 2, getMatch(0)
|
|
||||||
// will return the whole string, getMatch(1) will return the
|
|
||||||
// text that matched the backreference, and getMatch(2) will
|
|
||||||
// throw an exception because it is out of range.
|
|
||||||
QPDF_DLL
|
|
||||||
int nMatches() const;
|
|
||||||
|
|
||||||
// Flags for getMatch
|
|
||||||
|
|
||||||
// getMatch on a substring that didn't match should return
|
|
||||||
// empty string instead of throwing an exception
|
|
||||||
static int const gm_no_substring_returns_empty = (1 << 0);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void init(int nmatches, int nbackrefs, char const* subject);
|
|
||||||
void copy(Match const&);
|
|
||||||
void destroy();
|
|
||||||
|
|
||||||
int nbackrefs;
|
|
||||||
char const* subject;
|
|
||||||
int* ovector;
|
|
||||||
int ovecsize;
|
|
||||||
int nmatches;
|
|
||||||
};
|
|
||||||
|
|
||||||
// The value passed in as options is passed to pcre_exec. See man
|
|
||||||
// pcreapi for details.
|
|
||||||
QPDF_DLL
|
|
||||||
PCRE(char const* pattern, int options = 0);
|
|
||||||
QPDF_DLL
|
|
||||||
~PCRE();
|
|
||||||
|
|
||||||
QPDF_DLL
|
|
||||||
Match match(char const* subject, int options = 0, int startoffset = 0,
|
|
||||||
int size = -1);
|
|
||||||
|
|
||||||
QPDF_DLL
|
|
||||||
static void test(int n = 0);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// prohibit copying and assignment
|
|
||||||
PCRE(PCRE const&);
|
|
||||||
PCRE& operator=(PCRE const&);
|
|
||||||
|
|
||||||
pcre* code;
|
|
||||||
int nbackrefs;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // __PCRE_HH__
|
|
@ -9,7 +9,6 @@ BINS_libtests = \
|
|||||||
input_source \
|
input_source \
|
||||||
lzw \
|
lzw \
|
||||||
md5 \
|
md5 \
|
||||||
pcre \
|
|
||||||
png_filter \
|
png_filter \
|
||||||
pointer_holder \
|
pointer_holder \
|
||||||
qutil \
|
qutil \
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
#include <qpdf/PCRE.hh>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
|
||||||
{
|
|
||||||
if ((argc == 2) && (strcmp(argv[1], "--unicode-classes-supported") == 0))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
PCRE("^([\\p{L}]+)", PCRE_UTF8);
|
|
||||||
std::cout << "1" << std::endl;
|
|
||||||
}
|
|
||||||
catch (std::exception&)
|
|
||||||
{
|
|
||||||
std::cout << "0" << std::endl;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((argc == 2) && (strcmp(argv[1], "--unicode-classes") == 0))
|
|
||||||
{
|
|
||||||
PCRE::test(1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PCRE::test();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
#!/usr/bin/env perl
|
|
||||||
require 5.008;
|
|
||||||
BEGIN { $^W = 1; }
|
|
||||||
use strict;
|
|
||||||
|
|
||||||
chdir("pcre") or die "chdir testdir failed: $!\n";
|
|
||||||
|
|
||||||
require TestDriver;
|
|
||||||
|
|
||||||
my $td = new TestDriver('pcre');
|
|
||||||
|
|
||||||
$td->runtest("PCRE",
|
|
||||||
{$td->COMMAND => "pcre"},
|
|
||||||
{$td->FILE => "pcre.out",
|
|
||||||
$td->EXIT_STATUS => 0},
|
|
||||||
$td->NORMALIZE_NEWLINES);
|
|
||||||
|
|
||||||
chop(my $supported = `pcre --unicode-classes-supported`);
|
|
||||||
if ($supported =~ m/^1/)
|
|
||||||
{
|
|
||||||
my $xflags = 0;
|
|
||||||
if (`pcre --unicode-classes | wc -l` == 1)
|
|
||||||
{
|
|
||||||
# On Red Hat Enterprise Linux 5, the version of pcre provided
|
|
||||||
# by default claims to support unicode character classes, but
|
|
||||||
# they don't actually work. Since qpdf doesn't use this
|
|
||||||
# functionality, we won't care if this particular test case
|
|
||||||
# fails. If someone were to make general use of this wrapper,
|
|
||||||
# this test should be re-enabled, but on the other hand, they
|
|
||||||
# could just use the C++ interface that's been added to pcre
|
|
||||||
# since this code was written.
|
|
||||||
$xflags |= $td->EXPECT_FAILURE;
|
|
||||||
}
|
|
||||||
$td->runtest("unicode character classes",
|
|
||||||
{$td->COMMAND => "pcre --unicode-classes"},
|
|
||||||
{$td->FILE => "pcre-unicode-classes.out",
|
|
||||||
$td->EXIT_STATUS => 0},
|
|
||||||
$td->NORMALIZE_NEWLINES | $xflags);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$td->runtest("unicode classes are not supported",
|
|
||||||
{$td->STRING => "1"},
|
|
||||||
{$td->STRING => "1"});
|
|
||||||
}
|
|
||||||
|
|
||||||
$td->report(2);
|
|
@ -1,2 +0,0 @@
|
|||||||
no utf8: ab
|
|
||||||
utf8: abπdefq
|
|
@ -1,68 +0,0 @@
|
|||||||
PCRE error: compilation of a** failed at offset 2: nothing to repeat
|
|
||||||
3
|
|
||||||
key: value one two three
|
|
||||||
0
|
|
||||||
25
|
|
||||||
key
|
|
||||||
0
|
|
||||||
3
|
|
||||||
value one two three
|
|
||||||
5
|
|
||||||
19
|
|
||||||
PCRE error: no match
|
|
||||||
PCRE error: no match
|
|
||||||
2
|
|
||||||
aaa
|
|
||||||
aaa
|
|
||||||
--
|
|
||||||
hello
|
|
||||||
PCRE error: no match
|
|
||||||
qqqcqqq: no match
|
|
||||||
ab,c: 0: ab,c
|
|
||||||
ab,c: 0: 0, 4
|
|
||||||
ab,c: 1: ab,c
|
|
||||||
ab,c: 1: 0, 4
|
|
||||||
ab,c: 2: ab
|
|
||||||
ab,c: 2: 0, 2
|
|
||||||
ab,c: 3: b
|
|
||||||
ab,c: 3: 1, 1
|
|
||||||
ab,c: 4: c
|
|
||||||
ab,c: 4: 3, 1
|
|
||||||
ab: 0: ab
|
|
||||||
ab: 0: 0, 2
|
|
||||||
ab: 1: ab
|
|
||||||
ab: 1: 0, 2
|
|
||||||
ab: 2: ab
|
|
||||||
ab: 2: 0, 2
|
|
||||||
ab: 3: b
|
|
||||||
ab: 3: 1, 1
|
|
||||||
a: 0: a
|
|
||||||
a: 0: 0, 1
|
|
||||||
a: 1: a
|
|
||||||
a: 1: 0, 1
|
|
||||||
a: 2: a
|
|
||||||
a: 2: 0, 1
|
|
||||||
a,c: 0: a,c
|
|
||||||
a,c: 0: 0, 3
|
|
||||||
a,c: 1: a,c
|
|
||||||
a,c: 1: 0, 3
|
|
||||||
a,c: 2: a
|
|
||||||
a,c: 2: 0, 1
|
|
||||||
a,c: 3: no backref (getMatch)
|
|
||||||
a,c: 3: no backref (getOffsetLength)
|
|
||||||
a,c: 4: c
|
|
||||||
a,c: 4: 2, 1
|
|
||||||
c: 0: c
|
|
||||||
c: 0: 0, 1
|
|
||||||
c: 1: c
|
|
||||||
c: 1: 0, 1
|
|
||||||
c: 2: no backref (getMatch)
|
|
||||||
c: 2: no backref (getOffsetLength)
|
|
||||||
c: 3: no backref (getMatch)
|
|
||||||
c: 3: no backref (getOffsetLength)
|
|
||||||
c: 4: no backref (getMatch)
|
|
||||||
c: 4: no backref (getOffsetLength)
|
|
||||||
c: 5: c
|
|
||||||
c: 5: 0, 1
|
|
||||||
: 0:
|
|
||||||
: 0: 0, 0
|
|
@ -93,7 +93,7 @@
|
|||||||
<sect1 id="ref.prerequisites">
|
<sect1 id="ref.prerequisites">
|
||||||
<title>System Requirements</title>
|
<title>System Requirements</title>
|
||||||
<para>
|
<para>
|
||||||
The qpdf package has relatively few external dependencies. In
|
The qpdf package has only one external dependencies. In
|
||||||
order to build qpdf, the following packages are required:
|
order to build qpdf, the following packages are required:
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -101,11 +101,6 @@
|
|||||||
zlib: <ulink url="http://www.zlib.net/">http://www.zlib.net/</ulink>
|
zlib: <ulink url="http://www.zlib.net/">http://www.zlib.net/</ulink>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
pcre: <ulink url="http://www.pcre.org/">http://www.pcre.org/</ulink>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
gnu make 3.81 or newer: <ulink url="http://www.gnu.org/software/make">http://www.gnu.org/software/make</ulink>
|
gnu make 3.81 or newer: <ulink url="http://www.gnu.org/software/make">http://www.gnu.org/software/make</ulink>
|
||||||
@ -1466,7 +1461,7 @@ outfile.pdf</option>
|
|||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
When linking against the qpdf static library, you may also need to
|
When linking against the qpdf static library, you may also need to
|
||||||
specify <literal>-lpcre -lz</literal> on your link command. If
|
specify <literal>-lz</literal> on your link command. If
|
||||||
your system understands how to read libtool
|
your system understands how to read libtool
|
||||||
<filename>.la</filename> files, this may not be necessary.
|
<filename>.la</filename> files, this may not be necessary.
|
||||||
</para>
|
</para>
|
||||||
|
Loading…
Reference in New Issue
Block a user