New upstream version 2.47
This commit is contained in:
parent
062d493759
commit
72ebc9cbe9
10
Changes
10
Changes
|
@ -1,5 +1,15 @@
|
||||||
Revision history for Perl extension XML::Parser.
|
Revision history for Perl extension XML::Parser.
|
||||||
|
|
||||||
|
2.47 2023-12-28 (by Todd Rinaldo)
|
||||||
|
- #84 use $fh instead of $foo
|
||||||
|
- #85 Fix typo in documentation
|
||||||
|
- #89 Devel::CheckLib to from 0.99 -> 1.14
|
||||||
|
- Devel::CheckLibn 1.16
|
||||||
|
- #91 POD fix for verbatim text
|
||||||
|
- #97 Add a LICENSE file
|
||||||
|
- #94 Don't ship Expat/Makefile
|
||||||
|
- Various github workflow improvements. Windows is still not working.
|
||||||
|
|
||||||
2.46 2019-09-24 (by Todd Rinaldo)
|
2.46 2019-09-24 (by Todd Rinaldo)
|
||||||
- use foreach not for for loops
|
- use foreach not for for loops
|
||||||
- produce README.md so travis will show up on github
|
- produce README.md so travis will show up on github
|
||||||
|
|
|
@ -7,7 +7,7 @@ use strict;
|
||||||
use XSLoader;
|
use XSLoader;
|
||||||
use Carp;
|
use Carp;
|
||||||
|
|
||||||
our $VERSION = '2.46';
|
our $VERSION = '2.47';
|
||||||
|
|
||||||
our ( %Encoding_Table, @Encoding_Path, $have_File_Spec );
|
our ( %Encoding_Table, @Encoding_Path, $have_File_Spec );
|
||||||
|
|
||||||
|
@ -1147,7 +1147,7 @@ The element declaration handlers are passed objects of this class as the
|
||||||
content model of the element declaration. They also represent content
|
content model of the element declaration. They also represent content
|
||||||
particles, components of a content model.
|
particles, components of a content model.
|
||||||
|
|
||||||
When referred to as a string, these objects are automagicly converted to a
|
When referred to as a string, these objects are automagically converted to a
|
||||||
string representation of the model (or content particle).
|
string representation of the model (or content particle).
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
|
|
|
@ -0,0 +1,202 @@
|
||||||
|
The Artistic License 2.0
|
||||||
|
|
||||||
|
Copyright (c) 1998-2000 Larry Wall and Clark Cooper
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
This license establishes the terms under which a given free software
|
||||||
|
Package may be copied, modified, distributed, and/or redistributed.
|
||||||
|
The intent is that the Copyright Holder maintains some artistic
|
||||||
|
control over the development of that Package while still keeping the
|
||||||
|
Package available as open source and free software.
|
||||||
|
|
||||||
|
You are always permitted to make arrangements wholly outside of this
|
||||||
|
license directly with the Copyright Holder of a given Package. If the
|
||||||
|
terms of this license do not permit the full use that you propose to
|
||||||
|
make of the Package, you should contact the Copyright Holder and seek
|
||||||
|
a different licensing arrangement.
|
||||||
|
|
||||||
|
Definitions
|
||||||
|
|
||||||
|
"Copyright Holder" means the individual(s) or organization(s)
|
||||||
|
named in the copyright notice for the entire Package.
|
||||||
|
|
||||||
|
"Contributor" means any party that has contributed code or other
|
||||||
|
material to the Package, in accordance with the Copyright Holder's
|
||||||
|
procedures.
|
||||||
|
|
||||||
|
"You" and "your" means any person who would like to copy,
|
||||||
|
distribute, or modify the Package.
|
||||||
|
|
||||||
|
"Package" means the collection of files distributed by the
|
||||||
|
Copyright Holder, and derivatives of that collection and/or of
|
||||||
|
those files. A given Package may consist of either the Standard
|
||||||
|
Version, or a Modified Version.
|
||||||
|
|
||||||
|
"Distribute" means providing a copy of the Package or making it
|
||||||
|
accessible to anyone else, or in the case of a company or
|
||||||
|
organization, to others outside of your company or organization.
|
||||||
|
|
||||||
|
"Distributor Fee" means any fee that you charge for Distributing
|
||||||
|
this Package or providing support for this Package to another
|
||||||
|
party. It does not mean licensing fees.
|
||||||
|
|
||||||
|
"Standard Version" refers to the Package if it has not been
|
||||||
|
modified, or has been modified only in ways explicitly requested
|
||||||
|
by the Copyright Holder.
|
||||||
|
|
||||||
|
"Modified Version" means the Package, if it has been changed, and
|
||||||
|
such changes were not explicitly requested by the Copyright
|
||||||
|
Holder.
|
||||||
|
|
||||||
|
"Original License" means this Artistic License as Distributed with
|
||||||
|
the Standard Version of the Package, in its current version or as
|
||||||
|
it may be modified by The Perl Foundation in the future.
|
||||||
|
|
||||||
|
"Source" form means the source code, documentation source, and
|
||||||
|
configuration files for the Package.
|
||||||
|
|
||||||
|
"Compiled" form means the compiled bytecode, object code, binary,
|
||||||
|
or any other form resulting from mechanical transformation or
|
||||||
|
translation of the Source form.
|
||||||
|
|
||||||
|
|
||||||
|
Permission for Use and Modification Without Distribution
|
||||||
|
|
||||||
|
(1) You are permitted to use the Standard Version and create and use
|
||||||
|
Modified Versions for any purpose without restriction, provided that
|
||||||
|
you do not Distribute the Modified Version.
|
||||||
|
|
||||||
|
|
||||||
|
Permissions for Redistribution of the Standard Version
|
||||||
|
|
||||||
|
(2) You may Distribute verbatim copies of the Source form of the
|
||||||
|
Standard Version of this Package in any medium without restriction,
|
||||||
|
either gratis or for a Distributor Fee, provided that you duplicate
|
||||||
|
all of the original copyright notices and associated disclaimers. At
|
||||||
|
your discretion, such verbatim copies may or may not include a
|
||||||
|
Compiled form of the Package.
|
||||||
|
|
||||||
|
(3) You may apply any bug fixes, portability changes, and other
|
||||||
|
modifications made available from the Copyright Holder. The resulting
|
||||||
|
Package will still be considered the Standard Version, and as such
|
||||||
|
will be subject to the Original License.
|
||||||
|
|
||||||
|
|
||||||
|
Distribution of Modified Versions of the Package as Source
|
||||||
|
|
||||||
|
(4) You may Distribute your Modified Version as Source (either gratis
|
||||||
|
or for a Distributor Fee, and with or without a Compiled form of the
|
||||||
|
Modified Version) provided that you clearly document how it differs
|
||||||
|
from the Standard Version, including, but not limited to, documenting
|
||||||
|
any non-standard features, executables, or modules, and provided that
|
||||||
|
you do at least ONE of the following:
|
||||||
|
|
||||||
|
(a) make the Modified Version available to the Copyright Holder
|
||||||
|
of the Standard Version, under the Original License, so that the
|
||||||
|
Copyright Holder may include your modifications in the Standard
|
||||||
|
Version.
|
||||||
|
|
||||||
|
(b) ensure that installation of your Modified Version does not
|
||||||
|
prevent the user installing or running the Standard Version. In
|
||||||
|
addition, the Modified Version must bear a name that is different
|
||||||
|
from the name of the Standard Version.
|
||||||
|
|
||||||
|
(c) allow anyone who receives a copy of the Modified Version to
|
||||||
|
make the Source form of the Modified Version available to others
|
||||||
|
under
|
||||||
|
|
||||||
|
(i) the Original License or
|
||||||
|
|
||||||
|
(ii) a license that permits the licensee to freely copy,
|
||||||
|
modify and redistribute the Modified Version using the same
|
||||||
|
licensing terms that apply to the copy that the licensee
|
||||||
|
received, and requires that the Source form of the Modified
|
||||||
|
Version, and of any works derived from it, be made freely
|
||||||
|
available in that license fees are prohibited but Distributor
|
||||||
|
Fees are allowed.
|
||||||
|
|
||||||
|
|
||||||
|
Distribution of Compiled Forms of the Standard Version
|
||||||
|
or Modified Versions without the Source
|
||||||
|
|
||||||
|
(5) You may Distribute Compiled forms of the Standard Version without
|
||||||
|
the Source, provided that you include complete instructions on how to
|
||||||
|
get the Source of the Standard Version. Such instructions must be
|
||||||
|
valid at the time of your distribution. If these instructions, at any
|
||||||
|
time while you are carrying out such distribution, become invalid, you
|
||||||
|
must provide new instructions on demand or cease further distribution.
|
||||||
|
If you provide valid instructions or cease distribution within thirty
|
||||||
|
days after you become aware that the instructions are invalid, then
|
||||||
|
you do not forfeit any of your rights under this license.
|
||||||
|
|
||||||
|
(6) You may Distribute a Modified Version in Compiled form without
|
||||||
|
the Source, provided that you comply with Section 4 with respect to
|
||||||
|
the Source of the Modified Version.
|
||||||
|
|
||||||
|
|
||||||
|
Aggregating or Linking the Package
|
||||||
|
|
||||||
|
(7) You may aggregate the Package (either the Standard Version or
|
||||||
|
Modified Version) with other packages and Distribute the resulting
|
||||||
|
aggregation provided that you do not charge a licensing fee for the
|
||||||
|
Package. Distributor Fees are permitted, and licensing fees for other
|
||||||
|
components in the aggregation are permitted. The terms of this license
|
||||||
|
apply to the use and Distribution of the Standard or Modified Versions
|
||||||
|
as included in the aggregation.
|
||||||
|
|
||||||
|
(8) You are permitted to link Modified and Standard Versions with
|
||||||
|
other works, to embed the Package in a larger work of your own, or to
|
||||||
|
build stand-alone binary or bytecode versions of applications that
|
||||||
|
include the Package, and Distribute the result without restriction,
|
||||||
|
provided the result does not expose a direct interface to the Package.
|
||||||
|
|
||||||
|
|
||||||
|
Items That are Not Considered Part of a Modified Version
|
||||||
|
|
||||||
|
(9) Works (including, but not limited to, modules and scripts) that
|
||||||
|
merely extend or make use of the Package, do not, by themselves, cause
|
||||||
|
the Package to be a Modified Version. In addition, such works are not
|
||||||
|
considered parts of the Package itself, and are not subject to the
|
||||||
|
terms of this license.
|
||||||
|
|
||||||
|
|
||||||
|
General Provisions
|
||||||
|
|
||||||
|
(10) Any use, modification, and distribution of the Standard or
|
||||||
|
Modified Versions is governed by this Artistic License. By using,
|
||||||
|
modifying or distributing the Package, you accept this license. Do not
|
||||||
|
use, modify, or distribute the Package, if you do not accept this
|
||||||
|
license.
|
||||||
|
|
||||||
|
(11) If your Modified Version has been derived from a Modified
|
||||||
|
Version made by someone other than you, you are nevertheless required
|
||||||
|
to ensure that your Modified Version complies with the requirements of
|
||||||
|
this license.
|
||||||
|
|
||||||
|
(12) This license does not grant you the right to use any trademark,
|
||||||
|
service mark, tradename, or logo of the Copyright Holder.
|
||||||
|
|
||||||
|
(13) This license includes the non-exclusive, worldwide,
|
||||||
|
free-of-charge patent license to make, have made, use, offer to sell,
|
||||||
|
sell, import and otherwise transfer the Package with respect to any
|
||||||
|
patent claims licensable by the Copyright Holder that are necessarily
|
||||||
|
infringed by the Package. If you institute patent litigation
|
||||||
|
(including a cross-claim or counterclaim) against any party alleging
|
||||||
|
that the Package constitutes direct or contributory patent
|
||||||
|
infringement, then this Artistic License to you shall terminate on the
|
||||||
|
date that such litigation is filed.
|
||||||
|
|
||||||
|
(14) Disclaimer of Warranty:
|
||||||
|
THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
|
||||||
|
IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
||||||
|
NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL
|
||||||
|
LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL
|
||||||
|
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
129
MANIFEST
129
MANIFEST
|
@ -1,68 +1,71 @@
|
||||||
|
Changes Change log
|
||||||
|
Expat/encoding.h Header file; describes *.enc structure
|
||||||
|
Expat/Expat.pm XML::Parser::Expat module
|
||||||
|
Expat/Expat.xs Extension library
|
||||||
|
Expat/Makefile.PL perl MakeMaker script for XML::Parser::Expat
|
||||||
|
Expat/typemap XS typemap
|
||||||
inc/Devel/CheckLib.pm
|
inc/Devel/CheckLib.pm
|
||||||
Changes Change log
|
LICENSE
|
||||||
Expat/Expat.pm XML::Parser::Expat module
|
Makefile.PL perl MakeMaker script for XML::Parser
|
||||||
Expat/Expat.xs Extension library
|
MANIFEST This file
|
||||||
Expat/Makefile.PL perl MakeMaker script for XML::Parser::Expat
|
MANIFEST.SKIP
|
||||||
Expat/encoding.h Header file; describes *.enc structure
|
Parser.pm XML::Parser module
|
||||||
Expat/typemap XS typemap
|
Parser/Encodings/big5.enc Big5 binary encoding map
|
||||||
MANIFEST This file
|
Parser/Encodings/euc-kr.enc EUC-KR binary encoding map
|
||||||
Makefile.PL perl MakeMaker script for XML::Parser
|
|
||||||
Parser.pm XML::Parser module
|
|
||||||
Parser/LWPExternEnt.pl LWP based external entity handler
|
|
||||||
Parser/Encodings/Japanese_Encodings.msg Message about Japanese encodings.
|
|
||||||
Parser/Encodings/README Info about encoding maps
|
|
||||||
Parser/Encodings/big5.enc Big5 binary encoding map
|
|
||||||
Parser/Encodings/euc-kr.enc EUC-KR binary encoding map
|
|
||||||
Parser/Encodings/iso-8859-2.enc ISO-8859-2 binary encoding map
|
|
||||||
Parser/Encodings/iso-8859-3.enc ISO-8859-3 binary encoding map
|
|
||||||
Parser/Encodings/iso-8859-4.enc ISO-8859-4 binary encoding map
|
|
||||||
Parser/Encodings/iso-8859-5.enc ISO-8859-5 binary encoding map
|
|
||||||
Parser/Encodings/iso-8859-7.enc ISO-8859-7 binary encoding map
|
|
||||||
Parser/Encodings/iso-8859-8.enc ISO-8859-8 binary encoding map
|
|
||||||
Parser/Encodings/iso-8859-9.enc ISO-8859-9 binary encoding map
|
|
||||||
Parser/Encodings/iso-8859-15.enc ISO-8859-15 binary encoding map
|
|
||||||
Parser/Encodings/windows-1250.enc cp1250-WinLatin2 binary encoding map
|
|
||||||
Parser/Encodings/windows-1251.enc cp1251-Russian binary encoding map
|
|
||||||
Parser/Encodings/windows-1252.enc cp1252-WinLatin1 binary encoding map
|
|
||||||
Parser/Encodings/windows-1255.enc hebrew
|
|
||||||
Parser/Encodings/x-euc-jp-jisx0221.enc X-euc-jp-jisx0221 encoding map
|
|
||||||
Parser/Encodings/x-euc-jp-unicode.enc X-euc-jp-unicde encoding map
|
|
||||||
Parser/Encodings/x-sjis-cp932.enc x-sjis-cp932 encoding map
|
|
||||||
Parser/Encodings/x-sjis-jdk117.enc x-sjis-jdk117 encoding map
|
|
||||||
Parser/Encodings/x-sjis-jisx0221.enc x-sjis-jisx0221 encoding map
|
|
||||||
Parser/Encodings/x-sjis-unicode.enc x-sjis-unicode encoding map
|
|
||||||
Parser/Encodings/ibm866.enc
|
Parser/Encodings/ibm866.enc
|
||||||
|
Parser/Encodings/iso-8859-15.enc ISO-8859-15 binary encoding map
|
||||||
|
Parser/Encodings/iso-8859-2.enc ISO-8859-2 binary encoding map
|
||||||
|
Parser/Encodings/iso-8859-3.enc ISO-8859-3 binary encoding map
|
||||||
|
Parser/Encodings/iso-8859-4.enc ISO-8859-4 binary encoding map
|
||||||
|
Parser/Encodings/iso-8859-5.enc ISO-8859-5 binary encoding map
|
||||||
|
Parser/Encodings/iso-8859-7.enc ISO-8859-7 binary encoding map
|
||||||
|
Parser/Encodings/iso-8859-8.enc ISO-8859-8 binary encoding map
|
||||||
|
Parser/Encodings/iso-8859-9.enc ISO-8859-9 binary encoding map
|
||||||
|
Parser/Encodings/Japanese_Encodings.msg Message about Japanese encodings.
|
||||||
Parser/Encodings/koi8-r.enc
|
Parser/Encodings/koi8-r.enc
|
||||||
Parser/Style/Debug.pm Debug style parser
|
Parser/Encodings/README Info about encoding maps
|
||||||
Parser/Style/Objects.pm Objects style parser
|
Parser/Encodings/windows-1250.enc cp1250-WinLatin2 binary encoding map
|
||||||
Parser/Style/Stream.pm Stream style parser
|
Parser/Encodings/windows-1251.enc cp1251-Russian binary encoding map
|
||||||
Parser/Style/Subs.pm Subs style parser
|
Parser/Encodings/windows-1252.enc cp1252-WinLatin1 binary encoding map
|
||||||
Parser/Style/Tree.pm Tree style parser
|
Parser/Encodings/windows-1255.enc hebrew
|
||||||
README Short explanation
|
Parser/Encodings/x-euc-jp-jisx0221.enc X-euc-jp-jisx0221 encoding map
|
||||||
samples/canonical A utility to generate canonical XML
|
Parser/Encodings/x-euc-jp-unicode.enc X-euc-jp-unicde encoding map
|
||||||
samples/canontst.xml An xml document to demonstrate canonical
|
Parser/Encodings/x-sjis-cp932.enc x-sjis-cp932 encoding map
|
||||||
samples/ctest.dtd An external DTD used by canontst.xml
|
Parser/Encodings/x-sjis-jdk117.enc x-sjis-jdk117 encoding map
|
||||||
samples/REC-xml-19980210.xml The XML spec in xml form
|
Parser/Encodings/x-sjis-jisx0221.enc x-sjis-jisx0221 encoding map
|
||||||
samples/xmlcomments A utility to extract comments
|
Parser/Encodings/x-sjis-unicode.enc x-sjis-unicode encoding map
|
||||||
samples/xmlfilter A utility to filter elements
|
Parser/LWPExternEnt.pl LWP based external entity handler
|
||||||
samples/xmlstats A utility to report on element statistics
|
Parser/Style/Debug.pm Debug style parser
|
||||||
t/astress.t Test script
|
Parser/Style/Objects.pm Objects style parser
|
||||||
t/cdata.t Test script
|
Parser/Style/Stream.pm Stream style parser
|
||||||
t/decl.t Test script
|
Parser/Style/Subs.pm Subs style parser
|
||||||
t/defaulted.t Test script
|
Parser/Style/Tree.pm Tree style parser
|
||||||
t/encoding.t Test script
|
README Short explanation
|
||||||
t/external_ent.t Test script
|
README.md
|
||||||
t/file.t Test script
|
samples/canonical A utility to generate canonical XML
|
||||||
t/file_open_scalar.t Test script
|
samples/canontst.xml An xml document to demonstrate canonical
|
||||||
t/finish.t Test script
|
samples/ctest.dtd An external DTD used by canontst.xml
|
||||||
t/ext.ent External entity for parament.t test
|
samples/REC-xml-19980210.xml The XML spec in xml form
|
||||||
t/ext2.ent External entity for parament.t test
|
samples/xmlcomments A utility to extract comments
|
||||||
t/foo.dtd External DTD for parament.t test
|
samples/xmlfilter A utility to filter elements
|
||||||
t/namespaces.t Test script
|
samples/xmlstats A utility to report on element statistics
|
||||||
t/parament.t Test script
|
t/astress.t Test script
|
||||||
t/partial.t Test script
|
t/cdata.t Test script
|
||||||
t/skip.t Test script
|
t/decl.t Test script
|
||||||
t/stream.t Test script
|
t/defaulted.t Test script
|
||||||
t/styles.t Test script
|
t/encoding.t Test script
|
||||||
|
t/ext.ent External entity for parament.t test
|
||||||
|
t/ext2.ent External entity for parament.t test
|
||||||
|
t/external_ent.t Test script
|
||||||
|
t/file.t Test script
|
||||||
|
t/file_open_scalar.t Test script
|
||||||
|
t/finish.t Test script
|
||||||
|
t/foo.dtd External DTD for parament.t test
|
||||||
|
t/namespaces.t Test script
|
||||||
|
t/parament.t Test script
|
||||||
|
t/partial.t Test script
|
||||||
|
t/skip.t Test script
|
||||||
|
t/stream.t Test script
|
||||||
|
t/styles.t Test script
|
||||||
META.yml Module YAML meta-data (added by MakeMaker)
|
META.yml Module YAML meta-data (added by MakeMaker)
|
||||||
META.json Module JSON meta-data (added by MakeMaker)
|
META.json Module JSON meta-data (added by MakeMaker)
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
\.gitignore
|
||||||
|
\.perltidyrc
|
||||||
|
\.travis.yml
|
||||||
|
cpanfile
|
||||||
|
\.git/
|
||||||
|
^MANIFEST.bak
|
||||||
|
^MYMETA
|
||||||
|
/MYMETA
|
||||||
|
^Makefile$
|
||||||
|
\.github/
|
||||||
|
^Expat/Makefile$
|
|
@ -4,7 +4,7 @@
|
||||||
"Clark Cooper (coopercc@netheaven.com)"
|
"Clark Cooper (coopercc@netheaven.com)"
|
||||||
],
|
],
|
||||||
"dynamic_config" : 1,
|
"dynamic_config" : 1,
|
||||||
"generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010",
|
"generated_by" : "ExtUtils::MakeMaker version 7.64, CPAN::Meta::Converter version 2.150010",
|
||||||
"license" : [
|
"license" : [
|
||||||
"perl_5"
|
"perl_5"
|
||||||
],
|
],
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
"runtime" : {
|
"runtime" : {
|
||||||
"requires" : {
|
"requires" : {
|
||||||
"LWP::UserAgent" : "0",
|
"LWP::UserAgent" : "0",
|
||||||
"perl" : "5.00405"
|
"perl" : "5.004050"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"test" : {
|
"test" : {
|
||||||
|
@ -52,6 +52,6 @@
|
||||||
"url" : "http://github.com/toddr/XML-Parser"
|
"url" : "http://github.com/toddr/XML-Parser"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"version" : "2.46",
|
"version" : "2.47",
|
||||||
"x_serialization_backend" : "JSON::PP version 2.97001"
|
"x_serialization_backend" : "JSON::PP version 4.07"
|
||||||
}
|
}
|
||||||
|
|
6
META.yml
6
META.yml
|
@ -9,7 +9,7 @@ build_requires:
|
||||||
configure_requires:
|
configure_requires:
|
||||||
ExtUtils::MakeMaker: '0'
|
ExtUtils::MakeMaker: '0'
|
||||||
dynamic_config: 1
|
dynamic_config: 1
|
||||||
generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010'
|
generated_by: 'ExtUtils::MakeMaker version 7.64, CPAN::Meta::Converter version 2.150010'
|
||||||
license: perl
|
license: perl
|
||||||
meta-spec:
|
meta-spec:
|
||||||
url: http://module-build.sourceforge.net/META-spec-v1.4.html
|
url: http://module-build.sourceforge.net/META-spec-v1.4.html
|
||||||
|
@ -21,9 +21,9 @@ no_index:
|
||||||
- inc
|
- inc
|
||||||
requires:
|
requires:
|
||||||
LWP::UserAgent: '0'
|
LWP::UserAgent: '0'
|
||||||
perl: '5.00405'
|
perl: '5.004050'
|
||||||
resources:
|
resources:
|
||||||
bugtracker: https://github.com/toddr/XML-Parser/issues
|
bugtracker: https://github.com/toddr/XML-Parser/issues
|
||||||
repository: http://github.com/toddr/XML-Parser
|
repository: http://github.com/toddr/XML-Parser
|
||||||
version: '2.46'
|
version: '2.47'
|
||||||
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
|
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
|
||||||
|
|
|
@ -16,7 +16,7 @@ use Carp;
|
||||||
|
|
||||||
BEGIN {
|
BEGIN {
|
||||||
require XML::Parser::Expat;
|
require XML::Parser::Expat;
|
||||||
$VERSION = '2.46';
|
$VERSION = '2.47';
|
||||||
die "Parser.pm and Expat.pm versions don't match"
|
die "Parser.pm and Expat.pm versions don't match"
|
||||||
unless $VERSION eq $XML::Parser::Expat::VERSION;
|
unless $VERSION eq $XML::Parser::Expat::VERSION;
|
||||||
}
|
}
|
||||||
|
@ -346,8 +346,8 @@ XML::Parser - A perl module for parsing XML documents
|
||||||
Default => \&other);
|
Default => \&other);
|
||||||
|
|
||||||
open(my $fh, 'xmlgenerator |');
|
open(my $fh, 'xmlgenerator |');
|
||||||
$p3->parse($foo, ProtocolEncoding => 'ISO-8859-1');
|
$p3->parse($fh, ProtocolEncoding => 'ISO-8859-1');
|
||||||
close($foo);
|
close($fh);
|
||||||
|
|
||||||
$p3->parsefile('junk.xml', ErrorContext => 3);
|
$p3->parsefile('junk.xml', ErrorContext => 3);
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ So for example the result of parsing:
|
||||||
<foo><head id="a">Hello <em>there</em></head><bar>Howdy<ref/></bar>do</foo>
|
<foo><head id="a">Hello <em>there</em></head><bar>Howdy<ref/></bar>do</foo>
|
||||||
|
|
||||||
would be:
|
would be:
|
||||||
|
|
||||||
Tag Content
|
Tag Content
|
||||||
==================================================================
|
==================================================================
|
||||||
[foo, [{}, head, [{id => "a"}, 0, "Hello ", em, [{}, 0, "there"]],
|
[foo, [{}, head, [{id => "a"}, 0, "Hello ", em, [{}, 0, "there"]],
|
||||||
|
|
4
README
4
README
|
@ -21,8 +21,8 @@ SYNOPSIS
|
||||||
Default => \&other);
|
Default => \&other);
|
||||||
|
|
||||||
open(my $fh, 'xmlgenerator |');
|
open(my $fh, 'xmlgenerator |');
|
||||||
$p3->parse($foo, ProtocolEncoding => 'ISO-8859-1');
|
$p3->parse($fh, ProtocolEncoding => 'ISO-8859-1');
|
||||||
close($foo);
|
close($fh);
|
||||||
|
|
||||||
$p3->parsefile('junk.xml', ErrorContext => 3);
|
$p3->parsefile('junk.xml', ErrorContext => 3);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,491 @@
|
||||||
|
[](https://travis-ci.org/toddr/XML-Parser)
|
||||||
|
# NAME
|
||||||
|
|
||||||
|
XML::Parser - A perl module for parsing XML documents
|
||||||
|
|
||||||
|
# SYNOPSIS
|
||||||
|
|
||||||
|
use XML::Parser;
|
||||||
|
|
||||||
|
$p1 = XML::Parser->new(Style => 'Debug');
|
||||||
|
$p1->parsefile('REC-xml-19980210.xml');
|
||||||
|
$p1->parse('<foo id="me">Hello World</foo>');
|
||||||
|
|
||||||
|
# Alternative
|
||||||
|
$p2 = XML::Parser->new(Handlers => {Start => \&handle_start,
|
||||||
|
End => \&handle_end,
|
||||||
|
Char => \&handle_char});
|
||||||
|
$p2->parse($socket);
|
||||||
|
|
||||||
|
# Another alternative
|
||||||
|
$p3 = XML::Parser->new(ErrorContext => 2);
|
||||||
|
|
||||||
|
$p3->setHandlers(Char => \&text,
|
||||||
|
Default => \&other);
|
||||||
|
|
||||||
|
open(my $fh, 'xmlgenerator |');
|
||||||
|
$p3->parse($fh, ProtocolEncoding => 'ISO-8859-1');
|
||||||
|
close($fh);
|
||||||
|
|
||||||
|
$p3->parsefile('junk.xml', ErrorContext => 3);
|
||||||
|
|
||||||
|
# DESCRIPTION
|
||||||
|
|
||||||
|
This module provides ways to parse XML documents. It is built on top of
|
||||||
|
[XML::Parser::Expat](https://metacpan.org/pod/XML::Parser::Expat), which is a lower level interface to James Clark's
|
||||||
|
expat library. Each call to one of the parsing methods creates a new
|
||||||
|
instance of XML::Parser::Expat which is then used to parse the document.
|
||||||
|
Expat options may be provided when the XML::Parser object is created.
|
||||||
|
These options are then passed on to the Expat object on each parse call.
|
||||||
|
They can also be given as extra arguments to the parse methods, in which
|
||||||
|
case they override options given at XML::Parser creation time.
|
||||||
|
|
||||||
|
The behavior of the parser is controlled either by `["STYLES"](#styles)` and/or
|
||||||
|
`["HANDLERS"](#handlers)` options, or by ["setHandlers"](#sethandlers) method. These all provide
|
||||||
|
mechanisms for XML::Parser to set the handlers needed by XML::Parser::Expat.
|
||||||
|
If neither `Style` nor `Handlers` are specified, then parsing just
|
||||||
|
checks the document for being well-formed.
|
||||||
|
|
||||||
|
When underlying handlers get called, they receive as their first parameter
|
||||||
|
the _Expat_ object, not the Parser object.
|
||||||
|
|
||||||
|
# METHODS
|
||||||
|
|
||||||
|
- new
|
||||||
|
|
||||||
|
This is a class method, the constructor for XML::Parser. Options are passed
|
||||||
|
as keyword value pairs. Recognized options are:
|
||||||
|
|
||||||
|
- Style
|
||||||
|
|
||||||
|
This option provides an easy way to create a given style of parser. The
|
||||||
|
built in styles are: ["Debug"](#debug), ["Subs"](#subs), ["Tree"](#tree), ["Objects"](#objects),
|
||||||
|
and ["Stream"](#stream). These are all defined in separate packages under
|
||||||
|
`XML::Parser::Style::*`, and you can find further documentation for
|
||||||
|
each style both below, and in those packages.
|
||||||
|
|
||||||
|
Custom styles can be provided by giving a full package name containing
|
||||||
|
at least one '::'. This package should then have subs defined for each
|
||||||
|
handler it wishes to have installed. See ["STYLES"](#styles) below
|
||||||
|
for a discussion of each built in style.
|
||||||
|
|
||||||
|
- Handlers
|
||||||
|
|
||||||
|
When provided, this option should be an anonymous hash containing as
|
||||||
|
keys the type of handler and as values a sub reference to handle that
|
||||||
|
type of event. All the handlers get passed as their 1st parameter the
|
||||||
|
instance of expat that is parsing the document. Further details on
|
||||||
|
handlers can be found in ["HANDLERS"](#handlers). Any handler set here
|
||||||
|
overrides the corresponding handler set with the Style option.
|
||||||
|
|
||||||
|
- Pkg
|
||||||
|
|
||||||
|
Some styles will refer to subs defined in this package. If not provided,
|
||||||
|
it defaults to the package which called the constructor.
|
||||||
|
|
||||||
|
- ErrorContext
|
||||||
|
|
||||||
|
This is an Expat option. When this option is defined, errors are reported
|
||||||
|
in context. The value should be the number of lines to show on either side
|
||||||
|
of the line in which the error occurred.
|
||||||
|
|
||||||
|
- ProtocolEncoding
|
||||||
|
|
||||||
|
This is an Expat option. This sets the protocol encoding name. It defaults
|
||||||
|
to none. The built-in encodings are: `UTF-8`, `ISO-8859-1`, `UTF-16`, and
|
||||||
|
`US-ASCII`. Other encodings may be used if they have encoding maps in one
|
||||||
|
of the directories in the @Encoding\_Path list. Check ["ENCODINGS"](#encodings) for
|
||||||
|
more information on encoding maps. Setting the protocol encoding overrides
|
||||||
|
any encoding in the XML declaration.
|
||||||
|
|
||||||
|
- Namespaces
|
||||||
|
|
||||||
|
This is an Expat option. If this is set to a true value, then namespace
|
||||||
|
processing is done during the parse. See ["Namespaces" in XML::Parser::Expat](https://metacpan.org/pod/XML::Parser::Expat#Namespaces)
|
||||||
|
for further discussion of namespace processing.
|
||||||
|
|
||||||
|
- NoExpand
|
||||||
|
|
||||||
|
This is an Expat option. Normally, the parser will try to expand references
|
||||||
|
to entities defined in the internal subset. If this option is set to a true
|
||||||
|
value, and a default handler is also set, then the default handler will be
|
||||||
|
called when an entity reference is seen in text. This has no effect if a
|
||||||
|
default handler has not been registered, and it has no effect on the expansion
|
||||||
|
of entity references inside attribute values.
|
||||||
|
|
||||||
|
- Stream\_Delimiter
|
||||||
|
|
||||||
|
This is an Expat option. It takes a string value. When this string is found
|
||||||
|
alone on a line while parsing from a stream, then the parse is ended as if it
|
||||||
|
saw an end of file. The intended use is with a stream of xml documents in a
|
||||||
|
MIME multipart format. The string should not contain a trailing newline.
|
||||||
|
|
||||||
|
- ParseParamEnt
|
||||||
|
|
||||||
|
This is an Expat option. Unless standalone is set to "yes" in the XML
|
||||||
|
declaration, setting this to a true value allows the external DTD to be read,
|
||||||
|
and parameter entities to be parsed and expanded.
|
||||||
|
|
||||||
|
- NoLWP
|
||||||
|
|
||||||
|
This option has no effect if the ExternEnt or ExternEntFin handlers are
|
||||||
|
directly set. Otherwise, if true, it forces the use of a file based external
|
||||||
|
entity handler.
|
||||||
|
|
||||||
|
- Non\_Expat\_Options
|
||||||
|
|
||||||
|
If provided, this should be an anonymous hash whose keys are options that
|
||||||
|
shouldn't be passed to Expat. This should only be of concern to those
|
||||||
|
subclassing XML::Parser.
|
||||||
|
|
||||||
|
- setHandlers(TYPE, HANDLER \[, TYPE, HANDLER \[...\]\])
|
||||||
|
|
||||||
|
This method registers handlers for various parser events. It overrides any
|
||||||
|
previous handlers registered through the Style or Handler options or through
|
||||||
|
earlier calls to setHandlers. By providing a false or undefined value as
|
||||||
|
the handler, the existing handler can be unset.
|
||||||
|
|
||||||
|
This method returns a list of type, handler pairs corresponding to the
|
||||||
|
input. The handlers returned are the ones that were in effect prior to
|
||||||
|
the call.
|
||||||
|
|
||||||
|
See a description of the handler types in ["HANDLERS"](#handlers).
|
||||||
|
|
||||||
|
- parse(SOURCE \[, OPT => OPT\_VALUE \[...\]\])
|
||||||
|
|
||||||
|
The SOURCE parameter should either be a string containing the whole XML
|
||||||
|
document, or it should be an open IO::Handle. Constructor options to
|
||||||
|
XML::Parser::Expat given as keyword-value pairs may follow the SOURCE
|
||||||
|
parameter. These override, for this call, any options or attributes passed
|
||||||
|
through from the XML::Parser instance.
|
||||||
|
|
||||||
|
A die call is thrown if a parse error occurs. Otherwise it will return 1
|
||||||
|
or whatever is returned from the **Final** handler, if one is installed.
|
||||||
|
In other words, what parse may return depends on the style.
|
||||||
|
|
||||||
|
- parsestring
|
||||||
|
|
||||||
|
This is just an alias for parse for backwards compatibility.
|
||||||
|
|
||||||
|
- parsefile(FILE \[, OPT => OPT\_VALUE \[...\]\])
|
||||||
|
|
||||||
|
Open FILE for reading, then call parse with the open handle. The file
|
||||||
|
is closed no matter how parse returns. Returns what parse returns.
|
||||||
|
|
||||||
|
- parse\_start(\[ OPT => OPT\_VALUE \[...\]\])
|
||||||
|
|
||||||
|
Create and return a new instance of XML::Parser::ExpatNB. Constructor
|
||||||
|
options may be provided. If an init handler has been provided, it is
|
||||||
|
called before returning the ExpatNB object. Documents are parsed by
|
||||||
|
making incremental calls to the parse\_more method of this object, which
|
||||||
|
takes a string. A single call to the parse\_done method of this object,
|
||||||
|
which takes no arguments, indicates that the document is finished.
|
||||||
|
|
||||||
|
If there is a final handler installed, it is executed by the parse\_done
|
||||||
|
method before returning and the parse\_done method returns whatever is
|
||||||
|
returned by the final handler.
|
||||||
|
|
||||||
|
# HANDLERS
|
||||||
|
|
||||||
|
Expat is an event based parser. As the parser recognizes parts of the
|
||||||
|
document (say the start or end tag for an XML element), then any handlers
|
||||||
|
registered for that type of an event are called with suitable parameters.
|
||||||
|
All handlers receive an instance of XML::Parser::Expat as their first
|
||||||
|
argument. See ["METHODS" in XML::Parser::Expat](https://metacpan.org/pod/XML::Parser::Expat#METHODS) for a discussion of the
|
||||||
|
methods that can be called on this object.
|
||||||
|
|
||||||
|
## Init (Expat)
|
||||||
|
|
||||||
|
This is called just before the parsing of the document starts.
|
||||||
|
|
||||||
|
## Final (Expat)
|
||||||
|
|
||||||
|
This is called just after parsing has finished, but only if no errors
|
||||||
|
occurred during the parse. Parse returns what this returns.
|
||||||
|
|
||||||
|
## Start (Expat, Element \[, Attr, Val \[,...\]\])
|
||||||
|
|
||||||
|
This event is generated when an XML start tag is recognized. Element is the
|
||||||
|
name of the XML element type that is opened with the start tag. The Attr &
|
||||||
|
Val pairs are generated for each attribute in the start tag.
|
||||||
|
|
||||||
|
## End (Expat, Element)
|
||||||
|
|
||||||
|
This event is generated when an XML end tag is recognized. Note that
|
||||||
|
an XML empty tag (<foo/>) generates both a start and an end event.
|
||||||
|
|
||||||
|
## Char (Expat, String)
|
||||||
|
|
||||||
|
This event is generated when non-markup is recognized. The non-markup
|
||||||
|
sequence of characters is in String. A single non-markup sequence of
|
||||||
|
characters may generate multiple calls to this handler. Whatever the
|
||||||
|
encoding of the string in the original document, this is given to the
|
||||||
|
handler in UTF-8.
|
||||||
|
|
||||||
|
## Proc (Expat, Target, Data)
|
||||||
|
|
||||||
|
This event is generated when a processing instruction is recognized.
|
||||||
|
|
||||||
|
## Comment (Expat, Data)
|
||||||
|
|
||||||
|
This event is generated when a comment is recognized.
|
||||||
|
|
||||||
|
## CdataStart (Expat)
|
||||||
|
|
||||||
|
This is called at the start of a CDATA section.
|
||||||
|
|
||||||
|
## CdataEnd (Expat)
|
||||||
|
|
||||||
|
This is called at the end of a CDATA section.
|
||||||
|
|
||||||
|
## Default (Expat, String)
|
||||||
|
|
||||||
|
This is called for any characters that don't have a registered handler.
|
||||||
|
This includes both characters that are part of markup for which no
|
||||||
|
events are generated (markup declarations) and characters that
|
||||||
|
could generate events, but for which no handler has been registered.
|
||||||
|
|
||||||
|
Whatever the encoding in the original document, the string is returned to
|
||||||
|
the handler in UTF-8.
|
||||||
|
|
||||||
|
## Unparsed (Expat, Entity, Base, Sysid, Pubid, Notation)
|
||||||
|
|
||||||
|
This is called for a declaration of an unparsed entity. Entity is the name
|
||||||
|
of the entity. Base is the base to be used for resolving a relative URI.
|
||||||
|
Sysid is the system id. Pubid is the public id. Notation is the notation
|
||||||
|
name. Base and Pubid may be undefined.
|
||||||
|
|
||||||
|
## Notation (Expat, Notation, Base, Sysid, Pubid)
|
||||||
|
|
||||||
|
This is called for a declaration of notation. Notation is the notation name.
|
||||||
|
Base is the base to be used for resolving a relative URI. Sysid is the system
|
||||||
|
id. Pubid is the public id. Base, Sysid, and Pubid may all be undefined.
|
||||||
|
|
||||||
|
## ExternEnt (Expat, Base, Sysid, Pubid)
|
||||||
|
|
||||||
|
This is called when an external entity is referenced. Base is the base to be
|
||||||
|
used for resolving a relative URI. Sysid is the system id. Pubid is the public
|
||||||
|
id. Base, and Pubid may be undefined.
|
||||||
|
|
||||||
|
This handler should either return a string, which represents the contents of
|
||||||
|
the external entity, or return an open filehandle that can be read to obtain
|
||||||
|
the contents of the external entity, or return undef, which indicates the
|
||||||
|
external entity couldn't be found and will generate a parse error.
|
||||||
|
|
||||||
|
If an open filehandle is returned, it must be returned as either a glob
|
||||||
|
(\*FOO) or as a reference to a glob (e.g. an instance of IO::Handle).
|
||||||
|
|
||||||
|
A default handler is installed for this event. The default handler is
|
||||||
|
XML::Parser::lwp\_ext\_ent\_handler unless the NoLWP option was provided with
|
||||||
|
a true value, otherwise XML::Parser::file\_ext\_ent\_handler is the default
|
||||||
|
handler for external entities. Even without the NoLWP option, if the
|
||||||
|
URI or LWP modules are missing, the file based handler ends up being used
|
||||||
|
after giving a warning on the first external entity reference.
|
||||||
|
|
||||||
|
The LWP external entity handler will use proxies defined in the environment
|
||||||
|
(http\_proxy, ftp\_proxy, etc.).
|
||||||
|
|
||||||
|
Please note that the LWP external entity handler reads the entire
|
||||||
|
entity into a string and returns it, where as the file handler opens a
|
||||||
|
filehandle.
|
||||||
|
|
||||||
|
Also note that the file external entity handler will likely choke on
|
||||||
|
absolute URIs or file names that don't fit the conventions of the local
|
||||||
|
operating system.
|
||||||
|
|
||||||
|
The expat base method can be used to set a basename for
|
||||||
|
relative pathnames. If no basename is given, or if the basename is itself
|
||||||
|
a relative name, then it is relative to the current working directory.
|
||||||
|
|
||||||
|
## ExternEntFin (Expat)
|
||||||
|
|
||||||
|
This is called after parsing an external entity. It's not called unless
|
||||||
|
an ExternEnt handler is also set. There is a default handler installed
|
||||||
|
that pairs with the default ExternEnt handler.
|
||||||
|
|
||||||
|
If you're going to install your own ExternEnt handler, then you should
|
||||||
|
set (or unset) this handler too.
|
||||||
|
|
||||||
|
## Entity (Expat, Name, Val, Sysid, Pubid, Ndata, IsParam)
|
||||||
|
|
||||||
|
This is called when an entity is declared. For internal entities, the Val
|
||||||
|
parameter will contain the value and the remaining three parameters will be
|
||||||
|
undefined. For external entities, the Val parameter will be undefined, the
|
||||||
|
Sysid parameter will have the system id, the Pubid parameter will have the
|
||||||
|
public id if it was provided (it will be undefined otherwise), the Ndata
|
||||||
|
parameter will contain the notation for unparsed entities. If this is a
|
||||||
|
parameter entity declaration, then the IsParam parameter is true.
|
||||||
|
|
||||||
|
Note that this handler and the Unparsed handler above overlap. If both are
|
||||||
|
set, then this handler will not be called for unparsed entities.
|
||||||
|
|
||||||
|
## Element (Expat, Name, Model)
|
||||||
|
|
||||||
|
The element handler is called when an element declaration is found. Name
|
||||||
|
is the element name, and Model is the content model as an XML::Parser::Content
|
||||||
|
object. See ["XML::Parser::ContentModel Methods" in XML::Parser::Expat](https://metacpan.org/pod/XML::Parser::Expat#XML::Parser::ContentModel-Methods)
|
||||||
|
for methods available for this class.
|
||||||
|
|
||||||
|
## Attlist (Expat, Elname, Attname, Type, Default, Fixed)
|
||||||
|
|
||||||
|
This handler is called for each attribute in an ATTLIST declaration.
|
||||||
|
So an ATTLIST declaration that has multiple attributes will generate multiple
|
||||||
|
calls to this handler. The Elname parameter is the name of the element with
|
||||||
|
which the attribute is being associated. The Attname parameter is the name
|
||||||
|
of the attribute. Type is the attribute type, given as a string. Default is
|
||||||
|
the default value, which will either be "#REQUIRED", "#IMPLIED" or a quoted
|
||||||
|
string (i.e. the returned string will begin and end with a quote character).
|
||||||
|
If Fixed is true, then this is a fixed attribute.
|
||||||
|
|
||||||
|
## Doctype (Expat, Name, Sysid, Pubid, Internal)
|
||||||
|
|
||||||
|
This handler is called for DOCTYPE declarations. Name is the document type
|
||||||
|
name. Sysid is the system id of the document type, if it was provided,
|
||||||
|
otherwise it's undefined. Pubid is the public id of the document type,
|
||||||
|
which will be undefined if no public id was given. Internal is the internal
|
||||||
|
subset, given as a string. If there was no internal subset, it will be
|
||||||
|
undefined. Internal will contain all whitespace, comments, processing
|
||||||
|
instructions, and declarations seen in the internal subset. The declarations
|
||||||
|
will be there whether or not they have been processed by another handler
|
||||||
|
(except for unparsed entities processed by the Unparsed handler). However,
|
||||||
|
comments and processing instructions will not appear if they've been processed
|
||||||
|
by their respective handlers.
|
||||||
|
|
||||||
|
## \* DoctypeFin (Parser)
|
||||||
|
|
||||||
|
This handler is called after parsing of the DOCTYPE declaration has finished,
|
||||||
|
including any internal or external DTD declarations.
|
||||||
|
|
||||||
|
## XMLDecl (Expat, Version, Encoding, Standalone)
|
||||||
|
|
||||||
|
This handler is called for xml declarations. Version is a string containing
|
||||||
|
the version. Encoding is either undefined or contains an encoding string.
|
||||||
|
Standalone will be either true, false, or undefined if the standalone attribute
|
||||||
|
is yes, no, or not made respectively.
|
||||||
|
|
||||||
|
# STYLES
|
||||||
|
|
||||||
|
## Debug
|
||||||
|
|
||||||
|
This just prints out the document in outline form. Nothing special is
|
||||||
|
returned by parse.
|
||||||
|
|
||||||
|
## Subs
|
||||||
|
|
||||||
|
Each time an element starts, a sub by that name in the package specified
|
||||||
|
by the Pkg option is called with the same parameters that the Start
|
||||||
|
handler gets called with.
|
||||||
|
|
||||||
|
Each time an element ends, a sub with that name appended with an underscore
|
||||||
|
("\_"), is called with the same parameters that the End handler gets called
|
||||||
|
with.
|
||||||
|
|
||||||
|
Nothing special is returned by parse.
|
||||||
|
|
||||||
|
## Tree
|
||||||
|
|
||||||
|
Parse will return a parse tree for the document. Each node in the tree
|
||||||
|
takes the form of a tag, content pair. Text nodes are represented with
|
||||||
|
a pseudo-tag of "0" and the string that is their content. For elements,
|
||||||
|
the content is an array reference. The first item in the array is a
|
||||||
|
(possibly empty) hash reference containing attributes. The remainder of
|
||||||
|
the array is a sequence of tag-content pairs representing the content
|
||||||
|
of the element.
|
||||||
|
|
||||||
|
So for example the result of parsing:
|
||||||
|
|
||||||
|
<foo><head id="a">Hello <em>there</em></head><bar>Howdy<ref/></bar>do</foo>
|
||||||
|
|
||||||
|
would be:
|
||||||
|
|
||||||
|
Tag Content
|
||||||
|
==================================================================
|
||||||
|
[foo, [{}, head, [{id => "a"}, 0, "Hello ", em, [{}, 0, "there"]],
|
||||||
|
bar, [ {}, 0, "Howdy", ref, [{}]],
|
||||||
|
0, "do"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
The root document "foo", has 3 children: a "head" element, a "bar"
|
||||||
|
element and the text "do". After the empty attribute hash, these are
|
||||||
|
represented in it's contents by 3 tag-content pairs.
|
||||||
|
|
||||||
|
## Objects
|
||||||
|
|
||||||
|
This is similar to the Tree style, except that a hash object is created for
|
||||||
|
each element. The corresponding object will be in the class whose name
|
||||||
|
is created by appending "::" and the element name to the package set with
|
||||||
|
the Pkg option. Non-markup text will be in the ::Characters class. The
|
||||||
|
contents of the corresponding object will be in an anonymous array that
|
||||||
|
is the value of the Kids property for that object.
|
||||||
|
|
||||||
|
## Stream
|
||||||
|
|
||||||
|
This style also uses the Pkg package. If none of the subs that this
|
||||||
|
style looks for is there, then the effect of parsing with this style is
|
||||||
|
to print a canonical copy of the document without comments or declarations.
|
||||||
|
All the subs receive as their 1st parameter the Expat instance for the
|
||||||
|
document they're parsing.
|
||||||
|
|
||||||
|
It looks for the following routines:
|
||||||
|
|
||||||
|
- StartDocument
|
||||||
|
|
||||||
|
Called at the start of the parse .
|
||||||
|
|
||||||
|
- StartTag
|
||||||
|
|
||||||
|
Called for every start tag with a second parameter of the element type. The $\_
|
||||||
|
variable will contain a copy of the tag and the %\_ variable will contain
|
||||||
|
attribute values supplied for that element.
|
||||||
|
|
||||||
|
- EndTag
|
||||||
|
|
||||||
|
Called for every end tag with a second parameter of the element type. The $\_
|
||||||
|
variable will contain a copy of the end tag.
|
||||||
|
|
||||||
|
- Text
|
||||||
|
|
||||||
|
Called just before start or end tags with accumulated non-markup text in
|
||||||
|
the $\_ variable.
|
||||||
|
|
||||||
|
- PI
|
||||||
|
|
||||||
|
Called for processing instructions. The $\_ variable will contain a copy of
|
||||||
|
the PI and the target and data are sent as 2nd and 3rd parameters
|
||||||
|
respectively.
|
||||||
|
|
||||||
|
- EndDocument
|
||||||
|
|
||||||
|
Called at conclusion of the parse.
|
||||||
|
|
||||||
|
# ENCODINGS
|
||||||
|
|
||||||
|
XML documents may be encoded in character sets other than Unicode as
|
||||||
|
long as they may be mapped into the Unicode character set. Expat has
|
||||||
|
further restrictions on encodings. Read the xmlparse.h header file in
|
||||||
|
the expat distribution to see details on these restrictions.
|
||||||
|
|
||||||
|
Expat has built-in encodings for: `UTF-8`, `ISO-8859-1`, `UTF-16`, and
|
||||||
|
`US-ASCII`. Encodings are set either through the XML declaration
|
||||||
|
encoding attribute or through the ProtocolEncoding option to XML::Parser
|
||||||
|
or XML::Parser::Expat.
|
||||||
|
|
||||||
|
For encodings other than the built-ins, expat calls the function
|
||||||
|
load\_encoding in the Expat package with the encoding name. This function
|
||||||
|
looks for a file in the path list @XML::Parser::Expat::Encoding\_Path, that
|
||||||
|
matches the lower-cased name with a '.enc' extension. The first one it
|
||||||
|
finds, it loads.
|
||||||
|
|
||||||
|
If you wish to build your own encoding maps, check out the XML::Encoding
|
||||||
|
module from CPAN.
|
||||||
|
|
||||||
|
# AUTHORS
|
||||||
|
|
||||||
|
Larry Wall <`larry@wall.org`> wrote version 1.0.
|
||||||
|
|
||||||
|
Clark Cooper <`coopercc@netheaven.com`> picked up support, changed the API
|
||||||
|
for this version (2.x), provided documentation,
|
||||||
|
and added some standard package features.
|
||||||
|
|
||||||
|
Matt Sergeant <`matt@sergeant.org`> is now maintaining XML::Parser
|
|
@ -2,24 +2,24 @@
|
||||||
|
|
||||||
package Devel::CheckLib;
|
package Devel::CheckLib;
|
||||||
|
|
||||||
use 5.00405; #postfix foreach
|
use 5.00405; #postfix foreach
|
||||||
use strict;
|
use strict;
|
||||||
use vars qw($VERSION @ISA @EXPORT);
|
use vars qw($VERSION @ISA @EXPORT);
|
||||||
$VERSION = '0.99';
|
$VERSION = '1.16';
|
||||||
use Config qw(%Config);
|
use Config qw(%Config);
|
||||||
use Text::ParseWords 'quotewords';
|
use Text::ParseWords qw(quotewords shellwords);
|
||||||
|
|
||||||
use File::Spec;
|
use File::Spec;
|
||||||
use File::Temp;
|
use File::Temp;
|
||||||
|
|
||||||
require Exporter;
|
require Exporter;
|
||||||
@ISA = qw(Exporter);
|
@ISA = qw(Exporter);
|
||||||
@EXPORT = qw(assert_lib check_lib_or_exit check_lib);
|
@EXPORT = qw(assert_lib check_lib_or_exit check_lib);
|
||||||
|
|
||||||
# localising prevents the warningness leaking out of this module
|
# localising prevents the warningness leaking out of this module
|
||||||
local $^W = 1; # use warnings is a 5.6-ism
|
local $^W = 1; # use warnings is a 5.6-ism
|
||||||
|
|
||||||
_findcc(); # bomb out early if there's no compiler
|
_findcc(); # bomb out early if there's no compiler
|
||||||
|
|
||||||
=head1 NAME
|
=head1 NAME
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ and link to the libraries.
|
||||||
|
|
||||||
It works by trying to compile some code - which defaults to this:
|
It works by trying to compile some code - which defaults to this:
|
||||||
|
|
||||||
int main(void) { return 0; }
|
int main(int argc, char *argv[]) { return 0; }
|
||||||
|
|
||||||
and linking it to the specified libraries. If something pops out the end
|
and linking it to the specified libraries. If something pops out the end
|
||||||
which looks executable, it gets executed, and if main() returns 0 we know
|
which looks executable, it gets executed, and if main() returns 0 we know
|
||||||
|
@ -109,7 +109,7 @@ representing additional paths to search for libraries.
|
||||||
|
|
||||||
=item LIBS
|
=item LIBS
|
||||||
|
|
||||||
a C<ExtUtils::MakeMaker>-style space-seperated list of
|
a C<ExtUtils::MakeMaker>-style space-separated list of
|
||||||
libraries (each preceded by '-l') and directories (preceded by '-L').
|
libraries (each preceded by '-l') and directories (preceded by '-L').
|
||||||
|
|
||||||
This can also be supplied on the command-line.
|
This can also be supplied on the command-line.
|
||||||
|
@ -137,11 +137,32 @@ representing additional paths to search for headers.
|
||||||
|
|
||||||
=item INC
|
=item INC
|
||||||
|
|
||||||
a C<ExtUtils::MakeMaker>-style space-seperated list of
|
a C<ExtUtils::MakeMaker>-style space-separated list of
|
||||||
incpaths, each preceded by '-I'.
|
incpaths, each preceded by '-I'.
|
||||||
|
|
||||||
This can also be supplied on the command-line.
|
This can also be supplied on the command-line.
|
||||||
|
|
||||||
|
=item ccflags
|
||||||
|
|
||||||
|
Extra flags to pass to the compiler.
|
||||||
|
|
||||||
|
=item ldflags
|
||||||
|
|
||||||
|
Extra flags to pass to the linker.
|
||||||
|
|
||||||
|
=item analyze_binary
|
||||||
|
|
||||||
|
a callback function that will be invoked in order to perform custom
|
||||||
|
analysis of the generated binary. The callback arguments are the
|
||||||
|
library name and the path to the binary just compiled.
|
||||||
|
|
||||||
|
It is possible to use this callback, for instance, to inspect the
|
||||||
|
binary for further dependencies.
|
||||||
|
|
||||||
|
=item not_execute
|
||||||
|
|
||||||
|
Do not try to execute generated binary. Only check that compilation has not failed.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
=head2 check_lib_or_exit
|
=head2 check_lib_or_exit
|
||||||
|
@ -166,7 +187,7 @@ returning false instead of dieing, or true otherwise.
|
||||||
|
|
||||||
sub check_lib_or_exit {
|
sub check_lib_or_exit {
|
||||||
eval 'assert_lib(@_)';
|
eval 'assert_lib(@_)';
|
||||||
if ($@) {
|
if($@) {
|
||||||
warn $@;
|
warn $@;
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
@ -177,215 +198,301 @@ sub check_lib {
|
||||||
return $@ ? 0 : 1;
|
return $@ ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# borrowed from Text::ParseWords
|
||||||
|
sub _parse_line {
|
||||||
|
my($delimiter, $keep, $line) = @_;
|
||||||
|
my($word, @pieces);
|
||||||
|
|
||||||
|
no warnings 'uninitialized'; # we will be testing undef strings
|
||||||
|
|
||||||
|
while (length($line)) {
|
||||||
|
# This pattern is optimised to be stack conservative on older perls.
|
||||||
|
# Do not refactor without being careful and testing it on very long strings.
|
||||||
|
# See Perl bug #42980 for an example of a stack busting input.
|
||||||
|
$line =~ s/^
|
||||||
|
(?:
|
||||||
|
# double quoted string
|
||||||
|
(") # $quote
|
||||||
|
((?>[^\\"]*(?:\\.[^\\"]*)*))" # $quoted
|
||||||
|
| # --OR--
|
||||||
|
# singe quoted string
|
||||||
|
(') # $quote
|
||||||
|
((?>[^\\']*(?:\\.[^\\']*)*))' # $quoted
|
||||||
|
| # --OR--
|
||||||
|
# unquoted string
|
||||||
|
( # $unquoted
|
||||||
|
(?:\\.|[^\\"'])*?
|
||||||
|
)
|
||||||
|
# followed by
|
||||||
|
( # $delim
|
||||||
|
\Z(?!\n) # EOL
|
||||||
|
| # --OR--
|
||||||
|
(?-x:$delimiter) # delimiter
|
||||||
|
| # --OR--
|
||||||
|
(?!^)(?=["']) # a quote
|
||||||
|
)
|
||||||
|
)//xs or return; # extended layout
|
||||||
|
my ($quote, $quoted, $unquoted, $delim) = (($1 ? ($1,$2) : ($3,$4)), $5, $6);
|
||||||
|
|
||||||
|
return() unless( defined($quote) || length($unquoted) || length($delim));
|
||||||
|
|
||||||
|
if ($keep) {
|
||||||
|
$quoted = "$quote$quoted$quote";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$unquoted =~ s/\\(.)/$1/sg;
|
||||||
|
if (defined $quote) {
|
||||||
|
$quoted =~ s/\\(.)/$1/sg if ($quote eq '"');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$word .= substr($line, 0, 0); # leave results tainted
|
||||||
|
$word .= defined $quote ? $quoted : $unquoted;
|
||||||
|
|
||||||
|
if (length($delim)) {
|
||||||
|
push(@pieces, $word);
|
||||||
|
push(@pieces, $delim) if ($keep eq 'delimiters');
|
||||||
|
undef $word;
|
||||||
|
}
|
||||||
|
if (!length($line)) {
|
||||||
|
push(@pieces, $word);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(@pieces);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _parsewords {
|
||||||
|
return shellwords @_ if $^O ne 'MSWin32';
|
||||||
|
# for Win32, take off "" but leave \
|
||||||
|
map { my $s=$_; $s =~ s/^"(.*)"$/$1/; $s } grep defined && length, quotewords '\s+', 1, @_;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _compile_cmd {
|
||||||
|
my ($Config_cc, $cc, $cfile, $exefile, $incpaths, $ld, $Config_libs, $lib, $libpaths) = @_;
|
||||||
|
my @sys_cmd = @$cc;
|
||||||
|
if ( $Config_cc eq 'cl' ) { # Microsoft compiler
|
||||||
|
# this is horribly sensitive to the order of arguments
|
||||||
|
push @sys_cmd,
|
||||||
|
$cfile,
|
||||||
|
(defined $lib ? "${lib}.lib" : ()),
|
||||||
|
"/Fe$exefile",
|
||||||
|
(map '/I'.$_, @$incpaths),
|
||||||
|
"/link",
|
||||||
|
@$ld,
|
||||||
|
_parsewords($Config_libs),
|
||||||
|
(defined $lib ? map '/libpath:'.$_, @$libpaths : ()),
|
||||||
|
;
|
||||||
|
} elsif($Config_cc =~ /bcc32(\.exe)?/) { # Borland
|
||||||
|
push @sys_cmd,
|
||||||
|
@$ld,
|
||||||
|
(map "-I$_", @$incpaths),
|
||||||
|
"-o$exefile",
|
||||||
|
(defined $lib ? ((map "-L$_", @$libpaths), "-l$lib") : ()),
|
||||||
|
$cfile,
|
||||||
|
;
|
||||||
|
} else { # Unix-ish: gcc, Sun, AIX (gcc, cc), ...
|
||||||
|
push @sys_cmd,
|
||||||
|
(map "-I$_", @$incpaths),
|
||||||
|
$cfile,
|
||||||
|
(!defined $lib ? () : (
|
||||||
|
(map "-L$_", @$libpaths),
|
||||||
|
($^O eq 'darwin' ? (map { "-Wl,-rpath,$_" } @$libpaths) : ()),
|
||||||
|
"-l$lib",
|
||||||
|
)),
|
||||||
|
@$ld,
|
||||||
|
"-o", $exefile,
|
||||||
|
;
|
||||||
|
}
|
||||||
|
@sys_cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _make_cfile {
|
||||||
|
my ($use_headers, $function, $debug) = @_;
|
||||||
|
my $code = '';
|
||||||
|
$code .= qq{#include <$_>\n} for @$use_headers;
|
||||||
|
$code .= "int main(int argc, char *argv[]) { ".($function || 'return 0;')." }\n";
|
||||||
|
if ($debug) {
|
||||||
|
(my $c = $code) =~ s:^:# :gm;
|
||||||
|
warn "# Code:\n$c\n";
|
||||||
|
}
|
||||||
|
my ($ch, $cfile) = File::Temp::tempfile(
|
||||||
|
'assertlibXXXXXXXX', SUFFIX => '.c'
|
||||||
|
);
|
||||||
|
print $ch $code;
|
||||||
|
close $ch;
|
||||||
|
(my $ofile = $cfile) =~ s/\.c$/$Config{_o}/;
|
||||||
|
($cfile, $ofile);
|
||||||
|
}
|
||||||
|
|
||||||
sub assert_lib {
|
sub assert_lib {
|
||||||
my %args = @_;
|
my %args = @_;
|
||||||
my ( @libs, @libpaths, @headers, @incpaths );
|
$args{$_} = [$args{$_}]
|
||||||
|
for grep $args{$_} && !ref($args{$_}), qw(lib libpath header incpath);
|
||||||
|
my @libs = @{$args{lib} || []};
|
||||||
|
my @libpaths = @{$args{libpath} || []};
|
||||||
|
my @headers = @{$args{header} || []};
|
||||||
|
my @incpaths = @{$args{incpath} || []};
|
||||||
|
my $analyze_binary = $args{analyze_binary};
|
||||||
|
my $execute = !$args{not_execute};
|
||||||
|
|
||||||
# FIXME: these four just SCREAM "refactor" at me
|
my @argv = @ARGV;
|
||||||
@libs = ( ref( $args{lib} ) ? @{ $args{lib} } : $args{lib} )
|
push @argv, _parse_line('\s+', 0, $ENV{PERL_MM_OPT}||'');
|
||||||
if $args{lib};
|
|
||||||
@libpaths = ( ref( $args{libpath} ) ? @{ $args{libpath} } : $args{libpath} )
|
|
||||||
if $args{libpath};
|
|
||||||
@headers = ( ref( $args{header} ) ? @{ $args{header} } : $args{header} )
|
|
||||||
if $args{header};
|
|
||||||
@incpaths = ( ref( $args{incpath} ) ? @{ $args{incpath} } : $args{incpath} )
|
|
||||||
if $args{incpath};
|
|
||||||
|
|
||||||
# work-a-like for Makefile.PL's LIBS and INC arguments
|
# work-a-like for Makefile.PL's LIBS and INC arguments
|
||||||
# if given as command-line argument, append to %args
|
# if given as command-line argument, append to %args
|
||||||
for my $arg (@ARGV) {
|
for my $arg (@argv) {
|
||||||
for my $mm_attr_key (qw(LIBS INC)) {
|
for my $mm_attr_key (qw(LIBS INC)) {
|
||||||
if ( my ($mm_attr_value) = $arg =~ /\A $mm_attr_key = (.*)/x ) {
|
if (my ($mm_attr_value) = $arg =~ /\A $mm_attr_key = (.*)/x) {
|
||||||
|
# it is tempting to put some \s* into the expression, but the
|
||||||
# it is tempting to put some \s* into the expression, but the
|
# MM command-line parser only accepts LIBS etc. followed by =,
|
||||||
# MM command-line parser only accepts LIBS etc. followed by =,
|
# so we should not be any more lenient with whitespace than that
|
||||||
# so we should not be any more lenient with whitespace than that
|
|
||||||
$args{$mm_attr_key} .= " $mm_attr_value";
|
$args{$mm_attr_key} .= " $mm_attr_value";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# using special form of split to trim whitespace
|
if(defined($args{LIBS})) {
|
||||||
if ( defined( $args{LIBS} ) ) {
|
foreach my $arg (_parsewords($args{LIBS})) {
|
||||||
foreach my $arg ( split( ' ', $args{LIBS} ) ) {
|
die("LIBS argument badly-formed: $arg\n") unless($arg =~ /^-[lLR]/);
|
||||||
die("LIBS argument badly-formed: $arg\n") unless ( $arg =~ /^-[lLR]/ );
|
push @{$arg =~ /^-l/ ? \@libs : \@libpaths}, substr($arg, 2);
|
||||||
push @{ $arg =~ /^-l/ ? \@libs : \@libpaths }, substr( $arg, 2 );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( defined( $args{INC} ) ) {
|
if(defined($args{INC})) {
|
||||||
foreach my $arg ( split( ' ', $args{INC} ) ) {
|
foreach my $arg (_parsewords($args{INC})) {
|
||||||
die("INC argument badly-formed: $arg\n") unless ( $arg =~ /^-I/ );
|
die("INC argument badly-formed: $arg\n") unless($arg =~ /^-I/);
|
||||||
push @incpaths, substr( $arg, 2 );
|
push @incpaths, substr($arg, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my ( $cc, $ld ) = _findcc();
|
my ($cc, $ld) = _findcc($args{debug}, $args{ccflags}, $args{ldflags});
|
||||||
my @missing;
|
my @missing;
|
||||||
my @wrongresult;
|
my @wrongresult;
|
||||||
|
my @wronganalysis;
|
||||||
my @use_headers;
|
my @use_headers;
|
||||||
|
|
||||||
# first figure out which headers we can't find ...
|
# first figure out which headers we can't find ...
|
||||||
for my $header (@headers) {
|
for my $header (@headers) {
|
||||||
push @use_headers, $header;
|
push @use_headers, $header;
|
||||||
my ( $ch, $cfile ) = File::Temp::tempfile( 'assertlibXXXXXXXX', SUFFIX => '.c' );
|
my ($cfile, $ofile) = _make_cfile(\@use_headers, '', $args{debug});
|
||||||
my $ofile = $cfile;
|
my $exefile = File::Temp::mktemp( 'assertlibXXXXXXXX' ) . $Config{_exe};
|
||||||
$ofile =~ s/\.c$/$Config{_o}/;
|
my @sys_cmd = _compile_cmd($Config{cc}, $cc, $cfile, $exefile, \@incpaths, $ld, $Config{libs});
|
||||||
print $ch qq{#include <$_>\n} for @use_headers;
|
|
||||||
print $ch qq{int main(void) { return 0; }\n};
|
|
||||||
close($ch);
|
|
||||||
my $exefile = File::Temp::mktemp('assertlibXXXXXXXX') . $Config{_exe};
|
|
||||||
my @sys_cmd;
|
|
||||||
|
|
||||||
# FIXME: re-factor - almost identical code later when linking
|
|
||||||
if ( $Config{cc} eq 'cl' ) { # Microsoft compiler
|
|
||||||
require Win32;
|
|
||||||
@sys_cmd = (
|
|
||||||
@$cc,
|
|
||||||
$cfile,
|
|
||||||
"/Fe$exefile",
|
|
||||||
( map { '/I' . Win32::GetShortPathName($_) } @incpaths ),
|
|
||||||
"/link",
|
|
||||||
@$ld
|
|
||||||
);
|
|
||||||
}
|
|
||||||
elsif ( $Config{cc} =~ /bcc32(\.exe)?/ ) { # Borland
|
|
||||||
@sys_cmd = (
|
|
||||||
@$cc,
|
|
||||||
@$ld,
|
|
||||||
( map { "-I$_" } @incpaths ),
|
|
||||||
"-o$exefile",
|
|
||||||
$cfile
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else { # Unix-ish: gcc, Sun, AIX (gcc, cc), ...
|
|
||||||
@sys_cmd = (
|
|
||||||
@$cc,
|
|
||||||
@$ld,
|
|
||||||
$cfile,
|
|
||||||
( map { "-I$_" } @incpaths ),
|
|
||||||
"-o", "$exefile"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
warn "# @sys_cmd\n" if $args{debug};
|
warn "# @sys_cmd\n" if $args{debug};
|
||||||
my $rv = $args{debug} ? system(@sys_cmd) : _quiet_system(@sys_cmd);
|
my $rv = $args{debug} ? system(@sys_cmd) : _quiet_system(@sys_cmd);
|
||||||
push @missing, $header if $rv != 0 || !-x $exefile;
|
push @missing, $header if $rv != 0 || ! -f $exefile;
|
||||||
_cleanup_exe($exefile);
|
_cleanup_exe($exefile);
|
||||||
unlink $ofile if -e $ofile;
|
|
||||||
unlink $cfile;
|
unlink $cfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
# now do each library in turn with headers
|
# now do each library in turn with headers
|
||||||
my ( $ch, $cfile ) = File::Temp::tempfile( 'assertlibXXXXXXXX', SUFFIX => '.c' );
|
my ($cfile, $ofile) = _make_cfile(\@use_headers, @args{qw(function debug)});
|
||||||
my $ofile = $cfile;
|
for my $lib ( @libs ) {
|
||||||
$ofile =~ s/\.c$/$Config{_o}/;
|
last if $Config{cc} eq 'CC/DECC'; # VMS
|
||||||
print $ch qq{#include <$_>\n} foreach (@headers);
|
my $exefile = File::Temp::mktemp( 'assertlibXXXXXXXX' ) . $Config{_exe};
|
||||||
print $ch "int main(void) { " . ( $args{function} || 'return 0;' ) . " }\n";
|
my @sys_cmd = _compile_cmd($Config{cc}, $cc, $cfile, $exefile, \@incpaths, $ld, $Config{libs}, $lib, \@libpaths);
|
||||||
close($ch);
|
|
||||||
for my $lib (@libs) {
|
|
||||||
my $exefile = File::Temp::mktemp('assertlibXXXXXXXX') . $Config{_exe};
|
|
||||||
my @sys_cmd;
|
|
||||||
if ( $Config{cc} eq 'cl' ) { # Microsoft compiler
|
|
||||||
require Win32;
|
|
||||||
my @libpath = map { q{/libpath:} . Win32::GetShortPathName($_) } @libpaths;
|
|
||||||
|
|
||||||
# this is horribly sensitive to the order of arguments
|
|
||||||
@sys_cmd = (
|
|
||||||
@$cc,
|
|
||||||
$cfile,
|
|
||||||
"${lib}.lib",
|
|
||||||
"/Fe$exefile",
|
|
||||||
( map { '/I' . Win32::GetShortPathName($_) } @incpaths ),
|
|
||||||
"/link",
|
|
||||||
@$ld,
|
|
||||||
( map { '/libpath:' . Win32::GetShortPathName($_) } @libpaths ),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
elsif ( $Config{cc} eq 'CC/DECC' ) { # VMS
|
|
||||||
}
|
|
||||||
elsif ( $Config{cc} =~ /bcc32(\.exe)?/ ) { # Borland
|
|
||||||
@sys_cmd = (
|
|
||||||
@$cc,
|
|
||||||
@$ld,
|
|
||||||
"-o$exefile",
|
|
||||||
( map { "-I$_" } @incpaths ),
|
|
||||||
( map { "-L$_" } @libpaths ),
|
|
||||||
"-l$lib",
|
|
||||||
$cfile
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else { # Unix-ish
|
|
||||||
# gcc, Sun, AIX (gcc, cc)
|
|
||||||
@sys_cmd = (
|
|
||||||
@$cc,
|
|
||||||
@$ld,
|
|
||||||
$cfile,
|
|
||||||
"-o", "$exefile",
|
|
||||||
( map { "-I$_" } @incpaths ),
|
|
||||||
( map { "-L$_" } @libpaths ),
|
|
||||||
"-l$lib",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
warn "# @sys_cmd\n" if $args{debug};
|
warn "# @sys_cmd\n" if $args{debug};
|
||||||
|
local $ENV{LD_RUN_PATH} = join(":", grep $_, @libpaths, $ENV{LD_RUN_PATH}) unless $^O eq 'MSWin32' or $^O eq 'darwin';
|
||||||
|
local $ENV{PATH} = join(";", @libpaths).";".$ENV{PATH} if $^O eq 'MSWin32';
|
||||||
my $rv = $args{debug} ? system(@sys_cmd) : _quiet_system(@sys_cmd);
|
my $rv = $args{debug} ? system(@sys_cmd) : _quiet_system(@sys_cmd);
|
||||||
push @missing, $lib if $rv != 0 || !-x $exefile;
|
if ($rv != 0 || ! -f $exefile) {
|
||||||
my $absexefile = File::Spec->rel2abs($exefile);
|
push @missing, $lib;
|
||||||
$absexefile = '"' . $absexefile . '"' if $absexefile =~ m/\s/;
|
}
|
||||||
push @wrongresult, $lib if $rv == 0 && -x $exefile && system($absexefile) != 0;
|
else {
|
||||||
unlink $ofile if -e $ofile;
|
chmod 0755, $exefile;
|
||||||
|
my $absexefile = File::Spec->rel2abs($exefile);
|
||||||
|
$absexefile = '"'.$absexefile.'"' if $absexefile =~ m/\s/;
|
||||||
|
warn "# Execute($execute): $absexefile\n" if $args{debug};
|
||||||
|
if ($execute) {
|
||||||
|
my $retval = system($absexefile);
|
||||||
|
warn "# return value: $retval\n" if $args{debug};
|
||||||
|
push @wrongresult, $lib if $retval != 0;
|
||||||
|
}
|
||||||
|
push @wronganalysis, $lib
|
||||||
|
if $analyze_binary and !$analyze_binary->($lib, $exefile);
|
||||||
|
}
|
||||||
_cleanup_exe($exefile);
|
_cleanup_exe($exefile);
|
||||||
}
|
}
|
||||||
unlink $cfile;
|
unlink $cfile;
|
||||||
|
|
||||||
my $miss_string = join( q{, }, map { qq{'$_'} } @missing );
|
my $miss_string = join( q{, }, map qq{'$_'}, @missing );
|
||||||
die("Can't link/include C library $miss_string, aborting.\n") if @missing;
|
die("Can't link/include C library $miss_string, aborting.\n") if @missing;
|
||||||
my $wrong_string = join( q{, }, map { qq{'$_'} } @wrongresult );
|
my $wrong_string = join( q{, }, map qq{'$_'}, @wrongresult);
|
||||||
die("wrong result: $wrong_string\n") if @wrongresult;
|
die("wrong result: $wrong_string\n") if @wrongresult;
|
||||||
|
my $analysis_string = join(q{, }, map qq{'$_'}, @wronganalysis );
|
||||||
|
die("wrong analysis: $analysis_string") if @wronganalysis;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub _cleanup_exe {
|
sub _cleanup_exe {
|
||||||
my ($exefile) = @_;
|
my ($exefile) = @_;
|
||||||
my $ofile = $exefile;
|
my $ofile = $exefile;
|
||||||
$ofile =~ s/$Config{_exe}$/$Config{_o}/;
|
$ofile =~ s/$Config{_exe}$/$Config{_o}/;
|
||||||
unlink $exefile if -f $exefile;
|
# List of files to remove
|
||||||
unlink $ofile if -f $ofile;
|
my @rmfiles;
|
||||||
unlink "$exefile\.manifest" if -f "$exefile\.manifest";
|
push @rmfiles, $exefile, $ofile, "$exefile\.manifest";
|
||||||
if ( $Config{cc} eq 'cl' ) {
|
if ( $Config{cc} eq 'cl' ) {
|
||||||
|
|
||||||
# MSVC also creates foo.ilk and foo.pdb
|
# MSVC also creates foo.ilk and foo.pdb
|
||||||
my $ilkfile = $exefile;
|
my $ilkfile = $exefile;
|
||||||
$ilkfile =~ s/$Config{_exe}$/.ilk/;
|
$ilkfile =~ s/$Config{_exe}$/.ilk/;
|
||||||
my $pdbfile = $exefile;
|
my $pdbfile = $exefile;
|
||||||
$pdbfile =~ s/$Config{_exe}$/.pdb/;
|
$pdbfile =~ s/$Config{_exe}$/.pdb/;
|
||||||
unlink $ilkfile if -f $ilkfile;
|
push @rmfiles, $ilkfile, $pdbfile;
|
||||||
unlink $pdbfile if -f $pdbfile;
|
|
||||||
}
|
}
|
||||||
return;
|
foreach (grep -f, @rmfiles) {
|
||||||
|
unlink $_ or warn "Could not remove $_: $!";
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
# return ($cc, $ld)
|
# return ($cc, $ld)
|
||||||
# where $cc is an array ref of compiler name, compiler flags
|
# where $cc is an array ref of compiler name, compiler flags
|
||||||
# where $ld is an array ref of linker flags
|
# where $ld is an array ref of linker flags
|
||||||
sub _findcc {
|
sub _findcc {
|
||||||
|
my ($debug, $user_ccflags, $user_ldflags) = @_;
|
||||||
# Need to use $keep=1 to work with MSWin32 backslashes and quotes
|
# Need to use $keep=1 to work with MSWin32 backslashes and quotes
|
||||||
my $Config_ccflags = $Config{ccflags}; # use copy so ASPerl will compile
|
my $Config_ccflags = $Config{ccflags}; # use copy so ASPerl will compile
|
||||||
|
$Config_ccflags =~ s:-O\S*::; # stop GCC optimising away test code
|
||||||
my @Config_ldflags = ();
|
my @Config_ldflags = ();
|
||||||
for my $config_val ( @Config{qw(ldflags perllibs)} ) {
|
for my $config_val ( @Config{qw(ldflags)} ){
|
||||||
push @Config_ldflags, $config_val if ( $config_val =~ /\S/ );
|
push @Config_ldflags, $config_val if ( $config_val =~ /\S/ );
|
||||||
}
|
}
|
||||||
my @ccflags = grep { length } quotewords( '\s+', 1, $Config_ccflags || '' );
|
my @ccflags = grep { length } _parsewords($Config_ccflags||'', $user_ccflags||'');
|
||||||
my @ldflags = grep { length } quotewords( '\s+', 1, @Config_ldflags );
|
my @ldflags = grep { length && $_ !~ m/^-Wl/ } _parsewords(@Config_ldflags, $user_ldflags||'');
|
||||||
my @paths = split( /$Config{path_sep}/, $ENV{PATH} );
|
my @paths = split(/$Config{path_sep}/, $ENV{PATH});
|
||||||
my @cc = split( /\s+/, $Config{cc} );
|
my @cc = _parsewords($Config{cc});
|
||||||
return ( [ @cc, @ccflags ], \@ldflags ) if -x $cc[0];
|
if (check_compiler ($cc[0], $debug)) {
|
||||||
foreach my $path (@paths) {
|
return ( [ @cc, @ccflags ], \@ldflags );
|
||||||
my $compiler = File::Spec->catfile( $path, $cc[0] ) . $Config{_exe};
|
|
||||||
return ( [ $compiler, @cc[ 1 .. $#cc ], @ccflags ], \@ldflags )
|
|
||||||
if -x $compiler;
|
|
||||||
}
|
}
|
||||||
die("Couldn't find your C compiler\n");
|
# Find the extension for executables.
|
||||||
|
my $exe = $Config{_exe};
|
||||||
|
if ($^O eq 'cygwin') {
|
||||||
|
$exe = '';
|
||||||
|
}
|
||||||
|
foreach my $path (@paths) {
|
||||||
|
# Look for "$path/$cc[0].exe"
|
||||||
|
my $compiler = File::Spec->catfile($path, $cc[0]) . $exe;
|
||||||
|
if (check_compiler ($compiler, $debug)) {
|
||||||
|
return ([ $compiler, @cc[1 .. $#cc], @ccflags ], \@ldflags)
|
||||||
|
}
|
||||||
|
next if ! $exe;
|
||||||
|
# Look for "$path/$cc[0]" without the .exe, if necessary.
|
||||||
|
$compiler = File::Spec->catfile($path, $cc[0]);
|
||||||
|
if (check_compiler ($compiler, $debug)) {
|
||||||
|
return ([ $compiler, @cc[1 .. $#cc], @ccflags ], \@ldflags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
die("Couldn't find your C compiler.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub check_compiler
|
||||||
|
{
|
||||||
|
my ($compiler, $debug) = @_;
|
||||||
|
if (-f $compiler && -x $compiler) {
|
||||||
|
warn "# Compiler seems to be $compiler\n" if $debug;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
warn "# Compiler was not $compiler\n" if $debug;
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# code substantially borrowed from IPC::Run3
|
# code substantially borrowed from IPC::Run3
|
||||||
sub _quiet_system {
|
sub _quiet_system {
|
||||||
my (@cmd) = @_;
|
my (@cmd) = @_;
|
||||||
|
@ -395,24 +502,24 @@ sub _quiet_system {
|
||||||
local *STDERR_SAVE;
|
local *STDERR_SAVE;
|
||||||
open STDOUT_SAVE, ">&STDOUT" or die "CheckLib: $! saving STDOUT";
|
open STDOUT_SAVE, ">&STDOUT" or die "CheckLib: $! saving STDOUT";
|
||||||
open STDERR_SAVE, ">&STDERR" or die "CheckLib: $! saving STDERR";
|
open STDERR_SAVE, ">&STDERR" or die "CheckLib: $! saving STDERR";
|
||||||
|
|
||||||
# redirect to nowhere
|
# redirect to nowhere
|
||||||
local *DEV_NULL;
|
local *DEV_NULL;
|
||||||
open DEV_NULL, ">" . File::Spec->devnull
|
open DEV_NULL, ">" . File::Spec->devnull
|
||||||
or die "CheckLib: $! opening handle to null device";
|
or die "CheckLib: $! opening handle to null device";
|
||||||
open STDOUT, ">&" . fileno DEV_NULL
|
open STDOUT, ">&" . fileno DEV_NULL
|
||||||
or die "CheckLib: $! redirecting STDOUT to null handle";
|
or die "CheckLib: $! redirecting STDOUT to null handle";
|
||||||
open STDERR, ">&" . fileno DEV_NULL
|
open STDERR, ">&" . fileno DEV_NULL
|
||||||
or die "CheckLib: $! redirecting STDERR to null handle";
|
or die "CheckLib: $! redirecting STDERR to null handle";
|
||||||
|
|
||||||
# run system command
|
# run system command
|
||||||
my $rv = system(@cmd);
|
my $rv = system(@cmd);
|
||||||
|
|
||||||
# restore handles
|
# restore handles
|
||||||
open STDOUT, ">&" . fileno STDOUT_SAVE
|
open STDOUT, ">&" . fileno STDOUT_SAVE
|
||||||
or die "CheckLib: $! restoring STDOUT handle";
|
or die "CheckLib: $! restoring STDOUT handle";
|
||||||
open STDERR, ">&" . fileno STDERR_SAVE
|
open STDERR, ">&" . fileno STDERR_SAVE
|
||||||
or die "CheckLib: $! restoring STDERR handle";
|
or die "CheckLib: $! restoring STDERR handle";
|
||||||
|
|
||||||
return $rv;
|
return $rv;
|
||||||
}
|
}
|
||||||
|
@ -422,7 +529,7 @@ sub _quiet_system {
|
||||||
You must have a C compiler installed. We check for C<$Config{cc}>,
|
You must have a C compiler installed. We check for C<$Config{cc}>,
|
||||||
both literally as it is in Config.pm and also in the $PATH.
|
both literally as it is in Config.pm and also in the $PATH.
|
||||||
|
|
||||||
It has been tested with varying degrees on rigourousness on:
|
It has been tested with varying degrees of rigorousness on:
|
||||||
|
|
||||||
=over
|
=over
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue