From a1d229d14d19abcb40f261b60ec86a8ad5276531 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Fri, 19 Sep 2014 14:10:30 +0200 Subject: [PATCH] import from svn://proxdev/server/svn//libxdgmime-perl/pmg3 --- Makefile | 27 + README | 25 + Xdgmime/Changes | 6 + Xdgmime/MANIFEST | 10 + Xdgmime/Makefile.PL | 54 + Xdgmime/README | 40 + Xdgmime/Xdgmime.xs | 83 + Xdgmime/fallback/const-c.inc | 447 +++ Xdgmime/fallback/const-xs.inc | 90 + Xdgmime/lib/Xdgmime.pm | 195 + Xdgmime/ppport.h | 7063 +++++++++++++++++++++++++++++++++ Xdgmime/t/Xdgmime.t | 14 + Xdgmime/xdgmime.c | 934 +++++ Xdgmime/xdgmime.h | 133 + Xdgmime/xdgmimealias.c | 184 + Xdgmime/xdgmimealias.h | 51 + Xdgmime/xdgmimecache.c | 1069 +++++ Xdgmime/xdgmimecache.h | 81 + Xdgmime/xdgmimeglob.c | 691 ++++ Xdgmime/xdgmimeglob.h | 70 + Xdgmime/xdgmimeicon.c | 183 + Xdgmime/xdgmimeicon.h | 50 + Xdgmime/xdgmimeint.c | 206 + Xdgmime/xdgmimeint.h | 78 + Xdgmime/xdgmimemagic.c | 813 ++++ Xdgmime/xdgmimemagic.h | 57 + Xdgmime/xdgmimeparent.c | 219 + Xdgmime/xdgmimeparent.h | 51 + debian/changelog | 12 + debian/compat | 1 + debian/control | 13 + debian/copyright | 16 + debian/rules | 92 + exports.h | 18 + xdgmime-2012-06-01.tar.gz | Bin 0 -> 160562 bytes 35 files changed, 13076 insertions(+) create mode 100644 Makefile create mode 100644 README create mode 100644 Xdgmime/Changes create mode 100644 Xdgmime/MANIFEST create mode 100644 Xdgmime/Makefile.PL create mode 100644 Xdgmime/README create mode 100644 Xdgmime/Xdgmime.xs create mode 100644 Xdgmime/fallback/const-c.inc create mode 100644 Xdgmime/fallback/const-xs.inc create mode 100644 Xdgmime/lib/Xdgmime.pm create mode 100644 Xdgmime/ppport.h create mode 100644 Xdgmime/t/Xdgmime.t create mode 100644 Xdgmime/xdgmime.c create mode 100644 Xdgmime/xdgmime.h create mode 100644 Xdgmime/xdgmimealias.c create mode 100644 Xdgmime/xdgmimealias.h create mode 100644 Xdgmime/xdgmimecache.c create mode 100644 Xdgmime/xdgmimecache.h create mode 100644 Xdgmime/xdgmimeglob.c create mode 100644 Xdgmime/xdgmimeglob.h create mode 100644 Xdgmime/xdgmimeicon.c create mode 100644 Xdgmime/xdgmimeicon.h create mode 100644 Xdgmime/xdgmimeint.c create mode 100644 Xdgmime/xdgmimeint.h create mode 100644 Xdgmime/xdgmimemagic.c create mode 100644 Xdgmime/xdgmimemagic.h create mode 100644 Xdgmime/xdgmimeparent.c create mode 100644 Xdgmime/xdgmimeparent.h create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100755 debian/rules create mode 100644 exports.h create mode 100644 xdgmime-2012-06-01.tar.gz diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..84ec05a --- /dev/null +++ b/Makefile @@ -0,0 +1,27 @@ +RELEASE=3.0 + +OPKGNAME=Xdgmime +DEB = libxdgmime-perl_0.01-2_amd64.deb + +${DEB}: ${OPKGNAME}/Xdgmime.xs + -rm -rf build + cp -a ${OPKGNAME} build + cp -a debian build + cd build; dpkg-buildpackage -b -us -uc -rfakeroot + lintian ${DEB} + +.phony: upload +upload: ${DEB} + umount /proxmox/${RELEASE}; mount /proxmox/${RELEASE} -o rw + mkdir -p /proxmox/${RELEASE}/extra + rm -rf /proxmox/${RELEASE}/extra/libxdgmime-perl_*.deb + cp ${DEB} /proxmox/${RELEASE}/extra + cd /proxmox/${RELEASE}/extra; dpkg-scanpackages . /dev/null > Packages; gzip -9c Packages > Packages.gz + umount /proxmox/${RELEASE}; mount /proxmox/${RELEASE} -o ro + + +CLEANFILES = *~ debian/*~ *.deb build libxdgmime-perl_* + +.phony: clean +clean: + rm -rf ${CLEANFILES} diff --git a/README b/README new file mode 100644 index 0000000..88b0552 --- /dev/null +++ b/README @@ -0,0 +1,25 @@ +0.) initial package generated with following commands: +###################################################### + +git clone git://anongit.freedesktop.org/xdg/xdgmime + + +man h2xs +man perlxs +man perlxstut + +h2xs -Afn Xdgmime + +cp xdgmime-source/src/xdgmime*.[ch] Xdgmime/ + +create exports.h file in Xdgmime/exports.h + +# Note: following requires package 'libc-scan-perl' +# downloaded that from debian etch archive + +h2xs -Oxan Xdgmime exports.h + +edit Xdgmime/Xdgmime.xs +edit Xdgmime/lib/Xdgmime.pm +edit Xdgmime/Makefile (add -DHAVE_MMAP) + diff --git a/Xdgmime/Changes b/Xdgmime/Changes new file mode 100644 index 0000000..462f934 --- /dev/null +++ b/Xdgmime/Changes @@ -0,0 +1,6 @@ +Revision history for Perl extension Xdgmime. + +0.01 Fri Jun 1 10:46:21 2012 + - original version; created by h2xs 1.23 with options + xdgmime.h + diff --git a/Xdgmime/MANIFEST b/Xdgmime/MANIFEST new file mode 100644 index 0000000..363baee --- /dev/null +++ b/Xdgmime/MANIFEST @@ -0,0 +1,10 @@ +Changes +Makefile.PL +MANIFEST +ppport.h +README +Xdgmime.xs +t/Xdgmime.t +fallback/const-c.inc +fallback/const-xs.inc +lib/Xdgmime.pm diff --git a/Xdgmime/Makefile.PL b/Xdgmime/Makefile.PL new file mode 100644 index 0000000..de596c2 --- /dev/null +++ b/Xdgmime/Makefile.PL @@ -0,0 +1,54 @@ +use 5.010001; +use ExtUtils::MakeMaker; +# See lib/ExtUtils/MakeMaker.pm for details of how to influence +# the contents of the Makefile that is written. +WriteMakefile( + NAME => 'Xdgmime', + VERSION_FROM => 'lib/Xdgmime.pm', # finds $VERSION + PREREQ_PM => {}, # e.g., Module::Name => 1.1 + ($] >= 5.005 ? ## Add these new keywords supported since 5.005 + (ABSTRACT_FROM => 'lib/Xdgmime.pm', # retrieve abstract from module + AUTHOR => 'root ') : ()), + LIBS => [''], # e.g., '-lm' + DEFINE => '-DHAVE_MMAP', # e.g., '-DHAVE_SOMETHING' + INC => '-I.', # e.g., '-I. -I/usr/include/other' + # Un-comment this if you add C files to link with later: + OBJECT => '$(O_FILES)', # link all the C files too +); +if (eval {require ExtUtils::Constant; 1}) { + # If you edit these definitions to change the constants used by this module, + # you will need to use the generated const-c.inc and const-xs.inc + # files to replace their "fallback" counterparts before distributing your + # changes. + my @names = (qw(XDG_MIME_TYPE_EMPTY XDG_MIME_TYPE_TEXTPLAIN + XDG_MIME_TYPE_UNKNOWN _xdg_mime_mime_type_equal + _xdg_mime_mime_type_subclass _xdg_mime_unalias_mime_type + xdg_mime_dump xdg_mime_get_generic_icon xdg_mime_get_icon + xdg_mime_get_max_buffer_extents xdg_mime_get_mime_parents + xdg_mime_get_mime_type_for_data + xdg_mime_get_mime_type_for_file + xdg_mime_get_mime_type_from_file_name + xdg_mime_get_mime_types_from_file_name + xdg_mime_is_valid_mime_type xdg_mime_list_mime_parents + xdg_mime_media_type_equal xdg_mime_mime_type_equal + xdg_mime_mime_type_subclass xdg_mime_register_reload_callback + xdg_mime_remove_callback xdg_mime_shutdown xdg_mime_type_empty + xdg_mime_type_textplain xdg_mime_type_unknown + xdg_mime_unalias_mime_type)); + ExtUtils::Constant::WriteConstants( + NAME => 'Xdgmime', + NAMES => \@names, + DEFAULT_TYPE => 'IV', + C_FILE => 'const-c.inc', + XS_FILE => 'const-xs.inc', + ); + +} +else { + use File::Copy; + use File::Spec; + foreach my $file ('const-c.inc', 'const-xs.inc') { + my $fallback = File::Spec->catfile('fallback', $file); + copy ($fallback, $file) or die "Can't copy $fallback to $file: $!"; + } +} diff --git a/Xdgmime/README b/Xdgmime/README new file mode 100644 index 0000000..018c206 --- /dev/null +++ b/Xdgmime/README @@ -0,0 +1,40 @@ +Xdgmime version 0.01 +==================== + +The README is used to introduce the module and provide instructions on +how to install the module, any machine dependencies it may have (for +example C compilers and installed libraries) and any other information +that should be provided before the module is installed. + +A README file is required for CPAN modules since CPAN extracts the +README file from a module distribution so that people browsing the +archive can use it get an idea of the modules uses. It is usually a +good idea to provide version information here so that people can +decide whether fixes for the module are worth downloading. + +INSTALLATION + +To install this module type the following: + + perl Makefile.PL + make + make test + make install + +DEPENDENCIES + +This module requires these other modules and libraries: + + blah blah blah + +COPYRIGHT AND LICENCE + +Put the correct copyright and licence information here. + +Copyright (C) 2012 by root + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself, either Perl version 5.10.1 or, +at your option, any later version of Perl 5 you may have available. + + diff --git a/Xdgmime/Xdgmime.xs b/Xdgmime/Xdgmime.xs new file mode 100644 index 0000000..edd09bf --- /dev/null +++ b/Xdgmime/Xdgmime.xs @@ -0,0 +1,83 @@ +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + +#include "ppport.h" + +#include + +#include "const-c.inc" + +MODULE = Xdgmime PACKAGE = Xdgmime + +INCLUDE: const-xs.inc + +void +xdg_mime_dump() + +int +xdg_mime_get_max_buffer_extents() + +const char * +xdg_mime_get_mime_type_for_data(data, len) + const char * data + unsigned long len + CODE: + int result_prio; + RETVAL = xdg_mime_get_mime_type_for_data (data, len, &result_prio); + OUTPUT: + RETVAL + +const char * +xdg_mime_get_mime_type_for_file(file_name) + const char * file_name + CODE: + RETVAL = xdg_mime_get_mime_type_for_file (file_name, NULL); + OUTPUT: + RETVAL + +const char * +xdg_mime_get_mime_type_from_file_name(file_name) + const char * file_name + OUTPUT: + RETVAL + +int +xdg_mime_is_valid_mime_type(mime_type) + const char * mime_type + +int +xdg_mime_media_type_equal(mime_a, mime_b) + const char * mime_a + const char * mime_b + +int +xdg_mime_mime_type_equal(mime_a, mime_b) + const char * mime_a + const char * mime_b + +int +xdg_mime_mime_type_subclass(mime_a, mime_b) + const char * mime_a + const char * mime_b + +void +xdg_mime_shutdown() + +SV * +xdg_mime_list_mime_parents (mime_type) + const char * mime_type + INIT: + AV * results; + char **parents; + char **p; + results = (AV *)sv_2mortal((SV *)newAV()); + CODE: + parents = xdg_mime_list_mime_parents (mime_type); + for (p = parents; p && *p; p++) { + av_push(results, newSVpv(*p, 0)); + } + free (parents); + RETVAL = newRV((SV *)results); + OUTPUT: + RETVAL diff --git a/Xdgmime/fallback/const-c.inc b/Xdgmime/fallback/const-c.inc new file mode 100644 index 0000000..004c272 --- /dev/null +++ b/Xdgmime/fallback/const-c.inc @@ -0,0 +1,447 @@ +#define PERL_constant_NOTFOUND 1 +#define PERL_constant_NOTDEF 2 +#define PERL_constant_ISIV 3 +#define PERL_constant_ISNO 4 +#define PERL_constant_ISNV 5 +#define PERL_constant_ISPV 6 +#define PERL_constant_ISPVN 7 +#define PERL_constant_ISSV 8 +#define PERL_constant_ISUNDEF 9 +#define PERL_constant_ISUV 10 +#define PERL_constant_ISYES 11 + +#ifndef NVTYPE +typedef double NV; /* 5.6 and later define NVTYPE, and typedef NV to it. */ +#endif +#ifndef aTHX_ +#define aTHX_ /* 5.6 or later define this for threading support. */ +#endif +#ifndef pTHX_ +#define pTHX_ /* 5.6 or later define this for threading support. */ +#endif + +static int +constant_25 (pTHX_ const char *name, IV *iv_return) { + /* When generated this function returned values for the list of names given + here. However, subsequent manual editing may have added or removed some. + _xdg_mime_mime_type_equal xdg_mime_get_generic_icon + xdg_mime_get_mime_parents xdg_mime_media_type_equal */ + /* Offset 13 gives the best switch position. */ + switch (name[13]) { + case 'a': + if (memEQ(name, "xdg_mime_media_type_equal", 25)) { + /* ^ */ +#ifdef xdg_mime_media_type_equal + *iv_return = xdg_mime_media_type_equal; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + case 'e': + if (memEQ(name, "_xdg_mime_mime_type_equal", 25)) { + /* ^ */ +#ifdef _xdg_mime_mime_type_equal + *iv_return = _xdg_mime_mime_type_equal; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + case 'g': + if (memEQ(name, "xdg_mime_get_generic_icon", 25)) { + /* ^ */ +#ifdef xdg_mime_get_generic_icon + *iv_return = xdg_mime_get_generic_icon; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + case 'm': + if (memEQ(name, "xdg_mime_get_mime_parents", 25)) { + /* ^ */ +#ifdef xdg_mime_get_mime_parents + *iv_return = xdg_mime_get_mime_parents; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + } + return PERL_constant_NOTFOUND; +} + +static int +constant_27 (pTHX_ const char *name, IV *iv_return) { + /* When generated this function returned values for the list of names given + here. However, subsequent manual editing may have added or removed some. + _xdg_mime_unalias_mime_type xdg_mime_is_valid_mime_type + xdg_mime_mime_type_subclass */ + /* Offset 14 gives the best switch position. */ + switch (name[14]) { + case 'i': + if (memEQ(name, "_xdg_mime_unalias_mime_type", 27)) { + /* ^ */ +#ifdef _xdg_mime_unalias_mime_type + *iv_return = _xdg_mime_unalias_mime_type; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + case 'l': + if (memEQ(name, "xdg_mime_is_valid_mime_type", 27)) { + /* ^ */ +#ifdef xdg_mime_is_valid_mime_type + *iv_return = xdg_mime_is_valid_mime_type; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + case 't': + if (memEQ(name, "xdg_mime_mime_type_subclass", 27)) { + /* ^ */ +#ifdef xdg_mime_mime_type_subclass + *iv_return = xdg_mime_mime_type_subclass; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + } + return PERL_constant_NOTFOUND; +} + +static int +constant_31 (pTHX_ const char *name, IV *iv_return) { + /* When generated this function returned values for the list of names given + here. However, subsequent manual editing may have added or removed some. + xdg_mime_get_max_buffer_extents xdg_mime_get_mime_type_for_data + xdg_mime_get_mime_type_for_file */ + /* Offset 27 gives the best switch position. */ + switch (name[27]) { + case 'd': + if (memEQ(name, "xdg_mime_get_mime_type_for_data", 31)) { + /* ^ */ +#ifdef xdg_mime_get_mime_type_for_data + *iv_return = xdg_mime_get_mime_type_for_data; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + case 'e': + if (memEQ(name, "xdg_mime_get_max_buffer_extents", 31)) { + /* ^ */ +#ifdef xdg_mime_get_max_buffer_extents + *iv_return = xdg_mime_get_max_buffer_extents; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + case 'f': + if (memEQ(name, "xdg_mime_get_mime_type_for_file", 31)) { + /* ^ */ +#ifdef xdg_mime_get_mime_type_for_file + *iv_return = xdg_mime_get_mime_type_for_file; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + } + return PERL_constant_NOTFOUND; +} + +static int +constant (pTHX_ const char *name, STRLEN len, IV *iv_return) { + /* Initially switch on the length of the name. */ + /* When generated this function returned values for the list of names given + in this section of perl code. Rather than manually editing these functions + to add or remove constants, which would result in this comment and section + of code becoming inaccurate, we recommend that you edit this section of + code, and use it to regenerate a new set of constant functions which you + then use to replace the originals. + + Regenerate these constant functions by feeding this entire source file to + perl -x + +#!/usr/bin/perl -w +use ExtUtils::Constant qw (constant_types C_constant XS_constant); + +my $types = {map {($_, 1)} qw(IV)}; +my @names = (qw(XDG_MIME_TYPE_EMPTY XDG_MIME_TYPE_TEXTPLAIN + XDG_MIME_TYPE_UNKNOWN _xdg_mime_mime_type_equal + _xdg_mime_mime_type_subclass _xdg_mime_unalias_mime_type + xdg_mime_dump xdg_mime_get_generic_icon xdg_mime_get_icon + xdg_mime_get_max_buffer_extents xdg_mime_get_mime_parents + xdg_mime_get_mime_type_for_data xdg_mime_get_mime_type_for_file + xdg_mime_get_mime_type_from_file_name + xdg_mime_get_mime_types_from_file_name + xdg_mime_is_valid_mime_type xdg_mime_list_mime_parents + xdg_mime_media_type_equal xdg_mime_mime_type_equal + xdg_mime_mime_type_subclass xdg_mime_register_reload_callback + xdg_mime_remove_callback xdg_mime_shutdown xdg_mime_type_empty + xdg_mime_type_textplain xdg_mime_type_unknown + xdg_mime_unalias_mime_type)); + +print constant_types(), "\n"; # macro defs +foreach (C_constant ("Xdgmime", 'constant', 'IV', $types, undef, 3, @names) ) { + print $_, "\n"; # C constant subs +} +print "\n#### XS Section:\n"; +print XS_constant ("Xdgmime", $types); +__END__ + */ + + switch (len) { + case 13: + if (memEQ(name, "xdg_mime_dump", 13)) { +#ifdef xdg_mime_dump + *iv_return = xdg_mime_dump; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + case 17: + /* Names all of length 17. */ + /* xdg_mime_get_icon xdg_mime_shutdown */ + /* Offset 11 gives the best switch position. */ + switch (name[11]) { + case 't': + if (memEQ(name, "xdg_mime_get_icon", 17)) { + /* ^ */ +#ifdef xdg_mime_get_icon + *iv_return = xdg_mime_get_icon; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + case 'u': + if (memEQ(name, "xdg_mime_shutdown", 17)) { + /* ^ */ +#ifdef xdg_mime_shutdown + *iv_return = xdg_mime_shutdown; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + } + break; + case 19: + /* Names all of length 19. */ + /* XDG_MIME_TYPE_EMPTY xdg_mime_type_empty */ + /* Offset 18 gives the best switch position. */ + switch (name[18]) { + case 'Y': + if (memEQ(name, "XDG_MIME_TYPE_EMPT", 18)) { + /* Y */ +#ifdef XDG_MIME_TYPE_EMPTY + *iv_return = XDG_MIME_TYPE_EMPTY; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + case 'y': + if (memEQ(name, "xdg_mime_type_empt", 18)) { + /* y */ +#ifdef xdg_mime_type_empty + *iv_return = xdg_mime_type_empty; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + } + break; + case 21: + /* Names all of length 21. */ + /* XDG_MIME_TYPE_UNKNOWN xdg_mime_type_unknown */ + /* Offset 20 gives the best switch position. */ + switch (name[20]) { + case 'N': + if (memEQ(name, "XDG_MIME_TYPE_UNKNOW", 20)) { + /* N */ +#ifdef XDG_MIME_TYPE_UNKNOWN + *iv_return = XDG_MIME_TYPE_UNKNOWN; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + case 'n': + if (memEQ(name, "xdg_mime_type_unknow", 20)) { + /* n */ +#ifdef xdg_mime_type_unknown + *iv_return = xdg_mime_type_unknown; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + } + break; + case 23: + /* Names all of length 23. */ + /* XDG_MIME_TYPE_TEXTPLAIN xdg_mime_type_textplain */ + /* Offset 22 gives the best switch position. */ + switch (name[22]) { + case 'N': + if (memEQ(name, "XDG_MIME_TYPE_TEXTPLAI", 22)) { + /* N */ +#ifdef XDG_MIME_TYPE_TEXTPLAIN + *iv_return = XDG_MIME_TYPE_TEXTPLAIN; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + case 'n': + if (memEQ(name, "xdg_mime_type_textplai", 22)) { + /* n */ +#ifdef xdg_mime_type_textplain + *iv_return = xdg_mime_type_textplain; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + } + break; + case 24: + /* Names all of length 24. */ + /* xdg_mime_mime_type_equal xdg_mime_remove_callback */ + /* Offset 23 gives the best switch position. */ + switch (name[23]) { + case 'k': + if (memEQ(name, "xdg_mime_remove_callbac", 23)) { + /* k */ +#ifdef xdg_mime_remove_callback + *iv_return = xdg_mime_remove_callback; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + case 'l': + if (memEQ(name, "xdg_mime_mime_type_equa", 23)) { + /* l */ +#ifdef xdg_mime_mime_type_equal + *iv_return = xdg_mime_mime_type_equal; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + } + break; + case 25: + return constant_25 (aTHX_ name, iv_return); + break; + case 26: + /* Names all of length 26. */ + /* xdg_mime_list_mime_parents xdg_mime_unalias_mime_type */ + /* Offset 19 gives the best switch position. */ + switch (name[19]) { + case 'm': + if (memEQ(name, "xdg_mime_unalias_mime_type", 26)) { + /* ^ */ +#ifdef xdg_mime_unalias_mime_type + *iv_return = xdg_mime_unalias_mime_type; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + case 'p': + if (memEQ(name, "xdg_mime_list_mime_parents", 26)) { + /* ^ */ +#ifdef xdg_mime_list_mime_parents + *iv_return = xdg_mime_list_mime_parents; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + } + break; + case 27: + return constant_27 (aTHX_ name, iv_return); + break; + case 28: + if (memEQ(name, "_xdg_mime_mime_type_subclass", 28)) { +#ifdef _xdg_mime_mime_type_subclass + *iv_return = _xdg_mime_mime_type_subclass; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + case 31: + return constant_31 (aTHX_ name, iv_return); + break; + case 33: + if (memEQ(name, "xdg_mime_register_reload_callback", 33)) { +#ifdef xdg_mime_register_reload_callback + *iv_return = xdg_mime_register_reload_callback; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + case 37: + if (memEQ(name, "xdg_mime_get_mime_type_from_file_name", 37)) { +#ifdef xdg_mime_get_mime_type_from_file_name + *iv_return = xdg_mime_get_mime_type_from_file_name; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + case 38: + if (memEQ(name, "xdg_mime_get_mime_types_from_file_name", 38)) { +#ifdef xdg_mime_get_mime_types_from_file_name + *iv_return = xdg_mime_get_mime_types_from_file_name; + return PERL_constant_ISIV; +#else + return PERL_constant_NOTDEF; +#endif + } + break; + } + return PERL_constant_NOTFOUND; +} + diff --git a/Xdgmime/fallback/const-xs.inc b/Xdgmime/fallback/const-xs.inc new file mode 100644 index 0000000..f3436b0 --- /dev/null +++ b/Xdgmime/fallback/const-xs.inc @@ -0,0 +1,90 @@ +void +constant(sv) + PREINIT: +#ifdef dXSTARG + dXSTARG; /* Faster if we have it. */ +#else + dTARGET; +#endif + STRLEN len; + int type; + IV iv; + /* NV nv; Uncomment this if you need to return NVs */ + /* const char *pv; Uncomment this if you need to return PVs */ + INPUT: + SV * sv; + const char * s = SvPV(sv, len); + PPCODE: + /* Change this to constant(aTHX_ s, len, &iv, &nv); + if you need to return both NVs and IVs */ + type = constant(aTHX_ s, len, &iv); + /* Return 1 or 2 items. First is error message, or undef if no error. + Second, if present, is found value */ + switch (type) { + case PERL_constant_NOTFOUND: + sv = + sv_2mortal(newSVpvf("%s is not a valid Xdgmime macro", s)); + PUSHs(sv); + break; + case PERL_constant_NOTDEF: + sv = sv_2mortal(newSVpvf( + "Your vendor has not defined Xdgmime macro %s, used", + s)); + PUSHs(sv); + break; + case PERL_constant_ISIV: + EXTEND(SP, 1); + PUSHs(&PL_sv_undef); + PUSHi(iv); + break; + /* Uncomment this if you need to return NOs + case PERL_constant_ISNO: + EXTEND(SP, 1); + PUSHs(&PL_sv_undef); + PUSHs(&PL_sv_no); + break; */ + /* Uncomment this if you need to return NVs + case PERL_constant_ISNV: + EXTEND(SP, 1); + PUSHs(&PL_sv_undef); + PUSHn(nv); + break; */ + /* Uncomment this if you need to return PVs + case PERL_constant_ISPV: + EXTEND(SP, 1); + PUSHs(&PL_sv_undef); + PUSHp(pv, strlen(pv)); + break; */ + /* Uncomment this if you need to return PVNs + case PERL_constant_ISPVN: + EXTEND(SP, 1); + PUSHs(&PL_sv_undef); + PUSHp(pv, iv); + break; */ + /* Uncomment this if you need to return SVs + case PERL_constant_ISSV: + EXTEND(SP, 1); + PUSHs(&PL_sv_undef); + PUSHs(sv); + break; */ + /* Uncomment this if you need to return UNDEFs + case PERL_constant_ISUNDEF: + break; */ + /* Uncomment this if you need to return UVs + case PERL_constant_ISUV: + EXTEND(SP, 1); + PUSHs(&PL_sv_undef); + PUSHu((UV)iv); + break; */ + /* Uncomment this if you need to return YESs + case PERL_constant_ISYES: + EXTEND(SP, 1); + PUSHs(&PL_sv_undef); + PUSHs(&PL_sv_yes); + break; */ + default: + sv = sv_2mortal(newSVpvf( + "Unexpected return type %d while processing Xdgmime macro %s, used", + type, s)); + PUSHs(sv); + } diff --git a/Xdgmime/lib/Xdgmime.pm b/Xdgmime/lib/Xdgmime.pm new file mode 100644 index 0000000..eba6889 --- /dev/null +++ b/Xdgmime/lib/Xdgmime.pm @@ -0,0 +1,195 @@ +package Xdgmime; + +use 5.010001; +use strict; +use warnings; +use Carp; + +require Exporter; +use AutoLoader; + +our @ISA = qw(Exporter); + +# Items to export into callers namespace by default. Note: do not export +# names by default without a very good reason. Use EXPORT_OK instead. +# Do not simply export all your public functions/methods/constants. + +# This allows declaration use Xdgmime ':all'; +# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK +# will save memory. +our %EXPORT_TAGS = ( 'all' => [ qw( + XDG_MIME_TYPE_EMPTY + XDG_MIME_TYPE_TEXTPLAIN + XDG_MIME_TYPE_UNKNOWN + _xdg_mime_mime_type_equal + _xdg_mime_mime_type_subclass + _xdg_mime_unalias_mime_type + xdg_mime_dump + xdg_mime_get_generic_icon + xdg_mime_get_icon + xdg_mime_get_max_buffer_extents + xdg_mime_get_mime_parents + xdg_mime_get_mime_type_for_data + xdg_mime_get_mime_type_for_file + xdg_mime_get_mime_type_from_file_name + xdg_mime_get_mime_types_from_file_name + xdg_mime_is_valid_mime_type + xdg_mime_list_mime_parents + xdg_mime_media_type_equal + xdg_mime_mime_type_equal + xdg_mime_mime_type_subclass + xdg_mime_register_reload_callback + xdg_mime_remove_callback + xdg_mime_shutdown + xdg_mime_type_empty + xdg_mime_type_textplain + xdg_mime_type_unknown + xdg_mime_unalias_mime_type +) ] ); + +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); + +our @EXPORT = qw( + XDG_MIME_TYPE_EMPTY + XDG_MIME_TYPE_TEXTPLAIN + XDG_MIME_TYPE_UNKNOWN + _xdg_mime_mime_type_equal + _xdg_mime_mime_type_subclass + _xdg_mime_unalias_mime_type + xdg_mime_dump + xdg_mime_get_generic_icon + xdg_mime_get_icon + xdg_mime_get_max_buffer_extents + xdg_mime_get_mime_parents + xdg_mime_get_mime_type_for_data + xdg_mime_get_mime_type_for_file + xdg_mime_get_mime_type_from_file_name + xdg_mime_get_mime_types_from_file_name + xdg_mime_is_valid_mime_type + xdg_mime_list_mime_parents + xdg_mime_media_type_equal + xdg_mime_mime_type_equal + xdg_mime_mime_type_subclass + xdg_mime_register_reload_callback + xdg_mime_remove_callback + xdg_mime_shutdown + xdg_mime_type_empty + xdg_mime_type_textplain + xdg_mime_type_unknown + xdg_mime_unalias_mime_type +); + +our $VERSION = '0.01'; + +sub AUTOLOAD { + # This AUTOLOAD is used to 'autoload' constants from the constant() + # XS function. + + my $constname; + our $AUTOLOAD; + ($constname = $AUTOLOAD) =~ s/.*:://; + croak "&Xdgmime::constant not defined" if $constname eq 'constant'; + my ($error, $val) = constant($constname); + if ($error) { croak $error; } + { + no strict 'refs'; + # Fixed between 5.005_53 and 5.005_61 +#XXX if ($] >= 5.00561) { +#XXX *$AUTOLOAD = sub () { $val }; +#XXX } +#XXX else { + *$AUTOLOAD = sub { $val }; +#XXX } + } + goto &$AUTOLOAD; +} + +require XSLoader; +XSLoader::load('Xdgmime', $VERSION); + +# Preloaded methods go here. + +# Autoload methods go after =cut, and are processed by the autosplit program. + +1; +__END__ +# Below is stub documentation for your module. You'd better edit it! + +=head1 NAME + +Xdgmime - Perl extension for blah blah blah + +=head1 SYNOPSIS + + use Xdgmime; + blah blah blah + +=head1 DESCRIPTION + +Stub documentation for Xdgmime, created by h2xs. It looks like the +author of the extension was negligent enough to leave the stub +unedited. + +Blah blah blah. + +=head2 EXPORT + +None by default. + +=head2 Exportable constants + + XDG_MIME_TYPE_EMPTY + XDG_MIME_TYPE_TEXTPLAIN + XDG_MIME_TYPE_UNKNOWN + _xdg_mime_mime_type_equal + _xdg_mime_mime_type_subclass + _xdg_mime_unalias_mime_type + xdg_mime_dump + xdg_mime_get_generic_icon + xdg_mime_get_icon + xdg_mime_get_max_buffer_extents + xdg_mime_get_mime_parents + xdg_mime_get_mime_type_for_data + xdg_mime_get_mime_type_for_file + xdg_mime_get_mime_type_from_file_name + xdg_mime_get_mime_types_from_file_name + xdg_mime_is_valid_mime_type + xdg_mime_list_mime_parents + xdg_mime_media_type_equal + xdg_mime_mime_type_equal + xdg_mime_mime_type_subclass + xdg_mime_register_reload_callback + xdg_mime_remove_callback + xdg_mime_shutdown + xdg_mime_type_empty + xdg_mime_type_textplain + xdg_mime_type_unknown + xdg_mime_unalias_mime_type + + + +=head1 SEE ALSO + +Mention other useful documentation such as the documentation of +related modules or operating system documentation (such as man pages +in UNIX), or any relevant external documentation such as RFCs or +standards. + +If you have a mailing list set up for your module, mention it here. + +If you have a web site set up for your module, mention it here. + +=head1 AUTHOR + +root, Eroot@E + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2012 by root + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself, either Perl version 5.10.1 or, +at your option, any later version of Perl 5 you may have available. + + +=cut diff --git a/Xdgmime/ppport.h b/Xdgmime/ppport.h new file mode 100644 index 0000000..8ec0d5f --- /dev/null +++ b/Xdgmime/ppport.h @@ -0,0 +1,7063 @@ +#if 0 +<<'SKIP'; +#endif +/* +---------------------------------------------------------------------- + + ppport.h -- Perl/Pollution/Portability Version 3.19 + + Automatically created by Devel::PPPort running under perl 5.010001. + + Do NOT edit this file directly! -- Edit PPPort_pm.PL and the + includes in parts/inc/ instead. + + Use 'perldoc ppport.h' to view the documentation below. + +---------------------------------------------------------------------- + +SKIP + +=pod + +=head1 NAME + +ppport.h - Perl/Pollution/Portability version 3.19 + +=head1 SYNOPSIS + + perl ppport.h [options] [source files] + + Searches current directory for files if no [source files] are given + + --help show short help + + --version show version + + --patch=file write one patch file with changes + --copy=suffix write changed copies with suffix + --diff=program use diff program and options + + --compat-version=version provide compatibility with Perl version + --cplusplus accept C++ comments + + --quiet don't output anything except fatal errors + --nodiag don't show diagnostics + --nohints don't show hints + --nochanges don't suggest changes + --nofilter don't filter input files + + --strip strip all script and doc functionality from + ppport.h + + --list-provided list provided API + --list-unsupported list unsupported API + --api-info=name show Perl API portability information + +=head1 COMPATIBILITY + +This version of F is designed to support operation with Perl +installations back to 5.003, and has been tested up to 5.10.0. + +=head1 OPTIONS + +=head2 --help + +Display a brief usage summary. + +=head2 --version + +Display the version of F. + +=head2 --patch=I + +If this option is given, a single patch file will be created if +any changes are suggested. This requires a working diff program +to be installed on your system. + +=head2 --copy=I + +If this option is given, a copy of each file will be saved with +the given suffix that contains the suggested changes. This does +not require any external programs. Note that this does not +automagially add a dot between the original filename and the +suffix. If you want the dot, you have to include it in the option +argument. + +If neither C<--patch> or C<--copy> are given, the default is to +simply print the diffs for each file. This requires either +C or a C program to be installed. + +=head2 --diff=I + +Manually set the diff program and options to use. The default +is to use C, when installed, and output unified +context diffs. + +=head2 --compat-version=I + +Tell F to check for compatibility with the given +Perl version. The default is to check for compatibility with Perl +version 5.003. You can use this option to reduce the output +of F if you intend to be backward compatible only +down to a certain Perl version. + +=head2 --cplusplus + +Usually, F will detect C++ style comments and +replace them with C style comments for portability reasons. +Using this option instructs F to leave C++ +comments untouched. + +=head2 --quiet + +Be quiet. Don't print anything except fatal errors. + +=head2 --nodiag + +Don't output any diagnostic messages. Only portability +alerts will be printed. + +=head2 --nohints + +Don't output any hints. Hints often contain useful portability +notes. Warnings will still be displayed. + +=head2 --nochanges + +Don't suggest any changes. Only give diagnostic output and hints +unless these are also deactivated. + +=head2 --nofilter + +Don't filter the list of input files. By default, files not looking +like source code (i.e. not *.xs, *.c, *.cc, *.cpp or *.h) are skipped. + +=head2 --strip + +Strip all script and documentation functionality from F. +This reduces the size of F dramatically and may be useful +if you want to include F in smaller modules without +increasing their distribution size too much. + +The stripped F will have a C<--unstrip> option that allows +you to undo the stripping, but only if an appropriate C +module is installed. + +=head2 --list-provided + +Lists the API elements for which compatibility is provided by +F. Also lists if it must be explicitly requested, +if it has dependencies, and if there are hints or warnings for it. + +=head2 --list-unsupported + +Lists the API elements that are known not to be supported by +F and below which version of Perl they probably +won't be available or work. + +=head2 --api-info=I + +Show portability information for API elements matching I. +If I is surrounded by slashes, it is interpreted as a regular +expression. + +=head1 DESCRIPTION + +In order for a Perl extension (XS) module to be as portable as possible +across differing versions of Perl itself, certain steps need to be taken. + +=over 4 + +=item * + +Including this header is the first major one. This alone will give you +access to a large part of the Perl API that hasn't been available in +earlier Perl releases. Use + + perl ppport.h --list-provided + +to see which API elements are provided by ppport.h. + +=item * + +You should avoid using deprecated parts of the API. For example, using +global Perl variables without the C prefix is deprecated. Also, +some API functions used to have a C prefix. Using this form is +also deprecated. You can safely use the supported API, as F +will provide wrappers for older Perl versions. + +=item * + +If you use one of a few functions or variables that were not present in +earlier versions of Perl, and that can't be provided using a macro, you +have to explicitly request support for these functions by adding one or +more C<#define>s in your source code before the inclusion of F. + +These functions or variables will be marked C in the list shown +by C<--list-provided>. + +Depending on whether you module has a single or multiple files that +use such functions or variables, you want either C or global +variants. + +For a C function or variable (used only in a single source +file), use: + + #define NEED_function + #define NEED_variable + +For a global function or variable (used in multiple source files), +use: + + #define NEED_function_GLOBAL + #define NEED_variable_GLOBAL + +Note that you mustn't have more than one global request for the +same function or variable in your project. + + Function / Variable Static Request Global Request + ----------------------------------------------------------------------------------------- + PL_parser NEED_PL_parser NEED_PL_parser_GLOBAL + PL_signals NEED_PL_signals NEED_PL_signals_GLOBAL + eval_pv() NEED_eval_pv NEED_eval_pv_GLOBAL + grok_bin() NEED_grok_bin NEED_grok_bin_GLOBAL + grok_hex() NEED_grok_hex NEED_grok_hex_GLOBAL + grok_number() NEED_grok_number NEED_grok_number_GLOBAL + grok_numeric_radix() NEED_grok_numeric_radix NEED_grok_numeric_radix_GLOBAL + grok_oct() NEED_grok_oct NEED_grok_oct_GLOBAL + load_module() NEED_load_module NEED_load_module_GLOBAL + my_snprintf() NEED_my_snprintf NEED_my_snprintf_GLOBAL + my_sprintf() NEED_my_sprintf NEED_my_sprintf_GLOBAL + my_strlcat() NEED_my_strlcat NEED_my_strlcat_GLOBAL + my_strlcpy() NEED_my_strlcpy NEED_my_strlcpy_GLOBAL + newCONSTSUB() NEED_newCONSTSUB NEED_newCONSTSUB_GLOBAL + newRV_noinc() NEED_newRV_noinc NEED_newRV_noinc_GLOBAL + newSV_type() NEED_newSV_type NEED_newSV_type_GLOBAL + newSVpvn_flags() NEED_newSVpvn_flags NEED_newSVpvn_flags_GLOBAL + newSVpvn_share() NEED_newSVpvn_share NEED_newSVpvn_share_GLOBAL + pv_display() NEED_pv_display NEED_pv_display_GLOBAL + pv_escape() NEED_pv_escape NEED_pv_escape_GLOBAL + pv_pretty() NEED_pv_pretty NEED_pv_pretty_GLOBAL + sv_2pv_flags() NEED_sv_2pv_flags NEED_sv_2pv_flags_GLOBAL + sv_2pvbyte() NEED_sv_2pvbyte NEED_sv_2pvbyte_GLOBAL + sv_catpvf_mg() NEED_sv_catpvf_mg NEED_sv_catpvf_mg_GLOBAL + sv_catpvf_mg_nocontext() NEED_sv_catpvf_mg_nocontext NEED_sv_catpvf_mg_nocontext_GLOBAL + sv_pvn_force_flags() NEED_sv_pvn_force_flags NEED_sv_pvn_force_flags_GLOBAL + sv_setpvf_mg() NEED_sv_setpvf_mg NEED_sv_setpvf_mg_GLOBAL + sv_setpvf_mg_nocontext() NEED_sv_setpvf_mg_nocontext NEED_sv_setpvf_mg_nocontext_GLOBAL + vload_module() NEED_vload_module NEED_vload_module_GLOBAL + vnewSVpvf() NEED_vnewSVpvf NEED_vnewSVpvf_GLOBAL + warner() NEED_warner NEED_warner_GLOBAL + +To avoid namespace conflicts, you can change the namespace of the +explicitly exported functions / variables using the C +macro. Just C<#define> the macro before including C: + + #define DPPP_NAMESPACE MyOwnNamespace_ + #include "ppport.h" + +The default namespace is C. + +=back + +The good thing is that most of the above can be checked by running +F on your source code. See the next section for +details. + +=head1 EXAMPLES + +To verify whether F is needed for your module, whether you +should make any changes to your code, and whether any special defines +should be used, F can be run as a Perl script to check your +source code. Simply say: + + perl ppport.h + +The result will usually be a list of patches suggesting changes +that should at least be acceptable, if not necessarily the most +efficient solution, or a fix for all possible problems. + +If you know that your XS module uses features only available in +newer Perl releases, if you're aware that it uses C++ comments, +and if you want all suggestions as a single patch file, you could +use something like this: + + perl ppport.h --compat-version=5.6.0 --cplusplus --patch=test.diff + +If you only want your code to be scanned without any suggestions +for changes, use: + + perl ppport.h --nochanges + +You can specify a different C program or options, using +the C<--diff> option: + + perl ppport.h --diff='diff -C 10' + +This would output context diffs with 10 lines of context. + +If you want to create patched copies of your files instead, use: + + perl ppport.h --copy=.new + +To display portability information for the C function, +use: + + perl ppport.h --api-info=newSVpvn + +Since the argument to C<--api-info> can be a regular expression, +you can use + + perl ppport.h --api-info=/_nomg$/ + +to display portability information for all C<_nomg> functions or + + perl ppport.h --api-info=/./ + +to display information for all known API elements. + +=head1 BUGS + +If this version of F is causing failure during +the compilation of this module, please check if newer versions +of either this module or C are available on CPAN +before sending a bug report. + +If F was generated using the latest version of +C and is causing failure of this module, please +file a bug report using the CPAN Request Tracker at L. + +Please include the following information: + +=over 4 + +=item 1. + +The complete output from running "perl -V" + +=item 2. + +This file. + +=item 3. + +The name and version of the module you were trying to build. + +=item 4. + +A full log of the build that failed. + +=item 5. + +Any other information that you think could be relevant. + +=back + +For the latest version of this code, please get the C +module from CPAN. + +=head1 COPYRIGHT + +Version 3.x, Copyright (c) 2004-2009, Marcus Holland-Moritz. + +Version 2.x, Copyright (C) 2001, Paul Marquess. + +Version 1.x, Copyright (C) 1999, Kenneth Albanowski. + +This program is free software; you can redistribute it and/or +modify it under the same terms as Perl itself. + +=head1 SEE ALSO + +See L. + +=cut + +use strict; + +# Disable broken TRIE-optimization +BEGIN { eval '${^RE_TRIE_MAXBUF} = -1' if $] >= 5.009004 && $] <= 5.009005 } + +my $VERSION = 3.19; + +my %opt = ( + quiet => 0, + diag => 1, + hints => 1, + changes => 1, + cplusplus => 0, + filter => 1, + strip => 0, + version => 0, +); + +my($ppport) = $0 =~ /([\w.]+)$/; +my $LF = '(?:\r\n|[\r\n])'; # line feed +my $HS = "[ \t]"; # horizontal whitespace + +# Never use C comments in this file! +my $ccs = '/'.'*'; +my $cce = '*'.'/'; +my $rccs = quotemeta $ccs; +my $rcce = quotemeta $cce; + +eval { + require Getopt::Long; + Getopt::Long::GetOptions(\%opt, qw( + help quiet diag! filter! hints! changes! cplusplus strip version + patch=s copy=s diff=s compat-version=s + list-provided list-unsupported api-info=s + )) or usage(); +}; + +if ($@ and grep /^-/, @ARGV) { + usage() if "@ARGV" =~ /^--?h(?:elp)?$/; + die "Getopt::Long not found. Please don't use any options.\n"; +} + +if ($opt{version}) { + print "This is $0 $VERSION.\n"; + exit 0; +} + +usage() if $opt{help}; +strip() if $opt{strip}; + +if (exists $opt{'compat-version'}) { + my($r,$v,$s) = eval { parse_version($opt{'compat-version'}) }; + if ($@) { + die "Invalid version number format: '$opt{'compat-version'}'\n"; + } + die "Only Perl 5 is supported\n" if $r != 5; + die "Invalid version number: $opt{'compat-version'}\n" if $v >= 1000 || $s >= 1000; + $opt{'compat-version'} = sprintf "%d.%03d%03d", $r, $v, $s; +} +else { + $opt{'compat-version'} = 5; +} + +my %API = map { /^(\w+)\|([^|]*)\|([^|]*)\|(\w*)$/ + ? ( $1 => { + ($2 ? ( base => $2 ) : ()), + ($3 ? ( todo => $3 ) : ()), + (index($4, 'v') >= 0 ? ( varargs => 1 ) : ()), + (index($4, 'p') >= 0 ? ( provided => 1 ) : ()), + (index($4, 'n') >= 0 ? ( nothxarg => 1 ) : ()), + } ) + : die "invalid spec: $_" } qw( +AvFILLp|5.004050||p +AvFILL||| +CLASS|||n +CPERLscope|5.005000||p +CX_CURPAD_SAVE||| +CX_CURPAD_SV||| +CopFILEAV|5.006000||p +CopFILEGV_set|5.006000||p +CopFILEGV|5.006000||p +CopFILESV|5.006000||p +CopFILE_set|5.006000||p +CopFILE|5.006000||p +CopSTASHPV_set|5.006000||p +CopSTASHPV|5.006000||p +CopSTASH_eq|5.006000||p +CopSTASH_set|5.006000||p +CopSTASH|5.006000||p +CopyD|5.009002||p +Copy||| +CvPADLIST||| +CvSTASH||| +CvWEAKOUTSIDE||| +DEFSV_set|5.011000||p +DEFSV|5.004050||p +END_EXTERN_C|5.005000||p +ENTER||| +ERRSV|5.004050||p +EXTEND||| +EXTERN_C|5.005000||p +F0convert|||n +FREETMPS||| +GIMME_V||5.004000|n +GIMME|||n +GROK_NUMERIC_RADIX|5.007002||p +G_ARRAY||| +G_DISCARD||| +G_EVAL||| +G_METHOD|5.006001||p +G_NOARGS||| +G_SCALAR||| +G_VOID||5.004000| +GetVars||| +GvSVn|5.009003||p +GvSV||| +Gv_AMupdate||| +HEf_SVKEY||5.004000| +HeHASH||5.004000| +HeKEY||5.004000| +HeKLEN||5.004000| +HePV||5.004000| +HeSVKEY_force||5.004000| +HeSVKEY_set||5.004000| +HeSVKEY||5.004000| +HeUTF8||5.011000| +HeVAL||5.004000| +HvNAMELEN_get|5.009003||p +HvNAME_get|5.009003||p +HvNAME||| +INT2PTR|5.006000||p +IN_LOCALE_COMPILETIME|5.007002||p +IN_LOCALE_RUNTIME|5.007002||p +IN_LOCALE|5.007002||p +IN_PERL_COMPILETIME|5.008001||p +IS_NUMBER_GREATER_THAN_UV_MAX|5.007002||p +IS_NUMBER_INFINITY|5.007002||p +IS_NUMBER_IN_UV|5.007002||p +IS_NUMBER_NAN|5.007003||p +IS_NUMBER_NEG|5.007002||p +IS_NUMBER_NOT_INT|5.007002||p +IVSIZE|5.006000||p +IVTYPE|5.006000||p +IVdf|5.006000||p +LEAVE||| +LVRET||| +MARK||| +MULTICALL||5.011000| +MY_CXT_CLONE|5.009002||p +MY_CXT_INIT|5.007003||p +MY_CXT|5.007003||p +MoveD|5.009002||p +Move||| +NOOP|5.005000||p +NUM2PTR|5.006000||p +NVTYPE|5.006000||p +NVef|5.006001||p +NVff|5.006001||p +NVgf|5.006001||p +Newxc|5.009003||p +Newxz|5.009003||p +Newx|5.009003||p +Nullav||| +Nullch||| +Nullcv||| +Nullhv||| +Nullsv||| +ORIGMARK||| +PAD_BASE_SV||| +PAD_CLONE_VARS||| +PAD_COMPNAME_FLAGS||| +PAD_COMPNAME_GEN_set||| +PAD_COMPNAME_GEN||| +PAD_COMPNAME_OURSTASH||| +PAD_COMPNAME_PV||| +PAD_COMPNAME_TYPE||| +PAD_DUP||| +PAD_RESTORE_LOCAL||| +PAD_SAVE_LOCAL||| +PAD_SAVE_SETNULLPAD||| +PAD_SETSV||| +PAD_SET_CUR_NOSAVE||| +PAD_SET_CUR||| +PAD_SVl||| +PAD_SV||| +PERLIO_FUNCS_CAST|5.009003||p +PERLIO_FUNCS_DECL|5.009003||p +PERL_ABS|5.008001||p +PERL_BCDVERSION|5.011000||p +PERL_GCC_BRACE_GROUPS_FORBIDDEN|5.008001||p +PERL_HASH|5.004000||p +PERL_INT_MAX|5.004000||p +PERL_INT_MIN|5.004000||p +PERL_LONG_MAX|5.004000||p +PERL_LONG_MIN|5.004000||p +PERL_MAGIC_arylen|5.007002||p +PERL_MAGIC_backref|5.007002||p +PERL_MAGIC_bm|5.007002||p +PERL_MAGIC_collxfrm|5.007002||p +PERL_MAGIC_dbfile|5.007002||p +PERL_MAGIC_dbline|5.007002||p +PERL_MAGIC_defelem|5.007002||p +PERL_MAGIC_envelem|5.007002||p +PERL_MAGIC_env|5.007002||p +PERL_MAGIC_ext|5.007002||p +PERL_MAGIC_fm|5.007002||p +PERL_MAGIC_glob|5.011000||p +PERL_MAGIC_isaelem|5.007002||p +PERL_MAGIC_isa|5.007002||p +PERL_MAGIC_mutex|5.011000||p +PERL_MAGIC_nkeys|5.007002||p +PERL_MAGIC_overload_elem|5.007002||p +PERL_MAGIC_overload_table|5.007002||p +PERL_MAGIC_overload|5.007002||p +PERL_MAGIC_pos|5.007002||p +PERL_MAGIC_qr|5.007002||p +PERL_MAGIC_regdata|5.007002||p +PERL_MAGIC_regdatum|5.007002||p +PERL_MAGIC_regex_global|5.007002||p +PERL_MAGIC_shared_scalar|5.007003||p +PERL_MAGIC_shared|5.007003||p +PERL_MAGIC_sigelem|5.007002||p +PERL_MAGIC_sig|5.007002||p +PERL_MAGIC_substr|5.007002||p +PERL_MAGIC_sv|5.007002||p +PERL_MAGIC_taint|5.007002||p +PERL_MAGIC_tiedelem|5.007002||p +PERL_MAGIC_tiedscalar|5.007002||p +PERL_MAGIC_tied|5.007002||p +PERL_MAGIC_utf8|5.008001||p +PERL_MAGIC_uvar_elem|5.007003||p +PERL_MAGIC_uvar|5.007002||p +PERL_MAGIC_vec|5.007002||p +PERL_MAGIC_vstring|5.008001||p +PERL_PV_ESCAPE_ALL|5.009004||p +PERL_PV_ESCAPE_FIRSTCHAR|5.009004||p +PERL_PV_ESCAPE_NOBACKSLASH|5.009004||p +PERL_PV_ESCAPE_NOCLEAR|5.009004||p +PERL_PV_ESCAPE_QUOTE|5.009004||p +PERL_PV_ESCAPE_RE|5.009005||p +PERL_PV_ESCAPE_UNI_DETECT|5.009004||p +PERL_PV_ESCAPE_UNI|5.009004||p +PERL_PV_PRETTY_DUMP|5.009004||p +PERL_PV_PRETTY_ELLIPSES|5.010000||p +PERL_PV_PRETTY_LTGT|5.009004||p +PERL_PV_PRETTY_NOCLEAR|5.010000||p +PERL_PV_PRETTY_QUOTE|5.009004||p +PERL_PV_PRETTY_REGPROP|5.009004||p +PERL_QUAD_MAX|5.004000||p +PERL_QUAD_MIN|5.004000||p +PERL_REVISION|5.006000||p +PERL_SCAN_ALLOW_UNDERSCORES|5.007003||p +PERL_SCAN_DISALLOW_PREFIX|5.007003||p +PERL_SCAN_GREATER_THAN_UV_MAX|5.007003||p +PERL_SCAN_SILENT_ILLDIGIT|5.008001||p +PERL_SHORT_MAX|5.004000||p +PERL_SHORT_MIN|5.004000||p +PERL_SIGNALS_UNSAFE_FLAG|5.008001||p +PERL_SUBVERSION|5.006000||p +PERL_SYS_INIT3||5.006000| +PERL_SYS_INIT||| +PERL_SYS_TERM||5.011000| +PERL_UCHAR_MAX|5.004000||p +PERL_UCHAR_MIN|5.004000||p +PERL_UINT_MAX|5.004000||p +PERL_UINT_MIN|5.004000||p +PERL_ULONG_MAX|5.004000||p +PERL_ULONG_MIN|5.004000||p +PERL_UNUSED_ARG|5.009003||p +PERL_UNUSED_CONTEXT|5.009004||p +PERL_UNUSED_DECL|5.007002||p +PERL_UNUSED_VAR|5.007002||p +PERL_UQUAD_MAX|5.004000||p +PERL_UQUAD_MIN|5.004000||p +PERL_USE_GCC_BRACE_GROUPS|5.009004||p +PERL_USHORT_MAX|5.004000||p +PERL_USHORT_MIN|5.004000||p +PERL_VERSION|5.006000||p +PL_DBsignal|5.005000||p +PL_DBsingle|||pn +PL_DBsub|||pn +PL_DBtrace|||pn +PL_Sv|5.005000||p +PL_bufend|5.011000||p +PL_bufptr|5.011000||p +PL_compiling|5.004050||p +PL_copline|5.011000||p +PL_curcop|5.004050||p +PL_curstash|5.004050||p +PL_debstash|5.004050||p +PL_defgv|5.004050||p +PL_diehook|5.004050||p +PL_dirty|5.004050||p +PL_dowarn|||pn +PL_errgv|5.004050||p +PL_error_count|5.011000||p +PL_expect|5.011000||p +PL_hexdigit|5.005000||p +PL_hints|5.005000||p +PL_in_my_stash|5.011000||p +PL_in_my|5.011000||p +PL_last_in_gv|||n +PL_laststatval|5.005000||p +PL_lex_state|5.011000||p +PL_lex_stuff|5.011000||p +PL_linestr|5.011000||p +PL_modglobal||5.005000|n +PL_na|5.004050||pn +PL_no_modify|5.006000||p +PL_ofsgv|||n +PL_parser|5.009005||p +PL_perl_destruct_level|5.004050||p +PL_perldb|5.004050||p +PL_ppaddr|5.006000||p +PL_rsfp_filters|5.004050||p +PL_rsfp|5.004050||p +PL_rs|||n +PL_signals|5.008001||p +PL_stack_base|5.004050||p +PL_stack_sp|5.004050||p +PL_statcache|5.005000||p +PL_stdingv|5.004050||p +PL_sv_arenaroot|5.004050||p +PL_sv_no|5.004050||pn +PL_sv_undef|5.004050||pn +PL_sv_yes|5.004050||pn +PL_tainted|5.004050||p +PL_tainting|5.004050||p +PL_tokenbuf|5.011000||p +POP_MULTICALL||5.011000| +POPi|||n +POPl|||n +POPn|||n +POPpbytex||5.007001|n +POPpx||5.005030|n +POPp|||n +POPs|||n +PTR2IV|5.006000||p +PTR2NV|5.006000||p +PTR2UV|5.006000||p +PTR2nat|5.009003||p +PTR2ul|5.007001||p +PTRV|5.006000||p +PUSHMARK||| +PUSH_MULTICALL||5.011000| +PUSHi||| +PUSHmortal|5.009002||p +PUSHn||| +PUSHp||| +PUSHs||| +PUSHu|5.004000||p +PUTBACK||| +PerlIO_clearerr||5.007003| +PerlIO_close||5.007003| +PerlIO_context_layers||5.009004| +PerlIO_eof||5.007003| +PerlIO_error||5.007003| +PerlIO_fileno||5.007003| +PerlIO_fill||5.007003| +PerlIO_flush||5.007003| +PerlIO_get_base||5.007003| +PerlIO_get_bufsiz||5.007003| +PerlIO_get_cnt||5.007003| +PerlIO_get_ptr||5.007003| +PerlIO_read||5.007003| +PerlIO_seek||5.007003| +PerlIO_set_cnt||5.007003| +PerlIO_set_ptrcnt||5.007003| +PerlIO_setlinebuf||5.007003| +PerlIO_stderr||5.007003| +PerlIO_stdin||5.007003| +PerlIO_stdout||5.007003| +PerlIO_tell||5.007003| +PerlIO_unread||5.007003| +PerlIO_write||5.007003| +Perl_signbit||5.009005|n +PoisonFree|5.009004||p +PoisonNew|5.009004||p +PoisonWith|5.009004||p +Poison|5.008000||p +RETVAL|||n +Renewc||| +Renew||| +SAVECLEARSV||| +SAVECOMPPAD||| +SAVEPADSV||| +SAVETMPS||| +SAVE_DEFSV|5.004050||p +SPAGAIN||| +SP||| +START_EXTERN_C|5.005000||p +START_MY_CXT|5.007003||p +STMT_END|||p +STMT_START|||p +STR_WITH_LEN|5.009003||p +ST||| +SV_CONST_RETURN|5.009003||p +SV_COW_DROP_PV|5.008001||p +SV_COW_SHARED_HASH_KEYS|5.009005||p +SV_GMAGIC|5.007002||p +SV_HAS_TRAILING_NUL|5.009004||p +SV_IMMEDIATE_UNREF|5.007001||p +SV_MUTABLE_RETURN|5.009003||p +SV_NOSTEAL|5.009002||p +SV_SMAGIC|5.009003||p +SV_UTF8_NO_ENCODING|5.008001||p +SVfARG|5.009005||p +SVf_UTF8|5.006000||p +SVf|5.006000||p +SVt_IV||| +SVt_NV||| +SVt_PVAV||| +SVt_PVCV||| +SVt_PVHV||| +SVt_PVMG||| +SVt_PV||| +Safefree||| +Slab_Alloc||| +Slab_Free||| +Slab_to_rw||| +StructCopy||| +SvCUR_set||| +SvCUR||| +SvEND||| +SvGAMAGIC||5.006001| +SvGETMAGIC|5.004050||p +SvGROW||| +SvIOK_UV||5.006000| +SvIOK_notUV||5.006000| +SvIOK_off||| +SvIOK_only_UV||5.006000| +SvIOK_only||| +SvIOK_on||| +SvIOKp||| +SvIOK||| +SvIVX||| +SvIV_nomg|5.009001||p +SvIV_set||| +SvIVx||| +SvIV||| +SvIsCOW_shared_hash||5.008003| +SvIsCOW||5.008003| +SvLEN_set||| +SvLEN||| +SvLOCK||5.007003| +SvMAGIC_set|5.009003||p +SvNIOK_off||| +SvNIOKp||| +SvNIOK||| +SvNOK_off||| +SvNOK_only||| +SvNOK_on||| +SvNOKp||| +SvNOK||| +SvNVX||| +SvNV_set||| +SvNVx||| +SvNV||| +SvOK||| +SvOOK_offset||5.011000| +SvOOK||| +SvPOK_off||| +SvPOK_only_UTF8||5.006000| +SvPOK_only||| +SvPOK_on||| +SvPOKp||| +SvPOK||| +SvPVX_const|5.009003||p +SvPVX_mutable|5.009003||p +SvPVX||| +SvPV_const|5.009003||p +SvPV_flags_const_nolen|5.009003||p +SvPV_flags_const|5.009003||p +SvPV_flags_mutable|5.009003||p +SvPV_flags|5.007002||p +SvPV_force_flags_mutable|5.009003||p +SvPV_force_flags_nolen|5.009003||p +SvPV_force_flags|5.007002||p +SvPV_force_mutable|5.009003||p +SvPV_force_nolen|5.009003||p +SvPV_force_nomg_nolen|5.009003||p +SvPV_force_nomg|5.007002||p +SvPV_force|||p +SvPV_mutable|5.009003||p +SvPV_nolen_const|5.009003||p +SvPV_nolen|5.006000||p +SvPV_nomg_const_nolen|5.009003||p +SvPV_nomg_const|5.009003||p +SvPV_nomg|5.007002||p +SvPV_renew|5.009003||p +SvPV_set||| +SvPVbyte_force||5.009002| +SvPVbyte_nolen||5.006000| +SvPVbytex_force||5.006000| +SvPVbytex||5.006000| +SvPVbyte|5.006000||p +SvPVutf8_force||5.006000| +SvPVutf8_nolen||5.006000| +SvPVutf8x_force||5.006000| +SvPVutf8x||5.006000| +SvPVutf8||5.006000| +SvPVx||| +SvPV||| +SvREFCNT_dec||| +SvREFCNT_inc_NN|5.009004||p +SvREFCNT_inc_simple_NN|5.009004||p +SvREFCNT_inc_simple_void_NN|5.009004||p +SvREFCNT_inc_simple_void|5.009004||p +SvREFCNT_inc_simple|5.009004||p +SvREFCNT_inc_void_NN|5.009004||p +SvREFCNT_inc_void|5.009004||p +SvREFCNT_inc|||p +SvREFCNT||| +SvROK_off||| +SvROK_on||| +SvROK||| +SvRV_set|5.009003||p +SvRV||| +SvRXOK||5.009005| +SvRX||5.009005| +SvSETMAGIC||| +SvSHARED_HASH|5.009003||p +SvSHARE||5.007003| +SvSTASH_set|5.009003||p +SvSTASH||| +SvSetMagicSV_nosteal||5.004000| +SvSetMagicSV||5.004000| +SvSetSV_nosteal||5.004000| +SvSetSV||| +SvTAINTED_off||5.004000| +SvTAINTED_on||5.004000| +SvTAINTED||5.004000| +SvTAINT||| +SvTRUE||| +SvTYPE||| +SvUNLOCK||5.007003| +SvUOK|5.007001|5.006000|p +SvUPGRADE||| +SvUTF8_off||5.006000| +SvUTF8_on||5.006000| +SvUTF8||5.006000| +SvUVXx|5.004000||p +SvUVX|5.004000||p +SvUV_nomg|5.009001||p +SvUV_set|5.009003||p +SvUVx|5.004000||p +SvUV|5.004000||p +SvVOK||5.008001| +SvVSTRING_mg|5.009004||p +THIS|||n +UNDERBAR|5.009002||p +UTF8_MAXBYTES|5.009002||p +UVSIZE|5.006000||p +UVTYPE|5.006000||p +UVXf|5.007001||p +UVof|5.006000||p +UVuf|5.006000||p +UVxf|5.006000||p +WARN_ALL|5.006000||p +WARN_AMBIGUOUS|5.006000||p +WARN_ASSERTIONS|5.011000||p +WARN_BAREWORD|5.006000||p +WARN_CLOSED|5.006000||p +WARN_CLOSURE|5.006000||p +WARN_DEBUGGING|5.006000||p +WARN_DEPRECATED|5.006000||p +WARN_DIGIT|5.006000||p +WARN_EXEC|5.006000||p +WARN_EXITING|5.006000||p +WARN_GLOB|5.006000||p +WARN_INPLACE|5.006000||p +WARN_INTERNAL|5.006000||p +WARN_IO|5.006000||p +WARN_LAYER|5.008000||p +WARN_MALLOC|5.006000||p +WARN_MISC|5.006000||p +WARN_NEWLINE|5.006000||p +WARN_NUMERIC|5.006000||p +WARN_ONCE|5.006000||p +WARN_OVERFLOW|5.006000||p +WARN_PACK|5.006000||p +WARN_PARENTHESIS|5.006000||p +WARN_PIPE|5.006000||p +WARN_PORTABLE|5.006000||p +WARN_PRECEDENCE|5.006000||p +WARN_PRINTF|5.006000||p +WARN_PROTOTYPE|5.006000||p +WARN_QW|5.006000||p +WARN_RECURSION|5.006000||p +WARN_REDEFINE|5.006000||p +WARN_REGEXP|5.006000||p +WARN_RESERVED|5.006000||p +WARN_SEMICOLON|5.006000||p +WARN_SEVERE|5.006000||p +WARN_SIGNAL|5.006000||p +WARN_SUBSTR|5.006000||p +WARN_SYNTAX|5.006000||p +WARN_TAINT|5.006000||p +WARN_THREADS|5.008000||p +WARN_UNINITIALIZED|5.006000||p +WARN_UNOPENED|5.006000||p +WARN_UNPACK|5.006000||p +WARN_UNTIE|5.006000||p +WARN_UTF8|5.006000||p +WARN_VOID|5.006000||p +XCPT_CATCH|5.009002||p +XCPT_RETHROW|5.009002||p +XCPT_TRY_END|5.009002||p +XCPT_TRY_START|5.009002||p +XPUSHi||| +XPUSHmortal|5.009002||p +XPUSHn||| +XPUSHp||| +XPUSHs||| +XPUSHu|5.004000||p +XSPROTO|5.010000||p +XSRETURN_EMPTY||| +XSRETURN_IV||| +XSRETURN_NO||| +XSRETURN_NV||| +XSRETURN_PV||| +XSRETURN_UNDEF||| +XSRETURN_UV|5.008001||p +XSRETURN_YES||| +XSRETURN|||p +XST_mIV||| +XST_mNO||| +XST_mNV||| +XST_mPV||| +XST_mUNDEF||| +XST_mUV|5.008001||p +XST_mYES||| +XS_VERSION_BOOTCHECK||| +XS_VERSION||| +XSprePUSH|5.006000||p +XS||| +ZeroD|5.009002||p +Zero||| +_aMY_CXT|5.007003||p +_pMY_CXT|5.007003||p +aMY_CXT_|5.007003||p +aMY_CXT|5.007003||p +aTHXR_|5.011000||p +aTHXR|5.011000||p +aTHX_|5.006000||p +aTHX|5.006000||p +add_data|||n +addmad||| +allocmy||| +amagic_call||| +amagic_cmp_locale||| +amagic_cmp||| +amagic_i_ncmp||| +amagic_ncmp||| +any_dup||| +ao||| +append_elem||| +append_list||| +append_madprops||| +apply_attrs_my||| +apply_attrs_string||5.006001| +apply_attrs||| +apply||| +atfork_lock||5.007003|n +atfork_unlock||5.007003|n +av_arylen_p||5.009003| +av_clear||| +av_create_and_push||5.009005| +av_create_and_unshift_one||5.009005| +av_delete||5.006000| +av_exists||5.006000| +av_extend||| +av_fetch||| +av_fill||| +av_iter_p||5.011000| +av_len||| +av_make||| +av_pop||| +av_push||| +av_reify||| +av_shift||| +av_store||| +av_undef||| +av_unshift||| +ax|||n +bad_type||| +bind_match||| +block_end||| +block_gimme||5.004000| +block_start||| +boolSV|5.004000||p +boot_core_PerlIO||| +boot_core_UNIVERSAL||| +boot_core_mro||| +bytes_from_utf8||5.007001| +bytes_to_uni|||n +bytes_to_utf8||5.006001| +call_argv|5.006000||p +call_atexit||5.006000| +call_list||5.004000| +call_method|5.006000||p +call_pv|5.006000||p +call_sv|5.006000||p +calloc||5.007002|n +cando||| +cast_i32||5.006000| +cast_iv||5.006000| +cast_ulong||5.006000| +cast_uv||5.006000| +check_type_and_open||| +check_uni||| +checkcomma||| +checkposixcc||| +ckWARN|5.006000||p +ck_anoncode||| +ck_bitop||| +ck_concat||| +ck_defined||| +ck_delete||| +ck_die||| +ck_each||| +ck_eof||| +ck_eval||| +ck_exec||| +ck_exists||| +ck_exit||| +ck_ftst||| +ck_fun||| +ck_glob||| +ck_grep||| +ck_index||| +ck_join||| +ck_lfun||| +ck_listiob||| +ck_match||| +ck_method||| +ck_null||| +ck_open||| +ck_readline||| +ck_repeat||| +ck_require||| +ck_return||| +ck_rfun||| +ck_rvconst||| +ck_sassign||| +ck_select||| +ck_shift||| +ck_sort||| +ck_spair||| +ck_split||| +ck_subr||| +ck_substr||| +ck_svconst||| +ck_trunc||| +ck_unpack||| +ckwarn_d||5.009003| +ckwarn||5.009003| +cl_and|||n +cl_anything|||n +cl_init_zero|||n +cl_init|||n +cl_is_anything|||n +cl_or|||n +clear_placeholders||| +closest_cop||| +convert||| +cop_free||| +cr_textfilter||| +create_eval_scope||| +croak_nocontext|||vn +croak_xs_usage||5.011000| +croak|||v +csighandler||5.009003|n +curmad||| +custom_op_desc||5.007003| +custom_op_name||5.007003| +cv_ckproto_len||| +cv_clone||| +cv_const_sv||5.004000| +cv_dump||| +cv_undef||| +cx_dump||5.005000| +cx_dup||| +cxinc||| +dAXMARK|5.009003||p +dAX|5.007002||p +dITEMS|5.007002||p +dMARK||| +dMULTICALL||5.009003| +dMY_CXT_SV|5.007003||p +dMY_CXT|5.007003||p +dNOOP|5.006000||p +dORIGMARK||| +dSP||| +dTHR|5.004050||p +dTHXR|5.011000||p +dTHXa|5.006000||p +dTHXoa|5.006000||p +dTHX|5.006000||p +dUNDERBAR|5.009002||p +dVAR|5.009003||p +dXCPT|5.009002||p +dXSARGS||| +dXSI32||| +dXSTARG|5.006000||p +deb_curcv||| +deb_nocontext|||vn +deb_stack_all||| +deb_stack_n||| +debop||5.005000| +debprofdump||5.005000| +debprof||| +debstackptrs||5.007003| +debstack||5.007003| +debug_start_match||| +deb||5.007003|v +del_sv||| +delete_eval_scope||| +delimcpy||5.004000| +deprecate_old||| +deprecate||| +despatch_signals||5.007001| +destroy_matcher||| +die_nocontext|||vn +die_where||| +die|||v +dirp_dup||| +div128||| +djSP||| +do_aexec5||| +do_aexec||| +do_aspawn||| +do_binmode||5.004050| +do_chomp||| +do_chop||| +do_close||| +do_dump_pad||| +do_eof||| +do_exec3||| +do_execfree||| +do_exec||| +do_gv_dump||5.006000| +do_gvgv_dump||5.006000| +do_hv_dump||5.006000| +do_ipcctl||| +do_ipcget||| +do_join||| +do_kv||| +do_magic_dump||5.006000| +do_msgrcv||| +do_msgsnd||| +do_oddball||| +do_op_dump||5.006000| +do_op_xmldump||| +do_open9||5.006000| +do_openn||5.007001| +do_open||5.004000| +do_pmop_dump||5.006000| +do_pmop_xmldump||| +do_print||| +do_readline||| +do_seek||| +do_semop||| +do_shmio||| +do_smartmatch||| +do_spawn_nowait||| +do_spawn||| +do_sprintf||| +do_sv_dump||5.006000| +do_sysseek||| +do_tell||| +do_trans_complex_utf8||| +do_trans_complex||| +do_trans_count_utf8||| +do_trans_count||| +do_trans_simple_utf8||| +do_trans_simple||| +do_trans||| +do_vecget||| +do_vecset||| +do_vop||| +docatch||| +doeval||| +dofile||| +dofindlabel||| +doform||| +doing_taint||5.008001|n +dooneliner||| +doopen_pm||| +doparseform||| +dopoptoeval||| +dopoptogiven||| +dopoptolabel||| +dopoptoloop||| +dopoptosub_at||| +dopoptowhen||| +doref||5.009003| +dounwind||| +dowantarray||| +dump_all||5.006000| +dump_eval||5.006000| +dump_exec_pos||| +dump_fds||| +dump_form||5.006000| +dump_indent||5.006000|v +dump_mstats||| +dump_packsubs||5.006000| +dump_sub||5.006000| +dump_sv_child||| +dump_trie_interim_list||| +dump_trie_interim_table||| +dump_trie||| +dump_vindent||5.006000| +dumpuntil||| +dup_attrlist||| +emulate_cop_io||| +eval_pv|5.006000||p +eval_sv|5.006000||p +exec_failed||| +expect_number||| +fbm_compile||5.005000| +fbm_instr||5.005000| +feature_is_enabled||| +fetch_cop_label||5.011000| +filter_add||| +filter_del||| +filter_gets||| +filter_read||| +find_and_forget_pmops||| +find_array_subscript||| +find_beginning||| +find_byclass||| +find_hash_subscript||| +find_in_my_stash||| +find_runcv||5.008001| +find_rundefsvoffset||5.009002| +find_script||| +find_uninit_var||| +first_symbol|||n +fold_constants||| +forbid_setid||| +force_ident||| +force_list||| +force_next||| +force_version||| +force_word||| +forget_pmop||| +form_nocontext|||vn +form||5.004000|v +fp_dup||| +fprintf_nocontext|||vn +free_global_struct||| +free_tied_hv_pool||| +free_tmps||| +gen_constant_list||| +get_arena||| +get_aux_mg||| +get_av|5.006000||p +get_context||5.006000|n +get_cvn_flags||5.009005| +get_cv|5.006000||p +get_db_sub||| +get_debug_opts||| +get_hash_seed||| +get_hv|5.006000||p +get_isa_hash||| +get_mstats||| +get_no_modify||| +get_num||| +get_op_descs||5.005000| +get_op_names||5.005000| +get_opargs||| +get_ppaddr||5.006000| +get_re_arg||| +get_sv|5.006000||p +get_vtbl||5.005030| +getcwd_sv||5.007002| +getenv_len||| +glob_2number||| +glob_assign_glob||| +glob_assign_ref||| +gp_dup||| +gp_free||| +gp_ref||| +grok_bin|5.007003||p +grok_hex|5.007003||p +grok_number|5.007002||p +grok_numeric_radix|5.007002||p +grok_oct|5.007003||p +group_end||| +gv_AVadd||| +gv_HVadd||| +gv_IOadd||| +gv_SVadd||| +gv_autoload4||5.004000| +gv_check||| +gv_const_sv||5.009003| +gv_dump||5.006000| +gv_efullname3||5.004000| +gv_efullname4||5.006001| +gv_efullname||| +gv_ename||| +gv_fetchfile_flags||5.009005| +gv_fetchfile||| +gv_fetchmeth_autoload||5.007003| +gv_fetchmethod_autoload||5.004000| +gv_fetchmethod_flags||5.011000| +gv_fetchmethod||| +gv_fetchmeth||| +gv_fetchpvn_flags|5.009002||p +gv_fetchpvs|5.009004||p +gv_fetchpv||| +gv_fetchsv||5.009002| +gv_fullname3||5.004000| +gv_fullname4||5.006001| +gv_fullname||| +gv_get_super_pkg||| +gv_handler||5.007001| +gv_init_sv||| +gv_init||| +gv_name_set||5.009004| +gv_stashpvn|5.004000||p +gv_stashpvs|5.009003||p +gv_stashpv||| +gv_stashsv||| +he_dup||| +hek_dup||| +hfreeentries||| +hsplit||| +hv_assert||5.011000| +hv_auxinit|||n +hv_backreferences_p||| +hv_clear_placeholders||5.009001| +hv_clear||| +hv_common_key_len||5.010000| +hv_common||5.010000| +hv_copy_hints_hv||| +hv_delayfree_ent||5.004000| +hv_delete_common||| +hv_delete_ent||5.004000| +hv_delete||| +hv_eiter_p||5.009003| +hv_eiter_set||5.009003| +hv_exists_ent||5.004000| +hv_exists||| +hv_fetch_ent||5.004000| +hv_fetchs|5.009003||p +hv_fetch||| +hv_free_ent||5.004000| +hv_iterinit||| +hv_iterkeysv||5.004000| +hv_iterkey||| +hv_iternext_flags||5.008000| +hv_iternextsv||| +hv_iternext||| +hv_iterval||| +hv_kill_backrefs||| +hv_ksplit||5.004000| +hv_magic_check|||n +hv_magic||| +hv_name_set||5.009003| +hv_notallowed||| +hv_placeholders_get||5.009003| +hv_placeholders_p||5.009003| +hv_placeholders_set||5.009003| +hv_riter_p||5.009003| +hv_riter_set||5.009003| +hv_scalar||5.009001| +hv_store_ent||5.004000| +hv_store_flags||5.008000| +hv_stores|5.009004||p +hv_store||| +hv_undef||| +ibcmp_locale||5.004000| +ibcmp_utf8||5.007003| +ibcmp||| +incline||| +incpush_if_exists||| +incpush_use_sep||| +incpush||| +ingroup||| +init_argv_symbols||| +init_debugger||| +init_global_struct||| +init_i18nl10n||5.006000| +init_i18nl14n||5.006000| +init_ids||| +init_interp||| +init_main_stash||| +init_perllib||| +init_postdump_symbols||| +init_predump_symbols||| +init_stacks||5.005000| +init_tm||5.007002| +instr||| +intro_my||| +intuit_method||| +intuit_more||| +invert||| +io_close||| +isALNUMC|5.006000||p +isALNUM||| +isALPHA||| +isASCII|5.006000||p +isBLANK|5.006001||p +isCNTRL|5.006000||p +isDIGIT||| +isGRAPH|5.006000||p +isGV_with_GP|5.009004||p +isLOWER||| +isPRINT|5.004000||p +isPSXSPC|5.006001||p +isPUNCT|5.006000||p +isSPACE||| +isUPPER||| +isXDIGIT|5.006000||p +is_an_int||| +is_gv_magical_sv||| +is_handle_constructor|||n +is_list_assignment||| +is_lvalue_sub||5.007001| +is_uni_alnum_lc||5.006000| +is_uni_alnumc_lc||5.006000| +is_uni_alnumc||5.006000| +is_uni_alnum||5.006000| +is_uni_alpha_lc||5.006000| +is_uni_alpha||5.006000| +is_uni_ascii_lc||5.006000| +is_uni_ascii||5.006000| +is_uni_cntrl_lc||5.006000| +is_uni_cntrl||5.006000| +is_uni_digit_lc||5.006000| +is_uni_digit||5.006000| +is_uni_graph_lc||5.006000| +is_uni_graph||5.006000| +is_uni_idfirst_lc||5.006000| +is_uni_idfirst||5.006000| +is_uni_lower_lc||5.006000| +is_uni_lower||5.006000| +is_uni_print_lc||5.006000| +is_uni_print||5.006000| +is_uni_punct_lc||5.006000| +is_uni_punct||5.006000| +is_uni_space_lc||5.006000| +is_uni_space||5.006000| +is_uni_upper_lc||5.006000| +is_uni_upper||5.006000| +is_uni_xdigit_lc||5.006000| +is_uni_xdigit||5.006000| +is_utf8_alnumc||5.006000| +is_utf8_alnum||5.006000| +is_utf8_alpha||5.006000| +is_utf8_ascii||5.006000| +is_utf8_char_slow|||n +is_utf8_char||5.006000| +is_utf8_cntrl||5.006000| +is_utf8_common||| +is_utf8_digit||5.006000| +is_utf8_graph||5.006000| +is_utf8_idcont||5.008000| +is_utf8_idfirst||5.006000| +is_utf8_lower||5.006000| +is_utf8_mark||5.006000| +is_utf8_print||5.006000| +is_utf8_punct||5.006000| +is_utf8_space||5.006000| +is_utf8_string_loclen||5.009003| +is_utf8_string_loc||5.008001| +is_utf8_string||5.006001| +is_utf8_upper||5.006000| +is_utf8_xdigit||5.006000| +isa_lookup||| +items|||n +ix|||n +jmaybe||| +join_exact||| +keyword||| +leave_scope||| +lex_end||| +lex_start||| +linklist||| +listkids||| +list||| +load_module_nocontext|||vn +load_module|5.006000||pv +localize||| +looks_like_bool||| +looks_like_number||| +lop||| +mPUSHi|5.009002||p +mPUSHn|5.009002||p +mPUSHp|5.009002||p +mPUSHs|5.011000||p +mPUSHu|5.009002||p +mXPUSHi|5.009002||p +mXPUSHn|5.009002||p +mXPUSHp|5.009002||p +mXPUSHs|5.011000||p +mXPUSHu|5.009002||p +mad_free||| +madlex||| +madparse||| +magic_clear_all_env||| +magic_clearenv||| +magic_clearhint||| +magic_clearisa||| +magic_clearpack||| +magic_clearsig||| +magic_dump||5.006000| +magic_existspack||| +magic_freearylen_p||| +magic_freeovrld||| +magic_getarylen||| +magic_getdefelem||| +magic_getnkeys||| +magic_getpack||| +magic_getpos||| +magic_getsig||| +magic_getsubstr||| +magic_gettaint||| +magic_getuvar||| +magic_getvec||| +magic_get||| +magic_killbackrefs||| +magic_len||| +magic_methcall||| +magic_methpack||| +magic_nextpack||| +magic_regdata_cnt||| +magic_regdatum_get||| +magic_regdatum_set||| +magic_scalarpack||| +magic_set_all_env||| +magic_setamagic||| +magic_setarylen||| +magic_setcollxfrm||| +magic_setdbline||| +magic_setdefelem||| +magic_setenv||| +magic_sethint||| +magic_setisa||| +magic_setmglob||| +magic_setnkeys||| +magic_setpack||| +magic_setpos||| +magic_setregexp||| +magic_setsig||| +magic_setsubstr||| +magic_settaint||| +magic_setutf8||| +magic_setuvar||| +magic_setvec||| +magic_set||| +magic_sizepack||| +magic_wipepack||| +make_matcher||| +make_trie_failtable||| +make_trie||| +malloc_good_size|||n +malloced_size|||n +malloc||5.007002|n +markstack_grow||| +matcher_matches_sv||| +measure_struct||| +memEQ|5.004000||p +memNE|5.004000||p +mem_collxfrm||| +mem_log_common|||n +mess_alloc||| +mess_nocontext|||vn +mess||5.006000|v +method_common||| +mfree||5.007002|n +mg_clear||| +mg_copy||| +mg_dup||| +mg_find||| +mg_free||| +mg_get||| +mg_length||5.005000| +mg_localize||| +mg_magical||| +mg_set||| +mg_size||5.005000| +mini_mktime||5.007002| +missingterm||| +mode_from_discipline||| +modkids||| +mod||| +more_bodies||| +more_sv||| +moreswitches||| +mro_get_from_name||5.011000| +mro_get_linear_isa_dfs||| +mro_get_linear_isa||5.009005| +mro_get_private_data||5.011000| +mro_isa_changed_in||| +mro_meta_dup||| +mro_meta_init||| +mro_method_changed_in||5.009005| +mro_register||5.011000| +mro_set_mro||5.011000| +mro_set_private_data||5.011000| +mul128||| +mulexp10|||n +my_atof2||5.007002| +my_atof||5.006000| +my_attrs||| +my_bcopy|||n +my_betoh16|||n +my_betoh32|||n +my_betoh64|||n +my_betohi|||n +my_betohl|||n +my_betohs|||n +my_bzero|||n +my_chsize||| +my_clearenv||| +my_cxt_index||| +my_cxt_init||| +my_dirfd||5.009005| +my_exit_jump||| +my_exit||| +my_failure_exit||5.004000| +my_fflush_all||5.006000| +my_fork||5.007003|n +my_htobe16|||n +my_htobe32|||n +my_htobe64|||n +my_htobei|||n +my_htobel|||n +my_htobes|||n +my_htole16|||n +my_htole32|||n +my_htole64|||n +my_htolei|||n +my_htolel|||n +my_htoles|||n +my_htonl||| +my_kid||| +my_letoh16|||n +my_letoh32|||n +my_letoh64|||n +my_letohi|||n +my_letohl|||n +my_letohs|||n +my_lstat||| +my_memcmp||5.004000|n +my_memset|||n +my_ntohl||| +my_pclose||5.004000| +my_popen_list||5.007001| +my_popen||5.004000| +my_setenv||| +my_snprintf|5.009004||pvn +my_socketpair||5.007003|n +my_sprintf|5.009003||pvn +my_stat||| +my_strftime||5.007002| +my_strlcat|5.009004||pn +my_strlcpy|5.009004||pn +my_swabn|||n +my_swap||| +my_unexec||| +my_vsnprintf||5.009004|n +need_utf8|||n +newANONATTRSUB||5.006000| +newANONHASH||| +newANONLIST||| +newANONSUB||| +newASSIGNOP||| +newATTRSUB||5.006000| +newAVREF||| +newAV||| +newBINOP||| +newCONDOP||| +newCONSTSUB|5.004050||p +newCVREF||| +newDEFSVOP||| +newFORM||| +newFOROP||| +newGIVENOP||5.009003| +newGIVWHENOP||| +newGP||| +newGVOP||| +newGVREF||| +newGVgen||| +newHVREF||| +newHVhv||5.005000| +newHV||| +newIO||| +newLISTOP||| +newLOGOP||| +newLOOPEX||| +newLOOPOP||| +newMADPROP||| +newMADsv||| +newMYSUB||| +newNULLLIST||| +newOP||| +newPADOP||| +newPMOP||| +newPROG||| +newPVOP||| +newRANGE||| +newRV_inc|5.004000||p +newRV_noinc|5.004000||p +newRV||| +newSLICEOP||| +newSTATEOP||| +newSUB||| +newSVOP||| +newSVREF||| +newSV_type|5.009005||p +newSVhek||5.009003| +newSViv||| +newSVnv||| +newSVpvf_nocontext|||vn +newSVpvf||5.004000|v +newSVpvn_flags|5.011000||p +newSVpvn_share|5.007001||p +newSVpvn_utf8|5.011000||p +newSVpvn|5.004050||p +newSVpvs_flags|5.011000||p +newSVpvs_share||5.009003| +newSVpvs|5.009003||p +newSVpv||| +newSVrv||| +newSVsv||| +newSVuv|5.006000||p +newSV||| +newTOKEN||| +newUNOP||| +newWHENOP||5.009003| +newWHILEOP||5.009003| +newXS_flags||5.009004| +newXSproto||5.006000| +newXS||5.006000| +new_collate||5.006000| +new_constant||| +new_ctype||5.006000| +new_he||| +new_logop||| +new_numeric||5.006000| +new_stackinfo||5.005000| +new_version||5.009000| +new_warnings_bitfield||| +next_symbol||| +nextargv||| +nextchar||| +ninstr||| +no_bareword_allowed||| +no_fh_allowed||| +no_op||| +not_a_number||| +nothreadhook||5.008000| +nuke_stacks||| +num_overflow|||n +offer_nice_chunk||| +oopsAV||| +oopsHV||| +op_clear||| +op_const_sv||| +op_dump||5.006000| +op_free||| +op_getmad_weak||| +op_getmad||| +op_null||5.007002| +op_refcnt_dec||| +op_refcnt_inc||| +op_refcnt_lock||5.009002| +op_refcnt_unlock||5.009002| +op_xmldump||| +open_script||| +pMY_CXT_|5.007003||p +pMY_CXT|5.007003||p +pTHX_|5.006000||p +pTHX|5.006000||p +packWARN|5.007003||p +pack_cat||5.007003| +pack_rec||| +package||| +packlist||5.008001| +pad_add_anon||| +pad_add_name||| +pad_alloc||| +pad_block_start||| +pad_check_dup||| +pad_compname_type||| +pad_findlex||| +pad_findmy||| +pad_fixup_inner_anons||| +pad_free||| +pad_leavemy||| +pad_new||| +pad_peg|||n +pad_push||| +pad_reset||| +pad_setsv||| +pad_sv||5.011000| +pad_swipe||| +pad_tidy||| +pad_undef||| +parse_body||| +parse_unicode_opts||| +parser_dup||| +parser_free||| +path_is_absolute|||n +peep||| +pending_Slabs_to_ro||| +perl_alloc_using|||n +perl_alloc|||n +perl_clone_using|||n +perl_clone|||n +perl_construct|||n +perl_destruct||5.007003|n +perl_free|||n +perl_parse||5.006000|n +perl_run|||n +pidgone||| +pm_description||| +pmflag||| +pmop_dump||5.006000| +pmop_xmldump||| +pmruntime||| +pmtrans||| +pop_scope||| +pregcomp||5.009005| +pregexec||| +pregfree2||5.011000| +pregfree||| +prepend_elem||| +prepend_madprops||| +printbuf||| +printf_nocontext|||vn +process_special_blocks||| +ptr_table_clear||5.009005| +ptr_table_fetch||5.009005| +ptr_table_find|||n +ptr_table_free||5.009005| +ptr_table_new||5.009005| +ptr_table_split||5.009005| +ptr_table_store||5.009005| +push_scope||| +put_byte||| +pv_display|5.006000||p +pv_escape|5.009004||p +pv_pretty|5.009004||p +pv_uni_display||5.007003| +qerror||| +qsortsvu||| +re_compile||5.009005| +re_croak2||| +re_dup_guts||| +re_intuit_start||5.009005| +re_intuit_string||5.006000| +readpipe_override||| +realloc||5.007002|n +reentrant_free||| +reentrant_init||| +reentrant_retry|||vn +reentrant_size||| +ref_array_or_hash||| +refcounted_he_chain_2hv||| +refcounted_he_fetch||| +refcounted_he_free||| +refcounted_he_new_common||| +refcounted_he_new||| +refcounted_he_value||| +refkids||| +refto||| +ref||5.011000| +reg_check_named_buff_matched||| +reg_named_buff_all||5.009005| +reg_named_buff_exists||5.009005| +reg_named_buff_fetch||5.009005| +reg_named_buff_firstkey||5.009005| +reg_named_buff_iter||| +reg_named_buff_nextkey||5.009005| +reg_named_buff_scalar||5.009005| +reg_named_buff||| +reg_namedseq||| +reg_node||| +reg_numbered_buff_fetch||| +reg_numbered_buff_length||| +reg_numbered_buff_store||| +reg_qr_package||| +reg_recode||| +reg_scan_name||| +reg_skipcomment||| +reg_temp_copy||| +reganode||| +regatom||| +regbranch||| +regclass_swash||5.009004| +regclass||| +regcppop||| +regcppush||| +regcurly|||n +regdump_extflags||| +regdump||5.005000| +regdupe_internal||| +regexec_flags||5.005000| +regfree_internal||5.009005| +reghop3|||n +reghop4|||n +reghopmaybe3|||n +reginclass||| +reginitcolors||5.006000| +reginsert||| +regmatch||| +regnext||5.005000| +regpiece||| +regpposixcc||| +regprop||| +regrepeat||| +regtail_study||| +regtail||| +regtry||| +reguni||| +regwhite|||n +reg||| +repeatcpy||| +report_evil_fh||| +report_uninit||| +require_pv||5.006000| +require_tie_mod||| +restore_magic||| +rninstr||| +rsignal_restore||| +rsignal_save||| +rsignal_state||5.004000| +rsignal||5.004000| +run_body||| +run_user_filter||| +runops_debug||5.005000| +runops_standard||5.005000| +rvpv_dup||| +rxres_free||| +rxres_restore||| +rxres_save||| +safesyscalloc||5.006000|n +safesysfree||5.006000|n +safesysmalloc||5.006000|n +safesysrealloc||5.006000|n +same_dirent||| +save_I16||5.004000| +save_I32||| +save_I8||5.006000| +save_adelete||5.011000| +save_aelem||5.004050| +save_alloc||5.006000| +save_aptr||| +save_ary||| +save_bool||5.008001| +save_clearsv||| +save_delete||| +save_destructor_x||5.006000| +save_destructor||5.006000| +save_freeop||| +save_freepv||| +save_freesv||| +save_generic_pvref||5.006001| +save_generic_svref||5.005030| +save_gp||5.004000| +save_hash||| +save_hek_flags|||n +save_helem_flags||5.011000| +save_helem||5.004050| +save_hints||| +save_hptr||| +save_int||| +save_item||| +save_iv||5.005000| +save_lines||| +save_list||| +save_long||| +save_magic||| +save_mortalizesv||5.007001| +save_nogv||| +save_op||| +save_padsv_and_mortalize||5.011000| +save_pptr||| +save_pushi32ptr||| +save_pushptri32ptr||| +save_pushptrptr||| +save_pushptr||5.011000| +save_re_context||5.006000| +save_scalar_at||| +save_scalar||| +save_set_svflags||5.009000| +save_shared_pvref||5.007003| +save_sptr||| +save_svref||| +save_vptr||5.006000| +savepvn||| +savepvs||5.009003| +savepv||| +savesharedpvn||5.009005| +savesharedpv||5.007003| +savestack_grow_cnt||5.008001| +savestack_grow||| +savesvpv||5.009002| +sawparens||| +scalar_mod_type|||n +scalarboolean||| +scalarkids||| +scalarseq||| +scalarvoid||| +scalar||| +scan_bin||5.006000| +scan_commit||| +scan_const||| +scan_formline||| +scan_heredoc||| +scan_hex||| +scan_ident||| +scan_inputsymbol||| +scan_num||5.007001| +scan_oct||| +scan_pat||| +scan_str||| +scan_subst||| +scan_trans||| +scan_version||5.009001| +scan_vstring||5.009005| +scan_word||| +scope||| +screaminstr||5.005000| +search_const||| +seed||5.008001| +sequence_num||| +sequence_tail||| +sequence||| +set_context||5.006000|n +set_numeric_local||5.006000| +set_numeric_radix||5.006000| +set_numeric_standard||5.006000| +setdefout||| +share_hek_flags||| +share_hek||5.004000| +si_dup||| +sighandler|||n +simplify_sort||| +skipspace0||| +skipspace1||| +skipspace2||| +skipspace||| +softref2xv||| +sortcv_stacked||| +sortcv_xsub||| +sortcv||| +sortsv_flags||5.009003| +sortsv||5.007003| +space_join_names_mortal||| +ss_dup||| +stack_grow||| +start_force||| +start_glob||| +start_subparse||5.004000| +stashpv_hvname_match||5.011000| +stdize_locale||| +store_cop_label||| +strEQ||| +strGE||| +strGT||| +strLE||| +strLT||| +strNE||| +str_to_version||5.006000| +strip_return||| +strnEQ||| +strnNE||| +study_chunk||| +sub_crush_depth||| +sublex_done||| +sublex_push||| +sublex_start||| +sv_2bool||| +sv_2cv||| +sv_2io||| +sv_2iuv_common||| +sv_2iuv_non_preserve||| +sv_2iv_flags||5.009001| +sv_2iv||| +sv_2mortal||| +sv_2num||| +sv_2nv||| +sv_2pv_flags|5.007002||p +sv_2pv_nolen|5.006000||p +sv_2pvbyte_nolen|5.006000||p +sv_2pvbyte|5.006000||p +sv_2pvutf8_nolen||5.006000| +sv_2pvutf8||5.006000| +sv_2pv||| +sv_2uv_flags||5.009001| +sv_2uv|5.004000||p +sv_add_arena||| +sv_add_backref||| +sv_backoff||| +sv_bless||| +sv_cat_decode||5.008001| +sv_catpv_mg|5.004050||p +sv_catpvf_mg_nocontext|||pvn +sv_catpvf_mg|5.006000|5.004000|pv +sv_catpvf_nocontext|||vn +sv_catpvf||5.004000|v +sv_catpvn_flags||5.007002| +sv_catpvn_mg|5.004050||p +sv_catpvn_nomg|5.007002||p +sv_catpvn||| +sv_catpvs|5.009003||p +sv_catpv||| +sv_catsv_flags||5.007002| +sv_catsv_mg|5.004050||p +sv_catsv_nomg|5.007002||p +sv_catsv||| +sv_catxmlpvn||| +sv_catxmlsv||| +sv_chop||| +sv_clean_all||| +sv_clean_objs||| +sv_clear||| +sv_cmp_locale||5.004000| +sv_cmp||| +sv_collxfrm||| +sv_compile_2op||5.008001| +sv_copypv||5.007003| +sv_dec||| +sv_del_backref||| +sv_derived_from||5.004000| +sv_destroyable||5.010000| +sv_does||5.009004| +sv_dump||| +sv_dup_inc_multiple||| +sv_dup||| +sv_eq||| +sv_exp_grow||| +sv_force_normal_flags||5.007001| +sv_force_normal||5.006000| +sv_free2||| +sv_free_arenas||| +sv_free||| +sv_gets||5.004000| +sv_grow||| +sv_i_ncmp||| +sv_inc||| +sv_insert_flags||5.011000| +sv_insert||| +sv_isa||| +sv_isobject||| +sv_iv||5.005000| +sv_kill_backrefs||| +sv_len_utf8||5.006000| +sv_len||| +sv_magic_portable|5.011000|5.004000|p +sv_magicext||5.007003| +sv_magic||| +sv_mortalcopy||| +sv_ncmp||| +sv_newmortal||| +sv_newref||| +sv_nolocking||5.007003| +sv_nosharing||5.007003| +sv_nounlocking||| +sv_nv||5.005000| +sv_peek||5.005000| +sv_pos_b2u_midway||| +sv_pos_b2u||5.006000| +sv_pos_u2b_cached||| +sv_pos_u2b_forwards|||n +sv_pos_u2b_midway|||n +sv_pos_u2b||5.006000| +sv_pvbyten_force||5.006000| +sv_pvbyten||5.006000| +sv_pvbyte||5.006000| +sv_pvn_force_flags|5.007002||p +sv_pvn_force||| +sv_pvn_nomg|5.007003|5.005000|p +sv_pvn||5.005000| +sv_pvutf8n_force||5.006000| +sv_pvutf8n||5.006000| +sv_pvutf8||5.006000| +sv_pv||5.006000| +sv_recode_to_utf8||5.007003| +sv_reftype||| +sv_release_COW||| +sv_replace||| +sv_report_used||| +sv_reset||| +sv_rvweaken||5.006000| +sv_setiv_mg|5.004050||p +sv_setiv||| +sv_setnv_mg|5.006000||p +sv_setnv||| +sv_setpv_mg|5.004050||p +sv_setpvf_mg_nocontext|||pvn +sv_setpvf_mg|5.006000|5.004000|pv +sv_setpvf_nocontext|||vn +sv_setpvf||5.004000|v +sv_setpviv_mg||5.008001| +sv_setpviv||5.008001| +sv_setpvn_mg|5.004050||p +sv_setpvn||| +sv_setpvs|5.009004||p +sv_setpv||| +sv_setref_iv||| +sv_setref_nv||| +sv_setref_pvn||| +sv_setref_pv||| +sv_setref_uv||5.007001| +sv_setsv_cow||| +sv_setsv_flags||5.007002| +sv_setsv_mg|5.004050||p +sv_setsv_nomg|5.007002||p +sv_setsv||| +sv_setuv_mg|5.004050||p +sv_setuv|5.004000||p +sv_tainted||5.004000| +sv_taint||5.004000| +sv_true||5.005000| +sv_unglob||| +sv_uni_display||5.007003| +sv_unmagic||| +sv_unref_flags||5.007001| +sv_unref||| +sv_untaint||5.004000| +sv_upgrade||| +sv_usepvn_flags||5.009004| +sv_usepvn_mg|5.004050||p +sv_usepvn||| +sv_utf8_decode||5.006000| +sv_utf8_downgrade||5.006000| +sv_utf8_encode||5.006000| +sv_utf8_upgrade_flags_grow||5.011000| +sv_utf8_upgrade_flags||5.007002| +sv_utf8_upgrade_nomg||5.007002| +sv_utf8_upgrade||5.007001| +sv_uv|5.005000||p +sv_vcatpvf_mg|5.006000|5.004000|p +sv_vcatpvfn||5.004000| +sv_vcatpvf|5.006000|5.004000|p +sv_vsetpvf_mg|5.006000|5.004000|p +sv_vsetpvfn||5.004000| +sv_vsetpvf|5.006000|5.004000|p +sv_xmlpeek||| +svtype||| +swallow_bom||| +swap_match_buff||| +swash_fetch||5.007002| +swash_get||| +swash_init||5.006000| +sys_init3||5.010000|n +sys_init||5.010000|n +sys_intern_clear||| +sys_intern_dup||| +sys_intern_init||| +sys_term||5.010000|n +taint_env||| +taint_proper||| +tmps_grow||5.006000| +toLOWER||| +toUPPER||| +to_byte_substr||| +to_uni_fold||5.007003| +to_uni_lower_lc||5.006000| +to_uni_lower||5.007003| +to_uni_title_lc||5.006000| +to_uni_title||5.007003| +to_uni_upper_lc||5.006000| +to_uni_upper||5.007003| +to_utf8_case||5.007003| +to_utf8_fold||5.007003| +to_utf8_lower||5.007003| +to_utf8_substr||| +to_utf8_title||5.007003| +to_utf8_upper||5.007003| +token_free||| +token_getmad||| +tokenize_use||| +tokeq||| +tokereport||| +too_few_arguments||| +too_many_arguments||| +uiv_2buf|||n +unlnk||| +unpack_rec||| +unpack_str||5.007003| +unpackstring||5.008001| +unshare_hek_or_pvn||| +unshare_hek||| +unsharepvn||5.004000| +unwind_handler_stack||| +update_debugger_info||| +upg_version||5.009005| +usage||| +utf16_to_utf8_reversed||5.006001| +utf16_to_utf8||5.006001| +utf8_distance||5.006000| +utf8_hop||5.006000| +utf8_length||5.007001| +utf8_mg_pos_cache_update||| +utf8_to_bytes||5.006001| +utf8_to_uvchr||5.007001| +utf8_to_uvuni||5.007001| +utf8n_to_uvchr||| +utf8n_to_uvuni||5.007001| +utilize||| +uvchr_to_utf8_flags||5.007003| +uvchr_to_utf8||| +uvuni_to_utf8_flags||5.007003| +uvuni_to_utf8||5.007001| +validate_suid||| +varname||| +vcmp||5.009000| +vcroak||5.006000| +vdeb||5.007003| +vdie_common||| +vdie_croak_common||| +vdie||| +vform||5.006000| +visit||| +vivify_defelem||| +vivify_ref||| +vload_module|5.006000||p +vmess||5.006000| +vnewSVpvf|5.006000|5.004000|p +vnormal||5.009002| +vnumify||5.009000| +vstringify||5.009000| +vverify||5.009003| +vwarner||5.006000| +vwarn||5.006000| +wait4pid||| +warn_nocontext|||vn +warner_nocontext|||vn +warner|5.006000|5.004000|pv +warn|||v +watch||| +whichsig||| +write_no_mem||| +write_to_stderr||| +xmldump_all||| +xmldump_attr||| +xmldump_eval||| +xmldump_form||| +xmldump_indent|||v +xmldump_packsubs||| +xmldump_sub||| +xmldump_vindent||| +yyerror||| +yylex||| +yyparse||| +yywarn||| +); + +if (exists $opt{'list-unsupported'}) { + my $f; + for $f (sort { lc $a cmp lc $b } keys %API) { + next unless $API{$f}{todo}; + print "$f ", '.'x(40-length($f)), " ", format_version($API{$f}{todo}), "\n"; + } + exit 0; +} + +# Scan for possible replacement candidates + +my(%replace, %need, %hints, %warnings, %depends); +my $replace = 0; +my($hint, $define, $function); + +sub find_api +{ + my $code = shift; + $code =~ s{ + / (?: \*[^*]*\*+(?:[^$ccs][^*]*\*+)* / | /[^\r\n]*) + | "[^"\\]*(?:\\.[^"\\]*)*" + | '[^'\\]*(?:\\.[^'\\]*)*' }{}egsx; + grep { exists $API{$_} } $code =~ /(\w+)/mg; +} + +while () { + if ($hint) { + my $h = $hint->[0] eq 'Hint' ? \%hints : \%warnings; + if (m{^\s*\*\s(.*?)\s*$}) { + for (@{$hint->[1]}) { + $h->{$_} ||= ''; # suppress warning with older perls + $h->{$_} .= "$1\n"; + } + } + else { undef $hint } + } + + $hint = [$1, [split /,?\s+/, $2]] + if m{^\s*$rccs\s+(Hint|Warning):\s+(\w+(?:,?\s+\w+)*)\s*$}; + + if ($define) { + if ($define->[1] =~ /\\$/) { + $define->[1] .= $_; + } + else { + if (exists $API{$define->[0]} && $define->[1] !~ /^DPPP_\(/) { + my @n = find_api($define->[1]); + push @{$depends{$define->[0]}}, @n if @n + } + undef $define; + } + } + + $define = [$1, $2] if m{^\s*#\s*define\s+(\w+)(?:\([^)]*\))?\s+(.*)}; + + if ($function) { + if (/^}/) { + if (exists $API{$function->[0]}) { + my @n = find_api($function->[1]); + push @{$depends{$function->[0]}}, @n if @n + } + undef $function; + } + else { + $function->[1] .= $_; + } + } + + $function = [$1, ''] if m{^DPPP_\(my_(\w+)\)}; + + $replace = $1 if m{^\s*$rccs\s+Replace:\s+(\d+)\s+$rcce\s*$}; + $replace{$2} = $1 if $replace and m{^\s*#\s*define\s+(\w+)(?:\([^)]*\))?\s+(\w+)}; + $replace{$2} = $1 if m{^\s*#\s*define\s+(\w+)(?:\([^)]*\))?\s+(\w+).*$rccs\s+Replace\s+$rcce}; + $replace{$1} = $2 if m{^\s*$rccs\s+Replace (\w+) with (\w+)\s+$rcce\s*$}; + + if (m{^\s*$rccs\s+(\w+(\s*,\s*\w+)*)\s+depends\s+on\s+(\w+(\s*,\s*\w+)*)\s+$rcce\s*$}) { + my @deps = map { s/\s+//g; $_ } split /,/, $3; + my $d; + for $d (map { s/\s+//g; $_ } split /,/, $1) { + push @{$depends{$d}}, @deps; + } + } + + $need{$1} = 1 if m{^#if\s+defined\(NEED_(\w+)(?:_GLOBAL)?\)}; +} + +for (values %depends) { + my %s; + $_ = [sort grep !$s{$_}++, @$_]; +} + +if (exists $opt{'api-info'}) { + my $f; + my $count = 0; + my $match = $opt{'api-info'} =~ m!^/(.*)/$! ? $1 : "^\Q$opt{'api-info'}\E\$"; + for $f (sort { lc $a cmp lc $b } keys %API) { + next unless $f =~ /$match/; + print "\n=== $f ===\n\n"; + my $info = 0; + if ($API{$f}{base} || $API{$f}{todo}) { + my $base = format_version($API{$f}{base} || $API{$f}{todo}); + print "Supported at least starting from perl-$base.\n"; + $info++; + } + if ($API{$f}{provided}) { + my $todo = $API{$f}{todo} ? format_version($API{$f}{todo}) : "5.003"; + print "Support by $ppport provided back to perl-$todo.\n"; + print "Support needs to be explicitly requested by NEED_$f.\n" if exists $need{$f}; + print "Depends on: ", join(', ', @{$depends{$f}}), ".\n" if exists $depends{$f}; + print "\n$hints{$f}" if exists $hints{$f}; + print "\nWARNING:\n$warnings{$f}" if exists $warnings{$f}; + $info++; + } + print "No portability information available.\n" unless $info; + $count++; + } + $count or print "Found no API matching '$opt{'api-info'}'."; + print "\n"; + exit 0; +} + +if (exists $opt{'list-provided'}) { + my $f; + for $f (sort { lc $a cmp lc $b } keys %API) { + next unless $API{$f}{provided}; + my @flags; + push @flags, 'explicit' if exists $need{$f}; + push @flags, 'depend' if exists $depends{$f}; + push @flags, 'hint' if exists $hints{$f}; + push @flags, 'warning' if exists $warnings{$f}; + my $flags = @flags ? ' ['.join(', ', @flags).']' : ''; + print "$f$flags\n"; + } + exit 0; +} + +my @files; +my @srcext = qw( .xs .c .h .cc .cpp -c.inc -xs.inc ); +my $srcext = join '|', map { quotemeta $_ } @srcext; + +if (@ARGV) { + my %seen; + for (@ARGV) { + if (-e) { + if (-f) { + push @files, $_ unless $seen{$_}++; + } + else { warn "'$_' is not a file.\n" } + } + else { + my @new = grep { -f } glob $_ + or warn "'$_' does not exist.\n"; + push @files, grep { !$seen{$_}++ } @new; + } + } +} +else { + eval { + require File::Find; + File::Find::find(sub { + $File::Find::name =~ /($srcext)$/i + and push @files, $File::Find::name; + }, '.'); + }; + if ($@) { + @files = map { glob "*$_" } @srcext; + } +} + +if (!@ARGV || $opt{filter}) { + my(@in, @out); + my %xsc = map { /(.*)\.xs$/ ? ("$1.c" => 1, "$1.cc" => 1) : () } @files; + for (@files) { + my $out = exists $xsc{$_} || /\b\Q$ppport\E$/i || !/($srcext)$/i; + push @{ $out ? \@out : \@in }, $_; + } + if (@ARGV && @out) { + warning("Skipping the following files (use --nofilter to avoid this):\n| ", join "\n| ", @out); + } + @files = @in; +} + +die "No input files given!\n" unless @files; + +my(%files, %global, %revreplace); +%revreplace = reverse %replace; +my $filename; +my $patch_opened = 0; + +for $filename (@files) { + unless (open IN, "<$filename") { + warn "Unable to read from $filename: $!\n"; + next; + } + + info("Scanning $filename ..."); + + my $c = do { local $/; }; + close IN; + + my %file = (orig => $c, changes => 0); + + # Temporarily remove C/XS comments and strings from the code + my @ccom; + + $c =~ s{ + ( ^$HS*\#$HS*include\b[^\r\n]+\b(?:\Q$ppport\E|XSUB\.h)\b[^\r\n]* + | ^$HS*\#$HS*(?:define|elif|if(?:def)?)\b[^\r\n]* ) + | ( ^$HS*\#[^\r\n]* + | "[^"\\]*(?:\\.[^"\\]*)*" + | '[^'\\]*(?:\\.[^'\\]*)*' + | / (?: \*[^*]*\*+(?:[^$ccs][^*]*\*+)* / | /[^\r\n]* ) ) + }{ defined $2 and push @ccom, $2; + defined $1 ? $1 : "$ccs$#ccom$cce" }mgsex; + + $file{ccom} = \@ccom; + $file{code} = $c; + $file{has_inc_ppport} = $c =~ /^$HS*#$HS*include[^\r\n]+\b\Q$ppport\E\b/m; + + my $func; + + for $func (keys %API) { + my $match = $func; + $match .= "|$revreplace{$func}" if exists $revreplace{$func}; + if ($c =~ /\b(?:Perl_)?($match)\b/) { + $file{uses_replace}{$1}++ if exists $revreplace{$func} && $1 eq $revreplace{$func}; + $file{uses_Perl}{$func}++ if $c =~ /\bPerl_$func\b/; + if (exists $API{$func}{provided}) { + $file{uses_provided}{$func}++; + if (!exists $API{$func}{base} || $API{$func}{base} > $opt{'compat-version'}) { + $file{uses}{$func}++; + my @deps = rec_depend($func); + if (@deps) { + $file{uses_deps}{$func} = \@deps; + for (@deps) { + $file{uses}{$_} = 0 unless exists $file{uses}{$_}; + } + } + for ($func, @deps) { + $file{needs}{$_} = 'static' if exists $need{$_}; + } + } + } + if (exists $API{$func}{todo} && $API{$func}{todo} > $opt{'compat-version'}) { + if ($c =~ /\b$func\b/) { + $file{uses_todo}{$func}++; + } + } + } + } + + while ($c =~ /^$HS*#$HS*define$HS+(NEED_(\w+?)(_GLOBAL)?)\b/mg) { + if (exists $need{$2}) { + $file{defined $3 ? 'needed_global' : 'needed_static'}{$2}++; + } + else { warning("Possibly wrong #define $1 in $filename") } + } + + for (qw(uses needs uses_todo needed_global needed_static)) { + for $func (keys %{$file{$_}}) { + push @{$global{$_}{$func}}, $filename; + } + } + + $files{$filename} = \%file; +} + +# Globally resolve NEED_'s +my $need; +for $need (keys %{$global{needs}}) { + if (@{$global{needs}{$need}} > 1) { + my @targets = @{$global{needs}{$need}}; + my @t = grep $files{$_}{needed_global}{$need}, @targets; + @targets = @t if @t; + @t = grep /\.xs$/i, @targets; + @targets = @t if @t; + my $target = shift @targets; + $files{$target}{needs}{$need} = 'global'; + for (@{$global{needs}{$need}}) { + $files{$_}{needs}{$need} = 'extern' if $_ ne $target; + } + } +} + +for $filename (@files) { + exists $files{$filename} or next; + + info("=== Analyzing $filename ==="); + + my %file = %{$files{$filename}}; + my $func; + my $c = $file{code}; + my $warnings = 0; + + for $func (sort keys %{$file{uses_Perl}}) { + if ($API{$func}{varargs}) { + unless ($API{$func}{nothxarg}) { + my $changes = ($c =~ s{\b(Perl_$func\s*\(\s*)(?!aTHX_?)(\)|[^\s)]*\))} + { $1 . ($2 eq ')' ? 'aTHX' : 'aTHX_ ') . $2 }ge); + if ($changes) { + warning("Doesn't pass interpreter argument aTHX to Perl_$func"); + $file{changes} += $changes; + } + } + } + else { + warning("Uses Perl_$func instead of $func"); + $file{changes} += ($c =~ s{\bPerl_$func(\s*)\((\s*aTHX_?)?\s*} + {$func$1(}g); + } + } + + for $func (sort keys %{$file{uses_replace}}) { + warning("Uses $func instead of $replace{$func}"); + $file{changes} += ($c =~ s/\b$func\b/$replace{$func}/g); + } + + for $func (sort keys %{$file{uses_provided}}) { + if ($file{uses}{$func}) { + if (exists $file{uses_deps}{$func}) { + diag("Uses $func, which depends on ", join(', ', @{$file{uses_deps}{$func}})); + } + else { + diag("Uses $func"); + } + } + $warnings += hint($func); + } + + unless ($opt{quiet}) { + for $func (sort keys %{$file{uses_todo}}) { + print "*** WARNING: Uses $func, which may not be portable below perl ", + format_version($API{$func}{todo}), ", even with '$ppport'\n"; + $warnings++; + } + } + + for $func (sort keys %{$file{needed_static}}) { + my $message = ''; + if (not exists $file{uses}{$func}) { + $message = "No need to define NEED_$func if $func is never used"; + } + elsif (exists $file{needs}{$func} && $file{needs}{$func} ne 'static') { + $message = "No need to define NEED_$func when already needed globally"; + } + if ($message) { + diag($message); + $file{changes} += ($c =~ s/^$HS*#$HS*define$HS+NEED_$func\b.*$LF//mg); + } + } + + for $func (sort keys %{$file{needed_global}}) { + my $message = ''; + if (not exists $global{uses}{$func}) { + $message = "No need to define NEED_${func}_GLOBAL if $func is never used"; + } + elsif (exists $file{needs}{$func}) { + if ($file{needs}{$func} eq 'extern') { + $message = "No need to define NEED_${func}_GLOBAL when already needed globally"; + } + elsif ($file{needs}{$func} eq 'static') { + $message = "No need to define NEED_${func}_GLOBAL when only used in this file"; + } + } + if ($message) { + diag($message); + $file{changes} += ($c =~ s/^$HS*#$HS*define$HS+NEED_${func}_GLOBAL\b.*$LF//mg); + } + } + + $file{needs_inc_ppport} = keys %{$file{uses}}; + + if ($file{needs_inc_ppport}) { + my $pp = ''; + + for $func (sort keys %{$file{needs}}) { + my $type = $file{needs}{$func}; + next if $type eq 'extern'; + my $suffix = $type eq 'global' ? '_GLOBAL' : ''; + unless (exists $file{"needed_$type"}{$func}) { + if ($type eq 'global') { + diag("Files [@{$global{needs}{$func}}] need $func, adding global request"); + } + else { + diag("File needs $func, adding static request"); + } + $pp .= "#define NEED_$func$suffix\n"; + } + } + + if ($pp && ($c =~ s/^(?=$HS*#$HS*define$HS+NEED_\w+)/$pp/m)) { + $pp = ''; + $file{changes}++; + } + + unless ($file{has_inc_ppport}) { + diag("Needs to include '$ppport'"); + $pp .= qq(#include "$ppport"\n) + } + + if ($pp) { + $file{changes} += ($c =~ s/^($HS*#$HS*define$HS+NEED_\w+.*?)^/$1$pp/ms) + || ($c =~ s/^(?=$HS*#$HS*include.*\Q$ppport\E)/$pp/m) + || ($c =~ s/^($HS*#$HS*include.*XSUB.*\s*?)^/$1$pp/m) + || ($c =~ s/^/$pp/); + } + } + else { + if ($file{has_inc_ppport}) { + diag("No need to include '$ppport'"); + $file{changes} += ($c =~ s/^$HS*?#$HS*include.*\Q$ppport\E.*?$LF//m); + } + } + + # put back in our C comments + my $ix; + my $cppc = 0; + my @ccom = @{$file{ccom}}; + for $ix (0 .. $#ccom) { + if (!$opt{cplusplus} && $ccom[$ix] =~ s!^//!!) { + $cppc++; + $file{changes} += $c =~ s/$rccs$ix$rcce/$ccs$ccom[$ix] $cce/; + } + else { + $c =~ s/$rccs$ix$rcce/$ccom[$ix]/; + } + } + + if ($cppc) { + my $s = $cppc != 1 ? 's' : ''; + warning("Uses $cppc C++ style comment$s, which is not portable"); + } + + my $s = $warnings != 1 ? 's' : ''; + my $warn = $warnings ? " ($warnings warning$s)" : ''; + info("Analysis completed$warn"); + + if ($file{changes}) { + if (exists $opt{copy}) { + my $newfile = "$filename$opt{copy}"; + if (-e $newfile) { + error("'$newfile' already exists, refusing to write copy of '$filename'"); + } + else { + local *F; + if (open F, ">$newfile") { + info("Writing copy of '$filename' with changes to '$newfile'"); + print F $c; + close F; + } + else { + error("Cannot open '$newfile' for writing: $!"); + } + } + } + elsif (exists $opt{patch} || $opt{changes}) { + if (exists $opt{patch}) { + unless ($patch_opened) { + if (open PATCH, ">$opt{patch}") { + $patch_opened = 1; + } + else { + error("Cannot open '$opt{patch}' for writing: $!"); + delete $opt{patch}; + $opt{changes} = 1; + goto fallback; + } + } + mydiff(\*PATCH, $filename, $c); + } + else { +fallback: + info("Suggested changes:"); + mydiff(\*STDOUT, $filename, $c); + } + } + else { + my $s = $file{changes} == 1 ? '' : 's'; + info("$file{changes} potentially required change$s detected"); + } + } + else { + info("Looks good"); + } +} + +close PATCH if $patch_opened; + +exit 0; + + +sub try_use { eval "use @_;"; return $@ eq '' } + +sub mydiff +{ + local *F = shift; + my($file, $str) = @_; + my $diff; + + if (exists $opt{diff}) { + $diff = run_diff($opt{diff}, $file, $str); + } + + if (!defined $diff and try_use('Text::Diff')) { + $diff = Text::Diff::diff($file, \$str, { STYLE => 'Unified' }); + $diff = <
$tmp") { + print F $str; + close F; + + if (open F, "$prog $file $tmp |") { + while () { + s/\Q$tmp\E/$file.patched/; + $diff .= $_; + } + close F; + unlink $tmp; + return $diff; + } + + unlink $tmp; + } + else { + error("Cannot open '$tmp' for writing: $!"); + } + + return undef; +} + +sub rec_depend +{ + my($func, $seen) = @_; + return () unless exists $depends{$func}; + $seen = {%{$seen||{}}}; + return () if $seen->{$func}++; + my %s; + grep !$s{$_}++, map { ($_, rec_depend($_, $seen)) } @{$depends{$func}}; +} + +sub parse_version +{ + my $ver = shift; + + if ($ver =~ /^(\d+)\.(\d+)\.(\d+)$/) { + return ($1, $2, $3); + } + elsif ($ver !~ /^\d+\.[\d_]+$/) { + die "cannot parse version '$ver'\n"; + } + + $ver =~ s/_//g; + $ver =~ s/$/000000/; + + my($r,$v,$s) = $ver =~ /(\d+)\.(\d{3})(\d{3})/; + + $v = int $v; + $s = int $s; + + if ($r < 5 || ($r == 5 && $v < 6)) { + if ($s % 10) { + die "cannot parse version '$ver'\n"; + } + } + + return ($r, $v, $s); +} + +sub format_version +{ + my $ver = shift; + + $ver =~ s/$/000000/; + my($r,$v,$s) = $ver =~ /(\d+)\.(\d{3})(\d{3})/; + + $v = int $v; + $s = int $s; + + if ($r < 5 || ($r == 5 && $v < 6)) { + if ($s % 10) { + die "invalid version '$ver'\n"; + } + $s /= 10; + + $ver = sprintf "%d.%03d", $r, $v; + $s > 0 and $ver .= sprintf "_%02d", $s; + + return $ver; + } + + return sprintf "%d.%d.%d", $r, $v, $s; +} + +sub info +{ + $opt{quiet} and return; + print @_, "\n"; +} + +sub diag +{ + $opt{quiet} and return; + $opt{diag} and print @_, "\n"; +} + +sub warning +{ + $opt{quiet} and return; + print "*** ", @_, "\n"; +} + +sub error +{ + print "*** ERROR: ", @_, "\n"; +} + +my %given_hints; +my %given_warnings; +sub hint +{ + $opt{quiet} and return; + my $func = shift; + my $rv = 0; + if (exists $warnings{$func} && !$given_warnings{$func}++) { + my $warn = $warnings{$func}; + $warn =~ s!^!*** !mg; + print "*** WARNING: $func\n", $warn; + $rv++; + } + if ($opt{hints} && exists $hints{$func} && !$given_hints{$func}++) { + my $hint = $hints{$func}; + $hint =~ s/^/ /mg; + print " --- hint for $func ---\n", $hint; + } + $rv; +} + +sub usage +{ + my($usage) = do { local(@ARGV,$/)=($0); <> } =~ /^=head\d$HS+SYNOPSIS\s*^(.*?)\s*^=/ms; + my %M = ( 'I' => '*' ); + $usage =~ s/^\s*perl\s+\S+/$^X $0/; + $usage =~ s/([A-Z])<([^>]+)>/$M{$1}$2$M{$1}/g; + + print < }; + my($copy) = $self =~ /^=head\d\s+COPYRIGHT\s*^(.*?)^=\w+/ms; + $copy =~ s/^(?=\S+)/ /gms; + $self =~ s/^$HS+Do NOT edit.*?(?=^-)/$copy/ms; + $self =~ s/^SKIP.*(?=^__DATA__)/SKIP +if (\@ARGV && \$ARGV[0] eq '--unstrip') { + eval { require Devel::PPPort }; + \$@ and die "Cannot require Devel::PPPort, please install.\\n"; + if (eval \$Devel::PPPort::VERSION < $VERSION) { + die "$0 was originally generated with Devel::PPPort $VERSION.\\n" + . "Your Devel::PPPort is only version \$Devel::PPPort::VERSION.\\n" + . "Please install a newer version, or --unstrip will not work.\\n"; + } + Devel::PPPort::WriteFile(\$0); + exit 0; +} +print <$0" or die "cannot strip $0: $!\n"; + print OUT "$pl$c\n"; + + exit 0; +} + +__DATA__ +*/ + +#ifndef _P_P_PORTABILITY_H_ +#define _P_P_PORTABILITY_H_ + +#ifndef DPPP_NAMESPACE +# define DPPP_NAMESPACE DPPP_ +#endif + +#define DPPP_CAT2(x,y) CAT2(x,y) +#define DPPP_(name) DPPP_CAT2(DPPP_NAMESPACE, name) + +#ifndef PERL_REVISION +# if !defined(__PATCHLEVEL_H_INCLUDED__) && !(defined(PATCHLEVEL) && defined(SUBVERSION)) +# define PERL_PATCHLEVEL_H_IMPLICIT +# include +# endif +# if !(defined(PERL_VERSION) || (defined(SUBVERSION) && defined(PATCHLEVEL))) +# include +# endif +# ifndef PERL_REVISION +# define PERL_REVISION (5) + /* Replace: 1 */ +# define PERL_VERSION PATCHLEVEL +# define PERL_SUBVERSION SUBVERSION + /* Replace PERL_PATCHLEVEL with PERL_VERSION */ + /* Replace: 0 */ +# endif +#endif + +#define _dpppDEC2BCD(dec) ((((dec)/100)<<8)|((((dec)%100)/10)<<4)|((dec)%10)) +#define PERL_BCDVERSION ((_dpppDEC2BCD(PERL_REVISION)<<24)|(_dpppDEC2BCD(PERL_VERSION)<<12)|_dpppDEC2BCD(PERL_SUBVERSION)) + +/* It is very unlikely that anyone will try to use this with Perl 6 + (or greater), but who knows. + */ +#if PERL_REVISION != 5 +# error ppport.h only works with Perl version 5 +#endif /* PERL_REVISION != 5 */ +#ifndef dTHR +# define dTHR dNOOP +#endif +#ifndef dTHX +# define dTHX dNOOP +#endif + +#ifndef dTHXa +# define dTHXa(x) dNOOP +#endif +#ifndef pTHX +# define pTHX void +#endif + +#ifndef pTHX_ +# define pTHX_ +#endif + +#ifndef aTHX +# define aTHX +#endif + +#ifndef aTHX_ +# define aTHX_ +#endif + +#if (PERL_BCDVERSION < 0x5006000) +# ifdef USE_THREADS +# define aTHXR thr +# define aTHXR_ thr, +# else +# define aTHXR +# define aTHXR_ +# endif +# define dTHXR dTHR +#else +# define aTHXR aTHX +# define aTHXR_ aTHX_ +# define dTHXR dTHX +#endif +#ifndef dTHXoa +# define dTHXoa(x) dTHXa(x) +#endif + +#ifdef I_LIMITS +# include +#endif + +#ifndef PERL_UCHAR_MIN +# define PERL_UCHAR_MIN ((unsigned char)0) +#endif + +#ifndef PERL_UCHAR_MAX +# ifdef UCHAR_MAX +# define PERL_UCHAR_MAX ((unsigned char)UCHAR_MAX) +# else +# ifdef MAXUCHAR +# define PERL_UCHAR_MAX ((unsigned char)MAXUCHAR) +# else +# define PERL_UCHAR_MAX ((unsigned char)~(unsigned)0) +# endif +# endif +#endif + +#ifndef PERL_USHORT_MIN +# define PERL_USHORT_MIN ((unsigned short)0) +#endif + +#ifndef PERL_USHORT_MAX +# ifdef USHORT_MAX +# define PERL_USHORT_MAX ((unsigned short)USHORT_MAX) +# else +# ifdef MAXUSHORT +# define PERL_USHORT_MAX ((unsigned short)MAXUSHORT) +# else +# ifdef USHRT_MAX +# define PERL_USHORT_MAX ((unsigned short)USHRT_MAX) +# else +# define PERL_USHORT_MAX ((unsigned short)~(unsigned)0) +# endif +# endif +# endif +#endif + +#ifndef PERL_SHORT_MAX +# ifdef SHORT_MAX +# define PERL_SHORT_MAX ((short)SHORT_MAX) +# else +# ifdef MAXSHORT /* Often used in */ +# define PERL_SHORT_MAX ((short)MAXSHORT) +# else +# ifdef SHRT_MAX +# define PERL_SHORT_MAX ((short)SHRT_MAX) +# else +# define PERL_SHORT_MAX ((short) (PERL_USHORT_MAX >> 1)) +# endif +# endif +# endif +#endif + +#ifndef PERL_SHORT_MIN +# ifdef SHORT_MIN +# define PERL_SHORT_MIN ((short)SHORT_MIN) +# else +# ifdef MINSHORT +# define PERL_SHORT_MIN ((short)MINSHORT) +# else +# ifdef SHRT_MIN +# define PERL_SHORT_MIN ((short)SHRT_MIN) +# else +# define PERL_SHORT_MIN (-PERL_SHORT_MAX - ((3 & -1) == 3)) +# endif +# endif +# endif +#endif + +#ifndef PERL_UINT_MAX +# ifdef UINT_MAX +# define PERL_UINT_MAX ((unsigned int)UINT_MAX) +# else +# ifdef MAXUINT +# define PERL_UINT_MAX ((unsigned int)MAXUINT) +# else +# define PERL_UINT_MAX (~(unsigned int)0) +# endif +# endif +#endif + +#ifndef PERL_UINT_MIN +# define PERL_UINT_MIN ((unsigned int)0) +#endif + +#ifndef PERL_INT_MAX +# ifdef INT_MAX +# define PERL_INT_MAX ((int)INT_MAX) +# else +# ifdef MAXINT /* Often used in */ +# define PERL_INT_MAX ((int)MAXINT) +# else +# define PERL_INT_MAX ((int)(PERL_UINT_MAX >> 1)) +# endif +# endif +#endif + +#ifndef PERL_INT_MIN +# ifdef INT_MIN +# define PERL_INT_MIN ((int)INT_MIN) +# else +# ifdef MININT +# define PERL_INT_MIN ((int)MININT) +# else +# define PERL_INT_MIN (-PERL_INT_MAX - ((3 & -1) == 3)) +# endif +# endif +#endif + +#ifndef PERL_ULONG_MAX +# ifdef ULONG_MAX +# define PERL_ULONG_MAX ((unsigned long)ULONG_MAX) +# else +# ifdef MAXULONG +# define PERL_ULONG_MAX ((unsigned long)MAXULONG) +# else +# define PERL_ULONG_MAX (~(unsigned long)0) +# endif +# endif +#endif + +#ifndef PERL_ULONG_MIN +# define PERL_ULONG_MIN ((unsigned long)0L) +#endif + +#ifndef PERL_LONG_MAX +# ifdef LONG_MAX +# define PERL_LONG_MAX ((long)LONG_MAX) +# else +# ifdef MAXLONG +# define PERL_LONG_MAX ((long)MAXLONG) +# else +# define PERL_LONG_MAX ((long) (PERL_ULONG_MAX >> 1)) +# endif +# endif +#endif + +#ifndef PERL_LONG_MIN +# ifdef LONG_MIN +# define PERL_LONG_MIN ((long)LONG_MIN) +# else +# ifdef MINLONG +# define PERL_LONG_MIN ((long)MINLONG) +# else +# define PERL_LONG_MIN (-PERL_LONG_MAX - ((3 & -1) == 3)) +# endif +# endif +#endif + +#if defined(HAS_QUAD) && (defined(convex) || defined(uts)) +# ifndef PERL_UQUAD_MAX +# ifdef ULONGLONG_MAX +# define PERL_UQUAD_MAX ((unsigned long long)ULONGLONG_MAX) +# else +# ifdef MAXULONGLONG +# define PERL_UQUAD_MAX ((unsigned long long)MAXULONGLONG) +# else +# define PERL_UQUAD_MAX (~(unsigned long long)0) +# endif +# endif +# endif + +# ifndef PERL_UQUAD_MIN +# define PERL_UQUAD_MIN ((unsigned long long)0L) +# endif + +# ifndef PERL_QUAD_MAX +# ifdef LONGLONG_MAX +# define PERL_QUAD_MAX ((long long)LONGLONG_MAX) +# else +# ifdef MAXLONGLONG +# define PERL_QUAD_MAX ((long long)MAXLONGLONG) +# else +# define PERL_QUAD_MAX ((long long) (PERL_UQUAD_MAX >> 1)) +# endif +# endif +# endif + +# ifndef PERL_QUAD_MIN +# ifdef LONGLONG_MIN +# define PERL_QUAD_MIN ((long long)LONGLONG_MIN) +# else +# ifdef MINLONGLONG +# define PERL_QUAD_MIN ((long long)MINLONGLONG) +# else +# define PERL_QUAD_MIN (-PERL_QUAD_MAX - ((3 & -1) == 3)) +# endif +# endif +# endif +#endif + +/* This is based on code from 5.003 perl.h */ +#ifdef HAS_QUAD +# ifdef cray +#ifndef IVTYPE +# define IVTYPE int +#endif + +#ifndef IV_MIN +# define IV_MIN PERL_INT_MIN +#endif + +#ifndef IV_MAX +# define IV_MAX PERL_INT_MAX +#endif + +#ifndef UV_MIN +# define UV_MIN PERL_UINT_MIN +#endif + +#ifndef UV_MAX +# define UV_MAX PERL_UINT_MAX +#endif + +# ifdef INTSIZE +#ifndef IVSIZE +# define IVSIZE INTSIZE +#endif + +# endif +# else +# if defined(convex) || defined(uts) +#ifndef IVTYPE +# define IVTYPE long long +#endif + +#ifndef IV_MIN +# define IV_MIN PERL_QUAD_MIN +#endif + +#ifndef IV_MAX +# define IV_MAX PERL_QUAD_MAX +#endif + +#ifndef UV_MIN +# define UV_MIN PERL_UQUAD_MIN +#endif + +#ifndef UV_MAX +# define UV_MAX PERL_UQUAD_MAX +#endif + +# ifdef LONGLONGSIZE +#ifndef IVSIZE +# define IVSIZE LONGLONGSIZE +#endif + +# endif +# else +#ifndef IVTYPE +# define IVTYPE long +#endif + +#ifndef IV_MIN +# define IV_MIN PERL_LONG_MIN +#endif + +#ifndef IV_MAX +# define IV_MAX PERL_LONG_MAX +#endif + +#ifndef UV_MIN +# define UV_MIN PERL_ULONG_MIN +#endif + +#ifndef UV_MAX +# define UV_MAX PERL_ULONG_MAX +#endif + +# ifdef LONGSIZE +#ifndef IVSIZE +# define IVSIZE LONGSIZE +#endif + +# endif +# endif +# endif +#ifndef IVSIZE +# define IVSIZE 8 +#endif + +#ifndef PERL_QUAD_MIN +# define PERL_QUAD_MIN IV_MIN +#endif + +#ifndef PERL_QUAD_MAX +# define PERL_QUAD_MAX IV_MAX +#endif + +#ifndef PERL_UQUAD_MIN +# define PERL_UQUAD_MIN UV_MIN +#endif + +#ifndef PERL_UQUAD_MAX +# define PERL_UQUAD_MAX UV_MAX +#endif + +#else +#ifndef IVTYPE +# define IVTYPE long +#endif + +#ifndef IV_MIN +# define IV_MIN PERL_LONG_MIN +#endif + +#ifndef IV_MAX +# define IV_MAX PERL_LONG_MAX +#endif + +#ifndef UV_MIN +# define UV_MIN PERL_ULONG_MIN +#endif + +#ifndef UV_MAX +# define UV_MAX PERL_ULONG_MAX +#endif + +#endif + +#ifndef IVSIZE +# ifdef LONGSIZE +# define IVSIZE LONGSIZE +# else +# define IVSIZE 4 /* A bold guess, but the best we can make. */ +# endif +#endif +#ifndef UVTYPE +# define UVTYPE unsigned IVTYPE +#endif + +#ifndef UVSIZE +# define UVSIZE IVSIZE +#endif +#ifndef sv_setuv +# define sv_setuv(sv, uv) \ + STMT_START { \ + UV TeMpUv = uv; \ + if (TeMpUv <= IV_MAX) \ + sv_setiv(sv, TeMpUv); \ + else \ + sv_setnv(sv, (double)TeMpUv); \ + } STMT_END +#endif +#ifndef newSVuv +# define newSVuv(uv) ((uv) <= IV_MAX ? newSViv((IV)uv) : newSVnv((NV)uv)) +#endif +#ifndef sv_2uv +# define sv_2uv(sv) ((PL_Sv = (sv)), (UV) (SvNOK(PL_Sv) ? SvNV(PL_Sv) : sv_2nv(PL_Sv))) +#endif + +#ifndef SvUVX +# define SvUVX(sv) ((UV)SvIVX(sv)) +#endif + +#ifndef SvUVXx +# define SvUVXx(sv) SvUVX(sv) +#endif + +#ifndef SvUV +# define SvUV(sv) (SvIOK(sv) ? SvUVX(sv) : sv_2uv(sv)) +#endif + +#ifndef SvUVx +# define SvUVx(sv) ((PL_Sv = (sv)), SvUV(PL_Sv)) +#endif + +/* Hint: sv_uv + * Always use the SvUVx() macro instead of sv_uv(). + */ +#ifndef sv_uv +# define sv_uv(sv) SvUVx(sv) +#endif + +#if !defined(SvUOK) && defined(SvIOK_UV) +# define SvUOK(sv) SvIOK_UV(sv) +#endif +#ifndef XST_mUV +# define XST_mUV(i,v) (ST(i) = sv_2mortal(newSVuv(v)) ) +#endif + +#ifndef XSRETURN_UV +# define XSRETURN_UV(v) STMT_START { XST_mUV(0,v); XSRETURN(1); } STMT_END +#endif +#ifndef PUSHu +# define PUSHu(u) STMT_START { sv_setuv(TARG, (UV)(u)); PUSHTARG; } STMT_END +#endif + +#ifndef XPUSHu +# define XPUSHu(u) STMT_START { sv_setuv(TARG, (UV)(u)); XPUSHTARG; } STMT_END +#endif + +#ifdef HAS_MEMCMP +#ifndef memNE +# define memNE(s1,s2,l) (memcmp(s1,s2,l)) +#endif + +#ifndef memEQ +# define memEQ(s1,s2,l) (!memcmp(s1,s2,l)) +#endif + +#else +#ifndef memNE +# define memNE(s1,s2,l) (bcmp(s1,s2,l)) +#endif + +#ifndef memEQ +# define memEQ(s1,s2,l) (!bcmp(s1,s2,l)) +#endif + +#endif +#ifndef MoveD +# define MoveD(s,d,n,t) memmove((char*)(d),(char*)(s), (n) * sizeof(t)) +#endif + +#ifndef CopyD +# define CopyD(s,d,n,t) memcpy((char*)(d),(char*)(s), (n) * sizeof(t)) +#endif + +#ifdef HAS_MEMSET +#ifndef ZeroD +# define ZeroD(d,n,t) memzero((char*)(d), (n) * sizeof(t)) +#endif + +#else +#ifndef ZeroD +# define ZeroD(d,n,t) ((void)memzero((char*)(d), (n) * sizeof(t)), d) +#endif + +#endif +#ifndef PoisonWith +# define PoisonWith(d,n,t,b) (void)memset((char*)(d), (U8)(b), (n) * sizeof(t)) +#endif + +#ifndef PoisonNew +# define PoisonNew(d,n,t) PoisonWith(d,n,t,0xAB) +#endif + +#ifndef PoisonFree +# define PoisonFree(d,n,t) PoisonWith(d,n,t,0xEF) +#endif + +#ifndef Poison +# define Poison(d,n,t) PoisonFree(d,n,t) +#endif +#ifndef Newx +# define Newx(v,n,t) New(0,v,n,t) +#endif + +#ifndef Newxc +# define Newxc(v,n,t,c) Newc(0,v,n,t,c) +#endif + +#ifndef Newxz +# define Newxz(v,n,t) Newz(0,v,n,t) +#endif + +#ifndef PERL_UNUSED_DECL +# ifdef HASATTRIBUTE +# if (defined(__GNUC__) && defined(__cplusplus)) || defined(__INTEL_COMPILER) +# define PERL_UNUSED_DECL +# else +# define PERL_UNUSED_DECL __attribute__((unused)) +# endif +# else +# define PERL_UNUSED_DECL +# endif +#endif + +#ifndef PERL_UNUSED_ARG +# if defined(lint) && defined(S_SPLINT_S) /* www.splint.org */ +# include +# define PERL_UNUSED_ARG(x) NOTE(ARGUNUSED(x)) +# else +# define PERL_UNUSED_ARG(x) ((void)x) +# endif +#endif + +#ifndef PERL_UNUSED_VAR +# define PERL_UNUSED_VAR(x) ((void)x) +#endif + +#ifndef PERL_UNUSED_CONTEXT +# ifdef USE_ITHREADS +# define PERL_UNUSED_CONTEXT PERL_UNUSED_ARG(my_perl) +# else +# define PERL_UNUSED_CONTEXT +# endif +#endif +#ifndef NOOP +# define NOOP /*EMPTY*/(void)0 +#endif + +#ifndef dNOOP +# define dNOOP extern int /*@unused@*/ Perl___notused PERL_UNUSED_DECL +#endif + +#ifndef NVTYPE +# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) +# define NVTYPE long double +# else +# define NVTYPE double +# endif +typedef NVTYPE NV; +#endif + +#ifndef INT2PTR +# if (IVSIZE == PTRSIZE) && (UVSIZE == PTRSIZE) +# define PTRV UV +# define INT2PTR(any,d) (any)(d) +# else +# if PTRSIZE == LONGSIZE +# define PTRV unsigned long +# else +# define PTRV unsigned +# endif +# define INT2PTR(any,d) (any)(PTRV)(d) +# endif +#endif + +#ifndef PTR2ul +# if PTRSIZE == LONGSIZE +# define PTR2ul(p) (unsigned long)(p) +# else +# define PTR2ul(p) INT2PTR(unsigned long,p) +# endif +#endif +#ifndef PTR2nat +# define PTR2nat(p) (PTRV)(p) +#endif + +#ifndef NUM2PTR +# define NUM2PTR(any,d) (any)PTR2nat(d) +#endif + +#ifndef PTR2IV +# define PTR2IV(p) INT2PTR(IV,p) +#endif + +#ifndef PTR2UV +# define PTR2UV(p) INT2PTR(UV,p) +#endif + +#ifndef PTR2NV +# define PTR2NV(p) NUM2PTR(NV,p) +#endif + +#undef START_EXTERN_C +#undef END_EXTERN_C +#undef EXTERN_C +#ifdef __cplusplus +# define START_EXTERN_C extern "C" { +# define END_EXTERN_C } +# define EXTERN_C extern "C" +#else +# define START_EXTERN_C +# define END_EXTERN_C +# define EXTERN_C extern +#endif + +#if defined(PERL_GCC_PEDANTIC) +# ifndef PERL_GCC_BRACE_GROUPS_FORBIDDEN +# define PERL_GCC_BRACE_GROUPS_FORBIDDEN +# endif +#endif + +#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) && !defined(__cplusplus) +# ifndef PERL_USE_GCC_BRACE_GROUPS +# define PERL_USE_GCC_BRACE_GROUPS +# endif +#endif + +#undef STMT_START +#undef STMT_END +#ifdef PERL_USE_GCC_BRACE_GROUPS +# define STMT_START (void)( /* gcc supports ``({ STATEMENTS; })'' */ +# define STMT_END ) +#else +# if defined(VOIDFLAGS) && (VOIDFLAGS) && (defined(sun) || defined(__sun__)) && !defined(__GNUC__) +# define STMT_START if (1) +# define STMT_END else (void)0 +# else +# define STMT_START do +# define STMT_END while (0) +# endif +#endif +#ifndef boolSV +# define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no) +#endif + +/* DEFSV appears first in 5.004_56 */ +#ifndef DEFSV +# define DEFSV GvSV(PL_defgv) +#endif + +#ifndef SAVE_DEFSV +# define SAVE_DEFSV SAVESPTR(GvSV(PL_defgv)) +#endif + +#ifndef DEFSV_set +# define DEFSV_set(sv) (DEFSV = (sv)) +#endif + +/* Older perls (<=5.003) lack AvFILLp */ +#ifndef AvFILLp +# define AvFILLp AvFILL +#endif +#ifndef ERRSV +# define ERRSV get_sv("@",FALSE) +#endif + +/* Hint: gv_stashpvn + * This function's backport doesn't support the length parameter, but + * rather ignores it. Portability can only be ensured if the length + * parameter is used for speed reasons, but the length can always be + * correctly computed from the string argument. + */ +#ifndef gv_stashpvn +# define gv_stashpvn(str,len,create) gv_stashpv(str,create) +#endif + +/* Replace: 1 */ +#ifndef get_cv +# define get_cv perl_get_cv +#endif + +#ifndef get_sv +# define get_sv perl_get_sv +#endif + +#ifndef get_av +# define get_av perl_get_av +#endif + +#ifndef get_hv +# define get_hv perl_get_hv +#endif + +/* Replace: 0 */ +#ifndef dUNDERBAR +# define dUNDERBAR dNOOP +#endif + +#ifndef UNDERBAR +# define UNDERBAR DEFSV +#endif +#ifndef dAX +# define dAX I32 ax = MARK - PL_stack_base + 1 +#endif + +#ifndef dITEMS +# define dITEMS I32 items = SP - MARK +#endif +#ifndef dXSTARG +# define dXSTARG SV * targ = sv_newmortal() +#endif +#ifndef dAXMARK +# define dAXMARK I32 ax = POPMARK; \ + register SV ** const mark = PL_stack_base + ax++ +#endif +#ifndef XSprePUSH +# define XSprePUSH (sp = PL_stack_base + ax - 1) +#endif + +#if (PERL_BCDVERSION < 0x5005000) +# undef XSRETURN +# define XSRETURN(off) \ + STMT_START { \ + PL_stack_sp = PL_stack_base + ax + ((off) - 1); \ + return; \ + } STMT_END +#endif +#ifndef XSPROTO +# define XSPROTO(name) void name(pTHX_ CV* cv) +#endif + +#ifndef SVfARG +# define SVfARG(p) ((void*)(p)) +#endif +#ifndef PERL_ABS +# define PERL_ABS(x) ((x) < 0 ? -(x) : (x)) +#endif +#ifndef dVAR +# define dVAR dNOOP +#endif +#ifndef SVf +# define SVf "_" +#endif +#ifndef UTF8_MAXBYTES +# define UTF8_MAXBYTES UTF8_MAXLEN +#endif +#ifndef CPERLscope +# define CPERLscope(x) x +#endif +#ifndef PERL_HASH +# define PERL_HASH(hash,str,len) \ + STMT_START { \ + const char *s_PeRlHaSh = str; \ + I32 i_PeRlHaSh = len; \ + U32 hash_PeRlHaSh = 0; \ + while (i_PeRlHaSh--) \ + hash_PeRlHaSh = hash_PeRlHaSh * 33 + *s_PeRlHaSh++; \ + (hash) = hash_PeRlHaSh; \ + } STMT_END +#endif + +#ifndef PERLIO_FUNCS_DECL +# ifdef PERLIO_FUNCS_CONST +# define PERLIO_FUNCS_DECL(funcs) const PerlIO_funcs funcs +# define PERLIO_FUNCS_CAST(funcs) (PerlIO_funcs*)(funcs) +# else +# define PERLIO_FUNCS_DECL(funcs) PerlIO_funcs funcs +# define PERLIO_FUNCS_CAST(funcs) (funcs) +# endif +#endif + +/* provide these typedefs for older perls */ +#if (PERL_BCDVERSION < 0x5009003) + +# ifdef ARGSproto +typedef OP* (CPERLscope(*Perl_ppaddr_t))(ARGSproto); +# else +typedef OP* (CPERLscope(*Perl_ppaddr_t))(pTHX); +# endif + +typedef OP* (CPERLscope(*Perl_check_t)) (pTHX_ OP*); + +#endif +#ifndef isPSXSPC +# define isPSXSPC(c) (isSPACE(c) || (c) == '\v') +#endif + +#ifndef isBLANK +# define isBLANK(c) ((c) == ' ' || (c) == '\t') +#endif + +#ifdef EBCDIC +#ifndef isALNUMC +# define isALNUMC(c) isalnum(c) +#endif + +#ifndef isASCII +# define isASCII(c) isascii(c) +#endif + +#ifndef isCNTRL +# define isCNTRL(c) iscntrl(c) +#endif + +#ifndef isGRAPH +# define isGRAPH(c) isgraph(c) +#endif + +#ifndef isPRINT +# define isPRINT(c) isprint(c) +#endif + +#ifndef isPUNCT +# define isPUNCT(c) ispunct(c) +#endif + +#ifndef isXDIGIT +# define isXDIGIT(c) isxdigit(c) +#endif + +#else +# if (PERL_BCDVERSION < 0x5010000) +/* Hint: isPRINT + * The implementation in older perl versions includes all of the + * isSPACE() characters, which is wrong. The version provided by + * Devel::PPPort always overrides a present buggy version. + */ +# undef isPRINT +# endif +#ifndef isALNUMC +# define isALNUMC(c) (isALPHA(c) || isDIGIT(c)) +#endif + +#ifndef isASCII +# define isASCII(c) ((c) <= 127) +#endif + +#ifndef isCNTRL +# define isCNTRL(c) ((c) < ' ' || (c) == 127) +#endif + +#ifndef isGRAPH +# define isGRAPH(c) (isALNUM(c) || isPUNCT(c)) +#endif + +#ifndef isPRINT +# define isPRINT(c) (((c) >= 32 && (c) < 127)) +#endif + +#ifndef isPUNCT +# define isPUNCT(c) (((c) >= 33 && (c) <= 47) || ((c) >= 58 && (c) <= 64) || ((c) >= 91 && (c) <= 96) || ((c) >= 123 && (c) <= 126)) +#endif + +#ifndef isXDIGIT +# define isXDIGIT(c) (isDIGIT(c) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) +#endif + +#endif + +#ifndef PERL_SIGNALS_UNSAFE_FLAG + +#define PERL_SIGNALS_UNSAFE_FLAG 0x0001 + +#if (PERL_BCDVERSION < 0x5008000) +# define D_PPP_PERL_SIGNALS_INIT PERL_SIGNALS_UNSAFE_FLAG +#else +# define D_PPP_PERL_SIGNALS_INIT 0 +#endif + +#if defined(NEED_PL_signals) +static U32 DPPP_(my_PL_signals) = D_PPP_PERL_SIGNALS_INIT; +#elif defined(NEED_PL_signals_GLOBAL) +U32 DPPP_(my_PL_signals) = D_PPP_PERL_SIGNALS_INIT; +#else +extern U32 DPPP_(my_PL_signals); +#endif +#define PL_signals DPPP_(my_PL_signals) + +#endif + +/* Hint: PL_ppaddr + * Calling an op via PL_ppaddr requires passing a context argument + * for threaded builds. Since the context argument is different for + * 5.005 perls, you can use aTHXR (supplied by ppport.h), which will + * automatically be defined as the correct argument. + */ + +#if (PERL_BCDVERSION <= 0x5005005) +/* Replace: 1 */ +# define PL_ppaddr ppaddr +# define PL_no_modify no_modify +/* Replace: 0 */ +#endif + +#if (PERL_BCDVERSION <= 0x5004005) +/* Replace: 1 */ +# define PL_DBsignal DBsignal +# define PL_DBsingle DBsingle +# define PL_DBsub DBsub +# define PL_DBtrace DBtrace +# define PL_Sv Sv +# define PL_bufend bufend +# define PL_bufptr bufptr +# define PL_compiling compiling +# define PL_copline copline +# define PL_curcop curcop +# define PL_curstash curstash +# define PL_debstash debstash +# define PL_defgv defgv +# define PL_diehook diehook +# define PL_dirty dirty +# define PL_dowarn dowarn +# define PL_errgv errgv +# define PL_error_count error_count +# define PL_expect expect +# define PL_hexdigit hexdigit +# define PL_hints hints +# define PL_in_my in_my +# define PL_laststatval laststatval +# define PL_lex_state lex_state +# define PL_lex_stuff lex_stuff +# define PL_linestr linestr +# define PL_na na +# define PL_perl_destruct_level perl_destruct_level +# define PL_perldb perldb +# define PL_rsfp_filters rsfp_filters +# define PL_rsfp rsfp +# define PL_stack_base stack_base +# define PL_stack_sp stack_sp +# define PL_statcache statcache +# define PL_stdingv stdingv +# define PL_sv_arenaroot sv_arenaroot +# define PL_sv_no sv_no +# define PL_sv_undef sv_undef +# define PL_sv_yes sv_yes +# define PL_tainted tainted +# define PL_tainting tainting +# define PL_tokenbuf tokenbuf +/* Replace: 0 */ +#endif + +/* Warning: PL_parser + * For perl versions earlier than 5.9.5, this is an always + * non-NULL dummy. Also, it cannot be dereferenced. Don't + * use it if you can avoid is and unless you absolutely know + * what you're doing. + * If you always check that PL_parser is non-NULL, you can + * define DPPP_PL_parser_NO_DUMMY to avoid the creation of + * a dummy parser structure. + */ + +#if (PERL_BCDVERSION >= 0x5009005) +# ifdef DPPP_PL_parser_NO_DUMMY +# define D_PPP_my_PL_parser_var(var) ((PL_parser ? PL_parser : \ + (croak("panic: PL_parser == NULL in %s:%d", \ + __FILE__, __LINE__), (yy_parser *) NULL))->var) +# else +# ifdef DPPP_PL_parser_NO_DUMMY_WARNING +# define D_PPP_parser_dummy_warning(var) +# else +# define D_PPP_parser_dummy_warning(var) \ + warn("warning: dummy PL_" #var " used in %s:%d", __FILE__, __LINE__), +# endif +# define D_PPP_my_PL_parser_var(var) ((PL_parser ? PL_parser : \ + (D_PPP_parser_dummy_warning(var) &DPPP_(dummy_PL_parser)))->var) +#if defined(NEED_PL_parser) +static yy_parser DPPP_(dummy_PL_parser); +#elif defined(NEED_PL_parser_GLOBAL) +yy_parser DPPP_(dummy_PL_parser); +#else +extern yy_parser DPPP_(dummy_PL_parser); +#endif + +# endif + +/* PL_expect, PL_copline, PL_rsfp, PL_rsfp_filters, PL_linestr, PL_bufptr, PL_bufend, PL_lex_state, PL_lex_stuff, PL_tokenbuf depends on PL_parser */ +/* Warning: PL_expect, PL_copline, PL_rsfp, PL_rsfp_filters, PL_linestr, PL_bufptr, PL_bufend, PL_lex_state, PL_lex_stuff, PL_tokenbuf + * Do not use this variable unless you know exactly what you're + * doint. It is internal to the perl parser and may change or even + * be removed in the future. As of perl 5.9.5, you have to check + * for (PL_parser != NULL) for this variable to have any effect. + * An always non-NULL PL_parser dummy is provided for earlier + * perl versions. + * If PL_parser is NULL when you try to access this variable, a + * dummy is being accessed instead and a warning is issued unless + * you define DPPP_PL_parser_NO_DUMMY_WARNING. + * If DPPP_PL_parser_NO_DUMMY is defined, the code trying to access + * this variable will croak with a panic message. + */ + +# define PL_expect D_PPP_my_PL_parser_var(expect) +# define PL_copline D_PPP_my_PL_parser_var(copline) +# define PL_rsfp D_PPP_my_PL_parser_var(rsfp) +# define PL_rsfp_filters D_PPP_my_PL_parser_var(rsfp_filters) +# define PL_linestr D_PPP_my_PL_parser_var(linestr) +# define PL_bufptr D_PPP_my_PL_parser_var(bufptr) +# define PL_bufend D_PPP_my_PL_parser_var(bufend) +# define PL_lex_state D_PPP_my_PL_parser_var(lex_state) +# define PL_lex_stuff D_PPP_my_PL_parser_var(lex_stuff) +# define PL_tokenbuf D_PPP_my_PL_parser_var(tokenbuf) +# define PL_in_my D_PPP_my_PL_parser_var(in_my) +# define PL_in_my_stash D_PPP_my_PL_parser_var(in_my_stash) +# define PL_error_count D_PPP_my_PL_parser_var(error_count) + + +#else + +/* ensure that PL_parser != NULL and cannot be dereferenced */ +# define PL_parser ((void *) 1) + +#endif +#ifndef mPUSHs +# define mPUSHs(s) PUSHs(sv_2mortal(s)) +#endif + +#ifndef PUSHmortal +# define PUSHmortal PUSHs(sv_newmortal()) +#endif + +#ifndef mPUSHp +# define mPUSHp(p,l) sv_setpvn(PUSHmortal, (p), (l)) +#endif + +#ifndef mPUSHn +# define mPUSHn(n) sv_setnv(PUSHmortal, (NV)(n)) +#endif + +#ifndef mPUSHi +# define mPUSHi(i) sv_setiv(PUSHmortal, (IV)(i)) +#endif + +#ifndef mPUSHu +# define mPUSHu(u) sv_setuv(PUSHmortal, (UV)(u)) +#endif +#ifndef mXPUSHs +# define mXPUSHs(s) XPUSHs(sv_2mortal(s)) +#endif + +#ifndef XPUSHmortal +# define XPUSHmortal XPUSHs(sv_newmortal()) +#endif + +#ifndef mXPUSHp +# define mXPUSHp(p,l) STMT_START { EXTEND(sp,1); sv_setpvn(PUSHmortal, (p), (l)); } STMT_END +#endif + +#ifndef mXPUSHn +# define mXPUSHn(n) STMT_START { EXTEND(sp,1); sv_setnv(PUSHmortal, (NV)(n)); } STMT_END +#endif + +#ifndef mXPUSHi +# define mXPUSHi(i) STMT_START { EXTEND(sp,1); sv_setiv(PUSHmortal, (IV)(i)); } STMT_END +#endif + +#ifndef mXPUSHu +# define mXPUSHu(u) STMT_START { EXTEND(sp,1); sv_setuv(PUSHmortal, (UV)(u)); } STMT_END +#endif + +/* Replace: 1 */ +#ifndef call_sv +# define call_sv perl_call_sv +#endif + +#ifndef call_pv +# define call_pv perl_call_pv +#endif + +#ifndef call_argv +# define call_argv perl_call_argv +#endif + +#ifndef call_method +# define call_method perl_call_method +#endif +#ifndef eval_sv +# define eval_sv perl_eval_sv +#endif + +/* Replace: 0 */ +#ifndef PERL_LOADMOD_DENY +# define PERL_LOADMOD_DENY 0x1 +#endif + +#ifndef PERL_LOADMOD_NOIMPORT +# define PERL_LOADMOD_NOIMPORT 0x2 +#endif + +#ifndef PERL_LOADMOD_IMPORT_OPS +# define PERL_LOADMOD_IMPORT_OPS 0x4 +#endif + +#ifndef G_METHOD +# define G_METHOD 64 +# ifdef call_sv +# undef call_sv +# endif +# if (PERL_BCDVERSION < 0x5006000) +# define call_sv(sv, flags) ((flags) & G_METHOD ? perl_call_method((char *) SvPV_nolen_const(sv), \ + (flags) & ~G_METHOD) : perl_call_sv(sv, flags)) +# else +# define call_sv(sv, flags) ((flags) & G_METHOD ? Perl_call_method(aTHX_ (char *) SvPV_nolen_const(sv), \ + (flags) & ~G_METHOD) : Perl_call_sv(aTHX_ sv, flags)) +# endif +#endif + +/* Replace perl_eval_pv with eval_pv */ + +#ifndef eval_pv +#if defined(NEED_eval_pv) +static SV* DPPP_(my_eval_pv)(char *p, I32 croak_on_error); +static +#else +extern SV* DPPP_(my_eval_pv)(char *p, I32 croak_on_error); +#endif + +#ifdef eval_pv +# undef eval_pv +#endif +#define eval_pv(a,b) DPPP_(my_eval_pv)(aTHX_ a,b) +#define Perl_eval_pv DPPP_(my_eval_pv) + +#if defined(NEED_eval_pv) || defined(NEED_eval_pv_GLOBAL) + +SV* +DPPP_(my_eval_pv)(char *p, I32 croak_on_error) +{ + dSP; + SV* sv = newSVpv(p, 0); + + PUSHMARK(sp); + eval_sv(sv, G_SCALAR); + SvREFCNT_dec(sv); + + SPAGAIN; + sv = POPs; + PUTBACK; + + if (croak_on_error && SvTRUE(GvSV(errgv))) + croak(SvPVx(GvSV(errgv), na)); + + return sv; +} + +#endif +#endif + +#ifndef vload_module +#if defined(NEED_vload_module) +static void DPPP_(my_vload_module)(U32 flags, SV *name, SV *ver, va_list *args); +static +#else +extern void DPPP_(my_vload_module)(U32 flags, SV *name, SV *ver, va_list *args); +#endif + +#ifdef vload_module +# undef vload_module +#endif +#define vload_module(a,b,c,d) DPPP_(my_vload_module)(aTHX_ a,b,c,d) +#define Perl_vload_module DPPP_(my_vload_module) + +#if defined(NEED_vload_module) || defined(NEED_vload_module_GLOBAL) + +void +DPPP_(my_vload_module)(U32 flags, SV *name, SV *ver, va_list *args) +{ + dTHR; + dVAR; + OP *veop, *imop; + + OP * const modname = newSVOP(OP_CONST, 0, name); + /* 5.005 has a somewhat hacky force_normal that doesn't croak on + SvREADONLY() if PL_compling is true. Current perls take care in + ck_require() to correctly turn off SvREADONLY before calling + force_normal_flags(). This seems a better fix than fudging PL_compling + */ + SvREADONLY_off(((SVOP*)modname)->op_sv); + modname->op_private |= OPpCONST_BARE; + if (ver) { + veop = newSVOP(OP_CONST, 0, ver); + } + else + veop = NULL; + if (flags & PERL_LOADMOD_NOIMPORT) { + imop = sawparens(newNULLLIST()); + } + else if (flags & PERL_LOADMOD_IMPORT_OPS) { + imop = va_arg(*args, OP*); + } + else { + SV *sv; + imop = NULL; + sv = va_arg(*args, SV*); + while (sv) { + imop = append_elem(OP_LIST, imop, newSVOP(OP_CONST, 0, sv)); + sv = va_arg(*args, SV*); + } + } + { + const line_t ocopline = PL_copline; + COP * const ocurcop = PL_curcop; + const int oexpect = PL_expect; + +#if (PERL_BCDVERSION >= 0x5004000) + utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(FALSE, 0), + veop, modname, imop); +#else + utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(), + modname, imop); +#endif + PL_expect = oexpect; + PL_copline = ocopline; + PL_curcop = ocurcop; + } +} + +#endif +#endif + +#ifndef load_module +#if defined(NEED_load_module) +static void DPPP_(my_load_module)(U32 flags, SV *name, SV *ver, ...); +static +#else +extern void DPPP_(my_load_module)(U32 flags, SV *name, SV *ver, ...); +#endif + +#ifdef load_module +# undef load_module +#endif +#define load_module DPPP_(my_load_module) +#define Perl_load_module DPPP_(my_load_module) + +#if defined(NEED_load_module) || defined(NEED_load_module_GLOBAL) + +void +DPPP_(my_load_module)(U32 flags, SV *name, SV *ver, ...) +{ + va_list args; + va_start(args, ver); + vload_module(flags, name, ver, &args); + va_end(args); +} + +#endif +#endif +#ifndef newRV_inc +# define newRV_inc(sv) newRV(sv) /* Replace */ +#endif + +#ifndef newRV_noinc +#if defined(NEED_newRV_noinc) +static SV * DPPP_(my_newRV_noinc)(SV *sv); +static +#else +extern SV * DPPP_(my_newRV_noinc)(SV *sv); +#endif + +#ifdef newRV_noinc +# undef newRV_noinc +#endif +#define newRV_noinc(a) DPPP_(my_newRV_noinc)(aTHX_ a) +#define Perl_newRV_noinc DPPP_(my_newRV_noinc) + +#if defined(NEED_newRV_noinc) || defined(NEED_newRV_noinc_GLOBAL) +SV * +DPPP_(my_newRV_noinc)(SV *sv) +{ + SV *rv = (SV *)newRV(sv); + SvREFCNT_dec(sv); + return rv; +} +#endif +#endif + +/* Hint: newCONSTSUB + * Returns a CV* as of perl-5.7.1. This return value is not supported + * by Devel::PPPort. + */ + +/* newCONSTSUB from IO.xs is in the core starting with 5.004_63 */ +#if (PERL_BCDVERSION < 0x5004063) && (PERL_BCDVERSION != 0x5004005) +#if defined(NEED_newCONSTSUB) +static void DPPP_(my_newCONSTSUB)(HV *stash, const char *name, SV *sv); +static +#else +extern void DPPP_(my_newCONSTSUB)(HV *stash, const char *name, SV *sv); +#endif + +#ifdef newCONSTSUB +# undef newCONSTSUB +#endif +#define newCONSTSUB(a,b,c) DPPP_(my_newCONSTSUB)(aTHX_ a,b,c) +#define Perl_newCONSTSUB DPPP_(my_newCONSTSUB) + +#if defined(NEED_newCONSTSUB) || defined(NEED_newCONSTSUB_GLOBAL) + +/* This is just a trick to avoid a dependency of newCONSTSUB on PL_parser */ +/* (There's no PL_parser in perl < 5.005, so this is completely safe) */ +#define D_PPP_PL_copline PL_copline + +void +DPPP_(my_newCONSTSUB)(HV *stash, const char *name, SV *sv) +{ + U32 oldhints = PL_hints; + HV *old_cop_stash = PL_curcop->cop_stash; + HV *old_curstash = PL_curstash; + line_t oldline = PL_curcop->cop_line; + PL_curcop->cop_line = D_PPP_PL_copline; + + PL_hints &= ~HINT_BLOCK_SCOPE; + if (stash) + PL_curstash = PL_curcop->cop_stash = stash; + + newSUB( + +#if (PERL_BCDVERSION < 0x5003022) + start_subparse(), +#elif (PERL_BCDVERSION == 0x5003022) + start_subparse(0), +#else /* 5.003_23 onwards */ + start_subparse(FALSE, 0), +#endif + + newSVOP(OP_CONST, 0, newSVpv((char *) name, 0)), + newSVOP(OP_CONST, 0, &PL_sv_no), /* SvPV(&PL_sv_no) == "" -- GMB */ + newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv)) + ); + + PL_hints = oldhints; + PL_curcop->cop_stash = old_cop_stash; + PL_curstash = old_curstash; + PL_curcop->cop_line = oldline; +} +#endif +#endif + +/* + * Boilerplate macros for initializing and accessing interpreter-local + * data from C. All statics in extensions should be reworked to use + * this, if you want to make the extension thread-safe. See ext/re/re.xs + * for an example of the use of these macros. + * + * Code that uses these macros is responsible for the following: + * 1. #define MY_CXT_KEY to a unique string, e.g. "DynaLoader_guts" + * 2. Declare a typedef named my_cxt_t that is a structure that contains + * all the data that needs to be interpreter-local. + * 3. Use the START_MY_CXT macro after the declaration of my_cxt_t. + * 4. Use the MY_CXT_INIT macro such that it is called exactly once + * (typically put in the BOOT: section). + * 5. Use the members of the my_cxt_t structure everywhere as + * MY_CXT.member. + * 6. Use the dMY_CXT macro (a declaration) in all the functions that + * access MY_CXT. + */ + +#if defined(MULTIPLICITY) || defined(PERL_OBJECT) || \ + defined(PERL_CAPI) || defined(PERL_IMPLICIT_CONTEXT) + +#ifndef START_MY_CXT + +/* This must appear in all extensions that define a my_cxt_t structure, + * right after the definition (i.e. at file scope). The non-threads + * case below uses it to declare the data as static. */ +#define START_MY_CXT + +#if (PERL_BCDVERSION < 0x5004068) +/* Fetches the SV that keeps the per-interpreter data. */ +#define dMY_CXT_SV \ + SV *my_cxt_sv = get_sv(MY_CXT_KEY, FALSE) +#else /* >= perl5.004_68 */ +#define dMY_CXT_SV \ + SV *my_cxt_sv = *hv_fetch(PL_modglobal, MY_CXT_KEY, \ + sizeof(MY_CXT_KEY)-1, TRUE) +#endif /* < perl5.004_68 */ + +/* This declaration should be used within all functions that use the + * interpreter-local data. */ +#define dMY_CXT \ + dMY_CXT_SV; \ + my_cxt_t *my_cxtp = INT2PTR(my_cxt_t*,SvUV(my_cxt_sv)) + +/* Creates and zeroes the per-interpreter data. + * (We allocate my_cxtp in a Perl SV so that it will be released when + * the interpreter goes away.) */ +#define MY_CXT_INIT \ + dMY_CXT_SV; \ + /* newSV() allocates one more than needed */ \ + my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\ + Zero(my_cxtp, 1, my_cxt_t); \ + sv_setuv(my_cxt_sv, PTR2UV(my_cxtp)) + +/* This macro must be used to access members of the my_cxt_t structure. + * e.g. MYCXT.some_data */ +#define MY_CXT (*my_cxtp) + +/* Judicious use of these macros can reduce the number of times dMY_CXT + * is used. Use is similar to pTHX, aTHX etc. */ +#define pMY_CXT my_cxt_t *my_cxtp +#define pMY_CXT_ pMY_CXT, +#define _pMY_CXT ,pMY_CXT +#define aMY_CXT my_cxtp +#define aMY_CXT_ aMY_CXT, +#define _aMY_CXT ,aMY_CXT + +#endif /* START_MY_CXT */ + +#ifndef MY_CXT_CLONE +/* Clones the per-interpreter data. */ +#define MY_CXT_CLONE \ + dMY_CXT_SV; \ + my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\ + Copy(INT2PTR(my_cxt_t*, SvUV(my_cxt_sv)), my_cxtp, 1, my_cxt_t);\ + sv_setuv(my_cxt_sv, PTR2UV(my_cxtp)) +#endif + +#else /* single interpreter */ + +#ifndef START_MY_CXT + +#define START_MY_CXT static my_cxt_t my_cxt; +#define dMY_CXT_SV dNOOP +#define dMY_CXT dNOOP +#define MY_CXT_INIT NOOP +#define MY_CXT my_cxt + +#define pMY_CXT void +#define pMY_CXT_ +#define _pMY_CXT +#define aMY_CXT +#define aMY_CXT_ +#define _aMY_CXT + +#endif /* START_MY_CXT */ + +#ifndef MY_CXT_CLONE +#define MY_CXT_CLONE NOOP +#endif + +#endif + +#ifndef IVdf +# if IVSIZE == LONGSIZE +# define IVdf "ld" +# define UVuf "lu" +# define UVof "lo" +# define UVxf "lx" +# define UVXf "lX" +# else +# if IVSIZE == INTSIZE +# define IVdf "d" +# define UVuf "u" +# define UVof "o" +# define UVxf "x" +# define UVXf "X" +# endif +# endif +#endif + +#ifndef NVef +# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) && \ + defined(PERL_PRIfldbl) && (PERL_BCDVERSION != 0x5006000) + /* Not very likely, but let's try anyway. */ +# define NVef PERL_PRIeldbl +# define NVff PERL_PRIfldbl +# define NVgf PERL_PRIgldbl +# else +# define NVef "e" +# define NVff "f" +# define NVgf "g" +# endif +#endif + +#ifndef SvREFCNT_inc +# ifdef PERL_USE_GCC_BRACE_GROUPS +# define SvREFCNT_inc(sv) \ + ({ \ + SV * const _sv = (SV*)(sv); \ + if (_sv) \ + (SvREFCNT(_sv))++; \ + _sv; \ + }) +# else +# define SvREFCNT_inc(sv) \ + ((PL_Sv=(SV*)(sv)) ? (++(SvREFCNT(PL_Sv)),PL_Sv) : NULL) +# endif +#endif + +#ifndef SvREFCNT_inc_simple +# ifdef PERL_USE_GCC_BRACE_GROUPS +# define SvREFCNT_inc_simple(sv) \ + ({ \ + if (sv) \ + (SvREFCNT(sv))++; \ + (SV *)(sv); \ + }) +# else +# define SvREFCNT_inc_simple(sv) \ + ((sv) ? (SvREFCNT(sv)++,(SV*)(sv)) : NULL) +# endif +#endif + +#ifndef SvREFCNT_inc_NN +# ifdef PERL_USE_GCC_BRACE_GROUPS +# define SvREFCNT_inc_NN(sv) \ + ({ \ + SV * const _sv = (SV*)(sv); \ + SvREFCNT(_sv)++; \ + _sv; \ + }) +# else +# define SvREFCNT_inc_NN(sv) \ + (PL_Sv=(SV*)(sv),++(SvREFCNT(PL_Sv)),PL_Sv) +# endif +#endif + +#ifndef SvREFCNT_inc_void +# ifdef PERL_USE_GCC_BRACE_GROUPS +# define SvREFCNT_inc_void(sv) \ + ({ \ + SV * const _sv = (SV*)(sv); \ + if (_sv) \ + (void)(SvREFCNT(_sv)++); \ + }) +# else +# define SvREFCNT_inc_void(sv) \ + (void)((PL_Sv=(SV*)(sv)) ? ++(SvREFCNT(PL_Sv)) : 0) +# endif +#endif +#ifndef SvREFCNT_inc_simple_void +# define SvREFCNT_inc_simple_void(sv) STMT_START { if (sv) SvREFCNT(sv)++; } STMT_END +#endif + +#ifndef SvREFCNT_inc_simple_NN +# define SvREFCNT_inc_simple_NN(sv) (++SvREFCNT(sv), (SV*)(sv)) +#endif + +#ifndef SvREFCNT_inc_void_NN +# define SvREFCNT_inc_void_NN(sv) (void)(++SvREFCNT((SV*)(sv))) +#endif + +#ifndef SvREFCNT_inc_simple_void_NN +# define SvREFCNT_inc_simple_void_NN(sv) (void)(++SvREFCNT((SV*)(sv))) +#endif + +#ifndef newSV_type + +#if defined(NEED_newSV_type) +static SV* DPPP_(my_newSV_type)(pTHX_ svtype const t); +static +#else +extern SV* DPPP_(my_newSV_type)(pTHX_ svtype const t); +#endif + +#ifdef newSV_type +# undef newSV_type +#endif +#define newSV_type(a) DPPP_(my_newSV_type)(aTHX_ a) +#define Perl_newSV_type DPPP_(my_newSV_type) + +#if defined(NEED_newSV_type) || defined(NEED_newSV_type_GLOBAL) + +SV* +DPPP_(my_newSV_type)(pTHX_ svtype const t) +{ + SV* const sv = newSV(0); + sv_upgrade(sv, t); + return sv; +} + +#endif + +#endif + +#if (PERL_BCDVERSION < 0x5006000) +# define D_PPP_CONSTPV_ARG(x) ((char *) (x)) +#else +# define D_PPP_CONSTPV_ARG(x) (x) +#endif +#ifndef newSVpvn +# define newSVpvn(data,len) ((data) \ + ? ((len) ? newSVpv((data), (len)) : newSVpv("", 0)) \ + : newSV(0)) +#endif +#ifndef newSVpvn_utf8 +# define newSVpvn_utf8(s, len, u) newSVpvn_flags((s), (len), (u) ? SVf_UTF8 : 0) +#endif +#ifndef SVf_UTF8 +# define SVf_UTF8 0 +#endif + +#ifndef newSVpvn_flags + +#if defined(NEED_newSVpvn_flags) +static SV * DPPP_(my_newSVpvn_flags)(pTHX_ const char *s, STRLEN len, U32 flags); +static +#else +extern SV * DPPP_(my_newSVpvn_flags)(pTHX_ const char *s, STRLEN len, U32 flags); +#endif + +#ifdef newSVpvn_flags +# undef newSVpvn_flags +#endif +#define newSVpvn_flags(a,b,c) DPPP_(my_newSVpvn_flags)(aTHX_ a,b,c) +#define Perl_newSVpvn_flags DPPP_(my_newSVpvn_flags) + +#if defined(NEED_newSVpvn_flags) || defined(NEED_newSVpvn_flags_GLOBAL) + +SV * +DPPP_(my_newSVpvn_flags)(pTHX_ const char *s, STRLEN len, U32 flags) +{ + SV *sv = newSVpvn(D_PPP_CONSTPV_ARG(s), len); + SvFLAGS(sv) |= (flags & SVf_UTF8); + return (flags & SVs_TEMP) ? sv_2mortal(sv) : sv; +} + +#endif + +#endif + +/* Backwards compatibility stuff... :-( */ +#if !defined(NEED_sv_2pv_flags) && defined(NEED_sv_2pv_nolen) +# define NEED_sv_2pv_flags +#endif +#if !defined(NEED_sv_2pv_flags_GLOBAL) && defined(NEED_sv_2pv_nolen_GLOBAL) +# define NEED_sv_2pv_flags_GLOBAL +#endif + +/* Hint: sv_2pv_nolen + * Use the SvPV_nolen() or SvPV_nolen_const() macros instead of sv_2pv_nolen(). + */ +#ifndef sv_2pv_nolen +# define sv_2pv_nolen(sv) SvPV_nolen(sv) +#endif + +#ifdef SvPVbyte + +/* Hint: SvPVbyte + * Does not work in perl-5.6.1, ppport.h implements a version + * borrowed from perl-5.7.3. + */ + +#if (PERL_BCDVERSION < 0x5007000) + +#if defined(NEED_sv_2pvbyte) +static char * DPPP_(my_sv_2pvbyte)(pTHX_ SV *sv, STRLEN *lp); +static +#else +extern char * DPPP_(my_sv_2pvbyte)(pTHX_ SV *sv, STRLEN *lp); +#endif + +#ifdef sv_2pvbyte +# undef sv_2pvbyte +#endif +#define sv_2pvbyte(a,b) DPPP_(my_sv_2pvbyte)(aTHX_ a,b) +#define Perl_sv_2pvbyte DPPP_(my_sv_2pvbyte) + +#if defined(NEED_sv_2pvbyte) || defined(NEED_sv_2pvbyte_GLOBAL) + +char * +DPPP_(my_sv_2pvbyte)(pTHX_ SV *sv, STRLEN *lp) +{ + sv_utf8_downgrade(sv,0); + return SvPV(sv,*lp); +} + +#endif + +/* Hint: sv_2pvbyte + * Use the SvPVbyte() macro instead of sv_2pvbyte(). + */ + +#undef SvPVbyte + +#define SvPVbyte(sv, lp) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK) \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvbyte(sv, &lp)) + +#endif + +#else + +# define SvPVbyte SvPV +# define sv_2pvbyte sv_2pv + +#endif +#ifndef sv_2pvbyte_nolen +# define sv_2pvbyte_nolen(sv) sv_2pv_nolen(sv) +#endif + +/* Hint: sv_pvn + * Always use the SvPV() macro instead of sv_pvn(). + */ + +/* Hint: sv_pvn_force + * Always use the SvPV_force() macro instead of sv_pvn_force(). + */ + +/* If these are undefined, they're not handled by the core anyway */ +#ifndef SV_IMMEDIATE_UNREF +# define SV_IMMEDIATE_UNREF 0 +#endif + +#ifndef SV_GMAGIC +# define SV_GMAGIC 0 +#endif + +#ifndef SV_COW_DROP_PV +# define SV_COW_DROP_PV 0 +#endif + +#ifndef SV_UTF8_NO_ENCODING +# define SV_UTF8_NO_ENCODING 0 +#endif + +#ifndef SV_NOSTEAL +# define SV_NOSTEAL 0 +#endif + +#ifndef SV_CONST_RETURN +# define SV_CONST_RETURN 0 +#endif + +#ifndef SV_MUTABLE_RETURN +# define SV_MUTABLE_RETURN 0 +#endif + +#ifndef SV_SMAGIC +# define SV_SMAGIC 0 +#endif + +#ifndef SV_HAS_TRAILING_NUL +# define SV_HAS_TRAILING_NUL 0 +#endif + +#ifndef SV_COW_SHARED_HASH_KEYS +# define SV_COW_SHARED_HASH_KEYS 0 +#endif + +#if (PERL_BCDVERSION < 0x5007002) + +#if defined(NEED_sv_2pv_flags) +static char * DPPP_(my_sv_2pv_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags); +static +#else +extern char * DPPP_(my_sv_2pv_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags); +#endif + +#ifdef sv_2pv_flags +# undef sv_2pv_flags +#endif +#define sv_2pv_flags(a,b,c) DPPP_(my_sv_2pv_flags)(aTHX_ a,b,c) +#define Perl_sv_2pv_flags DPPP_(my_sv_2pv_flags) + +#if defined(NEED_sv_2pv_flags) || defined(NEED_sv_2pv_flags_GLOBAL) + +char * +DPPP_(my_sv_2pv_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags) +{ + STRLEN n_a = (STRLEN) flags; + return sv_2pv(sv, lp ? lp : &n_a); +} + +#endif + +#if defined(NEED_sv_pvn_force_flags) +static char * DPPP_(my_sv_pvn_force_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags); +static +#else +extern char * DPPP_(my_sv_pvn_force_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags); +#endif + +#ifdef sv_pvn_force_flags +# undef sv_pvn_force_flags +#endif +#define sv_pvn_force_flags(a,b,c) DPPP_(my_sv_pvn_force_flags)(aTHX_ a,b,c) +#define Perl_sv_pvn_force_flags DPPP_(my_sv_pvn_force_flags) + +#if defined(NEED_sv_pvn_force_flags) || defined(NEED_sv_pvn_force_flags_GLOBAL) + +char * +DPPP_(my_sv_pvn_force_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags) +{ + STRLEN n_a = (STRLEN) flags; + return sv_pvn_force(sv, lp ? lp : &n_a); +} + +#endif + +#endif + +#if (PERL_BCDVERSION < 0x5008008) || ( (PERL_BCDVERSION >= 0x5009000) && (PERL_BCDVERSION < 0x5009003) ) +# define DPPP_SVPV_NOLEN_LP_ARG &PL_na +#else +# define DPPP_SVPV_NOLEN_LP_ARG 0 +#endif +#ifndef SvPV_const +# define SvPV_const(sv, lp) SvPV_flags_const(sv, lp, SV_GMAGIC) +#endif + +#ifndef SvPV_mutable +# define SvPV_mutable(sv, lp) SvPV_flags_mutable(sv, lp, SV_GMAGIC) +#endif +#ifndef SvPV_flags +# define SvPV_flags(sv, lp, flags) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &lp, flags)) +#endif +#ifndef SvPV_flags_const +# define SvPV_flags_const(sv, lp, flags) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? ((lp = SvCUR(sv)), SvPVX_const(sv)) : \ + (const char*) sv_2pv_flags(sv, &lp, flags|SV_CONST_RETURN)) +#endif +#ifndef SvPV_flags_const_nolen +# define SvPV_flags_const_nolen(sv, flags) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? SvPVX_const(sv) : \ + (const char*) sv_2pv_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, flags|SV_CONST_RETURN)) +#endif +#ifndef SvPV_flags_mutable +# define SvPV_flags_mutable(sv, lp, flags) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) : \ + sv_2pv_flags(sv, &lp, flags|SV_MUTABLE_RETURN)) +#endif +#ifndef SvPV_force +# define SvPV_force(sv, lp) SvPV_force_flags(sv, lp, SV_GMAGIC) +#endif + +#ifndef SvPV_force_nolen +# define SvPV_force_nolen(sv) SvPV_force_flags_nolen(sv, SV_GMAGIC) +#endif + +#ifndef SvPV_force_mutable +# define SvPV_force_mutable(sv, lp) SvPV_force_flags_mutable(sv, lp, SV_GMAGIC) +#endif + +#ifndef SvPV_force_nomg +# define SvPV_force_nomg(sv, lp) SvPV_force_flags(sv, lp, 0) +#endif + +#ifndef SvPV_force_nomg_nolen +# define SvPV_force_nomg_nolen(sv) SvPV_force_flags_nolen(sv, 0) +#endif +#ifndef SvPV_force_flags +# define SvPV_force_flags(sv, lp, flags) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force_flags(sv, &lp, flags)) +#endif +#ifndef SvPV_force_flags_nolen +# define SvPV_force_flags_nolen(sv, flags) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ + ? SvPVX(sv) : sv_pvn_force_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, flags)) +#endif +#ifndef SvPV_force_flags_mutable +# define SvPV_force_flags_mutable(sv, lp, flags) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ + ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) \ + : sv_pvn_force_flags(sv, &lp, flags|SV_MUTABLE_RETURN)) +#endif +#ifndef SvPV_nolen +# define SvPV_nolen(sv) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? SvPVX(sv) : sv_2pv_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, SV_GMAGIC)) +#endif +#ifndef SvPV_nolen_const +# define SvPV_nolen_const(sv) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? SvPVX_const(sv) : sv_2pv_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, SV_GMAGIC|SV_CONST_RETURN)) +#endif +#ifndef SvPV_nomg +# define SvPV_nomg(sv, lp) SvPV_flags(sv, lp, 0) +#endif + +#ifndef SvPV_nomg_const +# define SvPV_nomg_const(sv, lp) SvPV_flags_const(sv, lp, 0) +#endif + +#ifndef SvPV_nomg_const_nolen +# define SvPV_nomg_const_nolen(sv) SvPV_flags_const_nolen(sv, 0) +#endif +#ifndef SvPV_renew +# define SvPV_renew(sv,n) STMT_START { SvLEN_set(sv, n); \ + SvPV_set((sv), (char *) saferealloc( \ + (Malloc_t)SvPVX(sv), (MEM_SIZE)((n)))); \ + } STMT_END +#endif +#ifndef SvMAGIC_set +# define SvMAGIC_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \ + (((XPVMG*) SvANY(sv))->xmg_magic = (val)); } STMT_END +#endif + +#if (PERL_BCDVERSION < 0x5009003) +#ifndef SvPVX_const +# define SvPVX_const(sv) ((const char*) (0 + SvPVX(sv))) +#endif + +#ifndef SvPVX_mutable +# define SvPVX_mutable(sv) (0 + SvPVX(sv)) +#endif +#ifndef SvRV_set +# define SvRV_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) >= SVt_RV); \ + (((XRV*) SvANY(sv))->xrv_rv = (val)); } STMT_END +#endif + +#else +#ifndef SvPVX_const +# define SvPVX_const(sv) ((const char*)((sv)->sv_u.svu_pv)) +#endif + +#ifndef SvPVX_mutable +# define SvPVX_mutable(sv) ((sv)->sv_u.svu_pv) +#endif +#ifndef SvRV_set +# define SvRV_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) >= SVt_RV); \ + ((sv)->sv_u.svu_rv = (val)); } STMT_END +#endif + +#endif +#ifndef SvSTASH_set +# define SvSTASH_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \ + (((XPVMG*) SvANY(sv))->xmg_stash = (val)); } STMT_END +#endif + +#if (PERL_BCDVERSION < 0x5004000) +#ifndef SvUV_set +# define SvUV_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \ + (((XPVIV*) SvANY(sv))->xiv_iv = (IV) (val)); } STMT_END +#endif + +#else +#ifndef SvUV_set +# define SvUV_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \ + (((XPVUV*) SvANY(sv))->xuv_uv = (val)); } STMT_END +#endif + +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(vnewSVpvf) +#if defined(NEED_vnewSVpvf) +static SV * DPPP_(my_vnewSVpvf)(pTHX_ const char *pat, va_list *args); +static +#else +extern SV * DPPP_(my_vnewSVpvf)(pTHX_ const char *pat, va_list *args); +#endif + +#ifdef vnewSVpvf +# undef vnewSVpvf +#endif +#define vnewSVpvf(a,b) DPPP_(my_vnewSVpvf)(aTHX_ a,b) +#define Perl_vnewSVpvf DPPP_(my_vnewSVpvf) + +#if defined(NEED_vnewSVpvf) || defined(NEED_vnewSVpvf_GLOBAL) + +SV * +DPPP_(my_vnewSVpvf)(pTHX_ const char *pat, va_list *args) +{ + register SV *sv = newSV(0); + sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)); + return sv; +} + +#endif +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vcatpvf) +# define sv_vcatpvf(sv, pat, args) sv_vcatpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)) +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vsetpvf) +# define sv_vsetpvf(sv, pat, args) sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)) +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_catpvf_mg) +#if defined(NEED_sv_catpvf_mg) +static void DPPP_(my_sv_catpvf_mg)(pTHX_ SV *sv, const char *pat, ...); +static +#else +extern void DPPP_(my_sv_catpvf_mg)(pTHX_ SV *sv, const char *pat, ...); +#endif + +#define Perl_sv_catpvf_mg DPPP_(my_sv_catpvf_mg) + +#if defined(NEED_sv_catpvf_mg) || defined(NEED_sv_catpvf_mg_GLOBAL) + +void +DPPP_(my_sv_catpvf_mg)(pTHX_ SV *sv, const char *pat, ...) +{ + va_list args; + va_start(args, pat); + sv_vcatpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); + SvSETMAGIC(sv); + va_end(args); +} + +#endif +#endif + +#ifdef PERL_IMPLICIT_CONTEXT +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_catpvf_mg_nocontext) +#if defined(NEED_sv_catpvf_mg_nocontext) +static void DPPP_(my_sv_catpvf_mg_nocontext)(SV *sv, const char *pat, ...); +static +#else +extern void DPPP_(my_sv_catpvf_mg_nocontext)(SV *sv, const char *pat, ...); +#endif + +#define sv_catpvf_mg_nocontext DPPP_(my_sv_catpvf_mg_nocontext) +#define Perl_sv_catpvf_mg_nocontext DPPP_(my_sv_catpvf_mg_nocontext) + +#if defined(NEED_sv_catpvf_mg_nocontext) || defined(NEED_sv_catpvf_mg_nocontext_GLOBAL) + +void +DPPP_(my_sv_catpvf_mg_nocontext)(SV *sv, const char *pat, ...) +{ + dTHX; + va_list args; + va_start(args, pat); + sv_vcatpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); + SvSETMAGIC(sv); + va_end(args); +} + +#endif +#endif +#endif + +/* sv_catpvf_mg depends on sv_catpvf_mg_nocontext */ +#ifndef sv_catpvf_mg +# ifdef PERL_IMPLICIT_CONTEXT +# define sv_catpvf_mg Perl_sv_catpvf_mg_nocontext +# else +# define sv_catpvf_mg Perl_sv_catpvf_mg +# endif +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vcatpvf_mg) +# define sv_vcatpvf_mg(sv, pat, args) \ + STMT_START { \ + sv_vcatpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)); \ + SvSETMAGIC(sv); \ + } STMT_END +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_setpvf_mg) +#if defined(NEED_sv_setpvf_mg) +static void DPPP_(my_sv_setpvf_mg)(pTHX_ SV *sv, const char *pat, ...); +static +#else +extern void DPPP_(my_sv_setpvf_mg)(pTHX_ SV *sv, const char *pat, ...); +#endif + +#define Perl_sv_setpvf_mg DPPP_(my_sv_setpvf_mg) + +#if defined(NEED_sv_setpvf_mg) || defined(NEED_sv_setpvf_mg_GLOBAL) + +void +DPPP_(my_sv_setpvf_mg)(pTHX_ SV *sv, const char *pat, ...) +{ + va_list args; + va_start(args, pat); + sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); + SvSETMAGIC(sv); + va_end(args); +} + +#endif +#endif + +#ifdef PERL_IMPLICIT_CONTEXT +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_setpvf_mg_nocontext) +#if defined(NEED_sv_setpvf_mg_nocontext) +static void DPPP_(my_sv_setpvf_mg_nocontext)(SV *sv, const char *pat, ...); +static +#else +extern void DPPP_(my_sv_setpvf_mg_nocontext)(SV *sv, const char *pat, ...); +#endif + +#define sv_setpvf_mg_nocontext DPPP_(my_sv_setpvf_mg_nocontext) +#define Perl_sv_setpvf_mg_nocontext DPPP_(my_sv_setpvf_mg_nocontext) + +#if defined(NEED_sv_setpvf_mg_nocontext) || defined(NEED_sv_setpvf_mg_nocontext_GLOBAL) + +void +DPPP_(my_sv_setpvf_mg_nocontext)(SV *sv, const char *pat, ...) +{ + dTHX; + va_list args; + va_start(args, pat); + sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); + SvSETMAGIC(sv); + va_end(args); +} + +#endif +#endif +#endif + +/* sv_setpvf_mg depends on sv_setpvf_mg_nocontext */ +#ifndef sv_setpvf_mg +# ifdef PERL_IMPLICIT_CONTEXT +# define sv_setpvf_mg Perl_sv_setpvf_mg_nocontext +# else +# define sv_setpvf_mg Perl_sv_setpvf_mg +# endif +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vsetpvf_mg) +# define sv_vsetpvf_mg(sv, pat, args) \ + STMT_START { \ + sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)); \ + SvSETMAGIC(sv); \ + } STMT_END +#endif + +#ifndef newSVpvn_share + +#if defined(NEED_newSVpvn_share) +static SV * DPPP_(my_newSVpvn_share)(pTHX_ const char *src, I32 len, U32 hash); +static +#else +extern SV * DPPP_(my_newSVpvn_share)(pTHX_ const char *src, I32 len, U32 hash); +#endif + +#ifdef newSVpvn_share +# undef newSVpvn_share +#endif +#define newSVpvn_share(a,b,c) DPPP_(my_newSVpvn_share)(aTHX_ a,b,c) +#define Perl_newSVpvn_share DPPP_(my_newSVpvn_share) + +#if defined(NEED_newSVpvn_share) || defined(NEED_newSVpvn_share_GLOBAL) + +SV * +DPPP_(my_newSVpvn_share)(pTHX_ const char *src, I32 len, U32 hash) +{ + SV *sv; + if (len < 0) + len = -len; + if (!hash) + PERL_HASH(hash, (char*) src, len); + sv = newSVpvn((char *) src, len); + sv_upgrade(sv, SVt_PVIV); + SvIVX(sv) = hash; + SvREADONLY_on(sv); + SvPOK_on(sv); + return sv; +} + +#endif + +#endif +#ifndef SvSHARED_HASH +# define SvSHARED_HASH(sv) (0 + SvUVX(sv)) +#endif +#ifndef HvNAME_get +# define HvNAME_get(hv) HvNAME(hv) +#endif +#ifndef HvNAMELEN_get +# define HvNAMELEN_get(hv) (HvNAME_get(hv) ? (I32)strlen(HvNAME_get(hv)) : 0) +#endif +#ifndef GvSVn +# define GvSVn(gv) GvSV(gv) +#endif + +#ifndef isGV_with_GP +# define isGV_with_GP(gv) isGV(gv) +#endif +#ifndef WARN_ALL +# define WARN_ALL 0 +#endif + +#ifndef WARN_CLOSURE +# define WARN_CLOSURE 1 +#endif + +#ifndef WARN_DEPRECATED +# define WARN_DEPRECATED 2 +#endif + +#ifndef WARN_EXITING +# define WARN_EXITING 3 +#endif + +#ifndef WARN_GLOB +# define WARN_GLOB 4 +#endif + +#ifndef WARN_IO +# define WARN_IO 5 +#endif + +#ifndef WARN_CLOSED +# define WARN_CLOSED 6 +#endif + +#ifndef WARN_EXEC +# define WARN_EXEC 7 +#endif + +#ifndef WARN_LAYER +# define WARN_LAYER 8 +#endif + +#ifndef WARN_NEWLINE +# define WARN_NEWLINE 9 +#endif + +#ifndef WARN_PIPE +# define WARN_PIPE 10 +#endif + +#ifndef WARN_UNOPENED +# define WARN_UNOPENED 11 +#endif + +#ifndef WARN_MISC +# define WARN_MISC 12 +#endif + +#ifndef WARN_NUMERIC +# define WARN_NUMERIC 13 +#endif + +#ifndef WARN_ONCE +# define WARN_ONCE 14 +#endif + +#ifndef WARN_OVERFLOW +# define WARN_OVERFLOW 15 +#endif + +#ifndef WARN_PACK +# define WARN_PACK 16 +#endif + +#ifndef WARN_PORTABLE +# define WARN_PORTABLE 17 +#endif + +#ifndef WARN_RECURSION +# define WARN_RECURSION 18 +#endif + +#ifndef WARN_REDEFINE +# define WARN_REDEFINE 19 +#endif + +#ifndef WARN_REGEXP +# define WARN_REGEXP 20 +#endif + +#ifndef WARN_SEVERE +# define WARN_SEVERE 21 +#endif + +#ifndef WARN_DEBUGGING +# define WARN_DEBUGGING 22 +#endif + +#ifndef WARN_INPLACE +# define WARN_INPLACE 23 +#endif + +#ifndef WARN_INTERNAL +# define WARN_INTERNAL 24 +#endif + +#ifndef WARN_MALLOC +# define WARN_MALLOC 25 +#endif + +#ifndef WARN_SIGNAL +# define WARN_SIGNAL 26 +#endif + +#ifndef WARN_SUBSTR +# define WARN_SUBSTR 27 +#endif + +#ifndef WARN_SYNTAX +# define WARN_SYNTAX 28 +#endif + +#ifndef WARN_AMBIGUOUS +# define WARN_AMBIGUOUS 29 +#endif + +#ifndef WARN_BAREWORD +# define WARN_BAREWORD 30 +#endif + +#ifndef WARN_DIGIT +# define WARN_DIGIT 31 +#endif + +#ifndef WARN_PARENTHESIS +# define WARN_PARENTHESIS 32 +#endif + +#ifndef WARN_PRECEDENCE +# define WARN_PRECEDENCE 33 +#endif + +#ifndef WARN_PRINTF +# define WARN_PRINTF 34 +#endif + +#ifndef WARN_PROTOTYPE +# define WARN_PROTOTYPE 35 +#endif + +#ifndef WARN_QW +# define WARN_QW 36 +#endif + +#ifndef WARN_RESERVED +# define WARN_RESERVED 37 +#endif + +#ifndef WARN_SEMICOLON +# define WARN_SEMICOLON 38 +#endif + +#ifndef WARN_TAINT +# define WARN_TAINT 39 +#endif + +#ifndef WARN_THREADS +# define WARN_THREADS 40 +#endif + +#ifndef WARN_UNINITIALIZED +# define WARN_UNINITIALIZED 41 +#endif + +#ifndef WARN_UNPACK +# define WARN_UNPACK 42 +#endif + +#ifndef WARN_UNTIE +# define WARN_UNTIE 43 +#endif + +#ifndef WARN_UTF8 +# define WARN_UTF8 44 +#endif + +#ifndef WARN_VOID +# define WARN_VOID 45 +#endif + +#ifndef WARN_ASSERTIONS +# define WARN_ASSERTIONS 46 +#endif +#ifndef packWARN +# define packWARN(a) (a) +#endif + +#ifndef ckWARN +# ifdef G_WARN_ON +# define ckWARN(a) (PL_dowarn & G_WARN_ON) +# else +# define ckWARN(a) PL_dowarn +# endif +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(warner) +#if defined(NEED_warner) +static void DPPP_(my_warner)(U32 err, const char *pat, ...); +static +#else +extern void DPPP_(my_warner)(U32 err, const char *pat, ...); +#endif + +#define Perl_warner DPPP_(my_warner) + +#if defined(NEED_warner) || defined(NEED_warner_GLOBAL) + +void +DPPP_(my_warner)(U32 err, const char *pat, ...) +{ + SV *sv; + va_list args; + + PERL_UNUSED_ARG(err); + + va_start(args, pat); + sv = vnewSVpvf(pat, &args); + va_end(args); + sv_2mortal(sv); + warn("%s", SvPV_nolen(sv)); +} + +#define warner Perl_warner + +#define Perl_warner_nocontext Perl_warner + +#endif +#endif + +/* concatenating with "" ensures that only literal strings are accepted as argument + * note that STR_WITH_LEN() can't be used as argument to macros or functions that + * under some configurations might be macros + */ +#ifndef STR_WITH_LEN +# define STR_WITH_LEN(s) (s ""), (sizeof(s)-1) +#endif +#ifndef newSVpvs +# define newSVpvs(str) newSVpvn(str "", sizeof(str) - 1) +#endif + +#ifndef newSVpvs_flags +# define newSVpvs_flags(str, flags) newSVpvn_flags(str "", sizeof(str) - 1, flags) +#endif + +#ifndef sv_catpvs +# define sv_catpvs(sv, str) sv_catpvn(sv, str "", sizeof(str) - 1) +#endif + +#ifndef sv_setpvs +# define sv_setpvs(sv, str) sv_setpvn(sv, str "", sizeof(str) - 1) +#endif + +#ifndef hv_fetchs +# define hv_fetchs(hv, key, lval) hv_fetch(hv, key "", sizeof(key) - 1, lval) +#endif + +#ifndef hv_stores +# define hv_stores(hv, key, val) hv_store(hv, key "", sizeof(key) - 1, val, 0) +#endif +#ifndef gv_fetchpvn_flags +# define gv_fetchpvn_flags(name, len, flags, svt) gv_fetchpv(name, flags, svt) +#endif + +#ifndef gv_fetchpvs +# define gv_fetchpvs(name, flags, svt) gv_fetchpvn_flags(name "", sizeof(name) - 1, flags, svt) +#endif + +#ifndef gv_stashpvs +# define gv_stashpvs(name, flags) gv_stashpvn(name "", sizeof(name) - 1, flags) +#endif +#ifndef SvGETMAGIC +# define SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END +#endif +#ifndef PERL_MAGIC_sv +# define PERL_MAGIC_sv '\0' +#endif + +#ifndef PERL_MAGIC_overload +# define PERL_MAGIC_overload 'A' +#endif + +#ifndef PERL_MAGIC_overload_elem +# define PERL_MAGIC_overload_elem 'a' +#endif + +#ifndef PERL_MAGIC_overload_table +# define PERL_MAGIC_overload_table 'c' +#endif + +#ifndef PERL_MAGIC_bm +# define PERL_MAGIC_bm 'B' +#endif + +#ifndef PERL_MAGIC_regdata +# define PERL_MAGIC_regdata 'D' +#endif + +#ifndef PERL_MAGIC_regdatum +# define PERL_MAGIC_regdatum 'd' +#endif + +#ifndef PERL_MAGIC_env +# define PERL_MAGIC_env 'E' +#endif + +#ifndef PERL_MAGIC_envelem +# define PERL_MAGIC_envelem 'e' +#endif + +#ifndef PERL_MAGIC_fm +# define PERL_MAGIC_fm 'f' +#endif + +#ifndef PERL_MAGIC_regex_global +# define PERL_MAGIC_regex_global 'g' +#endif + +#ifndef PERL_MAGIC_isa +# define PERL_MAGIC_isa 'I' +#endif + +#ifndef PERL_MAGIC_isaelem +# define PERL_MAGIC_isaelem 'i' +#endif + +#ifndef PERL_MAGIC_nkeys +# define PERL_MAGIC_nkeys 'k' +#endif + +#ifndef PERL_MAGIC_dbfile +# define PERL_MAGIC_dbfile 'L' +#endif + +#ifndef PERL_MAGIC_dbline +# define PERL_MAGIC_dbline 'l' +#endif + +#ifndef PERL_MAGIC_mutex +# define PERL_MAGIC_mutex 'm' +#endif + +#ifndef PERL_MAGIC_shared +# define PERL_MAGIC_shared 'N' +#endif + +#ifndef PERL_MAGIC_shared_scalar +# define PERL_MAGIC_shared_scalar 'n' +#endif + +#ifndef PERL_MAGIC_collxfrm +# define PERL_MAGIC_collxfrm 'o' +#endif + +#ifndef PERL_MAGIC_tied +# define PERL_MAGIC_tied 'P' +#endif + +#ifndef PERL_MAGIC_tiedelem +# define PERL_MAGIC_tiedelem 'p' +#endif + +#ifndef PERL_MAGIC_tiedscalar +# define PERL_MAGIC_tiedscalar 'q' +#endif + +#ifndef PERL_MAGIC_qr +# define PERL_MAGIC_qr 'r' +#endif + +#ifndef PERL_MAGIC_sig +# define PERL_MAGIC_sig 'S' +#endif + +#ifndef PERL_MAGIC_sigelem +# define PERL_MAGIC_sigelem 's' +#endif + +#ifndef PERL_MAGIC_taint +# define PERL_MAGIC_taint 't' +#endif + +#ifndef PERL_MAGIC_uvar +# define PERL_MAGIC_uvar 'U' +#endif + +#ifndef PERL_MAGIC_uvar_elem +# define PERL_MAGIC_uvar_elem 'u' +#endif + +#ifndef PERL_MAGIC_vstring +# define PERL_MAGIC_vstring 'V' +#endif + +#ifndef PERL_MAGIC_vec +# define PERL_MAGIC_vec 'v' +#endif + +#ifndef PERL_MAGIC_utf8 +# define PERL_MAGIC_utf8 'w' +#endif + +#ifndef PERL_MAGIC_substr +# define PERL_MAGIC_substr 'x' +#endif + +#ifndef PERL_MAGIC_defelem +# define PERL_MAGIC_defelem 'y' +#endif + +#ifndef PERL_MAGIC_glob +# define PERL_MAGIC_glob '*' +#endif + +#ifndef PERL_MAGIC_arylen +# define PERL_MAGIC_arylen '#' +#endif + +#ifndef PERL_MAGIC_pos +# define PERL_MAGIC_pos '.' +#endif + +#ifndef PERL_MAGIC_backref +# define PERL_MAGIC_backref '<' +#endif + +#ifndef PERL_MAGIC_ext +# define PERL_MAGIC_ext '~' +#endif + +/* That's the best we can do... */ +#ifndef sv_catpvn_nomg +# define sv_catpvn_nomg sv_catpvn +#endif + +#ifndef sv_catsv_nomg +# define sv_catsv_nomg sv_catsv +#endif + +#ifndef sv_setsv_nomg +# define sv_setsv_nomg sv_setsv +#endif + +#ifndef sv_pvn_nomg +# define sv_pvn_nomg sv_pvn +#endif + +#ifndef SvIV_nomg +# define SvIV_nomg SvIV +#endif + +#ifndef SvUV_nomg +# define SvUV_nomg SvUV +#endif + +#ifndef sv_catpv_mg +# define sv_catpv_mg(sv, ptr) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_catpv(TeMpSv,ptr); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_catpvn_mg +# define sv_catpvn_mg(sv, ptr, len) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_catpvn(TeMpSv,ptr,len); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_catsv_mg +# define sv_catsv_mg(dsv, ssv) \ + STMT_START { \ + SV *TeMpSv = dsv; \ + sv_catsv(TeMpSv,ssv); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_setiv_mg +# define sv_setiv_mg(sv, i) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_setiv(TeMpSv,i); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_setnv_mg +# define sv_setnv_mg(sv, num) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_setnv(TeMpSv,num); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_setpv_mg +# define sv_setpv_mg(sv, ptr) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_setpv(TeMpSv,ptr); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_setpvn_mg +# define sv_setpvn_mg(sv, ptr, len) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_setpvn(TeMpSv,ptr,len); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_setsv_mg +# define sv_setsv_mg(dsv, ssv) \ + STMT_START { \ + SV *TeMpSv = dsv; \ + sv_setsv(TeMpSv,ssv); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_setuv_mg +# define sv_setuv_mg(sv, i) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_setuv(TeMpSv,i); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_usepvn_mg +# define sv_usepvn_mg(sv, ptr, len) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_usepvn(TeMpSv,ptr,len); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif +#ifndef SvVSTRING_mg +# define SvVSTRING_mg(sv) (SvMAGICAL(sv) ? mg_find(sv, PERL_MAGIC_vstring) : NULL) +#endif + +/* Hint: sv_magic_portable + * This is a compatibility function that is only available with + * Devel::PPPort. It is NOT in the perl core. + * Its purpose is to mimic the 5.8.0 behaviour of sv_magic() when + * it is being passed a name pointer with namlen == 0. In that + * case, perl 5.8.0 and later store the pointer, not a copy of it. + * The compatibility can be provided back to perl 5.004. With + * earlier versions, the code will not compile. + */ + +#if (PERL_BCDVERSION < 0x5004000) + + /* code that uses sv_magic_portable will not compile */ + +#elif (PERL_BCDVERSION < 0x5008000) + +# define sv_magic_portable(sv, obj, how, name, namlen) \ + STMT_START { \ + SV *SvMp_sv = (sv); \ + char *SvMp_name = (char *) (name); \ + I32 SvMp_namlen = (namlen); \ + if (SvMp_name && SvMp_namlen == 0) \ + { \ + MAGIC *mg; \ + sv_magic(SvMp_sv, obj, how, 0, 0); \ + mg = SvMAGIC(SvMp_sv); \ + mg->mg_len = -42; /* XXX: this is the tricky part */ \ + mg->mg_ptr = SvMp_name; \ + } \ + else \ + { \ + sv_magic(SvMp_sv, obj, how, SvMp_name, SvMp_namlen); \ + } \ + } STMT_END + +#else + +# define sv_magic_portable(a, b, c, d, e) sv_magic(a, b, c, d, e) + +#endif + +#ifdef USE_ITHREADS +#ifndef CopFILE +# define CopFILE(c) ((c)->cop_file) +#endif + +#ifndef CopFILEGV +# define CopFILEGV(c) (CopFILE(c) ? gv_fetchfile(CopFILE(c)) : Nullgv) +#endif + +#ifndef CopFILE_set +# define CopFILE_set(c,pv) ((c)->cop_file = savepv(pv)) +#endif + +#ifndef CopFILESV +# define CopFILESV(c) (CopFILE(c) ? GvSV(gv_fetchfile(CopFILE(c))) : Nullsv) +#endif + +#ifndef CopFILEAV +# define CopFILEAV(c) (CopFILE(c) ? GvAV(gv_fetchfile(CopFILE(c))) : Nullav) +#endif + +#ifndef CopSTASHPV +# define CopSTASHPV(c) ((c)->cop_stashpv) +#endif + +#ifndef CopSTASHPV_set +# define CopSTASHPV_set(c,pv) ((c)->cop_stashpv = ((pv) ? savepv(pv) : Nullch)) +#endif + +#ifndef CopSTASH +# define CopSTASH(c) (CopSTASHPV(c) ? gv_stashpv(CopSTASHPV(c),GV_ADD) : Nullhv) +#endif + +#ifndef CopSTASH_set +# define CopSTASH_set(c,hv) CopSTASHPV_set(c, (hv) ? HvNAME(hv) : Nullch) +#endif + +#ifndef CopSTASH_eq +# define CopSTASH_eq(c,hv) ((hv) && (CopSTASHPV(c) == HvNAME(hv) \ + || (CopSTASHPV(c) && HvNAME(hv) \ + && strEQ(CopSTASHPV(c), HvNAME(hv))))) +#endif + +#else +#ifndef CopFILEGV +# define CopFILEGV(c) ((c)->cop_filegv) +#endif + +#ifndef CopFILEGV_set +# define CopFILEGV_set(c,gv) ((c)->cop_filegv = (GV*)SvREFCNT_inc(gv)) +#endif + +#ifndef CopFILE_set +# define CopFILE_set(c,pv) CopFILEGV_set((c), gv_fetchfile(pv)) +#endif + +#ifndef CopFILESV +# define CopFILESV(c) (CopFILEGV(c) ? GvSV(CopFILEGV(c)) : Nullsv) +#endif + +#ifndef CopFILEAV +# define CopFILEAV(c) (CopFILEGV(c) ? GvAV(CopFILEGV(c)) : Nullav) +#endif + +#ifndef CopFILE +# define CopFILE(c) (CopFILESV(c) ? SvPVX(CopFILESV(c)) : Nullch) +#endif + +#ifndef CopSTASH +# define CopSTASH(c) ((c)->cop_stash) +#endif + +#ifndef CopSTASH_set +# define CopSTASH_set(c,hv) ((c)->cop_stash = (hv)) +#endif + +#ifndef CopSTASHPV +# define CopSTASHPV(c) (CopSTASH(c) ? HvNAME(CopSTASH(c)) : Nullch) +#endif + +#ifndef CopSTASHPV_set +# define CopSTASHPV_set(c,pv) CopSTASH_set((c), gv_stashpv(pv,GV_ADD)) +#endif + +#ifndef CopSTASH_eq +# define CopSTASH_eq(c,hv) (CopSTASH(c) == (hv)) +#endif + +#endif /* USE_ITHREADS */ +#ifndef IN_PERL_COMPILETIME +# define IN_PERL_COMPILETIME (PL_curcop == &PL_compiling) +#endif + +#ifndef IN_LOCALE_RUNTIME +# define IN_LOCALE_RUNTIME (PL_curcop->op_private & HINT_LOCALE) +#endif + +#ifndef IN_LOCALE_COMPILETIME +# define IN_LOCALE_COMPILETIME (PL_hints & HINT_LOCALE) +#endif + +#ifndef IN_LOCALE +# define IN_LOCALE (IN_PERL_COMPILETIME ? IN_LOCALE_COMPILETIME : IN_LOCALE_RUNTIME) +#endif +#ifndef IS_NUMBER_IN_UV +# define IS_NUMBER_IN_UV 0x01 +#endif + +#ifndef IS_NUMBER_GREATER_THAN_UV_MAX +# define IS_NUMBER_GREATER_THAN_UV_MAX 0x02 +#endif + +#ifndef IS_NUMBER_NOT_INT +# define IS_NUMBER_NOT_INT 0x04 +#endif + +#ifndef IS_NUMBER_NEG +# define IS_NUMBER_NEG 0x08 +#endif + +#ifndef IS_NUMBER_INFINITY +# define IS_NUMBER_INFINITY 0x10 +#endif + +#ifndef IS_NUMBER_NAN +# define IS_NUMBER_NAN 0x20 +#endif +#ifndef GROK_NUMERIC_RADIX +# define GROK_NUMERIC_RADIX(sp, send) grok_numeric_radix(sp, send) +#endif +#ifndef PERL_SCAN_GREATER_THAN_UV_MAX +# define PERL_SCAN_GREATER_THAN_UV_MAX 0x02 +#endif + +#ifndef PERL_SCAN_SILENT_ILLDIGIT +# define PERL_SCAN_SILENT_ILLDIGIT 0x04 +#endif + +#ifndef PERL_SCAN_ALLOW_UNDERSCORES +# define PERL_SCAN_ALLOW_UNDERSCORES 0x01 +#endif + +#ifndef PERL_SCAN_DISALLOW_PREFIX +# define PERL_SCAN_DISALLOW_PREFIX 0x02 +#endif + +#ifndef grok_numeric_radix +#if defined(NEED_grok_numeric_radix) +static bool DPPP_(my_grok_numeric_radix)(pTHX_ const char ** sp, const char * send); +static +#else +extern bool DPPP_(my_grok_numeric_radix)(pTHX_ const char ** sp, const char * send); +#endif + +#ifdef grok_numeric_radix +# undef grok_numeric_radix +#endif +#define grok_numeric_radix(a,b) DPPP_(my_grok_numeric_radix)(aTHX_ a,b) +#define Perl_grok_numeric_radix DPPP_(my_grok_numeric_radix) + +#if defined(NEED_grok_numeric_radix) || defined(NEED_grok_numeric_radix_GLOBAL) +bool +DPPP_(my_grok_numeric_radix)(pTHX_ const char **sp, const char *send) +{ +#ifdef USE_LOCALE_NUMERIC +#ifdef PL_numeric_radix_sv + if (PL_numeric_radix_sv && IN_LOCALE) { + STRLEN len; + char* radix = SvPV(PL_numeric_radix_sv, len); + if (*sp + len <= send && memEQ(*sp, radix, len)) { + *sp += len; + return TRUE; + } + } +#else + /* older perls don't have PL_numeric_radix_sv so the radix + * must manually be requested from locale.h + */ +#include + dTHR; /* needed for older threaded perls */ + struct lconv *lc = localeconv(); + char *radix = lc->decimal_point; + if (radix && IN_LOCALE) { + STRLEN len = strlen(radix); + if (*sp + len <= send && memEQ(*sp, radix, len)) { + *sp += len; + return TRUE; + } + } +#endif +#endif /* USE_LOCALE_NUMERIC */ + /* always try "." if numeric radix didn't match because + * we may have data from different locales mixed */ + if (*sp < send && **sp == '.') { + ++*sp; + return TRUE; + } + return FALSE; +} +#endif +#endif + +#ifndef grok_number +#if defined(NEED_grok_number) +static int DPPP_(my_grok_number)(pTHX_ const char * pv, STRLEN len, UV * valuep); +static +#else +extern int DPPP_(my_grok_number)(pTHX_ const char * pv, STRLEN len, UV * valuep); +#endif + +#ifdef grok_number +# undef grok_number +#endif +#define grok_number(a,b,c) DPPP_(my_grok_number)(aTHX_ a,b,c) +#define Perl_grok_number DPPP_(my_grok_number) + +#if defined(NEED_grok_number) || defined(NEED_grok_number_GLOBAL) +int +DPPP_(my_grok_number)(pTHX_ const char *pv, STRLEN len, UV *valuep) +{ + const char *s = pv; + const char *send = pv + len; + const UV max_div_10 = UV_MAX / 10; + const char max_mod_10 = UV_MAX % 10; + int numtype = 0; + int sawinf = 0; + int sawnan = 0; + + while (s < send && isSPACE(*s)) + s++; + if (s == send) { + return 0; + } else if (*s == '-') { + s++; + numtype = IS_NUMBER_NEG; + } + else if (*s == '+') + s++; + + if (s == send) + return 0; + + /* next must be digit or the radix separator or beginning of infinity */ + if (isDIGIT(*s)) { + /* UVs are at least 32 bits, so the first 9 decimal digits cannot + overflow. */ + UV value = *s - '0'; + /* This construction seems to be more optimiser friendly. + (without it gcc does the isDIGIT test and the *s - '0' separately) + With it gcc on arm is managing 6 instructions (6 cycles) per digit. + In theory the optimiser could deduce how far to unroll the loop + before checking for overflow. */ + if (++s < send) { + int digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + /* Now got 9 digits, so need to check + each time for overflow. */ + digit = *s - '0'; + while (digit >= 0 && digit <= 9 + && (value < max_div_10 + || (value == max_div_10 + && digit <= max_mod_10))) { + value = value * 10 + digit; + if (++s < send) + digit = *s - '0'; + else + break; + } + if (digit >= 0 && digit <= 9 + && (s < send)) { + /* value overflowed. + skip the remaining digits, don't + worry about setting *valuep. */ + do { + s++; + } while (s < send && isDIGIT(*s)); + numtype |= + IS_NUMBER_GREATER_THAN_UV_MAX; + goto skip_value; + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + numtype |= IS_NUMBER_IN_UV; + if (valuep) + *valuep = value; + + skip_value: + if (GROK_NUMERIC_RADIX(&s, send)) { + numtype |= IS_NUMBER_NOT_INT; + while (s < send && isDIGIT(*s)) /* optional digits after the radix */ + s++; + } + } + else if (GROK_NUMERIC_RADIX(&s, send)) { + numtype |= IS_NUMBER_NOT_INT | IS_NUMBER_IN_UV; /* valuep assigned below */ + /* no digits before the radix means we need digits after it */ + if (s < send && isDIGIT(*s)) { + do { + s++; + } while (s < send && isDIGIT(*s)); + if (valuep) { + /* integer approximation is valid - it's 0. */ + *valuep = 0; + } + } + else + return 0; + } else if (*s == 'I' || *s == 'i') { + s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; + s++; if (s == send || (*s != 'F' && *s != 'f')) return 0; + s++; if (s < send && (*s == 'I' || *s == 'i')) { + s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; + s++; if (s == send || (*s != 'I' && *s != 'i')) return 0; + s++; if (s == send || (*s != 'T' && *s != 't')) return 0; + s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0; + s++; + } + sawinf = 1; + } else if (*s == 'N' || *s == 'n') { + /* XXX TODO: There are signaling NaNs and quiet NaNs. */ + s++; if (s == send || (*s != 'A' && *s != 'a')) return 0; + s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; + s++; + sawnan = 1; + } else + return 0; + + if (sawinf) { + numtype &= IS_NUMBER_NEG; /* Keep track of sign */ + numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT; + } else if (sawnan) { + numtype &= IS_NUMBER_NEG; /* Keep track of sign */ + numtype |= IS_NUMBER_NAN | IS_NUMBER_NOT_INT; + } else if (s < send) { + /* we can have an optional exponent part */ + if (*s == 'e' || *s == 'E') { + /* The only flag we keep is sign. Blow away any "it's UV" */ + numtype &= IS_NUMBER_NEG; + numtype |= IS_NUMBER_NOT_INT; + s++; + if (s < send && (*s == '-' || *s == '+')) + s++; + if (s < send && isDIGIT(*s)) { + do { + s++; + } while (s < send && isDIGIT(*s)); + } + else + return 0; + } + } + while (s < send && isSPACE(*s)) + s++; + if (s >= send) + return numtype; + if (len == 10 && memEQ(pv, "0 but true", 10)) { + if (valuep) + *valuep = 0; + return IS_NUMBER_IN_UV; + } + return 0; +} +#endif +#endif + +/* + * The grok_* routines have been modified to use warn() instead of + * Perl_warner(). Also, 'hexdigit' was the former name of PL_hexdigit, + * which is why the stack variable has been renamed to 'xdigit'. + */ + +#ifndef grok_bin +#if defined(NEED_grok_bin) +static UV DPPP_(my_grok_bin)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); +static +#else +extern UV DPPP_(my_grok_bin)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); +#endif + +#ifdef grok_bin +# undef grok_bin +#endif +#define grok_bin(a,b,c,d) DPPP_(my_grok_bin)(aTHX_ a,b,c,d) +#define Perl_grok_bin DPPP_(my_grok_bin) + +#if defined(NEED_grok_bin) || defined(NEED_grok_bin_GLOBAL) +UV +DPPP_(my_grok_bin)(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result) +{ + const char *s = start; + STRLEN len = *len_p; + UV value = 0; + NV value_nv = 0; + + const UV max_div_2 = UV_MAX / 2; + bool allow_underscores = *flags & PERL_SCAN_ALLOW_UNDERSCORES; + bool overflowed = FALSE; + + if (!(*flags & PERL_SCAN_DISALLOW_PREFIX)) { + /* strip off leading b or 0b. + for compatibility silently suffer "b" and "0b" as valid binary + numbers. */ + if (len >= 1) { + if (s[0] == 'b') { + s++; + len--; + } + else if (len >= 2 && s[0] == '0' && s[1] == 'b') { + s+=2; + len-=2; + } + } + } + + for (; len-- && *s; s++) { + char bit = *s; + if (bit == '0' || bit == '1') { + /* Write it in this wonky order with a goto to attempt to get the + compiler to make the common case integer-only loop pretty tight. + With gcc seems to be much straighter code than old scan_bin. */ + redo: + if (!overflowed) { + if (value <= max_div_2) { + value = (value << 1) | (bit - '0'); + continue; + } + /* Bah. We're just overflowed. */ + warn("Integer overflow in binary number"); + overflowed = TRUE; + value_nv = (NV) value; + } + value_nv *= 2.0; + /* If an NV has not enough bits in its mantissa to + * represent a UV this summing of small low-order numbers + * is a waste of time (because the NV cannot preserve + * the low-order bits anyway): we could just remember when + * did we overflow and in the end just multiply value_nv by the + * right amount. */ + value_nv += (NV)(bit - '0'); + continue; + } + if (bit == '_' && len && allow_underscores && (bit = s[1]) + && (bit == '0' || bit == '1')) + { + --len; + ++s; + goto redo; + } + if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT)) + warn("Illegal binary digit '%c' ignored", *s); + break; + } + + if ( ( overflowed && value_nv > 4294967295.0) +#if UVSIZE > 4 + || (!overflowed && value > 0xffffffff ) +#endif + ) { + warn("Binary number > 0b11111111111111111111111111111111 non-portable"); + } + *len_p = s - start; + if (!overflowed) { + *flags = 0; + return value; + } + *flags = PERL_SCAN_GREATER_THAN_UV_MAX; + if (result) + *result = value_nv; + return UV_MAX; +} +#endif +#endif + +#ifndef grok_hex +#if defined(NEED_grok_hex) +static UV DPPP_(my_grok_hex)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); +static +#else +extern UV DPPP_(my_grok_hex)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); +#endif + +#ifdef grok_hex +# undef grok_hex +#endif +#define grok_hex(a,b,c,d) DPPP_(my_grok_hex)(aTHX_ a,b,c,d) +#define Perl_grok_hex DPPP_(my_grok_hex) + +#if defined(NEED_grok_hex) || defined(NEED_grok_hex_GLOBAL) +UV +DPPP_(my_grok_hex)(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result) +{ + const char *s = start; + STRLEN len = *len_p; + UV value = 0; + NV value_nv = 0; + + const UV max_div_16 = UV_MAX / 16; + bool allow_underscores = *flags & PERL_SCAN_ALLOW_UNDERSCORES; + bool overflowed = FALSE; + const char *xdigit; + + if (!(*flags & PERL_SCAN_DISALLOW_PREFIX)) { + /* strip off leading x or 0x. + for compatibility silently suffer "x" and "0x" as valid hex numbers. + */ + if (len >= 1) { + if (s[0] == 'x') { + s++; + len--; + } + else if (len >= 2 && s[0] == '0' && s[1] == 'x') { + s+=2; + len-=2; + } + } + } + + for (; len-- && *s; s++) { + xdigit = strchr((char *) PL_hexdigit, *s); + if (xdigit) { + /* Write it in this wonky order with a goto to attempt to get the + compiler to make the common case integer-only loop pretty tight. + With gcc seems to be much straighter code than old scan_hex. */ + redo: + if (!overflowed) { + if (value <= max_div_16) { + value = (value << 4) | ((xdigit - PL_hexdigit) & 15); + continue; + } + warn("Integer overflow in hexadecimal number"); + overflowed = TRUE; + value_nv = (NV) value; + } + value_nv *= 16.0; + /* If an NV has not enough bits in its mantissa to + * represent a UV this summing of small low-order numbers + * is a waste of time (because the NV cannot preserve + * the low-order bits anyway): we could just remember when + * did we overflow and in the end just multiply value_nv by the + * right amount of 16-tuples. */ + value_nv += (NV)((xdigit - PL_hexdigit) & 15); + continue; + } + if (*s == '_' && len && allow_underscores && s[1] + && (xdigit = strchr((char *) PL_hexdigit, s[1]))) + { + --len; + ++s; + goto redo; + } + if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT)) + warn("Illegal hexadecimal digit '%c' ignored", *s); + break; + } + + if ( ( overflowed && value_nv > 4294967295.0) +#if UVSIZE > 4 + || (!overflowed && value > 0xffffffff ) +#endif + ) { + warn("Hexadecimal number > 0xffffffff non-portable"); + } + *len_p = s - start; + if (!overflowed) { + *flags = 0; + return value; + } + *flags = PERL_SCAN_GREATER_THAN_UV_MAX; + if (result) + *result = value_nv; + return UV_MAX; +} +#endif +#endif + +#ifndef grok_oct +#if defined(NEED_grok_oct) +static UV DPPP_(my_grok_oct)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); +static +#else +extern UV DPPP_(my_grok_oct)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); +#endif + +#ifdef grok_oct +# undef grok_oct +#endif +#define grok_oct(a,b,c,d) DPPP_(my_grok_oct)(aTHX_ a,b,c,d) +#define Perl_grok_oct DPPP_(my_grok_oct) + +#if defined(NEED_grok_oct) || defined(NEED_grok_oct_GLOBAL) +UV +DPPP_(my_grok_oct)(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result) +{ + const char *s = start; + STRLEN len = *len_p; + UV value = 0; + NV value_nv = 0; + + const UV max_div_8 = UV_MAX / 8; + bool allow_underscores = *flags & PERL_SCAN_ALLOW_UNDERSCORES; + bool overflowed = FALSE; + + for (; len-- && *s; s++) { + /* gcc 2.95 optimiser not smart enough to figure that this subtraction + out front allows slicker code. */ + int digit = *s - '0'; + if (digit >= 0 && digit <= 7) { + /* Write it in this wonky order with a goto to attempt to get the + compiler to make the common case integer-only loop pretty tight. + */ + redo: + if (!overflowed) { + if (value <= max_div_8) { + value = (value << 3) | digit; + continue; + } + /* Bah. We're just overflowed. */ + warn("Integer overflow in octal number"); + overflowed = TRUE; + value_nv = (NV) value; + } + value_nv *= 8.0; + /* If an NV has not enough bits in its mantissa to + * represent a UV this summing of small low-order numbers + * is a waste of time (because the NV cannot preserve + * the low-order bits anyway): we could just remember when + * did we overflow and in the end just multiply value_nv by the + * right amount of 8-tuples. */ + value_nv += (NV)digit; + continue; + } + if (digit == ('_' - '0') && len && allow_underscores + && (digit = s[1] - '0') && (digit >= 0 && digit <= 7)) + { + --len; + ++s; + goto redo; + } + /* Allow \octal to work the DWIM way (that is, stop scanning + * as soon as non-octal characters are seen, complain only iff + * someone seems to want to use the digits eight and nine). */ + if (digit == 8 || digit == 9) { + if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT)) + warn("Illegal octal digit '%c' ignored", *s); + } + break; + } + + if ( ( overflowed && value_nv > 4294967295.0) +#if UVSIZE > 4 + || (!overflowed && value > 0xffffffff ) +#endif + ) { + warn("Octal number > 037777777777 non-portable"); + } + *len_p = s - start; + if (!overflowed) { + *flags = 0; + return value; + } + *flags = PERL_SCAN_GREATER_THAN_UV_MAX; + if (result) + *result = value_nv; + return UV_MAX; +} +#endif +#endif + +#if !defined(my_snprintf) +#if defined(NEED_my_snprintf) +static int DPPP_(my_my_snprintf)(char * buffer, const Size_t len, const char * format, ...); +static +#else +extern int DPPP_(my_my_snprintf)(char * buffer, const Size_t len, const char * format, ...); +#endif + +#define my_snprintf DPPP_(my_my_snprintf) +#define Perl_my_snprintf DPPP_(my_my_snprintf) + +#if defined(NEED_my_snprintf) || defined(NEED_my_snprintf_GLOBAL) + +int +DPPP_(my_my_snprintf)(char *buffer, const Size_t len, const char *format, ...) +{ + dTHX; + int retval; + va_list ap; + va_start(ap, format); +#ifdef HAS_VSNPRINTF + retval = vsnprintf(buffer, len, format, ap); +#else + retval = vsprintf(buffer, format, ap); +#endif + va_end(ap); + if (retval < 0 || (len > 0 && (Size_t)retval >= len)) + Perl_croak(aTHX_ "panic: my_snprintf buffer overflow"); + return retval; +} + +#endif +#endif + +#if !defined(my_sprintf) +#if defined(NEED_my_sprintf) +static int DPPP_(my_my_sprintf)(char * buffer, const char * pat, ...); +static +#else +extern int DPPP_(my_my_sprintf)(char * buffer, const char * pat, ...); +#endif + +#define my_sprintf DPPP_(my_my_sprintf) +#define Perl_my_sprintf DPPP_(my_my_sprintf) + +#if defined(NEED_my_sprintf) || defined(NEED_my_sprintf_GLOBAL) + +int +DPPP_(my_my_sprintf)(char *buffer, const char* pat, ...) +{ + va_list args; + va_start(args, pat); + vsprintf(buffer, pat, args); + va_end(args); + return strlen(buffer); +} + +#endif +#endif + +#ifdef NO_XSLOCKS +# ifdef dJMPENV +# define dXCPT dJMPENV; int rEtV = 0 +# define XCPT_TRY_START JMPENV_PUSH(rEtV); if (rEtV == 0) +# define XCPT_TRY_END JMPENV_POP; +# define XCPT_CATCH if (rEtV != 0) +# define XCPT_RETHROW JMPENV_JUMP(rEtV) +# else +# define dXCPT Sigjmp_buf oldTOP; int rEtV = 0 +# define XCPT_TRY_START Copy(top_env, oldTOP, 1, Sigjmp_buf); rEtV = Sigsetjmp(top_env, 1); if (rEtV == 0) +# define XCPT_TRY_END Copy(oldTOP, top_env, 1, Sigjmp_buf); +# define XCPT_CATCH if (rEtV != 0) +# define XCPT_RETHROW Siglongjmp(top_env, rEtV) +# endif +#endif + +#if !defined(my_strlcat) +#if defined(NEED_my_strlcat) +static Size_t DPPP_(my_my_strlcat)(char * dst, const char * src, Size_t size); +static +#else +extern Size_t DPPP_(my_my_strlcat)(char * dst, const char * src, Size_t size); +#endif + +#define my_strlcat DPPP_(my_my_strlcat) +#define Perl_my_strlcat DPPP_(my_my_strlcat) + +#if defined(NEED_my_strlcat) || defined(NEED_my_strlcat_GLOBAL) + +Size_t +DPPP_(my_my_strlcat)(char *dst, const char *src, Size_t size) +{ + Size_t used, length, copy; + + used = strlen(dst); + length = strlen(src); + if (size > 0 && used < size - 1) { + copy = (length >= size - used) ? size - used - 1 : length; + memcpy(dst + used, src, copy); + dst[used + copy] = '\0'; + } + return used + length; +} +#endif +#endif + +#if !defined(my_strlcpy) +#if defined(NEED_my_strlcpy) +static Size_t DPPP_(my_my_strlcpy)(char * dst, const char * src, Size_t size); +static +#else +extern Size_t DPPP_(my_my_strlcpy)(char * dst, const char * src, Size_t size); +#endif + +#define my_strlcpy DPPP_(my_my_strlcpy) +#define Perl_my_strlcpy DPPP_(my_my_strlcpy) + +#if defined(NEED_my_strlcpy) || defined(NEED_my_strlcpy_GLOBAL) + +Size_t +DPPP_(my_my_strlcpy)(char *dst, const char *src, Size_t size) +{ + Size_t length, copy; + + length = strlen(src); + if (size > 0) { + copy = (length >= size) ? size - 1 : length; + memcpy(dst, src, copy); + dst[copy] = '\0'; + } + return length; +} + +#endif +#endif +#ifndef PERL_PV_ESCAPE_QUOTE +# define PERL_PV_ESCAPE_QUOTE 0x0001 +#endif + +#ifndef PERL_PV_PRETTY_QUOTE +# define PERL_PV_PRETTY_QUOTE PERL_PV_ESCAPE_QUOTE +#endif + +#ifndef PERL_PV_PRETTY_ELLIPSES +# define PERL_PV_PRETTY_ELLIPSES 0x0002 +#endif + +#ifndef PERL_PV_PRETTY_LTGT +# define PERL_PV_PRETTY_LTGT 0x0004 +#endif + +#ifndef PERL_PV_ESCAPE_FIRSTCHAR +# define PERL_PV_ESCAPE_FIRSTCHAR 0x0008 +#endif + +#ifndef PERL_PV_ESCAPE_UNI +# define PERL_PV_ESCAPE_UNI 0x0100 +#endif + +#ifndef PERL_PV_ESCAPE_UNI_DETECT +# define PERL_PV_ESCAPE_UNI_DETECT 0x0200 +#endif + +#ifndef PERL_PV_ESCAPE_ALL +# define PERL_PV_ESCAPE_ALL 0x1000 +#endif + +#ifndef PERL_PV_ESCAPE_NOBACKSLASH +# define PERL_PV_ESCAPE_NOBACKSLASH 0x2000 +#endif + +#ifndef PERL_PV_ESCAPE_NOCLEAR +# define PERL_PV_ESCAPE_NOCLEAR 0x4000 +#endif + +#ifndef PERL_PV_ESCAPE_RE +# define PERL_PV_ESCAPE_RE 0x8000 +#endif + +#ifndef PERL_PV_PRETTY_NOCLEAR +# define PERL_PV_PRETTY_NOCLEAR PERL_PV_ESCAPE_NOCLEAR +#endif +#ifndef PERL_PV_PRETTY_DUMP +# define PERL_PV_PRETTY_DUMP PERL_PV_PRETTY_ELLIPSES|PERL_PV_PRETTY_QUOTE +#endif + +#ifndef PERL_PV_PRETTY_REGPROP +# define PERL_PV_PRETTY_REGPROP PERL_PV_PRETTY_ELLIPSES|PERL_PV_PRETTY_LTGT|PERL_PV_ESCAPE_RE +#endif + +/* Hint: pv_escape + * Note that unicode functionality is only backported to + * those perl versions that support it. For older perl + * versions, the implementation will fall back to bytes. + */ + +#ifndef pv_escape +#if defined(NEED_pv_escape) +static char * DPPP_(my_pv_escape)(pTHX_ SV * dsv, char const * const str, const STRLEN count, const STRLEN max, STRLEN * const escaped, const U32 flags); +static +#else +extern char * DPPP_(my_pv_escape)(pTHX_ SV * dsv, char const * const str, const STRLEN count, const STRLEN max, STRLEN * const escaped, const U32 flags); +#endif + +#ifdef pv_escape +# undef pv_escape +#endif +#define pv_escape(a,b,c,d,e,f) DPPP_(my_pv_escape)(aTHX_ a,b,c,d,e,f) +#define Perl_pv_escape DPPP_(my_pv_escape) + +#if defined(NEED_pv_escape) || defined(NEED_pv_escape_GLOBAL) + +char * +DPPP_(my_pv_escape)(pTHX_ SV *dsv, char const * const str, + const STRLEN count, const STRLEN max, + STRLEN * const escaped, const U32 flags) +{ + const char esc = flags & PERL_PV_ESCAPE_RE ? '%' : '\\'; + const char dq = flags & PERL_PV_ESCAPE_QUOTE ? '"' : esc; + char octbuf[32] = "%123456789ABCDF"; + STRLEN wrote = 0; + STRLEN chsize = 0; + STRLEN readsize = 1; +#if defined(is_utf8_string) && defined(utf8_to_uvchr) + bool isuni = flags & PERL_PV_ESCAPE_UNI ? 1 : 0; +#endif + const char *pv = str; + const char * const end = pv + count; + octbuf[0] = esc; + + if (!(flags & PERL_PV_ESCAPE_NOCLEAR)) + sv_setpvs(dsv, ""); + +#if defined(is_utf8_string) && defined(utf8_to_uvchr) + if ((flags & PERL_PV_ESCAPE_UNI_DETECT) && is_utf8_string((U8*)pv, count)) + isuni = 1; +#endif + + for (; pv < end && (!max || wrote < max) ; pv += readsize) { + const UV u = +#if defined(is_utf8_string) && defined(utf8_to_uvchr) + isuni ? utf8_to_uvchr((U8*)pv, &readsize) : +#endif + (U8)*pv; + const U8 c = (U8)u & 0xFF; + + if (u > 255 || (flags & PERL_PV_ESCAPE_ALL)) { + if (flags & PERL_PV_ESCAPE_FIRSTCHAR) + chsize = my_snprintf(octbuf, sizeof octbuf, + "%"UVxf, u); + else + chsize = my_snprintf(octbuf, sizeof octbuf, + "%cx{%"UVxf"}", esc, u); + } else if (flags & PERL_PV_ESCAPE_NOBACKSLASH) { + chsize = 1; + } else { + if (c == dq || c == esc || !isPRINT(c)) { + chsize = 2; + switch (c) { + case '\\' : /* fallthrough */ + case '%' : if (c == esc) + octbuf[1] = esc; + else + chsize = 1; + break; + case '\v' : octbuf[1] = 'v'; break; + case '\t' : octbuf[1] = 't'; break; + case '\r' : octbuf[1] = 'r'; break; + case '\n' : octbuf[1] = 'n'; break; + case '\f' : octbuf[1] = 'f'; break; + case '"' : if (dq == '"') + octbuf[1] = '"'; + else + chsize = 1; + break; + default: chsize = my_snprintf(octbuf, sizeof octbuf, + pv < end && isDIGIT((U8)*(pv+readsize)) + ? "%c%03o" : "%c%o", esc, c); + } + } else { + chsize = 1; + } + } + if (max && wrote + chsize > max) { + break; + } else if (chsize > 1) { + sv_catpvn(dsv, octbuf, chsize); + wrote += chsize; + } else { + char tmp[2]; + my_snprintf(tmp, sizeof tmp, "%c", c); + sv_catpvn(dsv, tmp, 1); + wrote++; + } + if (flags & PERL_PV_ESCAPE_FIRSTCHAR) + break; + } + if (escaped != NULL) + *escaped= pv - str; + return SvPVX(dsv); +} + +#endif +#endif + +#ifndef pv_pretty +#if defined(NEED_pv_pretty) +static char * DPPP_(my_pv_pretty)(pTHX_ SV * dsv, char const * const str, const STRLEN count, const STRLEN max, char const * const start_color, char const * const end_color, const U32 flags); +static +#else +extern char * DPPP_(my_pv_pretty)(pTHX_ SV * dsv, char const * const str, const STRLEN count, const STRLEN max, char const * const start_color, char const * const end_color, const U32 flags); +#endif + +#ifdef pv_pretty +# undef pv_pretty +#endif +#define pv_pretty(a,b,c,d,e,f,g) DPPP_(my_pv_pretty)(aTHX_ a,b,c,d,e,f,g) +#define Perl_pv_pretty DPPP_(my_pv_pretty) + +#if defined(NEED_pv_pretty) || defined(NEED_pv_pretty_GLOBAL) + +char * +DPPP_(my_pv_pretty)(pTHX_ SV *dsv, char const * const str, const STRLEN count, + const STRLEN max, char const * const start_color, char const * const end_color, + const U32 flags) +{ + const U8 dq = (flags & PERL_PV_PRETTY_QUOTE) ? '"' : '%'; + STRLEN escaped; + + if (!(flags & PERL_PV_PRETTY_NOCLEAR)) + sv_setpvs(dsv, ""); + + if (dq == '"') + sv_catpvs(dsv, "\""); + else if (flags & PERL_PV_PRETTY_LTGT) + sv_catpvs(dsv, "<"); + + if (start_color != NULL) + sv_catpv(dsv, D_PPP_CONSTPV_ARG(start_color)); + + pv_escape(dsv, str, count, max, &escaped, flags | PERL_PV_ESCAPE_NOCLEAR); + + if (end_color != NULL) + sv_catpv(dsv, D_PPP_CONSTPV_ARG(end_color)); + + if (dq == '"') + sv_catpvs(dsv, "\""); + else if (flags & PERL_PV_PRETTY_LTGT) + sv_catpvs(dsv, ">"); + + if ((flags & PERL_PV_PRETTY_ELLIPSES) && escaped < count) + sv_catpvs(dsv, "..."); + + return SvPVX(dsv); +} + +#endif +#endif + +#ifndef pv_display +#if defined(NEED_pv_display) +static char * DPPP_(my_pv_display)(pTHX_ SV * dsv, const char * pv, STRLEN cur, STRLEN len, STRLEN pvlim); +static +#else +extern char * DPPP_(my_pv_display)(pTHX_ SV * dsv, const char * pv, STRLEN cur, STRLEN len, STRLEN pvlim); +#endif + +#ifdef pv_display +# undef pv_display +#endif +#define pv_display(a,b,c,d,e) DPPP_(my_pv_display)(aTHX_ a,b,c,d,e) +#define Perl_pv_display DPPP_(my_pv_display) + +#if defined(NEED_pv_display) || defined(NEED_pv_display_GLOBAL) + +char * +DPPP_(my_pv_display)(pTHX_ SV *dsv, const char *pv, STRLEN cur, STRLEN len, STRLEN pvlim) +{ + pv_pretty(dsv, pv, cur, pvlim, NULL, NULL, PERL_PV_PRETTY_DUMP); + if (len > cur && pv[cur] == '\0') + sv_catpvs(dsv, "\\0"); + return SvPVX(dsv); +} + +#endif +#endif + +#endif /* _P_P_PORTABILITY_H_ */ + +/* End of File ppport.h */ diff --git a/Xdgmime/t/Xdgmime.t b/Xdgmime/t/Xdgmime.t new file mode 100644 index 0000000..7af5bac --- /dev/null +++ b/Xdgmime/t/Xdgmime.t @@ -0,0 +1,14 @@ +# Before `make install' is performed this script should be runnable with +# `make test'. After `make install' it should work as `perl Xdgmime.t' + +######################### + +# change 'tests => 2' to 'tests => last_test_to_print'; + +use Test::More tests => 1; + +BEGIN { use_ok('Xdgmime') }; + +# Insert your test code below, the Test::More module is use()ed here so read +# its man page ( perldoc Test::More ) for help writing this test script. + diff --git a/Xdgmime/xdgmime.c b/Xdgmime/xdgmime.c new file mode 100644 index 0000000..c7b16bb --- /dev/null +++ b/Xdgmime/xdgmime.c @@ -0,0 +1,934 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmime.c: XDG Mime Spec mime resolver. Based on version 0.11 of the spec. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2003,2004 Red Hat, Inc. + * Copyright (C) 2003,2004 Jonathan Blandford + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "xdgmime.h" +#include "xdgmimeint.h" +#include "xdgmimeglob.h" +#include "xdgmimemagic.h" +#include "xdgmimealias.h" +#include "xdgmimeicon.h" +#include "xdgmimeparent.h" +#include "xdgmimecache.h" +#include +#include +#include +#include +#include +#include +#include + +typedef struct XdgDirTimeList XdgDirTimeList; +typedef struct XdgCallbackList XdgCallbackList; + +static int need_reread = TRUE; +static time_t last_stat_time = 0; + +static XdgGlobHash *global_hash = NULL; +static XdgMimeMagic *global_magic = NULL; +static XdgAliasList *alias_list = NULL; +static XdgParentList *parent_list = NULL; +static XdgDirTimeList *dir_time_list = NULL; +static XdgCallbackList *callback_list = NULL; +static XdgIconList *icon_list = NULL; +static XdgIconList *generic_icon_list = NULL; + +XdgMimeCache **_caches = NULL; +static int n_caches = 0; + +const char xdg_mime_type_unknown[] = "application/octet-stream"; +const char xdg_mime_type_empty[] = "application/x-zerosize"; +const char xdg_mime_type_textplain[] = "text/plain"; + + +enum +{ + XDG_CHECKED_UNCHECKED, + XDG_CHECKED_VALID, + XDG_CHECKED_INVALID +}; + +struct XdgDirTimeList +{ + time_t mtime; + char *directory_name; + int checked; + XdgDirTimeList *next; +}; + +struct XdgCallbackList +{ + XdgCallbackList *next; + XdgCallbackList *prev; + int callback_id; + XdgMimeCallback callback; + void *data; + XdgMimeDestroy destroy; +}; + +/* Function called by xdg_run_command_on_dirs. If it returns TRUE, further + * directories aren't looked at */ +typedef int (*XdgDirectoryFunc) (const char *directory, + void *user_data); + +static void +xdg_dir_time_list_add (char *file_name, + time_t mtime) +{ + XdgDirTimeList *list; + + for (list = dir_time_list; list; list = list->next) + { + if (strcmp (list->directory_name, file_name) == 0) + { + free (file_name); + return; + } + } + + list = calloc (1, sizeof (XdgDirTimeList)); + list->checked = XDG_CHECKED_UNCHECKED; + list->directory_name = file_name; + list->mtime = mtime; + list->next = dir_time_list; + dir_time_list = list; +} + +static void +xdg_dir_time_list_free (XdgDirTimeList *list) +{ + XdgDirTimeList *next; + + while (list) + { + next = list->next; + free (list->directory_name); + free (list); + list = next; + } +} + +static int +xdg_mime_init_from_directory (const char *directory) +{ + char *file_name; + struct stat st; + + assert (directory != NULL); + + file_name = malloc (strlen (directory) + strlen ("/mime/mime.cache") + 1); + strcpy (file_name, directory); strcat (file_name, "/mime/mime.cache"); + if (stat (file_name, &st) == 0) + { + XdgMimeCache *cache = _xdg_mime_cache_new_from_file (file_name); + + if (cache != NULL) + { + xdg_dir_time_list_add (file_name, st.st_mtime); + + _caches = realloc (_caches, sizeof (XdgMimeCache *) * (n_caches + 2)); + _caches[n_caches] = cache; + _caches[n_caches + 1] = NULL; + n_caches++; + + return FALSE; + } + } + free (file_name); + + file_name = malloc (strlen (directory) + strlen ("/mime/globs2") + 1); + strcpy (file_name, directory); strcat (file_name, "/mime/globs2"); + if (stat (file_name, &st) == 0) + { + _xdg_mime_glob_read_from_file (global_hash, file_name, TRUE); + xdg_dir_time_list_add (file_name, st.st_mtime); + } + else + { + free (file_name); + file_name = malloc (strlen (directory) + strlen ("/mime/globs") + 1); + strcpy (file_name, directory); strcat (file_name, "/mime/globs"); + if (stat (file_name, &st) == 0) + { + _xdg_mime_glob_read_from_file (global_hash, file_name, FALSE); + xdg_dir_time_list_add (file_name, st.st_mtime); + } + else + { + free (file_name); + } + } + + file_name = malloc (strlen (directory) + strlen ("/mime/magic") + 1); + strcpy (file_name, directory); strcat (file_name, "/mime/magic"); + if (stat (file_name, &st) == 0) + { + _xdg_mime_magic_read_from_file (global_magic, file_name); + xdg_dir_time_list_add (file_name, st.st_mtime); + } + else + { + free (file_name); + } + + file_name = malloc (strlen (directory) + strlen ("/mime/aliases") + 1); + strcpy (file_name, directory); strcat (file_name, "/mime/aliases"); + _xdg_mime_alias_read_from_file (alias_list, file_name); + free (file_name); + + file_name = malloc (strlen (directory) + strlen ("/mime/subclasses") + 1); + strcpy (file_name, directory); strcat (file_name, "/mime/subclasses"); + _xdg_mime_parent_read_from_file (parent_list, file_name); + free (file_name); + + file_name = malloc (strlen (directory) + strlen ("/mime/icons") + 1); + strcpy (file_name, directory); strcat (file_name, "/mime/icons"); + _xdg_mime_icon_read_from_file (icon_list, file_name); + free (file_name); + + file_name = malloc (strlen (directory) + strlen ("/mime/generic-icons") + 1); + strcpy (file_name, directory); strcat (file_name, "/mime/generic-icons"); + _xdg_mime_icon_read_from_file (generic_icon_list, file_name); + free (file_name); + + return FALSE; /* Keep processing */ +} + +/* Runs a command on all the directories in the search path */ +static void +xdg_run_command_on_dirs (XdgDirectoryFunc func, + void *user_data) +{ + const char *xdg_data_home; + const char *xdg_data_dirs; + const char *ptr; + + xdg_data_home = getenv ("XDG_DATA_HOME"); + if (xdg_data_home) + { + if ((func) (xdg_data_home, user_data)) + return; + } + else + { + const char *home; + + home = getenv ("HOME"); + if (home != NULL) + { + char *guessed_xdg_home; + int stop_processing; + + guessed_xdg_home = malloc (strlen (home) + strlen ("/.local/share/") + 1); + strcpy (guessed_xdg_home, home); + strcat (guessed_xdg_home, "/.local/share/"); + stop_processing = (func) (guessed_xdg_home, user_data); + free (guessed_xdg_home); + + if (stop_processing) + return; + } + } + + xdg_data_dirs = getenv ("XDG_DATA_DIRS"); + if (xdg_data_dirs == NULL) + xdg_data_dirs = "/usr/local/share/:/usr/share/"; + + ptr = xdg_data_dirs; + + while (*ptr != '\000') + { + const char *end_ptr; + char *dir; + int len; + int stop_processing; + + end_ptr = ptr; + while (*end_ptr != ':' && *end_ptr != '\000') + end_ptr ++; + + if (end_ptr == ptr) + { + ptr++; + continue; + } + + if (*end_ptr == ':') + len = end_ptr - ptr; + else + len = end_ptr - ptr + 1; + dir = malloc (len + 1); + strncpy (dir, ptr, len); + dir[len] = '\0'; + stop_processing = (func) (dir, user_data); + free (dir); + + if (stop_processing) + return; + + ptr = end_ptr; + } +} + +/* Checks file_path to make sure it has the same mtime as last time it was + * checked. If it has a different mtime, or if the file doesn't exist, it + * returns FALSE. + * + * FIXME: This doesn't protect against permission changes. + */ +static int +xdg_check_file (const char *file_path, + int *exists) +{ + struct stat st; + + /* If the file exists */ + if (stat (file_path, &st) == 0) + { + XdgDirTimeList *list; + + if (exists) + *exists = TRUE; + + for (list = dir_time_list; list; list = list->next) + { + if (! strcmp (list->directory_name, file_path)) + { + if (st.st_mtime == list->mtime) + list->checked = XDG_CHECKED_VALID; + else + list->checked = XDG_CHECKED_INVALID; + + return (list->checked != XDG_CHECKED_VALID); + } + } + return TRUE; + } + + if (exists) + *exists = FALSE; + + return FALSE; +} + +static int +xdg_check_dir (const char *directory, + int *invalid_dir_list) +{ + int invalid, exists; + char *file_name; + + assert (directory != NULL); + + /* Check the mime.cache file */ + file_name = malloc (strlen (directory) + strlen ("/mime/mime.cache") + 1); + strcpy (file_name, directory); strcat (file_name, "/mime/mime.cache"); + invalid = xdg_check_file (file_name, &exists); + free (file_name); + if (invalid) + { + *invalid_dir_list = TRUE; + return TRUE; + } + else if (exists) + { + return FALSE; + } + + /* Check the globs file */ + file_name = malloc (strlen (directory) + strlen ("/mime/globs") + 1); + strcpy (file_name, directory); strcat (file_name, "/mime/globs"); + invalid = xdg_check_file (file_name, NULL); + free (file_name); + if (invalid) + { + *invalid_dir_list = TRUE; + return TRUE; + } + + /* Check the magic file */ + file_name = malloc (strlen (directory) + strlen ("/mime/magic") + 1); + strcpy (file_name, directory); strcat (file_name, "/mime/magic"); + invalid = xdg_check_file (file_name, NULL); + free (file_name); + if (invalid) + { + *invalid_dir_list = TRUE; + return TRUE; + } + + return FALSE; /* Keep processing */ +} + +/* Walks through all the mime files stat()ing them to see if they've changed. + * Returns TRUE if they have. */ +static int +xdg_check_dirs (void) +{ + XdgDirTimeList *list; + int invalid_dir_list = FALSE; + + for (list = dir_time_list; list; list = list->next) + list->checked = XDG_CHECKED_UNCHECKED; + + xdg_run_command_on_dirs ((XdgDirectoryFunc) xdg_check_dir, + &invalid_dir_list); + + if (invalid_dir_list) + return TRUE; + + for (list = dir_time_list; list; list = list->next) + { + if (list->checked != XDG_CHECKED_VALID) + return TRUE; + } + + return FALSE; +} + +/* We want to avoid stat()ing on every single mime call, so we only look for + * newer files every 5 seconds. This will return TRUE if we need to reread the + * mime data from disk. + */ +static int +xdg_check_time_and_dirs (void) +{ + struct timeval tv; + time_t current_time; + int retval = FALSE; + + gettimeofday (&tv, NULL); + current_time = tv.tv_sec; + + if (current_time >= last_stat_time + 5) + { + retval = xdg_check_dirs (); + last_stat_time = current_time; + } + + return retval; +} + +/* Called in every public function. It reloads the hash function if need be. + */ +static void +xdg_mime_init (void) +{ + if (xdg_check_time_and_dirs ()) + { + xdg_mime_shutdown (); + } + + if (need_reread) + { + global_hash = _xdg_glob_hash_new (); + global_magic = _xdg_mime_magic_new (); + alias_list = _xdg_mime_alias_list_new (); + parent_list = _xdg_mime_parent_list_new (); + icon_list = _xdg_mime_icon_list_new (); + generic_icon_list = _xdg_mime_icon_list_new (); + + xdg_run_command_on_dirs ((XdgDirectoryFunc) xdg_mime_init_from_directory, + NULL); + + need_reread = FALSE; + } +} + +const char * +xdg_mime_get_mime_type_for_data (const void *data, + size_t len, + int *result_prio) +{ + const char *mime_type; + + if (len == 0) + { + *result_prio = 100; + return XDG_MIME_TYPE_EMPTY; + } + + xdg_mime_init (); + + if (_caches) + mime_type = _xdg_mime_cache_get_mime_type_for_data (data, len, result_prio); + else + mime_type = _xdg_mime_magic_lookup_data (global_magic, data, len, result_prio, NULL, 0); + + if (mime_type) + return mime_type; + + return _xdg_binary_or_text_fallback(data, len); +} + +const char * +xdg_mime_get_mime_type_for_file (const char *file_name, + struct stat *statbuf) +{ + const char *mime_type; + /* currently, only a few globs occur twice, and none + * more often, so 5 seems plenty. + */ + const char *mime_types[5]; + FILE *file; + unsigned char *data; + int max_extent; + int bytes_read; + struct stat buf; + const char *base_name; + int n; + + if (file_name == NULL) + return NULL; + if (! _xdg_utf8_validate (file_name)) + return NULL; + + xdg_mime_init (); + + if (_caches) + return _xdg_mime_cache_get_mime_type_for_file (file_name, statbuf); + + base_name = _xdg_get_base_name (file_name); + n = _xdg_glob_hash_lookup_file_name (global_hash, base_name, mime_types, 5); + + if (n == 1) + return mime_types[0]; + + if (!statbuf) + { + if (stat (file_name, &buf) != 0) + return XDG_MIME_TYPE_UNKNOWN; + + statbuf = &buf; + } + + if (!S_ISREG (statbuf->st_mode)) + return XDG_MIME_TYPE_UNKNOWN; + + /* FIXME: Need to make sure that max_extent isn't totally broken. This could + * be large and need getting from a stream instead of just reading it all + * in. */ + max_extent = _xdg_mime_magic_get_buffer_extents (global_magic); + data = malloc (max_extent); + if (data == NULL) + return XDG_MIME_TYPE_UNKNOWN; + + file = fopen (file_name, "r"); + if (file == NULL) + { + free (data); + return XDG_MIME_TYPE_UNKNOWN; + } + + bytes_read = fread (data, 1, max_extent, file); + if (ferror (file)) + { + free (data); + fclose (file); + return XDG_MIME_TYPE_UNKNOWN; + } + + mime_type = _xdg_mime_magic_lookup_data (global_magic, data, bytes_read, NULL, + mime_types, n); + + free (data); + fclose (file); + + if (mime_type) + return mime_type; + + return _xdg_binary_or_text_fallback(data, bytes_read); +} + +const char * +xdg_mime_get_mime_type_from_file_name (const char *file_name) +{ + const char *mime_type; + + xdg_mime_init (); + + if (_caches) + return _xdg_mime_cache_get_mime_type_from_file_name (file_name); + + if (_xdg_glob_hash_lookup_file_name (global_hash, file_name, &mime_type, 1)) + return mime_type; + else + return XDG_MIME_TYPE_UNKNOWN; +} + +int +xdg_mime_get_mime_types_from_file_name (const char *file_name, + const char *mime_types[], + int n_mime_types) +{ + xdg_mime_init (); + + if (_caches) + return _xdg_mime_cache_get_mime_types_from_file_name (file_name, mime_types, n_mime_types); + + return _xdg_glob_hash_lookup_file_name (global_hash, file_name, mime_types, n_mime_types); +} + +int +xdg_mime_is_valid_mime_type (const char *mime_type) +{ + /* FIXME: We should make this a better test + */ + return _xdg_utf8_validate (mime_type); +} + +void +xdg_mime_shutdown (void) +{ + XdgCallbackList *list; + + /* FIXME: Need to make this (and the whole library) thread safe */ + if (dir_time_list) + { + xdg_dir_time_list_free (dir_time_list); + dir_time_list = NULL; + } + + if (global_hash) + { + _xdg_glob_hash_free (global_hash); + global_hash = NULL; + } + if (global_magic) + { + _xdg_mime_magic_free (global_magic); + global_magic = NULL; + } + + if (alias_list) + { + _xdg_mime_alias_list_free (alias_list); + alias_list = NULL; + } + + if (parent_list) + { + _xdg_mime_parent_list_free (parent_list); + parent_list = NULL; + } + + if (icon_list) + { + _xdg_mime_icon_list_free (icon_list); + icon_list = NULL; + } + + if (generic_icon_list) + { + _xdg_mime_icon_list_free (generic_icon_list); + generic_icon_list = NULL; + } + + if (_caches) + { + int i; + + for (i = 0; i < n_caches; i++) + _xdg_mime_cache_unref (_caches[i]); + free (_caches); + _caches = NULL; + n_caches = 0; + } + + for (list = callback_list; list; list = list->next) + (list->callback) (list->data); + + need_reread = TRUE; +} + +int +xdg_mime_get_max_buffer_extents (void) +{ + xdg_mime_init (); + + if (_caches) + return _xdg_mime_cache_get_max_buffer_extents (); + + return _xdg_mime_magic_get_buffer_extents (global_magic); +} + +const char * +_xdg_mime_unalias_mime_type (const char *mime_type) +{ + const char *lookup; + + if (_caches) + return _xdg_mime_cache_unalias_mime_type (mime_type); + + if ((lookup = _xdg_mime_alias_list_lookup (alias_list, mime_type)) != NULL) + return lookup; + + return mime_type; +} + +const char * +xdg_mime_unalias_mime_type (const char *mime_type) +{ + xdg_mime_init (); + + return _xdg_mime_unalias_mime_type (mime_type); +} + +int +_xdg_mime_mime_type_equal (const char *mime_a, + const char *mime_b) +{ + const char *unalias_a, *unalias_b; + + unalias_a = _xdg_mime_unalias_mime_type (mime_a); + unalias_b = _xdg_mime_unalias_mime_type (mime_b); + + if (strcmp (unalias_a, unalias_b) == 0) + return 1; + + return 0; +} + +int +xdg_mime_mime_type_equal (const char *mime_a, + const char *mime_b) +{ + xdg_mime_init (); + + return _xdg_mime_mime_type_equal (mime_a, mime_b); +} + +int +xdg_mime_media_type_equal (const char *mime_a, + const char *mime_b) +{ + char *sep; + + sep = strchr (mime_a, '/'); + + if (sep && strncmp (mime_a, mime_b, sep - mime_a + 1) == 0) + return 1; + + return 0; +} + +#if 1 +static int +xdg_mime_is_super_type (const char *mime) +{ + int length; + const char *type; + + length = strlen (mime); + type = &(mime[length - 2]); + + if (strcmp (type, "/*") == 0) + return 1; + + return 0; +} +#endif + +int +_xdg_mime_mime_type_subclass (const char *mime, + const char *base) +{ + const char *umime, *ubase; + const char **parents; + + if (_caches) + return _xdg_mime_cache_mime_type_subclass (mime, base); + + umime = _xdg_mime_unalias_mime_type (mime); + ubase = _xdg_mime_unalias_mime_type (base); + + if (strcmp (umime, ubase) == 0) + return 1; + +#if 1 + /* Handle supertypes */ + if (xdg_mime_is_super_type (ubase) && + xdg_mime_media_type_equal (umime, ubase)) + return 1; +#endif + + /* Handle special cases text/plain and application/octet-stream */ + if (strcmp (ubase, "text/plain") == 0 && + strncmp (umime, "text/", 5) == 0) + return 1; + + if (strcmp (ubase, "application/octet-stream") == 0) + return 1; + + parents = _xdg_mime_parent_list_lookup (parent_list, umime); + for (; parents && *parents; parents++) + { + if (_xdg_mime_mime_type_subclass (*parents, ubase)) + return 1; + } + + return 0; +} + +int +xdg_mime_mime_type_subclass (const char *mime, + const char *base) +{ + xdg_mime_init (); + + return _xdg_mime_mime_type_subclass (mime, base); +} + +char ** +xdg_mime_list_mime_parents (const char *mime) +{ + const char **parents; + char **result; + int i, n; + + if (_caches) + return _xdg_mime_cache_list_mime_parents (mime); + + parents = xdg_mime_get_mime_parents (mime); + + if (!parents) + return NULL; + + for (i = 0; parents[i]; i++) ; + + n = (i + 1) * sizeof (char *); + result = (char **) malloc (n); + memcpy (result, parents, n); + + return result; +} + +const char ** +xdg_mime_get_mime_parents (const char *mime) +{ + const char *umime; + + xdg_mime_init (); + + umime = _xdg_mime_unalias_mime_type (mime); + + return _xdg_mime_parent_list_lookup (parent_list, umime); +} + +void +xdg_mime_dump (void) +{ + xdg_mime_init(); + + printf ("*** ALIASES ***\n\n"); + _xdg_mime_alias_list_dump (alias_list); + printf ("\n*** PARENTS ***\n\n"); + _xdg_mime_parent_list_dump (parent_list); + printf ("\n*** CACHE ***\n\n"); + _xdg_glob_hash_dump (global_hash); + printf ("\n*** GLOBS ***\n\n"); + _xdg_glob_hash_dump (global_hash); + printf ("\n*** GLOBS REVERSE TREE ***\n\n"); + _xdg_mime_cache_glob_dump (); +} + + +/* Registers a function to be called every time the mime database reloads its files + */ +int +xdg_mime_register_reload_callback (XdgMimeCallback callback, + void *data, + XdgMimeDestroy destroy) +{ + XdgCallbackList *list_el; + static int callback_id = 1; + + /* Make a new list element */ + list_el = calloc (1, sizeof (XdgCallbackList)); + list_el->callback_id = callback_id; + list_el->callback = callback; + list_el->data = data; + list_el->destroy = destroy; + list_el->next = callback_list; + if (list_el->next) + list_el->next->prev = list_el; + + callback_list = list_el; + callback_id ++; + + return callback_id - 1; +} + +void +xdg_mime_remove_callback (int callback_id) +{ + XdgCallbackList *list; + + for (list = callback_list; list; list = list->next) + { + if (list->callback_id == callback_id) + { + if (list->next) + list->next = list->prev; + + if (list->prev) + list->prev->next = list->next; + else + callback_list = list->next; + + /* invoke the destroy handler */ + (list->destroy) (list->data); + free (list); + return; + } + } +} + +const char * +xdg_mime_get_icon (const char *mime) +{ + xdg_mime_init (); + + if (_caches) + return _xdg_mime_cache_get_icon (mime); + + return _xdg_mime_icon_list_lookup (icon_list, mime); +} + +const char * +xdg_mime_get_generic_icon (const char *mime) +{ + xdg_mime_init (); + + if (_caches) + return _xdg_mime_cache_get_generic_icon (mime); + + return _xdg_mime_icon_list_lookup (generic_icon_list, mime); +} diff --git a/Xdgmime/xdgmime.h b/Xdgmime/xdgmime.h new file mode 100644 index 0000000..6a34edf --- /dev/null +++ b/Xdgmime/xdgmime.h @@ -0,0 +1,133 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmime.h: XDG Mime Spec mime resolver. Based on version 0.11 of the spec. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2003 Red Hat, Inc. + * Copyright (C) 2003 Jonathan Blandford + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#ifndef __XDG_MIME_H__ +#define __XDG_MIME_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef XDG_PREFIX +#define XDG_ENTRY(func) _XDG_ENTRY2(XDG_PREFIX,func) +#define _XDG_ENTRY2(prefix,func) _XDG_ENTRY3(prefix,func) +#define _XDG_ENTRY3(prefix,func) prefix##_##func + +#define XDG_RESERVED_ENTRY(func) _XDG_RESERVED_ENTRY2(XDG_PREFIX,func) +#define _XDG_RESERVED_ENTRY2(prefix,func) _XDG_RESERVED_ENTRY3(prefix,func) +#define _XDG_RESERVED_ENTRY3(prefix,func) _##prefix##_##func +#endif + +typedef void (*XdgMimeCallback) (void *user_data); +typedef void (*XdgMimeDestroy) (void *user_data); + + +#ifdef XDG_PREFIX +#define xdg_mime_get_mime_type_for_data XDG_ENTRY(get_mime_type_for_data) +#define xdg_mime_get_mime_type_for_file XDG_ENTRY(get_mime_type_for_file) +#define xdg_mime_get_mime_type_from_file_name XDG_ENTRY(get_mime_type_from_file_name) +#define xdg_mime_get_mime_types_from_file_name XDG_ENTRY(get_mime_types_from_file_name) +#define xdg_mime_is_valid_mime_type XDG_ENTRY(is_valid_mime_type) +#define xdg_mime_mime_type_equal XDG_ENTRY(mime_type_equal) +#define xdg_mime_media_type_equal XDG_ENTRY(media_type_equal) +#define xdg_mime_mime_type_subclass XDG_ENTRY(mime_type_subclass) +#define xdg_mime_get_mime_parents XDG_ENTRY(get_mime_parents) +#define xdg_mime_list_mime_parents XDG_ENTRY(list_mime_parents) +#define xdg_mime_unalias_mime_type XDG_ENTRY(unalias_mime_type) +#define xdg_mime_get_max_buffer_extents XDG_ENTRY(get_max_buffer_extents) +#define xdg_mime_shutdown XDG_ENTRY(shutdown) +#define xdg_mime_dump XDG_ENTRY(dump) +#define xdg_mime_register_reload_callback XDG_ENTRY(register_reload_callback) +#define xdg_mime_remove_callback XDG_ENTRY(remove_callback) +#define xdg_mime_type_unknown XDG_ENTRY(type_unknown) +#define xdg_mime_type_empty XDG_ENTRY(type_empty) +#define xdg_mime_type_textplain XDG_ENTRY(type_textplain) +#define xdg_mime_get_icon XDG_ENTRY(get_icon) +#define xdg_mime_get_generic_icon XDG_ENTRY(get_generic_icon) + +#define _xdg_mime_mime_type_equal XDG_RESERVED_ENTRY(mime_type_equal) +#define _xdg_mime_mime_type_subclass XDG_RESERVED_ENTRY(mime_type_subclass) +#define _xdg_mime_unalias_mime_type XDG_RESERVED_ENTRY(unalias_mime_type) +#endif + +extern const char xdg_mime_type_unknown[]; +extern const char xdg_mime_type_empty[]; +extern const char xdg_mime_type_textplain[]; +#define XDG_MIME_TYPE_UNKNOWN xdg_mime_type_unknown +#define XDG_MIME_TYPE_EMPTY xdg_mime_type_empty +#define XDG_MIME_TYPE_TEXTPLAIN xdg_mime_type_textplain + +const char *xdg_mime_get_mime_type_for_data (const void *data, + size_t len, + int *result_prio); +const char *xdg_mime_get_mime_type_for_file (const char *file_name, + struct stat *statbuf); +const char *xdg_mime_get_mime_type_from_file_name (const char *file_name); +int xdg_mime_get_mime_types_from_file_name(const char *file_name, + const char *mime_types[], + int n_mime_types); +int xdg_mime_is_valid_mime_type (const char *mime_type); +int xdg_mime_mime_type_equal (const char *mime_a, + const char *mime_b); +int xdg_mime_media_type_equal (const char *mime_a, + const char *mime_b); +int xdg_mime_mime_type_subclass (const char *mime_a, + const char *mime_b); + /* xdg_mime_get_mime_parents() is deprecated since it does + * not work correctly with caches. Use xdg_mime_list_parents() + * instead, but notice that that function expects you to free + * the array it returns. + */ +const char **xdg_mime_get_mime_parents (const char *mime); +char ** xdg_mime_list_mime_parents (const char *mime); +const char *xdg_mime_unalias_mime_type (const char *mime); +const char *xdg_mime_get_icon (const char *mime); +const char *xdg_mime_get_generic_icon (const char *mime); +int xdg_mime_get_max_buffer_extents (void); +void xdg_mime_shutdown (void); +void xdg_mime_dump (void); +int xdg_mime_register_reload_callback (XdgMimeCallback callback, + void *data, + XdgMimeDestroy destroy); +void xdg_mime_remove_callback (int callback_id); + + /* Private versions of functions that don't call xdg_mime_init () */ +int _xdg_mime_mime_type_equal (const char *mime_a, + const char *mime_b); +int _xdg_mime_mime_type_subclass (const char *mime, + const char *base); +const char *_xdg_mime_unalias_mime_type (const char *mime); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __XDG_MIME_H__ */ diff --git a/Xdgmime/xdgmimealias.c b/Xdgmime/xdgmimealias.c new file mode 100644 index 0000000..07d89eb --- /dev/null +++ b/Xdgmime/xdgmimealias.c @@ -0,0 +1,184 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimealias.c: Private file. Datastructure for storing the aliases. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2004 Red Hat, Inc. + * Copyright (C) 2004 Matthias Clasen + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "xdgmimealias.h" +#include "xdgmimeint.h" +#include +#include +#include +#include +#include + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +typedef struct XdgAlias XdgAlias; + +struct XdgAlias +{ + char *alias; + char *mime_type; +}; + +struct XdgAliasList +{ + struct XdgAlias *aliases; + int n_aliases; +}; + +XdgAliasList * +_xdg_mime_alias_list_new (void) +{ + XdgAliasList *list; + + list = malloc (sizeof (XdgAliasList)); + + list->aliases = NULL; + list->n_aliases = 0; + + return list; +} + +void +_xdg_mime_alias_list_free (XdgAliasList *list) +{ + int i; + + if (list->aliases) + { + for (i = 0; i < list->n_aliases; i++) + { + free (list->aliases[i].alias); + free (list->aliases[i].mime_type); + } + free (list->aliases); + } + free (list); +} + +static int +alias_entry_cmp (const void *v1, const void *v2) +{ + return strcmp (((XdgAlias *)v1)->alias, ((XdgAlias *)v2)->alias); +} + +const char * +_xdg_mime_alias_list_lookup (XdgAliasList *list, + const char *alias) +{ + XdgAlias *entry; + XdgAlias key; + + if (list->n_aliases > 0) + { + key.alias = (char *)alias; + key.mime_type = NULL; + + entry = bsearch (&key, list->aliases, list->n_aliases, + sizeof (XdgAlias), alias_entry_cmp); + if (entry) + return entry->mime_type; + } + + return NULL; +} + +void +_xdg_mime_alias_read_from_file (XdgAliasList *list, + const char *file_name) +{ + FILE *file; + char line[255]; + int alloc; + + file = fopen (file_name, "r"); + + if (file == NULL) + return; + + /* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars. + * Blah */ + alloc = list->n_aliases + 16; + list->aliases = realloc (list->aliases, alloc * sizeof (XdgAlias)); + while (fgets (line, 255, file) != NULL) + { + char *sep; + if (line[0] == '#') + continue; + + sep = strchr (line, ' '); + if (sep == NULL) + continue; + *(sep++) = '\000'; + sep[strlen (sep) -1] = '\000'; + if (list->n_aliases == alloc) + { + alloc <<= 1; + list->aliases = realloc (list->aliases, + alloc * sizeof (XdgAlias)); + } + list->aliases[list->n_aliases].alias = strdup (line); + list->aliases[list->n_aliases].mime_type = strdup (sep); + list->n_aliases++; + } + list->aliases = realloc (list->aliases, + list->n_aliases * sizeof (XdgAlias)); + + fclose (file); + + if (list->n_aliases > 1) + qsort (list->aliases, list->n_aliases, + sizeof (XdgAlias), alias_entry_cmp); +} + + +void +_xdg_mime_alias_list_dump (XdgAliasList *list) +{ + int i; + + if (list->aliases) + { + for (i = 0; i < list->n_aliases; i++) + { + printf ("%s %s\n", + list->aliases[i].alias, + list->aliases[i].mime_type); + } + } +} + + diff --git a/Xdgmime/xdgmimealias.h b/Xdgmime/xdgmimealias.h new file mode 100644 index 0000000..3c28012 --- /dev/null +++ b/Xdgmime/xdgmimealias.h @@ -0,0 +1,51 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimealias.h: Private file. Datastructure for storing the aliases. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2004 Red Hat, Inc. + * Copyright (C) 200 Matthias Clasen + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __XDG_MIME_ALIAS_H__ +#define __XDG_MIME_ALIAS_H__ + +#include "xdgmime.h" + +typedef struct XdgAliasList XdgAliasList; + +#ifdef XDG_PREFIX +#define _xdg_mime_alias_read_from_file XDG_RESERVED_ENTRY(alias_read_from_file) +#define _xdg_mime_alias_list_new XDG_RESERVED_ENTRY(alias_list_new) +#define _xdg_mime_alias_list_free XDG_RESERVED_ENTRY(alias_list_free) +#define _xdg_mime_alias_list_lookup XDG_RESERVED_ENTRY(alias_list_lookup) +#define _xdg_mime_alias_list_dump XDG_RESERVED_ENTRY(alias_list_dump) +#endif + +void _xdg_mime_alias_read_from_file (XdgAliasList *list, + const char *file_name); +XdgAliasList *_xdg_mime_alias_list_new (void); +void _xdg_mime_alias_list_free (XdgAliasList *list); +const char *_xdg_mime_alias_list_lookup (XdgAliasList *list, + const char *alias); +void _xdg_mime_alias_list_dump (XdgAliasList *list); + +#endif /* __XDG_MIME_ALIAS_H__ */ diff --git a/Xdgmime/xdgmimecache.c b/Xdgmime/xdgmimecache.c new file mode 100644 index 0000000..0ecaa4f --- /dev/null +++ b/Xdgmime/xdgmimecache.c @@ -0,0 +1,1069 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimealias.c: Private file. mmappable caches for mime data + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2005 Matthias Clasen + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include + +#include /* for ntohl/ntohs */ + +#ifdef HAVE_MMAP +#include +#else +#warning Building xdgmime without MMAP support. Binary "mime.cache" files will not be used. +#endif + +#include +#include + +#include "xdgmimecache.h" +#include "xdgmimeint.h" + +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +#ifndef _O_BINARY +#define _O_BINARY 0 +#endif + +#ifndef MAP_FAILED +#define MAP_FAILED ((void *) -1) +#endif + +#define MAJOR_VERSION 1 +#define MINOR_VERSION_MIN 1 +#define MINOR_VERSION_MAX 2 + +struct _XdgMimeCache +{ + int ref_count; + int minor; + + size_t size; + char *buffer; +}; + +#define GET_UINT16(cache,offset) (ntohs(*(xdg_uint16_t*)((cache) + (offset)))) +#define GET_UINT32(cache,offset) (ntohl(*(xdg_uint32_t*)((cache) + (offset)))) + +XdgMimeCache * +_xdg_mime_cache_ref (XdgMimeCache *cache) +{ + cache->ref_count++; + return cache; +} + +void +_xdg_mime_cache_unref (XdgMimeCache *cache) +{ + cache->ref_count--; + + if (cache->ref_count == 0) + { +#ifdef HAVE_MMAP + munmap (cache->buffer, cache->size); +#endif + free (cache); + } +} + +XdgMimeCache * +_xdg_mime_cache_new_from_file (const char *file_name) +{ + XdgMimeCache *cache = NULL; + +#ifdef HAVE_MMAP + int fd = -1; + struct stat st; + char *buffer = NULL; + int minor; + + /* Open the file and map it into memory */ + fd = open (file_name, O_RDONLY|_O_BINARY, 0); + + if (fd < 0) + return NULL; + + if (fstat (fd, &st) < 0 || st.st_size < 4) + goto done; + + buffer = (char *) mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); + + if (buffer == MAP_FAILED) + goto done; + + minor = GET_UINT16 (buffer, 2); + /* Verify version */ + if (GET_UINT16 (buffer, 0) != MAJOR_VERSION || + (minor < MINOR_VERSION_MIN || + minor > MINOR_VERSION_MAX)) + { + munmap (buffer, st.st_size); + + goto done; + } + + cache = (XdgMimeCache *) malloc (sizeof (XdgMimeCache)); + cache->minor = minor; + cache->ref_count = 1; + cache->buffer = buffer; + cache->size = st.st_size; + + done: + if (fd != -1) + close (fd); + +#endif /* HAVE_MMAP */ + + return cache; +} + +static int +cache_magic_matchlet_compare_to_data (XdgMimeCache *cache, + xdg_uint32_t offset, + const void *data, + size_t len) +{ + xdg_uint32_t range_start = GET_UINT32 (cache->buffer, offset); + xdg_uint32_t range_length = GET_UINT32 (cache->buffer, offset + 4); + xdg_uint32_t data_length = GET_UINT32 (cache->buffer, offset + 12); + xdg_uint32_t data_offset = GET_UINT32 (cache->buffer, offset + 16); + xdg_uint32_t mask_offset = GET_UINT32 (cache->buffer, offset + 20); + + int i, j; + + for (i = range_start; i < range_start + range_length; i++) + { + int valid_matchlet = TRUE; + + if (i + data_length > len) + return FALSE; + + if (mask_offset) + { + for (j = 0; j < data_length; j++) + { + if ((((unsigned char *)cache->buffer)[data_offset + j] & ((unsigned char *)cache->buffer)[mask_offset + j]) != + ((((unsigned char *) data)[j + i]) & ((unsigned char *)cache->buffer)[mask_offset + j])) + { + valid_matchlet = FALSE; + break; + } + } + } + else + { + valid_matchlet = memcmp(cache->buffer + data_offset, data + i, data_length) == 0; + } + + if (valid_matchlet) + return TRUE; + } + + return FALSE; +} + +static int +cache_magic_matchlet_compare (XdgMimeCache *cache, + xdg_uint32_t offset, + const void *data, + size_t len) +{ + xdg_uint32_t n_children = GET_UINT32 (cache->buffer, offset + 24); + xdg_uint32_t child_offset = GET_UINT32 (cache->buffer, offset + 28); + + int i; + + if (cache_magic_matchlet_compare_to_data (cache, offset, data, len)) + { + if (n_children == 0) + return TRUE; + + for (i = 0; i < n_children; i++) + { + if (cache_magic_matchlet_compare (cache, child_offset + 32 * i, + data, len)) + return TRUE; + } + } + + return FALSE; +} + +static const char * +cache_magic_compare_to_data (XdgMimeCache *cache, + xdg_uint32_t offset, + const void *data, + size_t len, + int *prio) +{ + xdg_uint32_t priority = GET_UINT32 (cache->buffer, offset); + xdg_uint32_t mimetype_offset = GET_UINT32 (cache->buffer, offset + 4); + xdg_uint32_t n_matchlets = GET_UINT32 (cache->buffer, offset + 8); + xdg_uint32_t matchlet_offset = GET_UINT32 (cache->buffer, offset + 12); + + int i; + + for (i = 0; i < n_matchlets; i++) + { + if (cache_magic_matchlet_compare (cache, matchlet_offset + i * 32, + data, len)) + { + *prio = priority; + + return cache->buffer + mimetype_offset; + } + } + + return NULL; +} + +static const char * +cache_magic_lookup_data (XdgMimeCache *cache, + const void *data, + size_t len, + int *prio, + const char *mime_types[], + int n_mime_types) +{ + xdg_uint32_t list_offset; + xdg_uint32_t n_entries; + xdg_uint32_t offset; + + int j, n; + + *prio = 0; + + list_offset = GET_UINT32 (cache->buffer, 24); + n_entries = GET_UINT32 (cache->buffer, list_offset); + offset = GET_UINT32 (cache->buffer, list_offset + 8); + + for (j = 0; j < n_entries; j++) + { + const char *match; + + match = cache_magic_compare_to_data (cache, offset + 16 * j, + data, len, prio); + if (match) + return match; + else + { + xdg_uint32_t mimetype_offset; + const char *non_match; + + mimetype_offset = GET_UINT32 (cache->buffer, offset + 16 * j + 4); + non_match = cache->buffer + mimetype_offset; + + for (n = 0; n < n_mime_types; n++) + { + if (mime_types[n] && + _xdg_mime_mime_type_equal (mime_types[n], non_match)) + mime_types[n] = NULL; + } + } + } + + return NULL; +} + +static const char * +cache_alias_lookup (const char *alias) +{ + const char *ptr; + int i, min, max, mid, cmp; + + for (i = 0; _caches[i]; i++) + { + XdgMimeCache *cache = _caches[i]; + xdg_uint32_t list_offset = GET_UINT32 (cache->buffer, 4); + xdg_uint32_t n_entries = GET_UINT32 (cache->buffer, list_offset); + xdg_uint32_t offset; + + min = 0; + max = n_entries - 1; + while (max >= min) + { + mid = (min + max) / 2; + + offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid); + ptr = cache->buffer + offset; + cmp = strcmp (ptr, alias); + + if (cmp < 0) + min = mid + 1; + else if (cmp > 0) + max = mid - 1; + else + { + offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid + 4); + return cache->buffer + offset; + } + } + } + + return NULL; +} + +typedef struct { + const char *mime; + int weight; +} MimeWeight; + +static int +cache_glob_lookup_literal (const char *file_name, + const char *mime_types[], + int n_mime_types, + int case_sensitive_check) +{ + const char *ptr; + int i, min, max, mid, cmp; + + for (i = 0; _caches[i]; i++) + { + XdgMimeCache *cache = _caches[i]; + xdg_uint32_t list_offset = GET_UINT32 (cache->buffer, 12); + xdg_uint32_t n_entries = GET_UINT32 (cache->buffer, list_offset); + xdg_uint32_t offset; + + min = 0; + max = n_entries - 1; + while (max >= min) + { + mid = (min + max) / 2; + + offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * mid); + ptr = cache->buffer + offset; + cmp = strcmp (ptr, file_name); + + if (cmp < 0) + min = mid + 1; + else if (cmp > 0) + max = mid - 1; + else + { + int weight = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * mid + 8); + int case_sensitive = weight & 0x100; + weight = weight & 0xff; + + if (case_sensitive_check || !case_sensitive) + { + offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * mid + 4); + mime_types[0] = (const char *)(cache->buffer + offset); + + return 1; + } + return 0; + } + } + } + + return 0; +} + +static int +cache_glob_lookup_fnmatch (const char *file_name, + MimeWeight mime_types[], + int n_mime_types, + int case_sensitive_check) +{ + const char *mime_type; + const char *ptr; + + int i, j, n; + + n = 0; + for (i = 0; _caches[i]; i++) + { + XdgMimeCache *cache = _caches[i]; + + xdg_uint32_t list_offset = GET_UINT32 (cache->buffer, 20); + xdg_uint32_t n_entries = GET_UINT32 (cache->buffer, list_offset); + + for (j = 0; j < n_entries && n < n_mime_types; j++) + { + xdg_uint32_t offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j); + xdg_uint32_t mimetype_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j + 4); + int weight = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j + 8); + int case_sensitive = weight & 0x100; + weight = weight & 0xff; + ptr = cache->buffer + offset; + mime_type = cache->buffer + mimetype_offset; + if (case_sensitive_check || !case_sensitive) + { + /* FIXME: Not UTF-8 safe */ + if (fnmatch (ptr, file_name, 0) == 0) + { + mime_types[n].mime = mime_type; + mime_types[n].weight = weight; + n++; + } + } + } + + if (n > 0) + return n; + } + + return 0; +} + +static int +cache_glob_node_lookup_suffix (XdgMimeCache *cache, + xdg_uint32_t n_entries, + xdg_uint32_t offset, + const char *file_name, + int len, + int case_sensitive_check, + MimeWeight mime_types[], + int n_mime_types) +{ + xdg_unichar_t character; + xdg_unichar_t match_char; + xdg_uint32_t mimetype_offset; + xdg_uint32_t n_children; + xdg_uint32_t child_offset; + int weight; + int case_sensitive; + + int min, max, mid, n, i; + + character = file_name[len - 1]; + + assert (character != 0); + + min = 0; + max = n_entries - 1; + while (max >= min) + { + mid = (min + max) / 2; + match_char = GET_UINT32 (cache->buffer, offset + 12 * mid); + if (match_char < character) + min = mid + 1; + else if (match_char > character) + max = mid - 1; + else + { + len--; + n = 0; + n_children = GET_UINT32 (cache->buffer, offset + 12 * mid + 4); + child_offset = GET_UINT32 (cache->buffer, offset + 12 * mid + 8); + + if (len > 0) + { + n = cache_glob_node_lookup_suffix (cache, + n_children, child_offset, + file_name, len, + case_sensitive_check, + mime_types, + n_mime_types); + } + if (n == 0) + { + i = 0; + while (n < n_mime_types && i < n_children) + { + match_char = GET_UINT32 (cache->buffer, child_offset + 12 * i); + if (match_char != 0) + break; + + mimetype_offset = GET_UINT32 (cache->buffer, child_offset + 12 * i + 4); + weight = GET_UINT32 (cache->buffer, child_offset + 12 * i + 8); + case_sensitive = weight & 0x100; + weight = weight & 0xff; + + if (case_sensitive_check || !case_sensitive) + { + mime_types[n].mime = cache->buffer + mimetype_offset; + mime_types[n].weight = weight; + n++; + } + i++; + } + } + return n; + } + } + return 0; +} + +static int +cache_glob_lookup_suffix (const char *file_name, + int len, + int ignore_case, + MimeWeight mime_types[], + int n_mime_types) +{ + int i, n; + + for (i = 0; _caches[i]; i++) + { + XdgMimeCache *cache = _caches[i]; + + xdg_uint32_t list_offset = GET_UINT32 (cache->buffer, 16); + xdg_uint32_t n_entries = GET_UINT32 (cache->buffer, list_offset); + xdg_uint32_t offset = GET_UINT32 (cache->buffer, list_offset + 4); + + n = cache_glob_node_lookup_suffix (cache, + n_entries, offset, + file_name, len, + ignore_case, + mime_types, + n_mime_types); + if (n > 0) + return n; + } + + return 0; +} + +static int compare_mime_weight (const void *a, const void *b) +{ + const MimeWeight *aa = (const MimeWeight *)a; + const MimeWeight *bb = (const MimeWeight *)b; + + return bb->weight - aa->weight; +} + +#define ISUPPER(c) ((c) >= 'A' && (c) <= 'Z') +static char * +ascii_tolower (const char *str) +{ + char *p, *lower; + + lower = strdup (str); + p = lower; + while (*p != 0) + { + char c = *p; + *p++ = ISUPPER (c) ? c - 'A' + 'a' : c; + } + return lower; +} + +static int +cache_glob_lookup_file_name (const char *file_name, + const char *mime_types[], + int n_mime_types) +{ + int n; + MimeWeight mimes[10]; + int n_mimes = 10; + int i; + int len; + char *lower_case; + + assert (file_name != NULL && n_mime_types > 0); + + /* First, check the literals */ + + lower_case = ascii_tolower (file_name); + + n = cache_glob_lookup_literal (lower_case, mime_types, n_mime_types, FALSE); + if (n > 0) + { + free (lower_case); + return n; + } + + n = cache_glob_lookup_literal (file_name, mime_types, n_mime_types, TRUE); + if (n > 0) + { + free (lower_case); + return n; + } + + len = strlen (file_name); + n = cache_glob_lookup_suffix (lower_case, len, FALSE, mimes, n_mimes); + if (n == 0) + n = cache_glob_lookup_suffix (file_name, len, TRUE, mimes, n_mimes); + + /* Last, try fnmatch */ + if (n == 0) + n = cache_glob_lookup_fnmatch (lower_case, mimes, n_mimes, FALSE); + if (n == 0) + n = cache_glob_lookup_fnmatch (file_name, mimes, n_mimes, TRUE); + + free (lower_case); + + qsort (mimes, n, sizeof (MimeWeight), compare_mime_weight); + + if (n_mime_types < n) + n = n_mime_types; + + for (i = 0; i < n; i++) + mime_types[i] = mimes[i].mime; + + return n; +} + +int +_xdg_mime_cache_get_max_buffer_extents (void) +{ + xdg_uint32_t offset; + xdg_uint32_t max_extent; + int i; + + max_extent = 0; + for (i = 0; _caches[i]; i++) + { + XdgMimeCache *cache = _caches[i]; + + offset = GET_UINT32 (cache->buffer, 24); + max_extent = MAX (max_extent, GET_UINT32 (cache->buffer, offset + 4)); + } + + return max_extent; +} + +static const char * +cache_get_mime_type_for_data (const void *data, + size_t len, + int *result_prio, + const char *mime_types[], + int n_mime_types) +{ + const char *mime_type; + int i, n, priority; + + priority = 0; + mime_type = NULL; + for (i = 0; _caches[i]; i++) + { + XdgMimeCache *cache = _caches[i]; + + int prio; + const char *match; + + match = cache_magic_lookup_data (cache, data, len, &prio, + mime_types, n_mime_types); + if (prio > priority) + { + priority = prio; + mime_type = match; + } + } + + if (result_prio) + *result_prio = priority; + + if (priority > 0) + { + /* Pick glob-result R where mime_type inherits from R */ + for (n = 0; n < n_mime_types; n++) + { + if (mime_types[n] && _xdg_mime_cache_mime_type_subclass(mime_types[n], mime_type)) + return mime_types[n]; + } + + /* Return magic match */ + return mime_type; + } + + /* Pick first glob result, as fallback */ + for (n = 0; n < n_mime_types; n++) + { + if (mime_types[n]) + return mime_types[n]; + } + + return NULL; +} + +const char * +_xdg_mime_cache_get_mime_type_for_data (const void *data, + size_t len, + int *result_prio) +{ + return cache_get_mime_type_for_data (data, len, result_prio, NULL, 0); +} + +const char * +_xdg_mime_cache_get_mime_type_for_file (const char *file_name, + struct stat *statbuf) +{ + const char *mime_type; + const char *mime_types[10]; + FILE *file; + unsigned char *data; + int max_extent; + int bytes_read; + struct stat buf; + const char *base_name; + int n; + + if (file_name == NULL) + return NULL; + + if (! _xdg_utf8_validate (file_name)) + return NULL; + + base_name = _xdg_get_base_name (file_name); + n = cache_glob_lookup_file_name (base_name, mime_types, 10); + + if (n == 1) + return mime_types[0]; + + if (!statbuf) + { + if (stat (file_name, &buf) != 0) + return XDG_MIME_TYPE_UNKNOWN; + + statbuf = &buf; + } + + if (statbuf->st_size == 0) + return XDG_MIME_TYPE_EMPTY; + + if (!S_ISREG (statbuf->st_mode)) + return XDG_MIME_TYPE_UNKNOWN; + + /* FIXME: Need to make sure that max_extent isn't totally broken. This could + * be large and need getting from a stream instead of just reading it all + * in. */ + max_extent = _xdg_mime_cache_get_max_buffer_extents (); + data = malloc (max_extent); + if (data == NULL) + return XDG_MIME_TYPE_UNKNOWN; + + file = fopen (file_name, "r"); + if (file == NULL) + { + free (data); + return XDG_MIME_TYPE_UNKNOWN; + } + + bytes_read = fread (data, 1, max_extent, file); + if (ferror (file)) + { + free (data); + fclose (file); + return XDG_MIME_TYPE_UNKNOWN; + } + + mime_type = cache_get_mime_type_for_data (data, bytes_read, NULL, + mime_types, n); + + if (!mime_type) + mime_type = _xdg_binary_or_text_fallback(data, bytes_read); + + free (data); + fclose (file); + + return mime_type; +} + +const char * +_xdg_mime_cache_get_mime_type_from_file_name (const char *file_name) +{ + const char *mime_type; + + if (cache_glob_lookup_file_name (file_name, &mime_type, 1)) + return mime_type; + else + return XDG_MIME_TYPE_UNKNOWN; +} + +int +_xdg_mime_cache_get_mime_types_from_file_name (const char *file_name, + const char *mime_types[], + int n_mime_types) +{ + return cache_glob_lookup_file_name (file_name, mime_types, n_mime_types); +} + +#if 1 +static int +is_super_type (const char *mime) +{ + int length; + const char *type; + + length = strlen (mime); + type = &(mime[length - 2]); + + if (strcmp (type, "/*") == 0) + return 1; + + return 0; +} +#endif + +int +_xdg_mime_cache_mime_type_subclass (const char *mime, + const char *base) +{ + const char *umime, *ubase; + + int i, j, min, max, med, cmp; + + umime = _xdg_mime_cache_unalias_mime_type (mime); + ubase = _xdg_mime_cache_unalias_mime_type (base); + + if (strcmp (umime, ubase) == 0) + return 1; + + /* We really want to handle text/ * in GtkFileFilter, so we just + * turn on the supertype matching + */ +#if 1 + /* Handle supertypes */ + if (is_super_type (ubase) && + xdg_mime_media_type_equal (umime, ubase)) + return 1; +#endif + + /* Handle special cases text/plain and application/octet-stream */ + if (strcmp (ubase, "text/plain") == 0 && + strncmp (umime, "text/", 5) == 0) + return 1; + + if (strcmp (ubase, "application/octet-stream") == 0) + return 1; + + for (i = 0; _caches[i]; i++) + { + XdgMimeCache *cache = _caches[i]; + + xdg_uint32_t list_offset = GET_UINT32 (cache->buffer, 8); + xdg_uint32_t n_entries = GET_UINT32 (cache->buffer, list_offset); + xdg_uint32_t offset, n_parents, parent_offset; + + min = 0; + max = n_entries - 1; + while (max >= min) + { + med = (min + max)/2; + + offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * med); + cmp = strcmp (cache->buffer + offset, umime); + if (cmp < 0) + min = med + 1; + else if (cmp > 0) + max = med - 1; + else + { + offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * med + 4); + n_parents = GET_UINT32 (cache->buffer, offset); + + for (j = 0; j < n_parents; j++) + { + parent_offset = GET_UINT32 (cache->buffer, offset + 4 + 4 * j); + if (_xdg_mime_cache_mime_type_subclass (cache->buffer + parent_offset, ubase)) + return 1; + } + + break; + } + } + } + + return 0; +} + +const char * +_xdg_mime_cache_unalias_mime_type (const char *mime) +{ + const char *lookup; + + lookup = cache_alias_lookup (mime); + + if (lookup) + return lookup; + + return mime; +} + +char ** +_xdg_mime_cache_list_mime_parents (const char *mime) +{ + int i, j, k, l, p; + char *all_parents[128]; /* we'll stop at 128 */ + char **result; + + mime = xdg_mime_unalias_mime_type (mime); + + p = 0; + for (i = 0; _caches[i]; i++) + { + XdgMimeCache *cache = _caches[i]; + + xdg_uint32_t list_offset = GET_UINT32 (cache->buffer, 8); + xdg_uint32_t n_entries = GET_UINT32 (cache->buffer, list_offset); + + for (j = 0; j < n_entries; j++) + { + xdg_uint32_t mimetype_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * j); + xdg_uint32_t parents_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * j + 4); + + if (strcmp (cache->buffer + mimetype_offset, mime) == 0) + { + xdg_uint32_t parent_mime_offset; + xdg_uint32_t n_parents = GET_UINT32 (cache->buffer, parents_offset); + + for (k = 0; k < n_parents && p < 127; k++) + { + parent_mime_offset = GET_UINT32 (cache->buffer, parents_offset + 4 + 4 * k); + + /* Don't add same parent multiple times. + * This can happen for instance if the same type is listed in multiple directories + */ + for (l = 0; l < p; l++) + { + if (strcmp (all_parents[l], cache->buffer + parent_mime_offset) == 0) + break; + } + + if (l == p) + all_parents[p++] = cache->buffer + parent_mime_offset; + } + + break; + } + } + } + all_parents[p++] = NULL; + + result = (char **) malloc (p * sizeof (char *)); + memcpy (result, all_parents, p * sizeof (char *)); + + return result; +} + +static const char * +cache_lookup_icon (const char *mime, int header) +{ + const char *ptr; + int i, min, max, mid, cmp; + + for (i = 0; _caches[i]; i++) + { + XdgMimeCache *cache = _caches[i]; + xdg_uint32_t list_offset = GET_UINT32 (cache->buffer, header); + xdg_uint32_t n_entries = GET_UINT32 (cache->buffer, list_offset); + xdg_uint32_t offset; + + min = 0; + max = n_entries - 1; + while (max >= min) + { + mid = (min + max) / 2; + + offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid); + ptr = cache->buffer + offset; + cmp = strcmp (ptr, mime); + + if (cmp < 0) + min = mid + 1; + else if (cmp > 0) + max = mid - 1; + else + { + offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid + 4); + return cache->buffer + offset; + } + } + } + + return NULL; +} + +const char * +_xdg_mime_cache_get_generic_icon (const char *mime) +{ + return cache_lookup_icon (mime, 36); +} + +const char * +_xdg_mime_cache_get_icon (const char *mime) +{ + return cache_lookup_icon (mime, 32); +} + +static void +dump_glob_node (XdgMimeCache *cache, + xdg_uint32_t offset, + int depth) +{ + xdg_unichar_t character; + xdg_uint32_t mime_offset; + xdg_uint32_t n_children; + xdg_uint32_t child_offset; + int i; + + character = GET_UINT32 (cache->buffer, offset); + mime_offset = GET_UINT32 (cache->buffer, offset + 4); + n_children = GET_UINT32 (cache->buffer, offset + 8); + child_offset = GET_UINT32 (cache->buffer, offset + 12); + for (i = 0; i < depth; i++) + printf (" "); + printf ("%c", character); + if (mime_offset) + printf (" - %s", cache->buffer + mime_offset); + printf ("\n"); + if (child_offset) + { + for (i = 0; i < n_children; i++) + dump_glob_node (cache, child_offset + 20 * i, depth + 1); + } +} + +void +_xdg_mime_cache_glob_dump (void) +{ + int i, j; + for (i = 0; _caches[i]; i++) + { + XdgMimeCache *cache = _caches[i]; + xdg_uint32_t list_offset; + xdg_uint32_t n_entries; + xdg_uint32_t offset; + list_offset = GET_UINT32 (cache->buffer, 16); + n_entries = GET_UINT32 (cache->buffer, list_offset); + offset = GET_UINT32 (cache->buffer, list_offset + 4); + for (j = 0; j < n_entries; j++) + dump_glob_node (cache, offset + 20 * j, 0); + } +} + + diff --git a/Xdgmime/xdgmimecache.h b/Xdgmime/xdgmimecache.h new file mode 100644 index 0000000..27f42d0 --- /dev/null +++ b/Xdgmime/xdgmimecache.h @@ -0,0 +1,81 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimecache.h: Private file. Datastructure for mmapped caches. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2005 Matthias Clasen + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __XDG_MIME_CACHE_H__ +#define __XDG_MIME_CACHE_H__ + +#include "xdgmime.h" + +typedef struct _XdgMimeCache XdgMimeCache; + +#ifdef XDG_PREFIX +#define _xdg_mime_cache_new_from_file XDG_RESERVED_ENTRY(cache_new_from_file) +#define _xdg_mime_cache_ref XDG_RESERVED_ENTRY(cache_ref) +#define _xdg_mime_cache_unref XDG_RESERVED_ENTRY(cache_unref) +#define _xdg_mime_cache_get_max_buffer_extents XDG_RESERVED_ENTRY(cache_get_max_buffer_extents) +#define _xdg_mime_cache_get_mime_type_for_data XDG_RESERVED_ENTRY(cache_get_mime_type_for_data) +#define _xdg_mime_cache_get_mime_type_for_file XDG_RESERVED_ENTRY(cache_get_mime_type_for_file) +#define _xdg_mime_cache_get_mime_type_from_file_name XDG_RESERVED_ENTRY(cache_get_mime_type_from_file_name) +#define _xdg_mime_cache_get_mime_types_from_file_name XDG_RESERVED_ENTRY(cache_get_mime_types_from_file_name) +#define _xdg_mime_cache_list_mime_parents XDG_RESERVED_ENTRY(cache_list_mime_parents) +#define _xdg_mime_cache_mime_type_subclass XDG_RESERVED_ENTRY(cache_mime_type_subclass) +#define _xdg_mime_cache_unalias_mime_type XDG_RESERVED_ENTRY(cache_unalias_mime_type) +#define _xdg_mime_cache_get_icon XDG_RESERVED_ENTRY(cache_get_icon) +#define _xdg_mime_cache_get_generic_icon XDG_RESERVED_ENTRY(cache_get_generic_icon) +#define _xdg_mime_cache_glob_dump XDG_RESERVED_ENTRY(cache_glob_dump) +#endif + +extern XdgMimeCache **_caches; + +XdgMimeCache *_xdg_mime_cache_new_from_file (const char *file_name); +XdgMimeCache *_xdg_mime_cache_ref (XdgMimeCache *cache); +void _xdg_mime_cache_unref (XdgMimeCache *cache); + + +const char *_xdg_mime_cache_get_mime_type_for_data (const void *data, + size_t len, + int *result_prio); +const char *_xdg_mime_cache_get_mime_type_for_file (const char *file_name, + struct stat *statbuf); +int _xdg_mime_cache_get_mime_types_from_file_name (const char *file_name, + const char *mime_types[], + int n_mime_types); +const char *_xdg_mime_cache_get_mime_type_from_file_name (const char *file_name); +int _xdg_mime_cache_is_valid_mime_type (const char *mime_type); +int _xdg_mime_cache_mime_type_equal (const char *mime_a, + const char *mime_b); +int _xdg_mime_cache_media_type_equal (const char *mime_a, + const char *mime_b); +int _xdg_mime_cache_mime_type_subclass (const char *mime_a, + const char *mime_b); +char **_xdg_mime_cache_list_mime_parents (const char *mime); +const char *_xdg_mime_cache_unalias_mime_type (const char *mime); +int _xdg_mime_cache_get_max_buffer_extents (void); +const char *_xdg_mime_cache_get_icon (const char *mime); +const char *_xdg_mime_cache_get_generic_icon (const char *mime); +void _xdg_mime_cache_glob_dump (void); + +#endif /* __XDG_MIME_CACHE_H__ */ diff --git a/Xdgmime/xdgmimeglob.c b/Xdgmime/xdgmimeglob.c new file mode 100644 index 0000000..f8434bc --- /dev/null +++ b/Xdgmime/xdgmimeglob.c @@ -0,0 +1,691 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimeglob.c: Private file. Datastructure for storing the globs. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2003 Red Hat, Inc. + * Copyright (C) 2003 Jonathan Blandford + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "xdgmimeglob.h" +#include "xdgmimeint.h" +#include +#include +#include +#include +#include + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +typedef struct XdgGlobHashNode XdgGlobHashNode; +typedef struct XdgGlobList XdgGlobList; + +struct XdgGlobHashNode +{ + xdg_unichar_t character; + const char *mime_type; + int weight; + int case_sensitive; + XdgGlobHashNode *next; + XdgGlobHashNode *child; +}; +struct XdgGlobList +{ + const char *data; + const char *mime_type; + int weight; + int case_sensitive; + XdgGlobList *next; +}; + +struct XdgGlobHash +{ + XdgGlobList *literal_list; + XdgGlobHashNode *simple_node; + XdgGlobList *full_list; +}; + + +/* XdgGlobList + */ +static XdgGlobList * +_xdg_glob_list_new (void) +{ + XdgGlobList *new_element; + + new_element = calloc (1, sizeof (XdgGlobList)); + + return new_element; +} + +/* Frees glob_list and all of it's children */ +static void +_xdg_glob_list_free (XdgGlobList *glob_list) +{ + XdgGlobList *ptr, *next; + + ptr = glob_list; + + while (ptr != NULL) + { + next = ptr->next; + + if (ptr->data) + free ((void *) ptr->data); + if (ptr->mime_type) + free ((void *) ptr->mime_type); + free (ptr); + + ptr = next; + } +} + +static XdgGlobList * +_xdg_glob_list_append (XdgGlobList *glob_list, + void *data, + const char *mime_type, + int weight, + int case_sensitive) +{ + XdgGlobList *new_element; + XdgGlobList *tmp_element; + + tmp_element = glob_list; + while (tmp_element != NULL) + { + if (strcmp (tmp_element->data, data) == 0 && + strcmp (tmp_element->mime_type, mime_type) == 0) + return glob_list; + + tmp_element = tmp_element->next; + } + + new_element = _xdg_glob_list_new (); + new_element->data = data; + new_element->mime_type = mime_type; + new_element->weight = weight; + new_element->case_sensitive = case_sensitive; + if (glob_list == NULL) + return new_element; + + tmp_element = glob_list; + while (tmp_element->next != NULL) + tmp_element = tmp_element->next; + + tmp_element->next = new_element; + + return glob_list; +} + +/* XdgGlobHashNode + */ + +static XdgGlobHashNode * +_xdg_glob_hash_node_new (void) +{ + XdgGlobHashNode *glob_hash_node; + + glob_hash_node = calloc (1, sizeof (XdgGlobHashNode)); + + return glob_hash_node; +} + +static void +_xdg_glob_hash_node_dump (XdgGlobHashNode *glob_hash_node, + int depth) +{ + int i; + for (i = 0; i < depth; i++) + printf (" "); + + printf ("%c", (char)glob_hash_node->character); + if (glob_hash_node->mime_type) + printf (" - %s %d\n", glob_hash_node->mime_type, glob_hash_node->weight); + else + printf ("\n"); + if (glob_hash_node->child) + _xdg_glob_hash_node_dump (glob_hash_node->child, depth + 1); + if (glob_hash_node->next) + _xdg_glob_hash_node_dump (glob_hash_node->next, depth); +} + +static XdgGlobHashNode * +_xdg_glob_hash_insert_ucs4 (XdgGlobHashNode *glob_hash_node, + xdg_unichar_t *text, + const char *mime_type, + int weight, + int case_sensitive) +{ + XdgGlobHashNode *node; + xdg_unichar_t character; + + character = text[0]; + + if ((glob_hash_node == NULL) || + (character < glob_hash_node->character)) + { + node = _xdg_glob_hash_node_new (); + node->character = character; + node->next = glob_hash_node; + glob_hash_node = node; + } + else if (character == glob_hash_node->character) + { + node = glob_hash_node; + } + else + { + XdgGlobHashNode *prev_node; + int found_node = FALSE; + + /* Look for the first character of text in glob_hash_node, and insert it if we + * have to.*/ + prev_node = glob_hash_node; + node = prev_node->next; + + while (node != NULL) + { + if (character < node->character) + { + node = _xdg_glob_hash_node_new (); + node->character = character; + node->next = prev_node->next; + prev_node->next = node; + + found_node = TRUE; + break; + } + else if (character == node->character) + { + found_node = TRUE; + break; + } + prev_node = node; + node = node->next; + } + + if (! found_node) + { + node = _xdg_glob_hash_node_new (); + node->character = character; + node->next = prev_node->next; + prev_node->next = node; + } + } + + text++; + if (*text == 0) + { + if (node->mime_type) + { + if (strcmp (node->mime_type, mime_type) != 0) + { + XdgGlobHashNode *child; + int found_node = FALSE; + + child = node->child; + while (child && child->character == 0) + { + if (strcmp (child->mime_type, mime_type) == 0) + { + found_node = TRUE; + break; + } + child = child->next; + } + + if (!found_node) + { + child = _xdg_glob_hash_node_new (); + child->character = 0; + child->mime_type = strdup (mime_type); + child->weight = weight; + child->case_sensitive = case_sensitive; + child->child = NULL; + child->next = node->child; + node->child = child; + } + } + } + else + { + node->mime_type = strdup (mime_type); + node->weight = weight; + node->case_sensitive = case_sensitive; + } + } + else + { + node->child = _xdg_glob_hash_insert_ucs4 (node->child, text, mime_type, weight, case_sensitive); + } + return glob_hash_node; +} + +/* glob must be valid UTF-8 */ +static XdgGlobHashNode * +_xdg_glob_hash_insert_text (XdgGlobHashNode *glob_hash_node, + const char *text, + const char *mime_type, + int weight, + int case_sensitive) +{ + XdgGlobHashNode *node; + xdg_unichar_t *unitext; + int len; + + unitext = _xdg_convert_to_ucs4 (text, &len); + _xdg_reverse_ucs4 (unitext, len); + node = _xdg_glob_hash_insert_ucs4 (glob_hash_node, unitext, mime_type, weight, case_sensitive); + free (unitext); + return node; +} + +typedef struct { + const char *mime; + int weight; +} MimeWeight; + +static int +_xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node, + const char *file_name, + int len, + int case_sensitive_check, + MimeWeight mime_types[], + int n_mime_types) +{ + int n; + XdgGlobHashNode *node; + xdg_unichar_t character; + + if (glob_hash_node == NULL) + return 0; + + character = file_name[len - 1]; + + for (node = glob_hash_node; node && character >= node->character; node = node->next) + { + if (character == node->character) + { + len--; + n = 0; + if (len > 0) + { + n = _xdg_glob_hash_node_lookup_file_name (node->child, + file_name, + len, + case_sensitive_check, + mime_types, + n_mime_types); + } + if (n == 0) + { + if (node->mime_type && + (case_sensitive_check || + !node->case_sensitive)) + { + mime_types[n].mime = node->mime_type; + mime_types[n].weight = node->weight; + n++; + } + node = node->child; + while (n < n_mime_types && node && node->character == 0) + { + if (node->mime_type && + (case_sensitive_check || + !node->case_sensitive)) + { + mime_types[n].mime = node->mime_type; + mime_types[n].weight = node->weight; + n++; + } + node = node->next; + } + } + return n; + } + } + + return 0; +} + +static int compare_mime_weight (const void *a, const void *b) +{ + const MimeWeight *aa = (const MimeWeight *)a; + const MimeWeight *bb = (const MimeWeight *)b; + + return bb->weight - aa->weight; +} + +#define ISUPPER(c) ((c) >= 'A' && (c) <= 'Z') +static char * +ascii_tolower (const char *str) +{ + char *p, *lower; + + lower = strdup (str); + p = lower; + while (*p != 0) + { + char c = *p; + *p++ = ISUPPER (c) ? c - 'A' + 'a' : c; + } + return lower; +} + +int +_xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash, + const char *file_name, + const char *mime_types[], + int n_mime_types) +{ + XdgGlobList *list; + int i, n; + MimeWeight mimes[10]; + int n_mimes = 10; + int len; + char *lower_case; + + /* First, check the literals */ + + assert (file_name != NULL && n_mime_types > 0); + + n = 0; + + lower_case = ascii_tolower (file_name); + + for (list = glob_hash->literal_list; list; list = list->next) + { + if (strcmp ((const char *)list->data, file_name) == 0) + { + mime_types[0] = list->mime_type; + free (lower_case); + return 1; + } + } + + for (list = glob_hash->literal_list; list; list = list->next) + { + if (!list->case_sensitive && + strcmp ((const char *)list->data, lower_case) == 0) + { + mime_types[0] = list->mime_type; + free (lower_case); + return 1; + } + } + + + len = strlen (file_name); + n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, lower_case, len, FALSE, + mimes, n_mimes); + if (n == 0) + n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, file_name, len, TRUE, + mimes, n_mimes); + + if (n == 0) + { + for (list = glob_hash->full_list; list && n < n_mime_types; list = list->next) + { + if (fnmatch ((const char *)list->data, file_name, 0) == 0) + { + mimes[n].mime = list->mime_type; + mimes[n].weight = list->weight; + n++; + } + } + } + free (lower_case); + + qsort (mimes, n, sizeof (MimeWeight), compare_mime_weight); + + if (n_mime_types < n) + n = n_mime_types; + + for (i = 0; i < n; i++) + mime_types[i] = mimes[i].mime; + + return n; +} + + + +/* XdgGlobHash + */ + +XdgGlobHash * +_xdg_glob_hash_new (void) +{ + XdgGlobHash *glob_hash; + + glob_hash = calloc (1, sizeof (XdgGlobHash)); + + return glob_hash; +} + + +static void +_xdg_glob_hash_free_nodes (XdgGlobHashNode *node) +{ + if (node) + { + if (node->child) + _xdg_glob_hash_free_nodes (node->child); + if (node->next) + _xdg_glob_hash_free_nodes (node->next); + if (node->mime_type) + free ((void *) node->mime_type); + free (node); + } +} + +void +_xdg_glob_hash_free (XdgGlobHash *glob_hash) +{ + _xdg_glob_list_free (glob_hash->literal_list); + _xdg_glob_list_free (glob_hash->full_list); + _xdg_glob_hash_free_nodes (glob_hash->simple_node); + free (glob_hash); +} + +XdgGlobType +_xdg_glob_determine_type (const char *glob) +{ + const char *ptr; + int maybe_in_simple_glob = FALSE; + int first_char = TRUE; + + ptr = glob; + + while (*ptr != '\0') + { + if (*ptr == '*' && first_char) + maybe_in_simple_glob = TRUE; + else if (*ptr == '\\' || *ptr == '[' || *ptr == '?' || *ptr == '*') + return XDG_GLOB_FULL; + + first_char = FALSE; + ptr = _xdg_utf8_next_char (ptr); + } + if (maybe_in_simple_glob) + return XDG_GLOB_SIMPLE; + else + return XDG_GLOB_LITERAL; +} + +/* glob must be valid UTF-8 */ +void +_xdg_glob_hash_append_glob (XdgGlobHash *glob_hash, + const char *glob, + const char *mime_type, + int weight, + int case_sensitive) +{ + XdgGlobType type; + + assert (glob_hash != NULL); + assert (glob != NULL); + + type = _xdg_glob_determine_type (glob); + + switch (type) + { + case XDG_GLOB_LITERAL: + glob_hash->literal_list = _xdg_glob_list_append (glob_hash->literal_list, strdup (glob), strdup (mime_type), weight, case_sensitive); + break; + case XDG_GLOB_SIMPLE: + glob_hash->simple_node = _xdg_glob_hash_insert_text (glob_hash->simple_node, glob + 1, mime_type, weight, case_sensitive); + break; + case XDG_GLOB_FULL: + glob_hash->full_list = _xdg_glob_list_append (glob_hash->full_list, strdup (glob), strdup (mime_type), weight, case_sensitive); + break; + } +} + +void +_xdg_glob_hash_dump (XdgGlobHash *glob_hash) +{ + XdgGlobList *list; + printf ("LITERAL STRINGS\n"); + if (!glob_hash || glob_hash->literal_list == NULL) + { + printf (" None\n"); + } + else + { + for (list = glob_hash->literal_list; list; list = list->next) + printf (" %s - %s %d\n", (char *)list->data, list->mime_type, list->weight); + } + printf ("\nSIMPLE GLOBS\n"); + if (!glob_hash || glob_hash->simple_node == NULL) + { + printf (" None\n"); + } + else + { + _xdg_glob_hash_node_dump (glob_hash->simple_node, 4); + } + + printf ("\nFULL GLOBS\n"); + if (!glob_hash || glob_hash->full_list == NULL) + { + printf (" None\n"); + } + else + { + for (list = glob_hash->full_list; list; list = list->next) + printf (" %s - %s %d\n", (char *)list->data, list->mime_type, list->weight); + } +} + + +void +_xdg_mime_glob_read_from_file (XdgGlobHash *glob_hash, + const char *file_name, + int version_two) +{ + FILE *glob_file; + char line[255]; + char *p; + + glob_file = fopen (file_name, "r"); + + if (glob_file == NULL) + return; + + /* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars. + * Blah */ + while (fgets (line, 255, glob_file) != NULL) + { + char *colon; + char *mimetype, *glob, *end; + int weight; + int case_sensitive; + + if (line[0] == '#' || line[0] == 0) + continue; + + end = line + strlen(line) - 1; + if (*end == '\n') + *end = 0; + + p = line; + if (version_two) + { + colon = strchr (p, ':'); + if (colon == NULL) + continue; + *colon = 0; + weight = atoi (p); + p = colon + 1; + } + else + weight = 50; + + colon = strchr (p, ':'); + if (colon == NULL) + continue; + *colon = 0; + + mimetype = p; + p = colon + 1; + glob = p; + case_sensitive = FALSE; + + colon = strchr (p, ':'); + if (version_two && colon != NULL) + { + char *flag; + + /* We got flags */ + *colon = 0; + p = colon + 1; + + /* Flags end at next colon */ + colon = strchr (p, ':'); + if (colon != NULL) + *colon = 0; + + flag = strstr (p, "cs"); + if (flag != NULL && + /* Start or after comma */ + (flag == p || + flag[-1] == ',') && + /* ends with comma or end of string */ + (flag[2] == 0 || + flag[2] == ',')) + case_sensitive = TRUE; + } + + _xdg_glob_hash_append_glob (glob_hash, glob, mimetype, weight, case_sensitive); + } + + fclose (glob_file); +} diff --git a/Xdgmime/xdgmimeglob.h b/Xdgmime/xdgmimeglob.h new file mode 100644 index 0000000..0018292 --- /dev/null +++ b/Xdgmime/xdgmimeglob.h @@ -0,0 +1,70 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimeglob.h: Private file. Datastructure for storing the globs. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2003 Red Hat, Inc. + * Copyright (C) 2003 Jonathan Blandford + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __XDG_MIME_GLOB_H__ +#define __XDG_MIME_GLOB_H__ + +#include "xdgmime.h" + +typedef struct XdgGlobHash XdgGlobHash; + +typedef enum +{ + XDG_GLOB_LITERAL, /* Makefile */ + XDG_GLOB_SIMPLE, /* *.gif */ + XDG_GLOB_FULL /* x*.[ch] */ +} XdgGlobType; + + +#ifdef XDG_PREFIX +#define _xdg_mime_glob_read_from_file XDG_RESERVED_ENTRY(glob_read_from_file) +#define _xdg_glob_hash_new XDG_RESERVED_ENTRY(hash_new) +#define _xdg_glob_hash_free XDG_RESERVED_ENTRY(hash_free) +#define _xdg_glob_hash_lookup_file_name XDG_RESERVED_ENTRY(hash_lookup_file_name) +#define _xdg_glob_hash_append_glob XDG_RESERVED_ENTRY(hash_append_glob) +#define _xdg_glob_determine_type XDG_RESERVED_ENTRY(determine_type) +#define _xdg_glob_hash_dump XDG_RESERVED_ENTRY(hash_dump) +#endif + +void _xdg_mime_glob_read_from_file (XdgGlobHash *glob_hash, + const char *file_name, + int version_two); +XdgGlobHash *_xdg_glob_hash_new (void); +void _xdg_glob_hash_free (XdgGlobHash *glob_hash); +int _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash, + const char *text, + const char *mime_types[], + int n_mime_types); +void _xdg_glob_hash_append_glob (XdgGlobHash *glob_hash, + const char *glob, + const char *mime_type, + int weight, + int case_sensitive); +XdgGlobType _xdg_glob_determine_type (const char *glob); +void _xdg_glob_hash_dump (XdgGlobHash *glob_hash); + +#endif /* __XDG_MIME_GLOB_H__ */ diff --git a/Xdgmime/xdgmimeicon.c b/Xdgmime/xdgmimeicon.c new file mode 100644 index 0000000..05c9473 --- /dev/null +++ b/Xdgmime/xdgmimeicon.c @@ -0,0 +1,183 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimeicon.c: Private file. Datastructure for storing the aliases. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2008 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "xdgmimeicon.h" +#include "xdgmimeint.h" +#include +#include +#include +#include +#include + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +typedef struct XdgIcon XdgIcon; + +struct XdgIcon +{ + char *mime_type; + char *icon_name; +}; + +struct XdgIconList +{ + struct XdgIcon *icons; + int n_icons; +}; + +XdgIconList * +_xdg_mime_icon_list_new (void) +{ + XdgIconList *list; + + list = malloc (sizeof (XdgIconList)); + + list->icons = NULL; + list->n_icons = 0; + + return list; +} + +void +_xdg_mime_icon_list_free (XdgIconList *list) +{ + int i; + + if (list->icons) + { + for (i = 0; i < list->n_icons; i++) + { + free (list->icons[i].mime_type); + free (list->icons[i].icon_name); + } + free (list->icons); + } + free (list); +} + +static int +icon_entry_cmp (const void *v1, const void *v2) +{ + return strcmp (((XdgIcon *)v1)->mime_type, ((XdgIcon *)v2)->mime_type); +} + +const char * +_xdg_mime_icon_list_lookup (XdgIconList *list, + const char *mime_type) +{ + XdgIcon *entry; + XdgIcon key; + + if (list->n_icons > 0) + { + key.mime_type = (char *)mime_type; + key.icon_name = NULL; + + entry = bsearch (&key, list->icons, list->n_icons, + sizeof (XdgIcon), icon_entry_cmp); + if (entry) + return entry->icon_name; + } + + return NULL; +} + +void +_xdg_mime_icon_read_from_file (XdgIconList *list, + const char *file_name) +{ + FILE *file; + char line[255]; + int alloc; + + file = fopen (file_name, "r"); + + if (file == NULL) + return; + + /* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars. + * Blah */ + alloc = list->n_icons + 16; + list->icons = realloc (list->icons, alloc * sizeof (XdgIcon)); + while (fgets (line, 255, file) != NULL) + { + char *sep; + if (line[0] == '#') + continue; + + sep = strchr (line, ':'); + if (sep == NULL) + continue; + *(sep++) = '\000'; + sep[strlen (sep) -1] = '\000'; + if (list->n_icons == alloc) + { + alloc <<= 1; + list->icons = realloc (list->icons, + alloc * sizeof (XdgIcon)); + } + list->icons[list->n_icons].mime_type = strdup (line); + list->icons[list->n_icons].icon_name = strdup (sep); + list->n_icons++; + } + list->icons = realloc (list->icons, + list->n_icons * sizeof (XdgIcon)); + + fclose (file); + + if (list->n_icons > 1) + qsort (list->icons, list->n_icons, + sizeof (XdgIcon), icon_entry_cmp); +} + + +void +_xdg_mime_icon_list_dump (XdgIconList *list) +{ + int i; + + if (list->icons) + { + for (i = 0; i < list->n_icons; i++) + { + printf ("%s %s\n", + list->icons[i].mime_type, + list->icons[i].icon_name); + } + } +} + + diff --git a/Xdgmime/xdgmimeicon.h b/Xdgmime/xdgmimeicon.h new file mode 100644 index 0000000..b5f2583 --- /dev/null +++ b/Xdgmime/xdgmimeicon.h @@ -0,0 +1,50 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimeicon.h: Private file. Datastructure for storing the aliases. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2008 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __XDG_MIME_ICON_H__ +#define __XDG_MIME_ICON_H__ + +#include "xdgmime.h" + +typedef struct XdgIconList XdgIconList; + +#ifdef XDG_PREFIX +#define _xdg_mime_icon_read_from_file XDG_ENTRY(icon_read_from_file) +#define _xdg_mime_icon_list_new XDG_ENTRY(icon_list_new) +#define _xdg_mime_icon_list_free XDG_ENTRY(icon_list_free) +#define _xdg_mime_icon_list_lookup XDG_ENTRY(icon_list_lookup) +#define _xdg_mime_icon_list_dump XDG_ENTRY(icon_list_dump) +#endif + +void _xdg_mime_icon_read_from_file (XdgIconList *list, + const char *file_name); +XdgIconList *_xdg_mime_icon_list_new (void); +void _xdg_mime_icon_list_free (XdgIconList *list); +const char *_xdg_mime_icon_list_lookup (XdgIconList *list, + const char *mime); +void _xdg_mime_icon_list_dump (XdgIconList *list); + +#endif /* __XDG_MIME_ICON_H__ */ diff --git a/Xdgmime/xdgmimeint.c b/Xdgmime/xdgmimeint.c new file mode 100644 index 0000000..cf789d9 --- /dev/null +++ b/Xdgmime/xdgmimeint.c @@ -0,0 +1,206 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimeint.c: Internal defines and functions. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2003 Red Hat, Inc. + * Copyright (C) 2003 Jonathan Blandford + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "xdgmimeint.h" +#include +#include + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +static const char _xdg_utf8_skip_data[256] = { + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1 +}; + +const char * const _xdg_utf8_skip = _xdg_utf8_skip_data; + + + +/* Returns the number of unprocessed characters. */ +xdg_unichar_t +_xdg_utf8_to_ucs4(const char *source) +{ + xdg_unichar_t ucs32; + if( ! ( *source & 0x80 ) ) + { + ucs32 = *source; + } + else + { + int bytelength = 0; + xdg_unichar_t result; + if ( ! (*source & 0x40) ) + { + ucs32 = *source; + } + else + { + if ( ! (*source & 0x20) ) + { + result = *source++ & 0x1F; + bytelength = 2; + } + else if ( ! (*source & 0x10) ) + { + result = *source++ & 0x0F; + bytelength = 3; + } + else if ( ! (*source & 0x08) ) + { + result = *source++ & 0x07; + bytelength = 4; + } + else if ( ! (*source & 0x04) ) + { + result = *source++ & 0x03; + bytelength = 5; + } + else if ( ! (*source & 0x02) ) + { + result = *source++ & 0x01; + bytelength = 6; + } + else + { + result = *source++; + bytelength = 1; + } + + for ( bytelength --; bytelength > 0; bytelength -- ) + { + result <<= 6; + result |= *source++ & 0x3F; + } + ucs32 = result; + } + } + return ucs32; +} + + +/* hullo. this is great code. don't rewrite it */ + +xdg_unichar_t +_xdg_ucs4_to_lower (xdg_unichar_t source) +{ + /* FIXME: Do a real to_upper sometime */ + /* CaseFolding-3.2.0.txt has a table of rules. */ + if ((source & 0xFF) == source) + return (xdg_unichar_t) tolower ((unsigned char) source); + return source; +} + +int +_xdg_utf8_validate (const char *source) +{ + /* FIXME: actually write */ + return TRUE; +} + +const char * +_xdg_get_base_name (const char *file_name) +{ + const char *base_name; + + if (file_name == NULL) + return NULL; + + base_name = strrchr (file_name, '/'); + + if (base_name == NULL) + return file_name; + else + return base_name + 1; +} + +xdg_unichar_t * +_xdg_convert_to_ucs4 (const char *source, int *len) +{ + xdg_unichar_t *out; + int i; + const char *p; + + out = malloc (sizeof (xdg_unichar_t) * (strlen (source) + 1)); + + p = source; + i = 0; + while (*p) + { + out[i++] = _xdg_utf8_to_ucs4 (p); + p = _xdg_utf8_next_char (p); + } + out[i] = 0; + *len = i; + + return out; +} + +void +_xdg_reverse_ucs4 (xdg_unichar_t *source, int len) +{ + xdg_unichar_t c; + int i; + + for (i = 0; i < len - i - 1; i++) + { + c = source[i]; + source[i] = source[len - i - 1]; + source[len - i - 1] = c; + } +} + +const char * +_xdg_binary_or_text_fallback(const void *data, size_t len) +{ + unsigned char *chardata; + int i; + + chardata = (unsigned char *) data; + for (i = 0; i < 32 && i < len; ++i) + { + if (chardata[i] < 32 && chardata[i] != 9 && chardata[i] != 10 && chardata[i] != 13) + return XDG_MIME_TYPE_UNKNOWN; /* binary data */ + } + + return XDG_MIME_TYPE_TEXTPLAIN; +} diff --git a/Xdgmime/xdgmimeint.h b/Xdgmime/xdgmimeint.h new file mode 100644 index 0000000..9e8b2cb --- /dev/null +++ b/Xdgmime/xdgmimeint.h @@ -0,0 +1,78 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimeint.h: Internal defines and functions. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2003 Red Hat, Inc. + * Copyright (C) 2003 Jonathan Blandford + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __XDG_MIME_INT_H__ +#define __XDG_MIME_INT_H__ + +#include "xdgmime.h" + + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +/* FIXME: Needs to be configure check */ +typedef unsigned int xdg_unichar_t; +typedef unsigned char xdg_uchar8_t; +typedef unsigned short xdg_uint16_t; +typedef unsigned int xdg_uint32_t; + +#ifdef XDG_PREFIX +#define _xdg_utf8_skip XDG_RESERVED_ENTRY(utf8_skip) +#define _xdg_utf8_to_ucs4 XDG_RESERVED_ENTRY(utf8_to_ucs4) +#define _xdg_ucs4_to_lower XDG_RESERVED_ENTRY(ucs4_to_lower) +#define _xdg_utf8_validate XDG_RESERVED_ENTRY(utf8_validate) +#define _xdg_get_base_name XDG_RESERVED_ENTRY(get_base_name) +#define _xdg_convert_to_ucs4 XDG_RESERVED_ENTRY(convert_to_ucs4) +#define _xdg_reverse_ucs4 XDG_RESERVED_ENTRY(reverse_ucs4) +#endif + +#define SWAP_BE16_TO_LE16(val) (xdg_uint16_t)(((xdg_uint16_t)(val) << 8)|((xdg_uint16_t)(val) >> 8)) + +#define SWAP_BE32_TO_LE32(val) (xdg_uint32_t)((((xdg_uint32_t)(val) & 0xFF000000U) >> 24) | \ + (((xdg_uint32_t)(val) & 0x00FF0000U) >> 8) | \ + (((xdg_uint32_t)(val) & 0x0000FF00U) << 8) | \ + (((xdg_uint32_t)(val) & 0x000000FFU) << 24)) +/* UTF-8 utils + */ +extern const char *const _xdg_utf8_skip; +#define _xdg_utf8_next_char(p) (char *)((p) + _xdg_utf8_skip[*(unsigned char *)(p)]) +#define _xdg_utf8_char_size(p) (int) (_xdg_utf8_skip[*(unsigned char *)(p)]) + +xdg_unichar_t _xdg_utf8_to_ucs4 (const char *source); +xdg_unichar_t _xdg_ucs4_to_lower (xdg_unichar_t source); +int _xdg_utf8_validate (const char *source); +xdg_unichar_t *_xdg_convert_to_ucs4 (const char *source, int *len); +void _xdg_reverse_ucs4 (xdg_unichar_t *source, int len); +const char *_xdg_get_base_name (const char *file_name); +const char *_xdg_binary_or_text_fallback(const void *data, size_t len); + +#endif /* __XDG_MIME_INT_H__ */ diff --git a/Xdgmime/xdgmimemagic.c b/Xdgmime/xdgmimemagic.c new file mode 100644 index 0000000..a2320f5 --- /dev/null +++ b/Xdgmime/xdgmimemagic.c @@ -0,0 +1,813 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimemagic.: Private file. Datastructure for storing magic files. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2003 Red Hat, Inc. + * Copyright (C) 2003 Jonathan Blandford + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include "xdgmimemagic.h" +#include "xdgmimeint.h" +#include +#include +#include +#include +#include +#include + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +#if !defined getc_unlocked && !defined HAVE_GETC_UNLOCKED +# define getc_unlocked(fp) getc (fp) +#endif + +typedef struct XdgMimeMagicMatch XdgMimeMagicMatch; +typedef struct XdgMimeMagicMatchlet XdgMimeMagicMatchlet; + +typedef enum +{ + XDG_MIME_MAGIC_SECTION, + XDG_MIME_MAGIC_MAGIC, + XDG_MIME_MAGIC_ERROR, + XDG_MIME_MAGIC_EOF +} XdgMimeMagicState; + +struct XdgMimeMagicMatch +{ + const char *mime_type; + int priority; + XdgMimeMagicMatchlet *matchlet; + XdgMimeMagicMatch *next; +}; + + +struct XdgMimeMagicMatchlet +{ + int indent; + int offset; + unsigned int value_length; + unsigned char *value; + unsigned char *mask; + unsigned int range_length; + unsigned int word_size; + XdgMimeMagicMatchlet *next; +}; + + +struct XdgMimeMagic +{ + XdgMimeMagicMatch *match_list; + int max_extent; +}; + +static XdgMimeMagicMatch * +_xdg_mime_magic_match_new (void) +{ + return calloc (1, sizeof (XdgMimeMagicMatch)); +} + + +static XdgMimeMagicMatchlet * +_xdg_mime_magic_matchlet_new (void) +{ + XdgMimeMagicMatchlet *matchlet; + + matchlet = malloc (sizeof (XdgMimeMagicMatchlet)); + + matchlet->indent = 0; + matchlet->offset = 0; + matchlet->value_length = 0; + matchlet->value = NULL; + matchlet->mask = NULL; + matchlet->range_length = 1; + matchlet->word_size = 1; + matchlet->next = NULL; + + return matchlet; +} + + +static void +_xdg_mime_magic_matchlet_free (XdgMimeMagicMatchlet *mime_magic_matchlet) +{ + if (mime_magic_matchlet) + { + if (mime_magic_matchlet->next) + _xdg_mime_magic_matchlet_free (mime_magic_matchlet->next); + if (mime_magic_matchlet->value) + free (mime_magic_matchlet->value); + if (mime_magic_matchlet->mask) + free (mime_magic_matchlet->mask); + free (mime_magic_matchlet); + } +} + + +/* Frees mime_magic_match and the remainder of its list + */ +static void +_xdg_mime_magic_match_free (XdgMimeMagicMatch *mime_magic_match) +{ + XdgMimeMagicMatch *ptr, *next; + + ptr = mime_magic_match; + while (ptr) + { + next = ptr->next; + + if (ptr->mime_type) + free ((void *) ptr->mime_type); + if (ptr->matchlet) + _xdg_mime_magic_matchlet_free (ptr->matchlet); + free (ptr); + + ptr = next; + } +} + +/* Reads in a hunk of data until a newline character or a '\000' is hit. The + * returned string is null terminated, and doesn't include the newline. + */ +static unsigned char * +_xdg_mime_magic_read_to_newline (FILE *magic_file, + int *end_of_file) +{ + unsigned char *retval; + int c; + int len, pos; + + len = 128; + pos = 0; + retval = malloc (len); + *end_of_file = FALSE; + + while (TRUE) + { + c = getc_unlocked (magic_file); + if (c == EOF) + { + *end_of_file = TRUE; + break; + } + if (c == '\n' || c == '\000') + break; + retval[pos++] = (unsigned char) c; + if (pos % 128 == 127) + { + len = len + 128; + retval = realloc (retval, len); + } + } + + retval[pos] = '\000'; + return retval; +} + +/* Returns the number read from the file, or -1 if no number could be read. + */ +static int +_xdg_mime_magic_read_a_number (FILE *magic_file, + int *end_of_file) +{ + /* LONG_MAX is about 20 characters on my system */ +#define MAX_NUMBER_SIZE 30 + char number_string[MAX_NUMBER_SIZE + 1]; + int pos = 0; + int c; + long retval = -1; + + while (TRUE) + { + c = getc_unlocked (magic_file); + + if (c == EOF) + { + *end_of_file = TRUE; + break; + } + if (! isdigit (c)) + { + ungetc (c, magic_file); + break; + } + number_string[pos] = (char) c; + pos++; + if (pos == MAX_NUMBER_SIZE) + break; + } + if (pos > 0) + { + number_string[pos] = '\000'; + errno = 0; + retval = strtol (number_string, NULL, 10); + + if ((retval < INT_MIN) || (retval > INT_MAX) || (errno != 0)) + return -1; + } + + return retval; +} + +/* Headers are of the format: + * [:] + */ +static XdgMimeMagicState +_xdg_mime_magic_parse_header (FILE *magic_file, XdgMimeMagicMatch *match) +{ + int c; + char *buffer; + char *end_ptr; + int end_of_file = 0; + + assert (magic_file != NULL); + assert (match != NULL); + + c = getc_unlocked (magic_file); + if (c == EOF) + return XDG_MIME_MAGIC_EOF; + if (c != '[') + return XDG_MIME_MAGIC_ERROR; + + match->priority = _xdg_mime_magic_read_a_number (magic_file, &end_of_file); + if (end_of_file) + return XDG_MIME_MAGIC_EOF; + if (match->priority == -1) + return XDG_MIME_MAGIC_ERROR; + + c = getc_unlocked (magic_file); + if (c == EOF) + return XDG_MIME_MAGIC_EOF; + if (c != ':') + return XDG_MIME_MAGIC_ERROR; + + buffer = (char *)_xdg_mime_magic_read_to_newline (magic_file, &end_of_file); + if (end_of_file) + return XDG_MIME_MAGIC_EOF; + + end_ptr = buffer; + while (*end_ptr != ']' && *end_ptr != '\000' && *end_ptr != '\n') + end_ptr++; + if (*end_ptr != ']') + { + free (buffer); + return XDG_MIME_MAGIC_ERROR; + } + *end_ptr = '\000'; + + match->mime_type = strdup (buffer); + free (buffer); + + return XDG_MIME_MAGIC_MAGIC; +} + +static XdgMimeMagicState +_xdg_mime_magic_parse_error (FILE *magic_file) +{ + int c; + + while (1) + { + c = getc_unlocked (magic_file); + if (c == EOF) + return XDG_MIME_MAGIC_EOF; + if (c == '\n') + return XDG_MIME_MAGIC_SECTION; + } +} + +/* Headers are of the format: + * [ indent ] ">" start-offset "=" value + * [ "&" mask ] [ "~" word-size ] [ "+" range-length ] "\n" + */ +static XdgMimeMagicState +_xdg_mime_magic_parse_magic_line (FILE *magic_file, + XdgMimeMagicMatch *match) +{ + XdgMimeMagicMatchlet *matchlet; + int c; + int end_of_file; + int indent = 0; + int bytes_read; + + assert (magic_file != NULL); + + /* Sniff the buffer to make sure it's a valid line */ + c = getc_unlocked (magic_file); + if (c == EOF) + return XDG_MIME_MAGIC_EOF; + else if (c == '[') + { + ungetc (c, magic_file); + return XDG_MIME_MAGIC_SECTION; + } + else if (c == '\n') + return XDG_MIME_MAGIC_MAGIC; + + /* At this point, it must be a digit or a '>' */ + end_of_file = FALSE; + if (isdigit (c)) + { + ungetc (c, magic_file); + indent = _xdg_mime_magic_read_a_number (magic_file, &end_of_file); + if (end_of_file) + return XDG_MIME_MAGIC_EOF; + if (indent == -1) + return XDG_MIME_MAGIC_ERROR; + c = getc_unlocked (magic_file); + if (c == EOF) + return XDG_MIME_MAGIC_EOF; + } + + if (c != '>') + return XDG_MIME_MAGIC_ERROR; + + matchlet = _xdg_mime_magic_matchlet_new (); + matchlet->indent = indent; + matchlet->offset = _xdg_mime_magic_read_a_number (magic_file, &end_of_file); + if (end_of_file) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_EOF; + } + if (matchlet->offset == -1) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_ERROR; + } + c = getc_unlocked (magic_file); + if (c == EOF) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_EOF; + } + else if (c != '=') + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_ERROR; + } + + /* Next two bytes determine how long the value is */ + matchlet->value_length = 0; + c = getc_unlocked (magic_file); + if (c == EOF) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_EOF; + } + matchlet->value_length = c & 0xFF; + matchlet->value_length = matchlet->value_length << 8; + + c = getc_unlocked (magic_file); + if (c == EOF) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_EOF; + } + matchlet->value_length = matchlet->value_length + (c & 0xFF); + + matchlet->value = malloc (matchlet->value_length); + + /* OOM */ + if (matchlet->value == NULL) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_ERROR; + } + bytes_read = fread (matchlet->value, 1, matchlet->value_length, magic_file); + if (bytes_read != matchlet->value_length) + { + _xdg_mime_magic_matchlet_free (matchlet); + if (feof (magic_file)) + return XDG_MIME_MAGIC_EOF; + else + return XDG_MIME_MAGIC_ERROR; + } + + c = getc_unlocked (magic_file); + if (c == '&') + { + matchlet->mask = malloc (matchlet->value_length); + /* OOM */ + if (matchlet->mask == NULL) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_ERROR; + } + bytes_read = fread (matchlet->mask, 1, matchlet->value_length, magic_file); + if (bytes_read != matchlet->value_length) + { + _xdg_mime_magic_matchlet_free (matchlet); + if (feof (magic_file)) + return XDG_MIME_MAGIC_EOF; + else + return XDG_MIME_MAGIC_ERROR; + } + c = getc_unlocked (magic_file); + } + + if (c == '~') + { + matchlet->word_size = _xdg_mime_magic_read_a_number (magic_file, &end_of_file); + if (end_of_file) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_EOF; + } + if (matchlet->word_size != 0 && + matchlet->word_size != 1 && + matchlet->word_size != 2 && + matchlet->word_size != 4) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_ERROR; + } + c = getc_unlocked (magic_file); + } + + if (c == '+') + { + matchlet->range_length = _xdg_mime_magic_read_a_number (magic_file, &end_of_file); + if (end_of_file) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_EOF; + } + if (matchlet->range_length == -1) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_ERROR; + } + c = getc_unlocked (magic_file); + } + + + if (c == '\n') + { + /* We clean up the matchlet, byte swapping if needed */ + if (matchlet->word_size > 1) + { + int i; + if (matchlet->value_length % matchlet->word_size != 0) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_ERROR; + } + /* FIXME: need to get this defined in a style file */ +#if LITTLE_ENDIAN + for (i = 0; i < matchlet->value_length; i = i + matchlet->word_size) + { + if (matchlet->word_size == 2) + *((xdg_uint16_t *) matchlet->value + i) = SWAP_BE16_TO_LE16 (*((xdg_uint16_t *) (matchlet->value + i))); + else if (matchlet->word_size == 4) + *((xdg_uint32_t *) matchlet->value + i) = SWAP_BE32_TO_LE32 (*((xdg_uint32_t *) (matchlet->value + i))); + if (matchlet->mask) + { + if (matchlet->word_size == 2) + *((xdg_uint16_t *) matchlet->mask + i) = SWAP_BE16_TO_LE16 (*((xdg_uint16_t *) (matchlet->mask + i))); + else if (matchlet->word_size == 4) + *((xdg_uint32_t *) matchlet->mask + i) = SWAP_BE32_TO_LE32 (*((xdg_uint32_t *) (matchlet->mask + i))); + + } + } +#endif + } + + matchlet->next = match->matchlet; + match->matchlet = matchlet; + + + return XDG_MIME_MAGIC_MAGIC; + } + + _xdg_mime_magic_matchlet_free (matchlet); + if (c == EOF) + return XDG_MIME_MAGIC_EOF; + + return XDG_MIME_MAGIC_ERROR; +} + +static int +_xdg_mime_magic_matchlet_compare_to_data (XdgMimeMagicMatchlet *matchlet, + const void *data, + size_t len) +{ + int i, j; + for (i = matchlet->offset; i < matchlet->offset + matchlet->range_length; i++) + { + int valid_matchlet = TRUE; + + if (i + matchlet->value_length > len) + return FALSE; + + if (matchlet->mask) + { + for (j = 0; j < matchlet->value_length; j++) + { + if ((matchlet->value[j] & matchlet->mask[j]) != + ((((unsigned char *) data)[j + i]) & matchlet->mask[j])) + { + valid_matchlet = FALSE; + break; + } + } + } + else + { + for (j = 0; j < matchlet->value_length; j++) + { + if (matchlet->value[j] != ((unsigned char *) data)[j + i]) + { + valid_matchlet = FALSE; + break; + } + } + } + if (valid_matchlet) + return TRUE; + } + return FALSE; +} + +static int +_xdg_mime_magic_matchlet_compare_level (XdgMimeMagicMatchlet *matchlet, + const void *data, + size_t len, + int indent) +{ + while ((matchlet != NULL) && (matchlet->indent == indent)) + { + if (_xdg_mime_magic_matchlet_compare_to_data (matchlet, data, len)) + { + if ((matchlet->next == NULL) || + (matchlet->next->indent <= indent)) + return TRUE; + + if (_xdg_mime_magic_matchlet_compare_level (matchlet->next, + data, + len, + indent + 1)) + return TRUE; + } + + do + { + matchlet = matchlet->next; + } + while (matchlet && matchlet->indent > indent); + } + + return FALSE; +} + +static int +_xdg_mime_magic_match_compare_to_data (XdgMimeMagicMatch *match, + const void *data, + size_t len) +{ + return _xdg_mime_magic_matchlet_compare_level (match->matchlet, data, len, 0); +} + +static void +_xdg_mime_magic_insert_match (XdgMimeMagic *mime_magic, + XdgMimeMagicMatch *match) +{ + XdgMimeMagicMatch *list; + + if (mime_magic->match_list == NULL) + { + mime_magic->match_list = match; + return; + } + + if (match->priority > mime_magic->match_list->priority) + { + match->next = mime_magic->match_list; + mime_magic->match_list = match; + return; + } + + list = mime_magic->match_list; + while (list->next != NULL) + { + if (list->next->priority < match->priority) + { + match->next = list->next; + list->next = match; + return; + } + list = list->next; + } + list->next = match; + match->next = NULL; +} + +XdgMimeMagic * +_xdg_mime_magic_new (void) +{ + return calloc (1, sizeof (XdgMimeMagic)); +} + +void +_xdg_mime_magic_free (XdgMimeMagic *mime_magic) +{ + if (mime_magic) { + _xdg_mime_magic_match_free (mime_magic->match_list); + free (mime_magic); + } +} + +int +_xdg_mime_magic_get_buffer_extents (XdgMimeMagic *mime_magic) +{ + return mime_magic->max_extent; +} + +const char * +_xdg_mime_magic_lookup_data (XdgMimeMagic *mime_magic, + const void *data, + size_t len, + int *result_prio, + const char *mime_types[], + int n_mime_types) +{ + XdgMimeMagicMatch *match; + const char *mime_type; + int n; + int prio; + + prio = 0; + mime_type = NULL; + for (match = mime_magic->match_list; match; match = match->next) + { + if (_xdg_mime_magic_match_compare_to_data (match, data, len)) + { + prio = match->priority; + mime_type = match->mime_type; + break; + } + else + { + for (n = 0; n < n_mime_types; n++) + { + if (mime_types[n] && + _xdg_mime_mime_type_equal (mime_types[n], match->mime_type)) + mime_types[n] = NULL; + } + } + } + + if (mime_type == NULL) + { + for (n = 0; n < n_mime_types; n++) + { + if (mime_types[n]) + mime_type = mime_types[n]; + } + } + + if (result_prio) + *result_prio = prio; + + return mime_type; +} + +static void +_xdg_mime_update_mime_magic_extents (XdgMimeMagic *mime_magic) +{ + XdgMimeMagicMatch *match; + int max_extent = 0; + + for (match = mime_magic->match_list; match; match = match->next) + { + XdgMimeMagicMatchlet *matchlet; + + for (matchlet = match->matchlet; matchlet; matchlet = matchlet->next) + { + int extent; + + extent = matchlet->value_length + matchlet->offset + matchlet->range_length; + if (max_extent < extent) + max_extent = extent; + } + } + + mime_magic->max_extent = max_extent; +} + +static XdgMimeMagicMatchlet * +_xdg_mime_magic_matchlet_mirror (XdgMimeMagicMatchlet *matchlets) +{ + XdgMimeMagicMatchlet *new_list; + XdgMimeMagicMatchlet *tmp; + + if ((matchlets == NULL) || (matchlets->next == NULL)) + return matchlets; + + new_list = NULL; + tmp = matchlets; + while (tmp != NULL) + { + XdgMimeMagicMatchlet *matchlet; + + matchlet = tmp; + tmp = tmp->next; + matchlet->next = new_list; + new_list = matchlet; + } + + return new_list; + +} + +static void +_xdg_mime_magic_read_magic_file (XdgMimeMagic *mime_magic, + FILE *magic_file) +{ + XdgMimeMagicState state; + XdgMimeMagicMatch *match = NULL; /* Quiet compiler */ + + state = XDG_MIME_MAGIC_SECTION; + + while (state != XDG_MIME_MAGIC_EOF) + { + switch (state) + { + case XDG_MIME_MAGIC_SECTION: + match = _xdg_mime_magic_match_new (); + state = _xdg_mime_magic_parse_header (magic_file, match); + if (state == XDG_MIME_MAGIC_EOF || state == XDG_MIME_MAGIC_ERROR) + _xdg_mime_magic_match_free (match); + break; + case XDG_MIME_MAGIC_MAGIC: + state = _xdg_mime_magic_parse_magic_line (magic_file, match); + if (state == XDG_MIME_MAGIC_SECTION || + (state == XDG_MIME_MAGIC_EOF && match->mime_type)) + { + match->matchlet = _xdg_mime_magic_matchlet_mirror (match->matchlet); + _xdg_mime_magic_insert_match (mime_magic, match); + } + else if (state == XDG_MIME_MAGIC_EOF || state == XDG_MIME_MAGIC_ERROR) + _xdg_mime_magic_match_free (match); + break; + case XDG_MIME_MAGIC_ERROR: + state = _xdg_mime_magic_parse_error (magic_file); + break; + case XDG_MIME_MAGIC_EOF: + default: + /* Make the compiler happy */ + assert (0); + } + } + _xdg_mime_update_mime_magic_extents (mime_magic); +} + +void +_xdg_mime_magic_read_from_file (XdgMimeMagic *mime_magic, + const char *file_name) +{ + FILE *magic_file; + char header[12]; + + magic_file = fopen (file_name, "r"); + + if (magic_file == NULL) + return; + + if (fread (header, 1, 12, magic_file) == 12) + { + if (memcmp ("MIME-Magic\0\n", header, 12) == 0) + _xdg_mime_magic_read_magic_file (mime_magic, magic_file); + } + + fclose (magic_file); +} diff --git a/Xdgmime/xdgmimemagic.h b/Xdgmime/xdgmimemagic.h new file mode 100644 index 0000000..35c8039 --- /dev/null +++ b/Xdgmime/xdgmimemagic.h @@ -0,0 +1,57 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimemagic.h: Private file. Datastructure for storing the magic files. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2003 Red Hat, Inc. + * Copyright (C) 2003 Jonathan Blandford + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __XDG_MIME_MAGIC_H__ +#define __XDG_MIME_MAGIC_H__ + +#include +#include "xdgmime.h" +typedef struct XdgMimeMagic XdgMimeMagic; + +#ifdef XDG_PREFIX +#define _xdg_mime_glob_read_from_file XDG_RESERVED_ENTRY(glob_read_from_file) +#define _xdg_mime_magic_new XDG_RESERVED_ENTRY(magic_new) +#define _xdg_mime_magic_read_from_file XDG_RESERVED_ENTRY(magic_read_from_file) +#define _xdg_mime_magic_free XDG_RESERVED_ENTRY(magic_free) +#define _xdg_mime_magic_get_buffer_extents XDG_RESERVED_ENTRY(magic_get_buffer_extents) +#define _xdg_mime_magic_lookup_data XDG_RESERVED_ENTRY(magic_lookup_data) +#endif + + +XdgMimeMagic *_xdg_mime_magic_new (void); +void _xdg_mime_magic_read_from_file (XdgMimeMagic *mime_magic, + const char *file_name); +void _xdg_mime_magic_free (XdgMimeMagic *mime_magic); +int _xdg_mime_magic_get_buffer_extents (XdgMimeMagic *mime_magic); +const char *_xdg_mime_magic_lookup_data (XdgMimeMagic *mime_magic, + const void *data, + size_t len, + int *result_prio, + const char *mime_types[], + int n_mime_types); + +#endif /* __XDG_MIME_MAGIC_H__ */ diff --git a/Xdgmime/xdgmimeparent.c b/Xdgmime/xdgmimeparent.c new file mode 100644 index 0000000..511bbac --- /dev/null +++ b/Xdgmime/xdgmimeparent.c @@ -0,0 +1,219 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimealias.c: Private file. Datastructure for storing the hierarchy. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2004 Red Hat, Inc. + * Copyright (C) 2004 Matthias Clasen + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "xdgmimeparent.h" +#include "xdgmimeint.h" +#include +#include +#include +#include +#include + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +typedef struct XdgMimeParents XdgMimeParents; + +struct XdgMimeParents +{ + char *mime; + char **parents; + int n_parents; +}; + +struct XdgParentList +{ + struct XdgMimeParents *parents; + int n_mimes; +}; + +XdgParentList * +_xdg_mime_parent_list_new (void) +{ + XdgParentList *list; + + list = malloc (sizeof (XdgParentList)); + + list->parents = NULL; + list->n_mimes = 0; + + return list; +} + +void +_xdg_mime_parent_list_free (XdgParentList *list) +{ + int i; + char **p; + + if (list->parents) + { + for (i = 0; i < list->n_mimes; i++) + { + for (p = list->parents[i].parents; *p; p++) + free (*p); + + free (list->parents[i].parents); + free (list->parents[i].mime); + } + free (list->parents); + } + free (list); +} + +static int +parent_entry_cmp (const void *v1, const void *v2) +{ + return strcmp (((XdgMimeParents *)v1)->mime, ((XdgMimeParents *)v2)->mime); +} + +const char ** +_xdg_mime_parent_list_lookup (XdgParentList *list, + const char *mime) +{ + XdgMimeParents *entry; + XdgMimeParents key; + + if (list->n_mimes > 0) + { + key.mime = (char *)mime; + key.parents = NULL; + + entry = bsearch (&key, list->parents, list->n_mimes, + sizeof (XdgMimeParents), &parent_entry_cmp); + if (entry) + return (const char **)entry->parents; + } + + return NULL; +} + +void +_xdg_mime_parent_read_from_file (XdgParentList *list, + const char *file_name) +{ + FILE *file; + char line[255]; + int i, alloc; + XdgMimeParents *entry; + + file = fopen (file_name, "r"); + + if (file == NULL) + return; + + /* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars. + * Blah */ + alloc = list->n_mimes + 16; + list->parents = realloc (list->parents, alloc * sizeof (XdgMimeParents)); + while (fgets (line, 255, file) != NULL) + { + char *sep; + if (line[0] == '#') + continue; + + sep = strchr (line, ' '); + if (sep == NULL) + continue; + *(sep++) = '\000'; + sep[strlen (sep) -1] = '\000'; + entry = NULL; + for (i = 0; i < list->n_mimes; i++) + { + if (strcmp (list->parents[i].mime, line) == 0) + { + entry = &(list->parents[i]); + break; + } + } + + if (!entry) + { + if (list->n_mimes == alloc) + { + alloc <<= 1; + list->parents = realloc (list->parents, + alloc * sizeof (XdgMimeParents)); + } + list->parents[list->n_mimes].mime = strdup (line); + list->parents[list->n_mimes].parents = NULL; + entry = &(list->parents[list->n_mimes]); + list->n_mimes++; + } + + if (!entry->parents) + { + entry->n_parents = 1; + entry->parents = malloc ((entry->n_parents + 1) * sizeof (char *)); + } + else + { + entry->n_parents += 1; + entry->parents = realloc (entry->parents, + (entry->n_parents + 2) * sizeof (char *)); + } + entry->parents[entry->n_parents - 1] = strdup (sep); + entry->parents[entry->n_parents] = NULL; + } + + list->parents = realloc (list->parents, + list->n_mimes * sizeof (XdgMimeParents)); + + fclose (file); + + if (list->n_mimes > 1) + qsort (list->parents, list->n_mimes, + sizeof (XdgMimeParents), &parent_entry_cmp); +} + + +void +_xdg_mime_parent_list_dump (XdgParentList *list) +{ + int i; + char **p; + + if (list->parents) + { + for (i = 0; i < list->n_mimes; i++) + { + for (p = list->parents[i].parents; *p; p++) + printf ("%s %s\n", list->parents[i].mime, *p); + } + } +} + + diff --git a/Xdgmime/xdgmimeparent.h b/Xdgmime/xdgmimeparent.h new file mode 100644 index 0000000..b564f41 --- /dev/null +++ b/Xdgmime/xdgmimeparent.h @@ -0,0 +1,51 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimeparent.h: Private file. Datastructure for storing the hierarchy. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2004 Red Hat, Inc. + * Copyright (C) 200 Matthias Clasen + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __XDG_MIME_PARENT_H__ +#define __XDG_MIME_PARENT_H__ + +#include "xdgmime.h" + +typedef struct XdgParentList XdgParentList; + +#ifdef XDG_PREFIX +#define _xdg_mime_parent_read_from_file XDG_RESERVED_ENTRY(parent_read_from_file) +#define _xdg_mime_parent_list_new XDG_RESERVED_ENTRY(parent_list_new) +#define _xdg_mime_parent_list_free XDG_RESERVED_ENTRY(parent_list_free) +#define _xdg_mime_parent_list_lookup XDG_RESERVED_ENTRY(parent_list_lookup) +#define _xdg_mime_parent_list_dump XDG_RESERVED_ENTRY(parent_list_dump) +#endif + +void _xdg_mime_parent_read_from_file (XdgParentList *list, + const char *file_name); +XdgParentList *_xdg_mime_parent_list_new (void); +void _xdg_mime_parent_list_free (XdgParentList *list); +const char **_xdg_mime_parent_list_lookup (XdgParentList *list, + const char *mime); +void _xdg_mime_parent_list_dump (XdgParentList *list); + +#endif /* __XDG_MIME_PARENT_H__ */ diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..8bde25e --- /dev/null +++ b/debian/changelog @@ -0,0 +1,12 @@ +libxdgmime-perl (0.01-2) unstable; urgency=low + + * new package for amd64 + + -- Proxmox Support Team Thu, 31 May 2012 10:25:15 +0200 + +libxdgmime-perl (0.01-1) stable; urgency=low + + * Initial Release. + + -- Proxmox Support Team Wed, 11 Jul 2007 12:52:19 +0200 + diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..937b2bc --- /dev/null +++ b/debian/control @@ -0,0 +1,13 @@ +Source: libxdgmime-perl +Section: perl +Priority: optional +Build-Depends: debhelper (>= 5.0.0), perl (>= 5.8.8-7) +Maintainer: Proxmox Support Team +Standards-Version: 3.7.2 + +Package: libxdgmime-perl +Architecture: any +Depends: ${perl:Depends}, ${shlibs:Depends}, ${misc:Depends}, +Description: Perl extension to access xdgmime functions + This module is a simple module that parses the proposed MIME spec listed + at http://freedesktop.org/. It is currently targetted at version 0.12. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..718d4c3 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,16 @@ +This is a debian package for the Xdgmime module, created by the +Proxmox Support Team using dh-make-perl. + +Copyright (C) 2003,2004 Red Hat, Inc. + +This module is a simple module that parses the proposed MIME spec +listed at http://freedesktop.org/. It is currently targetted at ver- +sion 0.12. + +It is dual-licensed under the terms of the GNU Lesser General Public +License, and the Academic Free License, version 2.0. + +The upstream author is: Jonathan Blandford, + +The perl wrapper code is created by the Proxmox Support Team +. diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..203c12d --- /dev/null +++ b/debian/rules @@ -0,0 +1,92 @@ +#!/usr/bin/make -f +# This debian/rules file is provided as a template for normal perl +# packages. It was created by Marc Brockschmidt for +# the Debian Perl Group (http://pkg-perl.alioth.debian.org/) but may +# be used freely wherever it is useful. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +# If set to a true value then MakeMaker's prompt function will +# always return the default without waiting for user input. +export PERL_MM_USE_DEFAULT=1 + +PACKAGE=$(shell dh_listpackages) + +ifndef PERL +PERL = /usr/bin/perl +endif + +TMP =$(CURDIR)/debian/$(PACKAGE) + +# Allow disabling build optimation by setting noopt in +# $DEB_BUILD_OPTIONS +CFLAGS = -Wall -g +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 +else + CFLAGS += -O2 +endif + +build: build-stamp +build-stamp: + dh_testdir + + # Add commands to compile the package here + $(PERL) Makefile.PL INSTALLDIRS=vendor + $(MAKE) OPTIMIZE="$(CFLAGS)" LD_RUN_PATH="" + + touch build-stamp + +clean: + dh_testdir + dh_testroot + + # Add commands to clean up after the build process here + [ ! -f Makefile ] || $(MAKE) realclean + + dh_clean build-stamp install-stamp + +install: build install-stamp +install-stamp: + dh_testdir + dh_testroot + dh_clean -k + + # Add commands to install the package into debian/$PACKAGE_NAME here + $(MAKE) test + $(MAKE) install DESTDIR=$(TMP) PREFIX=/usr + + touch install-stamp + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installdocs README + dh_installexamples +# dh_installmenu +# dh_installcron +# dh_installman + dh_installchangelogs Changes + dh_link + dh_strip + dh_compress + dh_fixperms + dh_makeshlibs + dh_installdeb + dh_perl + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +source diff: + @echo >&2 'source and diff are obsolete - use dpkg-source -b'; false + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary diff --git a/exports.h b/exports.h new file mode 100644 index 0000000..f77b4da --- /dev/null +++ b/exports.h @@ -0,0 +1,18 @@ +// exported functions - parseable by h2xs + +const char *xdg_mime_get_mime_type_for_data (const void *data, + unsigned long len); +const char *xdg_mime_get_mime_type_for_file (const char *file_name, + struct stat *statbuf); +const char *xdg_mime_get_mime_type_from_file_name (const char *file_name); +int xdg_mime_is_valid_mime_type (const char *mime_type); +int xdg_mime_mime_type_equal (const char *mime_a, + const char *mime_b); +int xdg_mime_media_type_equal (const char *mime_a, + const char *mime_b); +int xdg_mime_mime_type_subclass (const char *mime_a, + const char *mime_b); +int xdg_mime_get_max_buffer_extents (void); +void xdg_mime_shutdown (void); +void xdg_mime_dump (void); + diff --git a/xdgmime-2012-06-01.tar.gz b/xdgmime-2012-06-01.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..6d6337c75c629a41e72e3dd5784eee93102f8dbe GIT binary patch literal 160562 zcmV(uKym?{r}hZ^_{+R&h_u=y1wtzJK>KuP@1+PNf5y2pAlp3Bzc@;M&W+x4=NbqS1?2P`E`!3pBZhCve|Y>IC{zxV&Lnx$04O-ZLpfAB3mkv>ic7(Bp)5R`18~4G z0A;b6EG7paL9NWJjG-JBK!nn$94M zCMSBc*#Lt}^Mit0?hbH4Gbm_w2w-!lOa>ID1xIK>94G)Afa1Y_1`|qVvgvpllnu}T zJP!hkhG#H9EAV>|&cBdvf#Mk?D0OiW29pb+GPnSP1nO~_Py*-|1B@|^wzS%!85c}> z5SASt^ohOYizOYvGq_(&yg?r!1V1Q~rvSQ0VB^_T5CFI?p2eb3iFhsunZwh@lSojG zH;ct&bHCsMzU+=4xG{7s2xQ57k~f~F30eXS-u`)m_?C3J0Gkd@OkTX%W$g&H1UMY< z*)D(qutDc{dlNt_h~<*ylB+z`9Yj0{pi_xZ6L7zw|9bq--9%`?v><;T|39dIEq5yS zyEcKp%>Qs0428k+>K}&1{N(>1A>WEWk;x!a-M`Nof5!hPIN~e*M(0g%_JTqfIZk#o8Kq!E2646>3;r2!z*0^l8&?F~Ry5_tTq4<+Mi9Pp0DbO-5` z4UoNABs>>n$uDXyY|x4eK$VzmsymgT1TI4cxI_y0Tm#hRXj1?@iKDHqyLhvt%+X#_ z)>enC^k&mQRWKXDrh;cM8Q@6k>*fOHulAQ5hPZ$%%>buYqT@m4Wh*VZwTM6;x-=_f zB^>}e4|xAy)?d>83tajCQNC6GEIiQ@AZhZp>EB-CPwO9v`l|lX2#^wf*8dL>WhgJw zi*bhfP`MOcC<_31MHq`+hJ**uWDEic$LbIfFyc}v zaq;dPZQfRL|EA$rWe?^f1Wv%A@MHjmB;yePsE;Ay$uJ@e0e+$}BmhHz>tL}+6#5S* z_)_QyB8j9!LSjf*91^w&2Zh$bB6KiB0vv||v0)HoEDVAD!#Vzg7~xy>&m?#NL@wvM zoCE*X?|;l<|3@PcKhJ+ZLjElNJa+hZli=^a|3RbBKi~iS5cx~-Uu+Rr1OQ-&7##wR zL;!GTEDiu;iXp)<1SAQDMIo_(4hDunptX3~|80%M9{;WWk3^!8U%&rBpwNh){r`u^ z?j42};DrzTI}{`Cn;aWyaheYU=tK-@ZVM_1l*Ey5hkX~a^ zl)?1Ei=A%n0f?)y&*>*84{xSlNoWN=_4v(E=zHT!HdJirNVTCQtp;(2@9-#xi7y*J zT-kGYb8xIrY;0Q0dh@h~-FvQASxK)o8(SFGOUslOB%_c~;(XB_=W6&vUX`iX*VBIC zn_t(gXEXSwuzAGbII3PRiJe?u7TnhqBRUr)Qhg;nKc?@QL9S=e%=A6dtf@cJS8etE z?);0b@83aEKCC+zES%!ClY6)IZUp{wSJ$BL+ue4@l7~{#w7nN_N3thMW|sS7uk9&d zunNekGeZ3%7CREwfPl|FwFUtPj~_i9tD}_G?M);EiwiZ+Of+;9g!Mo1GT)FIitR;B zDS&|Q3eOtp8YxGFS|;kviRZxA7rZOY5E7)1tZQlU-Y0a!C$F>uB_HiePV`MFkk0Re z<4AP*p^9r=23k4g7w*LhyWjCSF~fa4=o53HbxJ5|lfM#)>}z7;kk;Z{6?Lqtxwz}) zdXDBhFG|CN5i%_x$SyCunOJz?VMl-@Wo1^a%JvKN1EF@?WcRJ6)aGQ%?{s-?SEh5s zE%8M&NEEIsl2-X9p9$Z=DB}g-Xr=kOb6MT(*7w(B9p3(dNX!co@QQ+KHk>pM*lxp# zPv~(_>^N6-?n*63RBiT@8uVU`io03VefR6Qv|_X89i{fr#3PfqQ|$*&%D;%)Z#nM! zC?S6m>W7+qGni9q`@kYFS}(Co@pIqs`DvnOt!h-d+705S_Wt9PzQWvepN|a#65TJz z)~{C+Kt-{gxCHyIUBaU=f+gasqjwXo!L`xvg;q@>6e%$iWiZ10*E zCpR0iux*qvw@nB_9{fdE`6`e-u5_(X07fHEz3@!HsurB3-OYA38RVJeEChRyO|i<+heO zkC03=>u9-Y)4J&w58o8PX~nwjl0Lp0dlZSCp@Tc9o$>^aiy^)nUa!trwTsR_RJ3}z z%+XM{G>O!lW#i35GeSamGe9yZK+M0sSGeAK`Hjz_in}Y2Q^rSD?8SK7q{@Mw)>$#i zq2dC)-nhyw3s*KCFRik5bkyH2TXG!zNZbXziErJzS*yhTF^=xYsjG8tPmLPWWILi{ zoI4LnzgL6`w? zBGt-;;&hw%Qfq8Yd=;AP)yCTj_FsE&BFZ@-)Kl?gNb1RAseT8Ik2c5}zlRb>%3X>y zi`pKwmm_0F4sH7+o@u(O+tfwq?6GQAe6+$q%!9Um@r;B}0cHJBX5;H&LMZ3Kd5K!z zwg6j8)j;okB7Qpfl*W38cI}j{$HSx7g1$yt*_6XXLmOW0b?Pf?Ge1AzDY=vNvf|ja zu8Lvxjtp~q>IeUPMa2_`%2XGAUvR2FC2Tsrg3Wc6uPNA3s{e~wm566hUrN^=sj=T8 zPGyKbTT@s+(JNKc(R@|hTARI~a!YfG`NWg(KX4A>!WA&beg)s1I9n#R5; zwHiu#-pGwf>Zu+&G^0AuwBf<6r#7>7N7a}gC9E~%2p^o>!+t$7wd|u#b&T30gG!0J zY0T2pcw zU6kDx@2k;U21O5TVri5>3_>^G3yr9(@{2UN-l~4qtvB7$Kk#fwUXii{AGfS|qE zEt4ra)=t*9^O%=zqpP-#y7-=Qw+ACX+BBYnQVOY83D z!KmL))laZ2KA!HkY!R^%x$r>g*vV;NTv_IbUU>Ol@+Ezh3_kor8r)D|Xl>}>a`9?tk4e7^6O(0TcLdz9yD&?u?J|&YN%C^kn z?9+XeOMnXSpp&h5CY1khR=`1Ru~ogIg6|=UCgbhO5xb|>H8yYe9PL!CGEMr zXZBl|+%7PhJrJPujC-eVNL`v%MkrG@Bl~O-{0NIT^mJ*y^>9n~8~i!|p}zx{*! z8=R=~PoxC5?AlgsLkT{g->=&8Xl-6)R@F_Z`EdiuS5fi?(xDc9IdF82GyzLFx@E8u^yRDER5{8%p4j zm(pVn9lJdlb7%LS0x5HKx6=LapahtemizpH#O|G^2jKQkR!1jMfP-Gr`zM-lk{{S& z+GBi~QRkm4!zJNj6Sz8kS^tsTgfY{(wtG%HuO5jsD1AwP`0ykbGKCPC4==f#Dbdrg z;SD}Ix6j`vx$(^PxkoZG4MfwJR+hc=&M=jQF20VOgIirq4;%MvX zVP8;Rm}TNs`Pf3x)Ap`&LPqQpbv-dIJJz05Frse1IafiKsC(j$UWl-E{A8WTeSyBP z8%eC*m{kw+_vwu9P}e*Y7i%}+5GyHlKb14^Ij2(js%gUve)`s+SZP*!|DA0aLvbf3 zZf4(^h)meTg8McR?+5ee$x%(-G##+$XtLS*4DY(LG+1X$QRwBsR;cfL#iL~*zl-8e zY}3k~&wqJ4M2K1|($**PxSe_EoD{EvmhyfH7>&=L4skn=x$10I7%Og09aA}WaL+Sc znSv4MuZ<0PmyR_S*VP4`_%%TuW!{N<`wt@ifkCWxX&Oeywr$(CZQHhO+cq<{Z98Mz zHgl4Dzu$BI!CK9#>h6pDa6xu5U&E<>6c&f9Dpe$SR)g(8Fmn|uNg|hP#cdu*l543r zJvVQ#AjV}y8;Z~c3)FYjbLvj8R7`K*`7sBQjv18h_CgGkOd1NSktfvv$ z@5HyAvOmWP0bbGj6iHw(4vmF){_%}+37?vzE5LbiF;4(7)**}YCYJ&ls-=?vg6B`@ z(S8Q!N_OVV!u-#v|Ja4d?N1c1P?ZulqofXD$cA&(k6?2vyQ2ycu{Yw~D{P7We9tuZ z^fVkf(H(3NrF1E`c0!XJD|50-K8E}MN2(bB~?{W^S99Pcvs`ZwZ!X! zhgS|tAg{e3`n>JjZO!;#;gBdNHD|5m?&>zx-Wt+vR!;R_QYuOljfFWUr9{Zi7C7(o8Sq%J-CBWh1BK>DJ^Z?Lu>%ev z-Q&?*bx>M^Lu`0NR~#1zcmCT)c-_eH=$?4b5!ir|A=^RRobk$?eWVa%AE_-tH#{0U znA8o})xO!~vvX4C(piZn=RXzYm?Yb;NBT4V(NEqQQ5!je!;l3<{DtD}QUOEmE_j5) z{)Ch3h!J?<*!@-?IO({qeP&MtI`c45=0`3h;`ItR6bzNp2&%PqKI# z@Nyj)?dqSbiWZX}JsVfPb1Xr1&A=^$ofUzb8Z?uGvQM%OhIU)`2!EB@LWsj8e)apQ zGBoE5%zHBF$!`umy~h)6Ns$ft)21drkKOY%JlBXyRx%BYy9XS~RH6pmT_~|rKXi%i zwzJ$Y4?G)dEQWdWryN+v?ieZw6A$X`WTmY$SYUcTDK|V*1eh!Q3_9z34#omFb*~&o%BO zZFPPVC`3Cb?ne^U3I^P1#aJVYj)U7G@=p#; z%*8&97J^uNq1X=NFGCs5CqNeu>=P>i@v#cSiQzxee_W6daR@&gmDRToOE<0y2TN zK6~K4L^g+>Yd>|(m>`ARr>ui#*OgBs^Zd1plC;wn0g8@xxxu;PC|tq9T&h&54*{86)?{D%Zw+#^Zb zcKN!t1*6YMs@%8rK)I`TqY=f7FD`;VU`f`-xoC*r1zMN~rQ0^(gA;g2bU)@FV<0+d zZ%hFUd?Y{R)lK_2tP|+&*oxzZ0OfO|<|YvJ0@kwB#$87;p}py(^PLcYpo5TYd#>Wx z9kau8InSIdGJWN3c9K1%`az}e*oZs%e9P(m07~?$XHJpVyzj7c$`VYfPd48e6AZgx z5#A5z5y0~xypRqlh!G8hMlVp7KGH&aXh8%XIkpKiQbPg&A?q~?8W$7!(t<0&2L9C( zWL@iMiUUkTm3NfelpCK1raXpDKX!XiyHEs!Qr z_d~Kwc;VeG5JoO%s#m%2K(z^v5HtEQAKC&u0AIeqV*I|LpWx+9O|@mLpsSY9b!nW~ zF+RoX`vQ6Upu_WqnE!x%0(`oAG|PeyHCE>3saH@+<raeIFfI@du zwc5m6ireGY2=)Vb!?n{mgA8Qw$RVBXg8e6CDgX*4DlN@>hCIGIo3j~2pt$(}mVgLF z4C4ginS!zzl7yV;J)az?svHs&%@bnA*x0UI5rm%AfEiD4JGurLSP>lQyf`L2{^DT~ z;>3(h1Bgv0v&7Zd6rjjNSR)%FQ3k#2k6_>(#J`>E)=8PWv})R}@Lg?N{2mncmb{=V zA9CzY)eqaGb~%R)_{(cV=Xjw888Aj2wLl9wE{Gx)BnJpRH_IUP`Ue!z1xaLg0-~js zqE>&c_XL>V!O`uE)eW4(_nCXu)|fjhqeX~FSi+>DC@Mpadk$*UmMWoWF&aE>477phTE3v zGG&VW;63>=<9xWT;eEx#{CRv^vJE7s!TAv7cx`hyN{?-CbCT%QDwU^9{}+$ zi509cLlV^}kdD9xqVzO?M5b}nghO#Ty9CPl#eJIog(6#{-xw{IT9@F)K?4yh)~#0zVnW+&QEHg!Ky@mn2Qc~3r$P=m zlnyngeH*4}$QH%1Lpxm1b2Dhi=_zE0KlwFz1!#XBaBD54x*zZA_m5}O>&rF|0edCB zAR1^O`6NtoehqHQq&9Jp{eeCmG$dKKRhI+znDf&E9&*(SgHi^=#Jn-S0Qc-PGs?&L zM@asSGGNATeWCC%3lf{xJBuu{_FxWRiRK(vBgit5?6K_S+aw_zhtWT8GR0>0T^6cNZuGtiyB{Mie{-R7Z>!x6C!qx@P7EJn7@r4@M$* zk{}0TCj=TZmu|~SAV3!U5zycBmibNY=_vPDp{LqLOB5D;>1;qp+X;h}(!DI9RPCj9 zaKs`-Qe&=XvLQng1QLnh1w|7P#dbXJg>Xp-2xJ*;@;Zx$%z66i{c-xqmxDJayi}du zlwpf$2OLipKe*(ocZm`9iO(cnNvH+SYuw)f03MuT&omjGE#n{*H%sBG4;zZL-h2qN3n=?p? zU`t)^%I^e=1N&-3$oJZmD4u@e-<)k3zTk#zGGd!-SaJrkQ+|*vFSWu0`pj}oEWMZ| z%7a;gg@cq~Bp1D5cP8BNN06X(_i=p&H~fSl&V~wBSm9D2fT{sC3mLG#e(qaBsCOn# zFLU}n-S7133JP$x{(OQoqL>BZooK9|)=Z^pF#v8ZGO2GI2lhTnAtx$S{$V?JC6AeG zSs6q61{(%F0`M zWUYRv-RBeNnPZn83&+g{GMf3u8N!Pb`v@851#T@|o1FMsY9&hVR@Ir@p5!6%WbL2U zoO>o0TFJ$)R^Ap)n74L&d1idh7{W)t#m@-4!2U?k-X}f|lxH_NE8uwfKi%G653ATj znDY`R?Rx~-ctN2vN*JK5GY)q(!t?v7;Ksmvl?`+SQ8aTaw1g=vTam-yitO{UQnqLW zl&O;O7}(~(GwKM?g_0P*S}U4S01cTvTvOh5hm3z5{v7l9dwe{-XYt-mqaO)mmzLrq z2IRpkpQog?hd?f4;q(9rCCWRAYjF^q?O^C8xcVS*P|W8I7o3(bexA1O8x*vn5H?_s z`yq{qzQA;;L;dW2^;|IjTorU*DBI3ws|S+!+fsT=GP%GbMg-|wD5_511t#e`o?yEK z&mxweF2=;>z0ZV7qvxX_xGr|h`+zuNXqk6*vdJlX4r191>`K;Q2kY$IRG2-;=IV84 z@q4U$q#w^@midEp*J$>N=lg(r9E!B1{2OP*{U4d|GhvX*CbJGNvkWpv@Mq|VTvF3Y zqI~(ucRPfxr&)g;f1Ol{=(lX!geAj}4t^|aoxL5ZEg$u;5njEt+tvE5rrV%^WYKc& zwfiEhe;fSh3ZZt0fVDcmSi+b9t84zZ2~L9YC770h?5-;ca>$%TzCU585^)L@W7}d` zSBIs0Q64+RG(mjN)#L?6dm|fp#yXcw4lGg4`e1K?W}dRxwffVLbBUv{+qPZ^-b8uy zL~xYPaDP>U2u&dNDwt#??mI&kmB1}*rz;ck7phF1iYLIF@jAqT9FoGrSToe=kSSFK zSWg%a{PF|zIrHOB`0w|p{^@g~s|)JWjqpiQjiytiA@jA`AK->0u|~ospq4P-UtHI< zF3am%L!sUnbRzSZnBb?)k(HLLt&B+{2EnaaSm;F!7P_}ujw3?M!B;h|aQYCJmcDQV8V{=ndm`-NyY1+kmp zkyqb&4M;VuT_yi1GcIHxx?Q=2@5d}#*H060=rvI%r1#PFpbZoc%2x9M^vCpENh0~L zOWJMz8~FP~fqFG)ucAs`)-eE;GbphLKs8SkvKzK&iQ14TkyfnveNM{FTL)f+0vnmV z4vEacV5cs3rkIvRDYdB7*CK0LWKMC-DO<7HUo=lk#+IJGuCRQquLh+G2LO2Z> z7#+2hj(9`l@!@8V4Zz4q;MPH+p)10^S^T=l_0Aft9Eg}o)lg|_sCUAoR1P>eaC_DRt zJQzTzGZ>b@{Y~EP3iFDKH~i9e$Pk_DI=A(D*%3&s(Va|{YDIZ-7rFl@fdRBvht=(7 z)(C#?D%cTChx(@!+zzG}|0vX6;}Mf5|i*dGqDj-<>5` z(3=p&AMgTtpeh6Fe_Hr31B}3Gva-imn{d((qEG~IKPJwYB6XrmN;{C9e7GQuSam(R z-rM^`tBIMwQdgpwu(9rHP1Bh-b9)%9tDyb5>kb@B4wu0RNq@1u?&fD+LeL8?Xh{RJ ztG@F#M(b=_-n?~am5g+lISrF@P4>)f zN0z$kS>e2l32PSAA2Ve`S9rpOT&E<;`Dn6uFK>_OAgA_bpS8yq=(IbxsT$}OnY<-A zlCWmMR-11BH!TDDoioJOcV$94g!$T7pyb-0yEdyf&iG#9^!K9vEWgY~BwOi9`lkDc z_r!mHAHV&t;Dpwtm)8%&@>@wRx;d9yVqJN42WPiii!RAT?!Q-rApkjs+Fw0N@{Oep z!|1(^D(J88)U39U#apkg#J;3DZ?S45zov>+(WQ8x)$1O1Lb0!`wlJ?DXxYy<3Er^L zwpmnlGNGaNOdufhD5oWwdql<|57-gRapLo7b2eQKU<{KQK?Z{Nq&P8#D2DuLtEpbe z7BV(O^uzu-F8FOFVp85h~6e$w*(t)QrBP`` zilYWqOS%-v+KA)WF2-Sbgzp#+cx&;fA-=w4pLV0g@JS`6p$CMJZR;#m(VFA5iILlD z_f!U7-5|-?cVHQmejhi{T@^z+M=LCL&_cVh(63)8e3)}|)ZeekTft0Vs`oY|D z{6+nr7XGgtef7`H!~L73Q~LVfI_Uue14&;C@=4@Y@D2i^>Rcnxnf=F1`M6TSGj8d{pi=S5$npMMPv}fm*gWT-vu-T|n{-aKH!*|VQeY1K7?x6Zge7BZe`wF}#vFux{ z?!YyyNW8C5cni|_IU3?RX-a54wZ&WXZZuyY?*Z@{!Iz34ZZ(2Rj! zd{p(yXBTu&72L*bLvB35ZCasjxgU}a)8j=5cJKQ)a4Bwi3PF|u`h!02c8wd56d{Sm#eYq9j2E=WID9{`rt z%W%8{an;IV;UzR5v&TDBKLP8FrqlS(VL$}XhjB|`PUVh@lp{evv9kViPwHQI%e zuD=P@Tc|o~N#r_|qV{vb5cVx2+@#QWZ7kg^h^u4%l*`@*7t;*;!Ftwus#4ZEw;zr% zAm=nuE*yiAanz-C>o@_LlbF-S(ApVBo$Qxi=ei!%w~;Z&-vu466|4(G%_}plvKw^q zZ_N0?n8{yPWc7y+qrHW?4V#sCdu;di@eZZ_?x?(k;RApAJU4mo_Y6VB4U1U09&F2J z6P6g`HFo>zon50x>#S zhJYDX7Q^b&S%bB;!hY@L$U^>+C&*belT&w|+ygoy3Qbstl~LUGy&PCas)W@+-OiWc zH{gnP!D(P8d>OsD_X5`L;};sPi%|}8fiPL=ajkQxlr=DNC z)~1x2WfD`<^~wfW7E>Wxi!JVPGO1GZ)M}kISFkX*Hugw~OA*p4qvwc`>u?aq`~bVY-t;IE>#AkNYpa5!D9IU&v$#njQAQY)B+XC7)xHt zlPyc8A;8wk+L~0g={Pnq&f8sNKlgreg0@X0EgM$L>}0VVX3iI{j41=+mIa*I#KYm9 zp4XKTv{LB?FVH!(QEULw&Jod>GNcgYgFkRN!YTF|i!&!Mr<9?!Gmx_DlYTdpP{CcQ z)rq@(ajL*S`)20%Wd_f=vQ+-#ulS)z7nZN zb_=Tk>K9VIw*wBP&-8s--22Zjb;Eh6KZH2$U#kHm!$=9E!(@2N)d;iyP9Iit%pJ6+qzJ4Ki%b)A?k)`U!%MF-x-z= z4G-Z$C_d)?n$+rl{=%Jg!4OYp?#b_$nsvvnWz*@$PGF~uso@if`dCWljIm>T#;Y~k z&WmPSr_8=PTlIds$P*}T1tE`t>k8~Yl$al57!06nT23l><9B-C;E<6{%#UyGeJ}q! zXnpb?H0<%8X{^gdgqPD-Yxbu!ufrAc$cU>Mh%ui(rwfY9pt0Et zuAHhgsLDtC9x^@9CU`TvN3`-H@pefFMUM5ri2mR6OE@kCLXtNtd-wnO|X<#5Ox!jK|FT zh+GbT_2z5dg z+PKO)qtX8ZQWqy}(SFZu|Bw@>+>g%iOU@nJgY(a<_U_UX1iMsLt5MbKPFXzUBn0@! z1;xN+&g5-lM=bgpI`(PQV0YCT{vMvYcg8kK+TFQ5?V-8Dlo7eP^;PNPHV1qQacurtAIz;`>+@@DGi6u$!SJp zo1AOD^l``tU9%;ev!-&AszSm$ClvubwUK)B2R2Mkm)4@Sgi|L`rwyUOGl;o(FX1-F zrK<3n{*86xS8*O!XzMe-h9k@&Bg`x}y0-LftXAfef{}%0p zYI>;e1mY~rC5%z@vWvW3Gd0KDq)8qr@HCCSU+Fv31A`NxBm`CZh|h%dM74NV{5=bz)1SDjz1bte~yk!+%DZN_(o?i;)vw}N;;~IWmM$Pdmway zqIPFUlkE0NDMcP_m@in|9S$##;YJ6_UwSBkw_}#yw}5^HuKW=alK*dP zGvD)Hvh+(Wb{pj>;zFpzb*Mm5M@9ZP=qe zpurb2Tz#!U)s1V-(_+DNWD#sXeFp$dvHo0~)R)#1fC3Nksf_;QO_hIE(h?ksHzHlXFCF%)6W1E_0sM0kQh zl{paGEW{x->E9xD!v9;uo~o;F9(tRXN-DEtCmaSr z#=^o4->zc0--sX+wItu$O=fgF43V$H+l;4)2SoHJTueDpfuJ>|RkRvX#Hi^=q-2f& z@|0yIzoja`FH{3v3OdnIu4H9qLM}_Io|Sc@V2Y~HQn1sI{q1P;2>@?fKV*>_jubDq z4$!udzvO%99WIHV#ce=y2%3BzG{hP!>T;WdEB@6N=pc2RbK;yfh@WJ^+0bNUH;X1j zrp^H3`)G+}j?1;Ik$Xm}qmrmXuJT<^)oc7Vll$z^L6V$%+uL7ob5LbqX3o$8zGnCG zdEKd%9-pn6*3jov*U%N!QyH>FXG{~-6h;0 z*!-}=+4V+37!R>z(KC%bHo>#hdZ(JPDk`T+4(*qbE2q7iYv~#ZuNF{kqn5$w=G&F1vhnF0Jgw;n776P06ws?Vj(4(KqT8}2h1es7b==)Cb*G=G>_lZXND;-d-Nej=;i zlsuWhU>w?Gm*q5`xFx>uW3a7@$qjd5!J_$%^pnOd>HoF9|Iez=>eET#SUBag#X=Cn zSbl_A8_B~`IOyg@gS&?c4aTAB>SL?sC5+-k3Z-P*1-2AzxRY9|9v9;(W!$V~l~T!e zP}LGSjEmC==*xu*;frV*(!a|}qzsoNbuCI=jAIuyNDKQ@!x8pfBkT;rnY))R7DPQ* z9$9%`o$pdY*Z2kV@J)0tc{eqczf~?-;)buR1HnBF6aAcpwf6>LX)Y}82e3uf=!4r&7O68&{2?_6mZ5H%O zNBYs%4>hYgDmp6t2E3l4y%{-u17#fUtx@Fp)f()c#{)NebOJKwMtx1&(pS?Ha@R6j zGZNxX?$JX7D3gI^PT3edW+IkR482fF{j`a{D1ks(<46R38vn>$aw)_43CJ4Y?UwqF z=+Dba4>KTu?LD5TPcOi`*)EmIq9F>RBd${w{VGo=OJ=LLl+FtJ@z#dM6G6yX;%3e~ zP1r*Wgi^fcnBjyy3gS>~h_9regGj-))vL`x;=c~}GcRe7!}LK%x3JbkCZK+8ZW zJp?nwaa?3Vwo0mKY{3Pu9@{2dUl|G{US1vUyiIrBXvZC%J-dpIFeaIFA~{K!Bc_bF z&1o*&|F@xuA!?7g;EvouGf_U;5Uwm2AvAIY4qP_9R=T+rJ)^~y(VU8{V5A}Nd8LfH z%VBv7tW$-LZQ_?}ott%}@Aj`=$)6w&ooRdY^d^38e#`Oo@LnA`JF0K>p%}on-y_)g z3uLr05Ce0dx&T9gU6#RWK3n~Cxe4rosPrh6FXpfDro1IdTPR$^1?o0RgJ+ z6)|D50mYWcLf73hLj0x{55F^JtqKC>5($JEM^*rBC^S~swxCILYJ>u(dqu8BUzvn` zRzS>!4ZA^UnY;!w&2e_5eAS)TZBQ^!ROGHL70TVx%3~3HFPUw^QS(KePGwo>cGQ?x zc#9Z2HtWgZ;{980RowdFR!>(tcZzPDfiA_oBNg-I^SQVeK3xVaUF07Emi;$X30+;G zG{Y=!k(O+w0T)~#5(uR80yC6=BPIG`l&F-o)0e6RE>UZYU`xU~joo1{Mu{j;t)Y2$ z)OVyqIfOlZh#0?URl5oZx{k#4SZW@D1nvM)t*zCdoGKQHi?=f=bK+pGCS zmEsy`jO7!cpRriLI2b%20e4fAf!_<71YA~g_d=aws(YJNS&98N{Ge*Ge35ci{8MCP z(??kaOTAw?ViaGbu`L91FqM2&(@LTM(~NtAW(vrzi`FT5ZdP$gnXA9_7|C@kT;5#h z`r^+%`X>;1^p`ID2B46PAqwR#!vHM_{M)8AWFT9zOVe!VrqT0I_|7RI2S+@x${pG~ zpdka-9N8@~k9~UbX~dr(%sKAE??aD^m|0>`=29&HIY7q04%JyBq@h3Mv(lX@!-|yO z&Aq|lfV%PtU{N4eE<~2MMq-p|9FJg9#tz60&xTaf9X-SuNP{fI^H9yx5LyL+=h6)t zGk~=bG%s2@w?+>-Ri_8)*jc5}LBk=JBWmb#GQ0*jdSJ=y>zvJxT)QOU?gPx5+(-2= zKY@MMss4?<9J?=HDhA@oPZRS_^>YknYo0O4zkVaqu6{>EwvOoUF}h9WqW*861eg&f zu(Ia>=n`=9jjaEu$_z;=m0EpZN!?)G!#DJDaz|H{M;=%2T zR*twcV;(%5Elebd=Yb<+Z<-pNlZwN-!`;{DG90D2n3nW(0@=7pj+YY(!xTrh5(gFIc;jWXh$!!naH2a3|qzT2ByR>}hRi#ybTuu3GitOMnzPTzu3w%DXt>Vo)oV-WnLdFNEE@>!*5!=fi^E5kDiL46&plM>Qp3N_&A*iLhe!#2@=d`e2xfD=cN{5H{#KLNubyY zGIMC?Vv*J~>nN3OWqo6ouk)pqy@?)q=G!}u`&w!pwD*Y`%iQ*SQ|(#<+T#RU2?%l? z265e!o#)-%E$h%#n$8=mUI!h~>kQ2QL`}J&|J@U$wl^1)wJLMFg(5^S?;_Y?Q*p0O@2*#hJa%7&Z$&cd{~ z0M^_yPVA}F7&AcfO0x7a_Co(|hf@R%goalRL^r_`%h`VqVb0y>3x|Kypnw}!&3FK& zDD8Q^aF}->SC3?!A!hzgN7s^SQg$lG`TF(N^4A}Ww9}+l`o{TVGRqEM#)xruD8vNQ zI%)lv0yk;RdWPreKHsSFyH`>z>ebhg{IGqxzhspympqDQT7lNKev5t9c!0NWdSm{( zc+Qm*wECM=-JhtP=t0-xm#8U7Yyn|K_Si$ z8a*X4If|4bk-wxOm1rbLMP4U#*@H75ha*oi$RE5;gIaPsHq6?c!GD*#gAK>l@>C6h?;?@`SvRa!oO4NWC6rPQa)l!oMi3iDx8-wPtz{3S%iF;|=eMp&lmyY^^!o{?_ZE z@6Ybl^d3+0=^jiXVR*E7aeAAD8a1gDCi{e1k&)wb?j?wbla*pbmAeI7olZp6PRfRi z3!BD?MNMSY-Po3PcwNsaqsR`!? ze)k56j=U1S!oa=|{SXBCIR>tt9bu{thuTM(TZBhkq{Og9lCu*OxNvwF#W7Na3iBE2gA9``bV^yu z!C|LiizIaiRAf#sv95P3?QRclHV8Wl%M|7wFC5vcUiG{;)m8dH$)q|YEXQ{eLxhtr zzL&f|%yLFjO|-IYG~w1E`Vc~F@C=;KE-S9PFKbhss@yH%T}%|mM5$G1W$Lowy)gPZ zSd=}qEl&@8MA>~axOfd+R@c?M(}$of;mX0l{U1QZI#C#88kQWQ2xVLX*5jk>X9#H{ zTV5F_lm0Or0~OCRBinG#@;lntfjBM_gDACPc-L2I6FVB#8$C1m<|QZt%)BiEIjEA zGfLI?o6`o1*nwJk@{a4cJ$BvYO;ey$*eskfz8@s8jULh2Dm zdf$IEG;I;Ll$Q$LAJLC6gkx(c>)a84lv6En)yyx|Ea~BN8&ha& zKlmQE7McFw4q3R8RrtWQgRk&Q3b2CaEjGtS$@8r!|1On&W4TRTT%+(f!K-APUySLIwMUSS;{_afjTraA;?546g zl)aADic%%lfhcL)Fd=K|NNltnp?@G55{dt)oBSJV*?F_!_p zz~w`}`LWbEh)K@~qbDd;Q6=7F3XaFbH$3D4C;FOmO*Gf^oQ-O#-qR21LlDa0>rcBP zAB>%K-fOtt`>q~(m=A=`W<%zx_sR+&>h3J$m+9F&Mdc~iIhdjci4JGGBwXVz{bSoV z_eRDoC&63JBXv#rBA4uUHaroo?nmwge*%WYKpNH;)879Jojuf)V;I)bJ7lOUa2?zu z-8?53_Fz~b%g$a|wN;3x9AK3dkR_o?ZaG)U;R*PTmo6&OV&0 zooCdaP1hy4#5U6yQMD&{M@W`DQMSk;ofZ0gO-mGXHu2|)`OcrAg+aKEm$l}+K^cdp zRV#abVw6acIit{>*ScJbd{)DwR$xFw`WKjF4>pamd5PL@?8r-vj@n1EUumFvR@0z* z4>7C5G0>!Tz zS1n;;lW;!|et|;$>UM^d&0QbLSjfmqN3_@b63;&F<{l2Cv(!(aq_r#^(w7)6c<{JF%DbCryR@?#?P z$jHTG$%+;hH1eB&Q?OZeyGcY;d$_D%HDX|pQkC19c)L~SV4@-={SMmku7%CJkm6l} zdWEiGTt?gfsL8d*9+UBfXxR!#Q9579iwT$JK^oIK*?G@*zh5(J-^2<4u_U`BFBT-! zdYk$Lg#z5w?cW((7Wbib-WMQzL?H7h#QS$8#-n`eS%!;;w&5A7SBSDvVE!Z6>xT#j zy4Zb3zz2w5YrmHDPdkbGe=pB?M)iP3so0deB|{PV*-7|@SsdnbQM6KfM|)i~9TE+L z%1xWH63?^=uWR+oxl4`jI5lj`%ytUG z$uQQEy7!!?BC+Om0=6tw4% z#i_Eg!ZIg*oA<1jLwHXUc!V17|0CjckB0;1=`mXnE3j$g)@MAYb-XeI54a6 z>&=`syg9~=m|;!iox6dHlUxrRqxcbclRPk^dFa-!L8KJGF+_(_mk8tv8z|XSoZzEv zxI%9j(=m+ULwI7Z0L+12xOtB{RDZ9Ox>y#zxoE+J)U94$EVAXFbtZ}@Vg3JQxYwU3 z%?AWRx18a~%F23?Cv2)sW-_|SSR8c~A6_vYw)%tWTCq-ZM{;ta`m^~~V9KT6jZL!< ztE^H`l08(NVd^o3XZWPv`ghYBOvgM zXFTTsuT5}gMnY>i$?K$plBbiSrqJC4(Hbrey674mbbRI?=DF9#0X=dA9Cv0%+vA`S zop$^5yYz&{cO$6P6FYhLmiN%AXmnCMK1V}bxlE(04xB-c<_?r}0Pf~l`wMg8P;BQ3 zyM7|r>`&}oFI@$S>T{lzY8ygvr5b*BoY#gg)?oO1o4O6|LzRKbIsYAOOxcAJpy=rL z9?*P_x9oxb&MvcDEa?;E@K7j@5Ij4)wO%sqy0|i9s>_K8$Pprmt*qG0tC|u_(5dOZ znqL-TZ$VMg9%IY4m?6Mv-N4hU*cK($^C9=5=C#`P4ouRCuCz~BPa4bEGnHA&J7h!Z zR>B%b^O#oodaNH6P?Z@%hH!+jUZ;e6{Q_`i459pMft=->DrR)^f&IELebkuT8w2^9 z{bKw<6blU^wHqk*6NG7Y=HhMfreTisnKw(qrVW8MbqF`IHKZQdhO4WmN1W=Z5xObz z?lBg1)sbER5>1!8)PJlX=AXk+L{^{Gw{YoOI3l-)QH3NVzQm5ko`r|qOt_1_c+aua zrtN0WWT+zoVw6`F1e+R^SBNV8kdR<+5o>T$F@{M}_Dxbjm4h4j<-?w1CKMs0!C5Uz zNz{8#gw`E#ybK+Rvc_xPb@sN?6}0tu2f@+8or2TDvVEN?#d(eo^a?L2@Mmoffb!1p zikxE#S-;BVyrkX}-Nxbu_2K*IAUJu1Xg}VqbYKv-la?j*_xyGSe5{+&m*=Es^EbIR z>-Ta@hQpyVa&E9VY>oLh0iz#|Sz5t%p>E|#r+pX(y<_+0j@>DcQ~@dxOEg)B_=e+*k%`ag#Kj@tAzP$T&vMNbq} zv=vJ5tDQ!Y%d(1nhE#GP-yWz4T9-2#^Tc76one6(h)pb8u+26+%QXY*xU8llN$7Wx zDG+Ckh46%+mkyBvt##Q*KZtq@Rbm=NXQd@&+9<_3g`8+{SkySH-0V=#)5ZXB7)sv$ z>>OjPbN2F-qazyh=@_)Zxy@=yjv_~CMTFZ58U0Vb07vO^*gY)uzWum86ycpJIYKwz zCx#feHqNUYsu#4lFVaW%b25x_pZkq1?~~b%ai2u=*d~5|Z19L^0%0{8p&Z0|nl1yl zhhHZuXg5K3E#Y7ghk#3h=Pp2UZ@RH?QMY_kp3}|6y;mFcIQe%~_*Bw=FGR^ofiV6P z@kDD-hj=x@BWh~ z>%3K9$*iY6|%{tTpX3Urp!=r|}WVqp_o z_wpZdk(@=B!M6~(3CD3l(x`FuoaEWVxW5Cz8(f71*{T$iA_{p))8g_;z>(`IBzc13N!=rK-1RqJ_i{T>?JCc(A zQ+5TR2LIN$SI&`L=%lYNl5c{8+0;GMMVD&b-xAe(_p#~@Y`{a=hOJ-Dz7>^y9foDx`~!?MDXf(IdI2|1lWEp7^P#Nw#QyPG|1okwa^ zy7w2yp|iH@owzIdURn6ABfYKf60@3dE8dtE=3O!smm8X2eFk<@;iIoIulo`2QR{@vjDj-TFlZ>UAclG*%D8l|H59LHPm~n%YEb;1N&Q;`KqHI9Z$*I%kHy z^P5c|A|BPIwYqnw4q7fa8gtQxnpQK8wPK|iHheiXY^Esu5@p*7olc7liGA# zWf+b!?qfAvmL7L5TH{d;X2+%N;VL6~d&KggzoO7BryG_9Xh#h(JIr3-BD-!50#mDL zLKQw8{DD-}OaoPh-Q>nlRCmwXlNd8ALZF(B*~yb%H3G$2B8Vamv8uUb`=tnt*D3XRx-x|oK|Bv~ z6u${M296VHie7MZi(%RptK=|jxXv>)FEXIJ<4I>(^~HkVsem&<^{8m~Z8MyTgz1K; z9pWyt#4O?D+rv6?l&VvIIA=kOx=xMav3{7olo(n)Lps_|tMHX%SaOr5w*mt1>1eK>0soJWwHX+hXTpj`aSQW?*NCh&{3I9LkAbGP$hs8EK`@g%b-@wZ zcj7Oxo@E6S9pb0 z3hZ^f)F5pdL_4_(m-jzlgow+%Y2G&b_7nEe2zR;I8jW3DZ+s)eksoJN?m@ch5^aSy z(XN>j?u2s{(2hr!OYwV_2Cs0J0@NWjpi}FdW^;J0%yPW*96{I=^r$>z&^pV%V%|W` z#eKu`{@YRIwf^gV0r&5yU^>a{k|Y}cP^C^+D3eQz*~JmW78+v8`F#CSO3X!>9?`pb zZ=7@>#HZB6aZ!H?8G9FLi(hsXzewq&NaQ3~FMz4oj0-3OuVj4*hLu)qRUJ!BLTv-3 zSO-%|6GJOQm|)F4q{Q(J!Uet8l&2d*Uk#M~^tLj4VUyjP?+rab3EOE%(Pbg!dEl3J zI=<3>^bL}nThN?lu-oz9wGCnXP7#gf=k(1SRuJRR4#n&Z7fcs(6<>!s7e;@_?)c}O z9KZDXaBju=2C{!F?}Fz`koN;#qaY8vWYq-nDeb(rYXrGIO3%VKLYmstOT{B=aTZ%2Ndm*UBXUI zTEHz)YIkf=do7-zaeBc9-)XOyz48xoFV~@(3|I_WRCk~RgaNQxMU*YmloF+=rv<-*I4MGPUU6YOP;H%3V_@rQWxa$Iq|)cSur=>0qj|kgx)+{KLCfIj+zsuD zy8|nVJE==IxjP-@%?m#LvqKk}%$HI*cmj}gsi;}2_G4`g3Ql|NkG??3+0WbrZo9p| zF$`_|FNUq#xers6$=J!;ZiWDBM`L5qS^OFt<*cz!m3HK(p7&3`Q)c%Hd}%^`fdm@u zAkqo`{+vRG+}{Mf{zg?sTGPcDlgoi1{Pip0EqHv)hE0jiMm(r*OtEM?Xr5sP=XQPx zBpf0G+Ezt#l4!2^Xxy2GX%-~aysUKLR{|s*M`p?pA%K)(nW&|WmXeiAAWeDJ!}JMH ztj^?Im}GO(FHRjX@Y~5uM80`(M`-(6*aqI`spnG6Q9Su#>pVhPO5_+PwL#!m(do6< z#OOcn1Tji}GV6&_YwYjWLJ&5t@H?4f^qWt%!!n@mjc?_I7rtB-I zHTTYHx=w2&U)8eZ-McLo4Any)-uWv2!(A$Edvz;8Sz7RhAr=7HXul28m(cLgaA^?7 z;jtzQvvU7KrGnDHe<9fICpB1iv(=?p^0rM>M4pJk9X`#H$s$-%tO;@JkC(FclYxBi zRR5Sa{LYaGNDy)nqO2~q87)=oNy$cQv1=Vjx*AjDwpP>yEOIPny(O&ue3lWL*f^N! zQX6j_H!TaIb!xNDa@pW(cPykH!#PA9OKN@a*pU-w+rGdpyD?02jHNSp%(Cp1%Bo{~ zWi%D8FooWSzpyG>B&ao-EBvYSPpb-QjtivnB0F~zB;CB@r&65(8wv}~nnQ>%5lgTv zBg~3tR-GSpo>)4r*Q;bg8%R00miUf9^R7(^d>{A|pVc(Tj_fO zU30Lx%o56&=QHR6P-J}KKYJ+tcPid{N=f60S&&L%yWt|V1OhH6;T=3Fo5NP5sgNe= z?V}X32SD!A@cjOnc>I@AQU_{CFIffBS{9SWHQJ^qNZo}wM|ZZsMfMmMDTAr6wy5=3 zacjReVs29`7_CYyqgGaOFU}?|z|ecfLFzGPLWpyrH-x7jIa|gXio!2Zf>j!2z5I*& zCn3l7)6$GcLKM31-M?|4U6Y_)yKkSoOBXYszCFO18D5ne1kXb2SUnBLCJY#cim7HH z5#r`R88+}9YUj@XKy1c5)Je6#IfplQ*KH6`idW{Pvi#McKfc=UiPTV47n%U7>s=|?Z0hMEUIfbZaZL^*Cu=>PNN4lhN@dcAp zte|5}xR2MBLCyI}_nqGlQncmRFa-G%_Ep9Jw%Zw8(;1$f?>x;?ZWMlePtKctf(FrI z!Xes*AvNSJqpcbLlC@Z`6s$%tjQzw-$B3v<^Nnp9n%)Ng0%^$Y9F~arAF2E|#1Vac zk7`r=G{D@#TSljJtJK_a(iWXO;)PEzbm!tH76Bcpd{@-z=mmoXsArkO-?H{HS3UI)r) z9Joo0Ce?y?rN7~_L}YqI_xl(t1qZCotLf2!vMs_^*X-m?UWX?inrB5F09+}4BTg$Y zZLwd!S6_&5j~czc)!|tz+*HpfUED(m4pXTLnuowS&oQ)%xVE9+4>JEa{9Jn&H38!8 z4bWzcAsuIPx*-JO^4+B}mir#g(7`)9=^u(s*!;I;6IOSvJY8Bv_atCRn1_U{AB@74 zB36*Cba1gWbrVW<5j(r>^WMjwEQyE+QiP;sWNlgj!irOB8nzD9!diLIxtFCFc4R;_ z3t7^(%!J>r1dnlwbTx|(~m=|`Ijsgcf$Sf9a7P=W?{pak2 z!4R#e3tWtvvcxQFfOR{}#W2f9>Pe!IG<<6e z|zOI-Tq z*a`9!;w;-)Zhy@=fOzN}icLOS{4T}vrEQk7_hGKm`xe?;+zliA3yxC_e+n@^@xNp6 zSiyh89nrsJHXTNSR5F{bW*(v;hZY>8qhSfH3{pxNc8nYX1Y7NEIXVA37n#{Y|JA1A zHBXiMrG=Edd zXAGnqgJBM1?>s2bM+O9*-qJ@#hWTW2pD>$^pvpn5yiY0>tMOt@Y?;*HSC}0A~w@$N#}I`&H&13vOucp-yKo z2_Be4E(Rn7bDzsOfHau8j(mpztiaT}W*9t%$c;bwf5ODS;wN(Zj_Rw1!Mtu$=AI}j zf(XJpj`zgkve=W1NSsKd{86K7+nzTykD@r0T!QzyU64r>KxnAZ!4!lOxo^KI2^8nF`FOV zM=_Xah5XPQtaiAuFGf6Ap;v^)727h&@7fa2ytP1{0jJew>$s`Kpr!qGd3)+0;h991 zZdi`;bpjGcn&W%N5Icp|#&FCYSo*qKz(3mIxXnrl8Ke(B>})1{G*XdFwbHL5e5TTP@RLgx9* z-_Cm79mL%S>=9rdEoMeDq!6PhU&o)QafGufqbzpOKy)3!!c6e`ZaLpF%yBy@V0N9L zF64hvd^*H+DV$%?ChHX=Hn?!qqv|ut5QnFSAUw9Z+?o660?P=KjP^L&T)6@cM0o|@@B@PuAOdg_0-$zA_|qUfj3hy+VF%GKHg7j-ib6ch;- z)})0^d~*MW=8PBV-sL?|QPF`~aj|ziOJ*d&)9=qzm|SM8Shz*wL)lfVUCAb>MXA%8 zQHARSN>d0RX?7MlsHNB0x7LLs_Z1{c+No(R!q8zTcuy@1ytEL{K@fLs89th;{g2RV z*yMbMRl7)R3aZj(i!MAm5lK~x9Op9s*(&e6eYdd!5Qz@Eu9k#(h{ApP-8Kgq=@PGf zM`hK!WaqV}F0V)99AZ%%b9HVGTqukNBA4KiNX6x7=O>_EF82Q>kseUV7II9#WwH)cU z=vUAjC&}NbT(+3O_S^jxMt=~?nx#{=nup-TJ=|c;BU(t>>pnqUHR%w#m3}Pkww|5e zS({KHK;?XMei{0=v^n#k@hF^?$N2*Ft$H{l{5w2LlD6LdC-42B0&hQsQm;R>_)r$Y zpB1rW+cdHmTboohkT9oBUH8@Hgg}S7C2PjUneoNJNy&i3TCzZHuSn&0cCK)!!CJAl zDoN4GS5}!;)hCZc$q)*PuDKW~0Bx$pi>ZTMx+zF#v9C0zBDGFE$_9F85f8m$Fw9`= zO$80Cjf3(19PJ|~XELT5Kd}>tR&}*5DD`tER*hG>Q!YTSMtd_kMCaHSRL-XIQA4I8 zK>dt(1IZD3Q4!0tivrF)qp{)f>r5ZzlE)`w{{>vHnrHB({wZE$EW9s1VpGJO&3K`F;MVsShhW5N6o(4-g?VSciikbhw*idr1|? z{y1F;lke-ddDS;<;B7yq@O<q_3U|OMD{FYj?-nwDb`{u+$u83Czd zG{|G2S&HUl4+Zi9Q#$^4=Ni4#G zkLDT3_StvS9bg;_xytS}RPS=R*OGiWx*RjnwH$J6ZTH2{3+P4k6Z3||DASX!UAzI( z4?2@JNiRc})PTFEPe0(_J)+Fq^`r6}vYYAg7YVsG{D!+6*mZmIPxNCt|A$+p<^P+M z{-Amv5u$S66IUpNBA^!i0xTprt7uGiHTu0a?uy8d|A;^?H*Lt8wf)W}DndbRIytF9 zZLP^{Y>g7+XqE69hNVm~gK36y!g*p|PpUs0OuXMLdLr{U=r12MkFiU-|) zkMJf)TmNT{4^;0oQ}Ea=;S06qUPRNS|LIg(_V*` zOx;s?+$d6%-CmWm62s)I2q6q!`UTSjgRQDvYjgLbo<>|BF&(TF;Lnb5Vt<`cy9_`%B+*UA%Jp+x=AED&{vRvs^7PhDn5VY&;(l5iKdPY;@C3N-FE*-^ET2ETG>R61;KBzkQ|i zC?zoFEahBr=g``AAYWjt$w+;})M8{m@G-{$ZDm+s~vdTo= zfuMtw8&QZvBTKvxzTug{O)W%Avvn0x)BK1U!`|EdQdudAAz@C2fSiVug*>^JWFVr! zDhqLuf4ESo&M;QU5y*kP;31+^0J3D?P3&Nss|b9$noJRN+a54GRpr~l2K%yO@(pKB zzqD!O*p`7>wK}GG-`uUw$3s6SZZNC{=(LPytDP|GwhxljatEFT{2OkK#bc&yh@Zgm zWa<5S4}N|0Ak9H-ujwrKMASi)z6*s^8_@)IgBw`+z7Vdf;zk5hU1Rf$L&ZTnyH-^% zDu=?QDyOyH zEX1^#TA+{=Be#W!ZCtEeniLaE=Q;(F=Tyw492m+}is%4o_oct-b;zi=@zuK(IQZpF z8+*QwwHYb4TB`PAuG_7Pq34s#O0XQ_HrNnp4DWyajfG<54q7)hbol5PBn%;-kTE#P zKF_r`r;_#t>T1S8pSRRng3Pk+8jRy#zh=w1GWSy7^9D9EY_p#8pDe~J|CjZIz5YPO z`$&-5E|s|pK`=JfZ}~YPg@dt9P&$r`)sd3}Ld$eV>-RO{OP|PqS}<^|i89j}CBrIqJ|y``#h6z52I@V8`bL zPzPN?1&Mdu3(Ikp2xx~&T$=^)IXv}0f@o00$OeG2q1NAkxk{9Jb-&s2uMncLGXFcI zla(JPKnT12MsEmOVL&oxkU~-{LmHCQ$r?3HFyCra2X1U)TDo?Y zwjmoxEl)V8dpC~k)t@cR51m z(cT8r5>~mvcHPRV08O~hz5{Qd*sq=|81?dCi-F!YA5`2_8k$T8zAe7!E2c|=!*%u5 z`Gg|hmcZeZ5uYH@EtU^p2^caMD4H%b9^B>h`|g2-yq5ZnCW&!#77C?anz}g`4wlnmHx= zZ>w2gzem2%xA4uJW>Z1vytX5hDT$lTm>UDs>+1x@a|%9>4zXSjDXmlW#8&=n9sMN* z=)UG{Tm{!T&W+h!iwT7ZY$7AK1w(0?B9r!dVP%*TybWAiDMbT@_bCIq);R%>W$&_N zz?Cj6e%JL=XAu1SlkXEWM^q*v+x5;YKePO$jEer|#GA#|Mdx}!5HNtoBjjpboA%Yr z%0zglb{?6G&oGoK^3lcF!R6%L*JImC#|pAd@>_^=os7Fo4(9YP10w(ss1eZ#7$#|8 zGS%Hr9d7#jBPu@S$PjRB+8{vi3f8#J1sIQ~g5^u+T(fv@S;*5Sa>p87cYoG$-vk)9n35B*hWGoE8$=HLS)sk~%FvtSU zLAK6zq7*S8J9R~vFm6RJqJJNwj;=EP%JuhAs!6F(7U03jN3nwyk}p-yFkxAQr?!)q zk0Q3zsR{Jw?^a)^Ot+oi_S5t9wLJ*TnNitWI7Iuc1uiCfPv9tvt*`ILrUvi0KI8dw zB9iLVFp-tEJHxUBc=V{uB? zM>H`h4{kJw4%uTR!W&n<{{(1$fglquFzjSUQ4pNVEQ%-g1W_!0lVUi@q3PJLdcZoN zl&EP+J{JK%DqamFgg6Ovjiw(m&$h@jNV1+ltQV*JW!+*KtEarsvsy;S_-6$12O}h~ z@r(>%%dC(QE1^xxk$6vTOMY)c`pnY>MjDk|(O~#ff47Gl(F|==;_eO+O&M$w{ZHQ3 zq(C>z+u`NA2UUwaG+~_Hd!b?(JzN$nz|dg|X88)o<^(GtHD;(;(y*RK{FRRY2BAo; zn%)G&4%N=&__9)WQoyQMx6Aq28ZWs|ZTP~QH)8lQ6hK6R5fmMz7fNqZ8&C?BuTvc0 zY4fTr6R>$bN{iX6CQQH$tdU7j;OHY-W`>A^P_PF7ukrR|$&yTo>lX#&uw>z6a%5>kUiKbdr4cxz+uD{J{RYDjy$o2c4Fg~1#@^&J-Um-Lq`BM zg~0J?y!+*x{6KqIB+O2-Bb>uk$PT^ANz9f9OM<5PasNn!cDB)&Ww-1arZVJ{DltAx zi^9%nw3=QqPay2Z8mfW$M})IUg07q)e5-KEY%O%cqCqLh0pWl8fYLyMxD{McIeZTr z55jcHxCp;Be=oMlVzq)5_?34KN(gtFA2^)I5$qmK**1i>*E4QSc){o%2c40Rh5|z* ztsKSNAX6a^lhFSBTp*Rw@V9X7Q))1dUuPaRenPK5Bi&Cg)k?n7g(Z~H*c4B{KGwLf zgLgXFvO#;a{BlE(8g9{sr^Z0pF?JCWKokFvlg5AeP3pg~#VCc^s+2?M3OkjZQLrSP z7LX%nZo%i%ysSXwW`N~%zb_R)XuPfrlZwA%pP!3fw8H90hpMUB9ZKx5?{uWy>`&x2 z#QL?zx>^#=4W9QvJ+oM98k&0ic|2qQarUbSkb-J0j52IilE7D?=-oRiK7&eLx=iJp zR`6|hm&csgb$F!9lJSgQgxKfxWH?}aJ%iqXcRNeH70xFP^T7F7;Lq55ky5!*qsSw9 z-Ad;S+y!L1nOEojqN%H{_fX?X+E#;5EE@f0wJbGK4=R9O+&r~)e`s-u|2p$Jh6HIK zOL7Idz$Xy-l$Z9;Q7Jmplt;H#huVTh1F}FdJA&GjWmqx-KyS~-@yKR&{vR0l3P2KK zeIvmvFlprT{4=DofPI8=aVdowQV8QhymrS?`40GEZ75nqb6J{lW;=ya*J3NsJdWr= z3~mi47{}H~LYUn5jZ{Vs0_g56$*;@f&4J^QnUTGRi^FoR-hJ3**MU;dHo`ArW11T; z5ppyZBh29+;&x{K>D1?6Fd}?n@%8gkbb(cpU=fO7p<(j!*%(U*93kc4MVZ8LLgw8t z#b4KVuV)x_`j9E&WA$v4AmMB5@7h4q!6~4eM1U0jUp^j{&q|9{j_NhWVA^9ulE&AXwbFWB?r7 z=N*7L!XZ)~5W0z2L0Hj=aWg&Kb^iccRazLkO_TP z38|9E9B3ldQN;NWuf3lNWd5O#``V?7OJO^tU|Y(bB<@-t;CJ>6x$h_uI0%JiO`7m| zfeKl!9n%7c7j53dPTkOoeoXqwI{1#ta}?mb>7PatTf^ zKKEXMdN1a=CIdafdc@S?FMVc6h``xMK8ydPGSv@s)#{I z+^AIMP=MzV1dutGHN({dOWBi!d2uLo3eSwdYcHxUd>PJj`L0t!@E{drot4Z{mmmq_ zVkMyb1Ua?#W(SiOj^Oy5KJ`M4aV9q|6i9DpXwx&jhK%t9m_D~`i9?PPu-X!uF+anz z4k^I}WV#*jPbT(roJkEP3ae@|adkMEz8L;GJv;M-ztvL23m z9CA&%==7gHDBUD8QhG@8|`G0fZXmv>-MP z)M)q$^YMY&^td9^pKo(Pxl0MVhls~A+3rsgOgf1`gN1SF4EYXlm7Tq)M>_T0u z{Vf{+$Td$6hU<|~VHH)zQaI|WV6MbvZET@+VCI=pZfK>Dfq2ltoy4BdDPr(D+a`yE zRcI>Jj>V&4$jc9!*=mdcCv06Cmq%t29ZHJi7$6R6R;!m>-6Fe&lX1`&gEB(=eGT zjBUUeY5Tx)IQoLBI75aNWamDAjBUakBaQh_*3E@Q@l8<(0Ky?(FO^`<#uV{)^!C0b z%tl;kg0M9kyzEMN?;~x0h9)L5Xdj*+9}{A-A?CuGqJKB zFg1Q8VcwP{J(Y$40)lfz)J6lC+AAs_a$OOWBbD7$k`z8Mf5#}sXutEkCt>tK+*`)I zJ1yl3HYXjcEFy!Go9j1Lqjq+YD3(`5^YObx1+|}Y!BV?f0`W7ewX{~$*U%ap-%BC@U5CGFp5c#&3a~*eLj{*&(KS^#w3?T2=yzt?LqMo@ro`m zVrh+x90HcRYBX-U7<&-b-!O%3Z;=NrdG$`O#2cb!pN(mHlJVlHm$NvZc1?|1QlK3Q zpgW=qRA!`?e!&l@1C9#CLY8SH&`ux{hkls7mL-3)05 ze$QhY_tJlPr>|K{ZuPu$nw#bLIX1KWxZgn2o2qe&#Xi66lYH&?6^XPJ*T;f^azM;Or@ro< zSvTrdbjvibzjZr$+WRD4ik&ODYrpr5E`8VS<*r(!QB8U{Tw7o)~NtZial)Gp2tktc1Vnw2hB zG}70Yx=f>1?r4Q7h0TqNGC0=k-XuE*GC6VqjoO5T?26!L+DEgX%T=dsAS}``=wyHl ziQ(YmZUa}G#ye<4BjZ46v~PWVDUu7MlahuV`Zkwt@~9d)8`?6C^S%z21_0RG1Os}P zX_Nl?wgCKBuhRFGiR;PMMg7yOqX8E|soru72ngCij5x+%V-ZA>U3p=3w zeIS4r?seyh8}6=HYGU(BEnYM3#CmK-kYibo5QwfsH7{L6ARoHa2nr6^{`VtlnLPJC zYOA2w8nLTQaMFrjkZ`D1?~rGnT)d^Ze=r&naU(=H)w@F#u;Np;M07N!NRc@NaE)Ex zvKJVP35Co4C?x41hXl&zocM20(M57l3Xe%RduCBg;Af2{>lZE058VCc&s@E}9`ujZ zX>9=7rHY(;3Y2XD;*x2@7B5^SXepMt5a4#N6?@iv!FjYHwC|P!5G!&XM=SD<_V=-RE-% z9ZxMt$NK`GyMP~b)b>P}gE|hR`O6i8Q$F|-^2@gS5<8SjXtNa*Pyr-@Zdfv4 zcI|IZ7Z;U$=D>YGjl|eo+c*a92K(K>)gg!!%^XlY!!6cOULm5DzTGLW7b(w=>@f}N z1Tpr-x-)w#Z^Tl^o5NG?!YI2ovEJv)8E{I&!h0pA2vPDAf4+yo;TD(<@Z0j-L42*Wjk zNA`UZeSM&SO)A@?g6*m@jX!Mg_l7MM&n58T2oy+?0XV)P>;K532;U>IY?veTgVUAT zkB3WoFCVS0i4r!$(q=ys9dpyIUO3p6J|OZE^UN6QY7ETsaRw{GaOzSU?p3v+3#B`s z{x+FPFIH(#W9XYC2@G=)=lVe6t(B+I<}GhQuT>k8GmQB)DGZC$l;EI$ptIXeZ zfX3x;69lwq6?!=`9qa5Rgg+8$&c@U0L`YQfq zlE@ZOTJmt2&svf+@Xm1WYg1oNNmMq|ugKMd9T8pCr&g7Zgj3LiTttmE%w z#i+RMNPzEb*s4HP1%eEkq;NI^HDqA><+WX#nxvWt>Lm>Z)5Wt=d zr^5~I8KbYfrz~VtYd=OziQcL1W>4kb?-Azqt<9h?$B(nWmCDTd`#1BbUhH;Gf}V=` zGHL5vz^316^RCTJP^dQxxq;})csOcs5s?E(RBPFgDYzR zJ6b)ti{9U-HzI&5tHAjVi>1~bd{euMGpU9sSRl&=r5s;#d-Z(uRxMbAjt(=}*!x!M zc}D^4)FrM^l~(twkZ4p7d*ysopQff?OvVfMc>p(Ua@sR!*3~sohUWXtyL`TE&!GK1 z5xxD)H+%dMoPUJ8eM#^-wV&kMt4>ECz%%qw$};q01jq9ml;KUd0EqXHXFslYg~uaG zBNL7Bg62n;jB)L0H+n3rBee_JV!p44{ag_FOLD{LEJZiuh60CPDI)j5u=D~KrjcG0 zPclz_-JjVQ*gaPZOgyv&O-LtU8O27Dfjgx74Q_wNSv-Br?6hf;YRk7=yX}ka+k|}& zYH}q6L(U*YQ%5yREq3F)R$#a zZIL9y5qHR}0d>le5@|8$Equ7sYR%_$c=q9P7jEd9)Gpt!=LZ5zZ9g2}mOoLpPLfSK zec@simUzlAlc}A78zRo`^ws0Z>cq>LgD0Khi*@efszezp$La$mpF?j^h)98vk8vt2t0B>pBc0_3J^@C3A>*g8KPh^LRK!=uoc7t67U?CAuYx^jtfbA={#5R&*8qQ%>%(7I9eV7GeAht?vCZqRIh{V8WlCT zzyK74t;X*Oej`TT-rV>$&EAjW@9e5J7r5d3zR5;a%WhbY9NpOgs2~B9(EaDFa*lBV ztO#$>2#X~)%hf^46D{G3{+QONJl;hCE6=^)$JO%fABXCyJ=VmF&grH+pL+PP8x7b? zI*FJ`ea~vF6?X8B5#&Hvq23}Mdnv+M60K9jvgigpw*Z-oV{%$UoM9P}BG{6zN)EBQ zn;417V=^iJ@%F%}j_Q7SyoD|GFY}~3-bS=+^d7)ZP2rbbT#p>y1Zle=1{jf7E>QRc zD$BHO*99=Zq#}w%;CVD;=w)~k-TpRu+%8Rwf>O_eX`L{N1ZxcBKv@VR=O$0yML<-n z#)LJQ`Sw;SlszAwzCe}>LQzGiS(jid?{&L6859Y>W;Xrz)@K0mT>M*cGpZ~yg(K_= zLxVN?hG8v()BM*RT`(h{<~o&jwb_gSO2k<-twE)jM(3tShh9J$zyn{&iVGt}ssR_R z!X_P26lJZ}ZN}Kl=@oP>vYl!ZGMY}JVpErG5LYyf;kd+N%=(@+ttj3~%{0we!ho0> z)s6(|Oqn?$So1&L8t@lvni)3XExu5n) z)^}d-+ck$l^|gmkJkHL@%}UEmo^&Yajp6=S8b*5^ykhCy-GSB*o9qs%q?DwkTbP-d zmR**Wq>=nBZ3a6YZT7;$|8p)X%IU;blW=)_gT5-Ij0*m9kjla7qc5I<$ZGQK8m70_wXazj)wWHNi5LEfJtVYHOc-r` z(Tp84>aLucDZk^YuV_i$G*JF|l#^5dSRQ>w_aEwk)K9k(nWg(vKV&T9k>5cTbisyt zZL@I{WAg^9n}m)&K>TSpuF}$is_EGod6_UQj){o=A?0g?cFQZj=hW9-)BT`XEl0|j zf(M>J9&>tMd)c+jRsFLaG;S_qSL5^*RnbV$N`rDSDS9rS1~`+nPp{r_&N;0oO2)jM zOc_c1-06lW3|3B{^Qw27-C?iQDbu>Rc zbO02zL9Vu8dE|^F%=~+OEM)G4@`a`vUg1vRDn2NPVr^#<%NXXUoQ3mj#GD*|9r=Xu@l%~1d@i-1aTNIP=WBY)V|O9_ z;eJP1Qb_?xO9;`{-3FPT5p;+Wp*$$8EP~+dl3TgpBiaNk%JX|=Hoo;n#_JL9M5O3? znf5qgKg?`s>H^K8?m>=9xb=`}s^w-OhAL|Sxppp~MA+xqBaCNRB8tnZ5B0y}OyfY7 zHFnShL5`z|9tSQPSoPxD+V=JFxsoG2#Z%{Z;kg}kYOP|4<{{&4ktRC(Ly<>cn(>ac zA&!gjp8{f7gsB6> zha_2WMEQH11b=`@4g5mauRe>9kQ59oB}B6H&0DpCNP0chh) zmPJ5_hrAcgswX6%(2Y``J+M7W$gVnE&ogobR;nd|)ady)^sm_*;o=*qY4clJSBZ?XD8C3~$hNXT8$~)ew z3z}VBdcJ<$bH4ZNTj6#!U8Y z>pt{E>>3_8FR3pgThH)Q!oLh%We(&h;|UjH#97kdTl2axOEYSBt=LeH(b0!Md1*<3 zd;xkC9aYA#0ITBU7T_UVT;D9WJ;s|aH}?-Xz@A9No}`iC8}71d=eF@*OHO+9j9}Wf zIh3$;@+H@xT9#~B3V2-R@=vx#*2F!k@U^JFF>tNFQUa}mm08G)2ya>Zi)4a_U)ZRi zP*81$H(^ib#cT`eeZY4LIdO}J=R{DUq3<_dkD^O3T)AdO=gfeWz9JBI&+;XdQs4@A z3mZ5;G!H$jg*odx3fW}8F@!1s=ig{n-e9k75=7`pZhhjl;1Ws`vQ9C6k`SL31xfu# zvmONQMaCM%c#9XZT_#aIN}8d&QF$T$GzmtOGhMEi$LFFD8(7eoN52I-y8hv&cLXmG|*_m0h&R~Hq`EhLeR*5 zC<9M#=(H&o?I`7H$yO&zIhNo6&Tr1n${8k$=_6AQv1Eafl597U)k(9DN%Tn~qmSfz zA)`?m#87~v7D6~PSxl!~CIq-$j9la21LVYp&BchxB;?9ll4q4avE>7+tdWCF4}=^` z|I+jT#`?sd0&uT1D)%8lY`%?3=oqJ9u@!B^rl8xxXu$8RQT*7DkWgw?i;6yryy;tw z78%LZ4JcQ&GcEFZQTNkxTRfJ@rn5%o<~#7A5WT6T6;*0#yeTh`nAhb61J(Z{FVqvk zKeLBl@`*LrN;5m*&ES%R=fJhtDhx!-@9XewtOFNnpAu52AE~#Bt_Jk|I*D~k6Qi%9 zGy!S*u~Ko(D|4n}K?{R&xfYdtSLe!hLOD`j;7Ybj#UZro@|wH45hzrvyjT%MAR>M{ z`1tWIEj=_4#kOaLLi@ zGtC>Nnw2AC>lVU?E%E_iuk0=6rA7m2_Y|h^&3Y0!IyMKHlti!pdjYK1izhr0xBHz! zI(_twcc!>$v8)ly4j}MJMWD96zN~ddsqQGs05qO1mB`()QwOjKn;k>9@<5Q2z2Aht z{(}7dd$fuDD+Z4i(Sm0y8h=_KT_5X|bu%q8Du{h&$kIMJL+djOFe`;vbV*~nHrPy+R*|~Ry z4?cW=!T^D2d2>;?6;O~R8a-=Ay16RrHj5d`L~*h^%Neddnqbn)RwY-FI`1-n8-LYt zYPCdmxc?gq51v`L|Kh?)y#3C?{UNMhx%cAAN&MGWo?spPF9&6GPIQ`qwAm>0(t%|_LTb(ODJGb(*@-bf2s?*kT!&2WyM zZMn~4*~|V4XPjNkj+kF!!hj;542Cro3cDpMy`s#BuhD8*EsU>}? zcmvE-cnI5*9?WAU=rWe(6Y(`UBJu>CFcrzF-jZRe#BlRC{U#tH^8Ya+60Fj;~P z7~{6&sG9hrS?o11AgH@)h72`p(<75J*GalCe15pSv!OwABI|pI3ie@OH(e4(+0l(o zr^0MG5J*MD__V!UZdHnRmS!b!hi%%Ii??UtZ?b-9NasVGO%;roAg{`r9x9qL#v}Z^idkO0#v!w>-skmSxTLs#* zPI@=na?(52GOxX#uCN+C3YURu;kxuY0-gLUM3V@{A&IU)GRL9yXFFToV8eMZ`w!{{ak*+SAhoE@ih5IwzJx7G# zib24FDd1O|^o7z^_blKIn92xD^fKU<2vr~kk>Vf}pwBxpAO)VZggqr$YD-%HY3sqs z`4zNz7~dU(7`YVQw`Lib!VJmSRK zOko9N07a%KfB@u(a3%D53NAzM5?pOf7SdoX5WZII$PotSph^t&Ubrp{I7A`0Bey~- za4~#3?R~ts>Ou4T8a_2Uo#uJ(x`B(8BXO3Gd8|r!BUhkij4NQinxgNd;q16`^bsM= z!_)R@@0ucLo%YU;yIp8qbf5{B%}($1=&If9z~xov@}hfO1L$&|q**64FVpihW1nHc zFq;-vOt@hZ|2395L?>Mf95&`yZj*~Ky2!x94t`uIU5QObK_ezjYXgK0zC>=^2LhW& zNm5C`b#;zeRDsuTpvN&~94=jEa;QQ#A`N?cb)ES`87f+R)`a@Y-QC^l?q2=R3S4!Y z6y8qZsqjrVvN#wMYv>7&*BoP2ICSM;Vd5>dfIqA`?-pd1kR&P;LWN$MFqXn9C?2Z5 z@GUVGR>a&sDTAUZ{ZN7FumGS;qDtY(6VRW}*6;)cy(u;o@X3gq*lK-+!&2dUVR2q7 zr>RB(XXYa~fIj-JZS}F9$T{Kjc&bRkQUjM`(u*nNkAr1nS3Rk+^hAply~ zAl%xAXCX0yI)F4h3oE+SV`-x7t8ZXzv6fk&@t~M7esBPvKb-VW+82j?Z1Cewvt4>` zEQ^f&1iKd8Jw3Z@A7`<##Mn9X!>AC>?Ed0!A zB3;e6h9r!;A-}zha&0JVqq5>hV?CrLYwFy)H^6KWXm@{_AZS0>cCQ0)KSm;`J z_U+gWE&D5eLif(PeUx2=dr9q!>D=Ui^3u&*fk#i4sb$&>`fS!XD-%g;BU2#xB#jXl zi)NUq&?(K=_$!i?xT;m?KUCsA|A(fEGm8)#C}|k+b_UImc6+|!U)*7zg~Uuqnm92u zQ~Vwb?STRNVBppa@hIcS`aac(qua!Co6a(7un`_|rryYR?(upv;(?7Zp!S8Sv2WED zr+3r(=INSLhraZ96=hZ7+j3dqq-yc-PRY?Ws(!Cy%i1D5D^TnSOW?S^3g4k+Xo!sE zugDsZ*a51FrxIr#0TrL9osr9gpO0Obk4NR%%Djq((ZFl5zQQMz&wRp>6XO zB!q9wn&ulC<@#{ZpRTp;xTOnGsz}cX4$f$ZDH#u{V=G!7BHV)O+a4nO1wjQ zOqtH&K0t@L&pdosWu=QO&(3UQ`;e;)9Ku>(=o9+=xu+jRJbmT2)-KMhW%8WAmXgWYztab3;)m z+$8jE(>SIe^Rh61h<@9BiNnm`kP3L1XnD?vZ^)@JUtLwlI0sl4j&_ zU*&69*v`-AZyZco!9yVw^{p!ynw6x$!EpTLX0`ChfXG#iCFy)eZpN&I|p6`;Gw_Kd=xU1-Qs-nRD+iie=w>k>^_Tt6jO)ot(4nPMdZW^-#4eTxh9K2aG-BZ={FwtF?Q4`yq-w+E=ktB5-%w4e} zVgW9A%JBtj7sy=|1wPcNg4%lFU+jM)!LzLjc%02VYf~FZlAqD9C^Hcl$pV4rChpD} zJ5I*3;Rdh+@OT^^hob2&NxihXwfz8V9sci^nf30j24UliC1wn&M^?ToGpkC29^2{d zutgT}XY63e!kuZH@SUPuCD5=rORG&9&>M6HJ@zG}62!h-E2*k3|f>_jdR9SvF~>fW{$nRu&RLvJGZqFZyX0(| zRcXY6lFiF<`D`$_xw+Y$=A1{oxGJ;dZkEpmMH!?~kVnM;LE!%f*>aV~vw6w354!B> z-rlc$_~$53(EqfH33f3fs(Lw1g7C zo74B~m=^`~z2Pa(gM_`SE|WO4Xk$Uame^R#fzHbnO(fdRB`WMSiYh39z9Hi=^wa8^ zWVM_5C)g?40`!B7og(BGKm2)(3J;ixdPlt zJI7}ShcIRI^62>J;v-V<`sm_xe16Vezdd6k_HJ}`adhzhcyz|zy+3>R_I$j%!Ol5X zY$k^KIIYvY!tSE8x z$%ySe-QVBe+5dI#Kl|+c`3T7ybUMGp(}+*m;port!UZ5LugFHq>4EEJYU;-K&^0@!&wmcXnQ1i~Pk zyD0x&lu?`!iB?k%?x5DTD$w7R&DL_YcKZJKcxa8ojp+nMs|S*xJtIdb zX2QHj5}zdacXQl3lC2mh^GP9|!aqCUrVItrnfH z9fncM}$EKkQW=htdg=SM4Ctk4ijAzDp8c3x+3 zWY6uvmJnF8UU9%RTR~4G{t^U0)cCqeLlh-}6Tt)uFRwtgvc&=dmkH=6FsXpZ@o0*> zdCto!PYd!9eKxIf6DCpCE}{Ab@bO6mWK4xcUeDR5*6obFk`eN6GYS z$HXGc;a^SGHZ6y982TC~X0zc`eiobV-5n z8bLE=A@>e#g@#oPowIvok>j=F$UW^>~0S<@{wdc zwXs{kRm)VAyxdKcfB-EM%~ooer2Izkc1mKmEy}W3FuvrCdy1B6AbnC@pUJA>FWVK=2cbkh>o@|SsE#L3 z1b)JIu-BvGa|r)7jO%DRoF7mU4Eu_w51}9m(tVY~r~yKlV9;x;ffc}74!KV|p0?oo z%3raPCk1zqX>;a3#9oWL`14~N-qdi`VRC)5`c7t(5;{BE_i)_ofEMTL7`AVx$^w4G zC1Q5-Al^^_`hHy}0B!uIPCNYgf70_G;w`0xym$!iYETHp@JuA0b)K1Yw9c^yb(BSQ z878<>KL~|3G?z%3G}o!La_OH+CZ@m-LZJlY5=RMkoiv?w|5U_LlFyGVKVtK=$Xtjng9DbanX9`vdoDq4g^qz z883Ny4bsNE=+)?AG&y{GGBzIC8Sgq}?B1S=tk)UVXNClbH0@;0>r`z#1!1zIj-x?M ztxqFrL9GBZtFUSvk!lH`8=^o_l-Y7()IbD{_0b+9AqF`1u?zh{GALj@KG3GIVQixg zwNDh8F=!yoF%7_Syn{9%sCeImVAmEllzG&L$#7n5!w&3jhw2JSZW~qr;pmuGeO?`% zoqNWwc+vKdwYA2yRAyb!8pkv zWS2@owPt~ufQ;>rO|6mfm;eP>SpXF}suNLq_LyyLF{eplxuM!9gE6|TK@)7H-S8)l z+aQX{IITEI$eP!)Cc?5X5%u-CMs>$Vm5k9h0JT{S0@hdtfrD#tc}nUI!}>V2kId^@ zlRv>{%-MkA$7WWWJ`)&Qh3(J_I^Ddssk=&VPh!-ngwWNk;)g1q*GI-7!NR z9|)grythJJO?u>6rz;owraZl#EI29pI!(44mdj#GJ?iq51BLRTLusv)dvq>NuOVHD zD2FozP#ht9`cl!%nTS<9yt`DWd;#gLsn`h>Cf)rvEhY-;<(_C8ww+T;nfW7SAyx^< zwZR74wQ;p-iB#6QrhIj0NbS&y<*=WsH4nh~dI{+v%13MQTdLL1XLdtz=?wY-boOUd zd;Z-xw|;u~AxN$;49K%;HrJ^k-AF?W3)=p+yL8cN&KDR&6r9U_e)ag8%iTDl`(bC+ z$)g%WH*j`aw`!3@VxoB4(VpWEZC)7X{5_i?GHlH=G?^cGQ{YAp++_}dA{l0EtKsU0 z9as3)CeV=X57205wQKB|D$Kl9t&{?Bh!R0IpcnzA`$l0PRO8niwj)%zL~0eDZ1!1^ zu^SEpk`!f{eV1MJr;U z&9LHv*Wj*hi5iKUDA>AA%199VK}xKo`vCG-I;?Uk!l~m@)KfqY$JyEmxg?IrrcnUS zW~;om9D)r3CY9H_<@E%}*2>`wc=5b`(dP;Kt+5k{_3LJ4PB-gUh3aIu5*GlK$PdI# zgjk7pDK6zrPTo9@k_v@W?L3teT>hpM&+RKD$%RM#b611aWJ z8D%%ACR|5))@3Spu6s3#>Irlxf(>{WY4NajIjUa9cLzK7qw3XbD%!i_-D^^fO0Z{! zeNU-YbM%b%-EO*Vmc`opxWKjpa^(^6$3&|5<6d)ff~jxL1*)D=7BDXBHWT;~O0HE9 zPF{&F+{l|Mc#u1h@i&A9vegdBb6!+Q37L1CHS3gmC2gNnVQ6G|HWVObe{Zk0X`|yk zIXW3nE}n~2 zxu;Wp(8AaCfkB!G4d2=5T-M4)TK+Ol1ISE)2E3g%naaCWhL-N|KKjup5ZHH*8Wn=Z zk6jw*;lG#F^j1ZoU{?CrWYrftAM8qCT_PpOLg;1XO&mg~h=uwzOGy$valtv8mdI4t zH*rVgi-IkI=yJ77V+L(27oUFnjH|ysIvxuW@l%x+@hk-wEb~)&7Y!|75qy~dg8{T^ zxm=Z89I(}IssPdTO8jL|m|HD$0a8oc3fS#RsT8uf@t_J5B=V}9{?~+}qM&pFX3xa6 z?ZwuqTTP`Azbi2lTurCmBmjVEtVQ=}b1RWHWSHU}vujX&V-rOm_IXVed7OQ}^%S4> zKI?&xw0_#o$$vnN!!RV=Ga;bsq~4$Yar*YdsrJ?qHqf^vwZYnCADvH*&dQW0{dCX+P)b$Td9cuc2-eactKTp4fsWlKzi?Nl~5rx{|94d1;N;MA+{UYfMP z_zqm2eoK$N-?x}1YK;aHp68h8P~)AbOv5BAq{-bEzaQG=3~_RQqc~#2-aNr%Q+Yz| zB3?uKr)-J_zkBSB>R?(rrA7&zeA*o$(L;LT8a}mSZ~}TS$7*{!y$q;hw~ggiOmw?a z0f(Jyp$;L%dYqLitcVQ>-&i&odn1 zLpS7NmIOVQ+l=hxX}vYNmQ6cvlEfO$3S!4>E@3%tXAQH%T8p^vnVgu#B;;+2SSh<$ z$(rKL_C2duS$x|vcA_uVu_yV<1fG?2Cf~M>N%h4lW`eJ<;8~$jNmzHK=EU2I6Rt-1 z+?ft-F&K2uNMm|`#bWlmzEKUIo;)!ptaT??r8zeXe2PEUj_TFQsu9)eu`_a$MfdmO&Ep(|o>4PmW0mqx_u`h=Te3@hPD5+_iZA3xMADKjbPVMYRM6{fiU9Qu(5WJQ*U+t>sYGaQ19#hTMP~(31QC$J>sjyXb*NxXJPz- za{uy3OyB3|TjvAoI13LNQml?zG;1)P;Z&iP?fw%5J9Ur)ArTOX1CzRlrF|GfyH8I) z5f#*uwh4-Hlw?6y7kR}s;ssyO1tc-B&$J??jsO+sYH^;gl6MagkyW%8?e61veY&=` zRm!3XGt@*Cx`~#YM54FML5qOho4sC-jgF5-=i_r=N$>CU@6`WJj4%>QU z-i^-2rx&fzY{CS%dUjrecQ86Q9DAUd(ue?4FOAf|yg7dR(udS{fjJxhIX*idLz+1D zp=M`v2wp%I!lIW&dWtgkd2CXiL#HF|pS%FSNJG+k?&4tX;5#?-73Va&#Ru^PH0}&+b7o*eZJzk*iVgJ) zhT;Yf*VRBAF~Bp;>+DL{t5S(M1(!K0@P;lzDTArip!AC@=?L|A7FbWMZas^_nqS+_ z^#FA#0sfXP%Ty`VhGo6XG`m$h0e127ClcZ=b1#BCPfj&q{|8XdJZZRt19+URSZ#CS zHW2=N{ED6ALxCZXm+5qx+}xDp$b~j943J(jH#Z((3s7S$SCS#L)BoO;jIpt0hr8Aj zh>@Osw7c4sR_Zk2sCfhn?$L9&x&ZfR%6xhx)!N5~gIN$A7(laA>onojn=ROaw&&;Y z^zjqi;X8~%>Vj?sK_&N>RI~vuiKHIz0Pv?|`2V2+g!{#Qjx$T!jm0Mp+8qVTnjdvE2v*J z;Pm+T3}A>F+z{1*eqe^Pf_~)zQF9#n(nroI7aqL-Lri`leza&Wm}*lm`moXUmbo<0 zcA+yt%#r(u;!8Rkf0uuO0Y?!&~FM*=?)i~0H=^m*Sako%nXsZ{nPy;+)^pA?-LEE zAU+JDiO<}OZ9pW1x>3&2&dJ&c8rw!2Rp44r5K(B~1yF|lX7sJe$!HtG7H|P|oK7@A z01vfX1GQd*Pf)u=E(wRc7gA$Aj1ogU=OG$4M@lqx#e82!O(f|w@>`k$!SK01zIk{Y zL-+m}K6i)1?)~`r0>Ns|v6n7sOvM(V&yX4I5+qP-)ZN5nZ+LZsBHhdWZGZf%Ex7KF z?|Y*WTt5t<3xn=(+`oFf?G9n^I2=5TdhK^GqBL={aj4DHTQ_5%;e??#J*o)vWn%v` zPP0TMeGlejsZ+|OY>6roa4~wnZ7O|^QKpSXnbfTpz@`vz%!`#^7(|L|N-bD6&v6E| z;K!d~OwnZ&20n2q9Kk5k3}pG{E!#T*ERDqtr%Hk31OmuKQ10b#znjems1xPouzXfU|8lt*7vo z=}c|NfI@+7udTfF*-nQ=au)#ckHbUf@K86@b`%`;M!n(hy^lprcYEGaIgc*tzKf_b zq6!IUMc$xza%wfT4ym4tC1)Pgn@`?M?=V-y_b0@CX+Yg{G%?wQgP}4!JJ@_>2Z9c&l2I&N3LCg7e zU~jR?J!$he3onz-lK9L^g&=)W+9J%tm6}8UjBx4Oc~Y(%%tnNpDJf&h5anQ%D#>W# z`b5e%R7zk~QxM`Z94J|$RUT$x!fm{qDrG9bEL2f|(?X2&_7z|jJ~@w+$5#Q^o|G?vSs1)%5n82p88plyE$9p#h$;%|bK*JfX1&Tum%*%z z3%;bgL>7H=Fbk0hwJ3NAZ0<>kvam81-1xCTs&Y>XE8|c&iJ?zeUY8ul7FH5G%;j%Q zb^tO7<5@#Xz41*)A5SWDc8n@{WAv zgo1G_aQ0OqQ-9PmGR^Hij#d44JXm@~t^!?}LsNg_3cjyayXA&mE9A=94tv%vWfrCm z%>q)IFJDWX4nbzHQk^R6p1O6&Qm)Fnr^rPrjhmDYQ&koHkHb`zOy4sMKzu`GucGP= zbDu!*?BNo9ogncbX|7N_PNfd?ral$Jii;QI7YI}SIzB$T#GO;whDVt%u2S-tfuUZM zcr9}afpmBjkMAnXmp<(112xds5b344)xq<(zUztQ_2FJ$MwojXK~*FI9M|-9vKiF0 zWY9(z8@_0saQhFYEyHTL{YO;7ep(| z&}z}j`ZE!=D_mK8)^jIlOq|VIHko#G!l$qa?H;PJ!P^|K%j~JFU+X)D=qJHB#!emV zn8*XcmYAo>1);gcO!7y@>E!X?2W6x)>urFEgXxIrvNO(pHQRq)-S#Ww3d58QG9j`M z^81x_wve~plKoSDHJ0tjUd-vfe*w6`x*@!*0(hLwS6Oe{Mi71$f5k*bVp66qr|Dri zMitkJ1;__s71pG1J?=RQCiGH4;%r$5Yb7!zFaPA zlb8^X@F&5d8jGiOE}YPFVvpAoFXt>;#dPWmFwZSGZZv)Z=o1ev9brQ^bZh&Rt{fqJ zOa#sYhm#OaXRiA3drUmv5jB_1&XO2C>XMM7Q^ZGNl}+1qJTjv$bP!;w01Fax%0f7< zHKg55oU@p)AYe=gNNB!HI z!9}eE142@o6`{MB&S;iHF_V4o5#i8)r}^JunK^%1 zWHM>AS<~7AI)RYkR4ikPO(d9fDGm44SRt~?`8}>(QHTh98-ze?1s#rxtlA{+VeD$VRnAEMx zmv4Nw3}dI7@oWINz7s=5GSbSvDp6_(I7R}(aVB^vIMa@LICaX`ZZO;4WVFOr!3j3? z7|Wy1laOQFEn*y!C726FJxj&eFp?_h3PApVk1%s^Wx8N;`VYYgFbnFIm8n+G5@cv| zJ?iyZnLL4r@`lom3EoX1=s+)qA)!F}w+FM@$mR~HItR%F%~P%d;jEbjXqF*EJR3Tc z+yf?6uzov)Hy#DwQ-3IZybfMlNgT0tA(C zYy04dtTvh??b9=86dMIqRUNPaOpV=2M?5{=?EU0O1xMi{C-T_^<~vlji)~~V8&Bq# z%tCJDa>y+k-fb4sO0mdnl+-fPiAqXn7Pz;RQidVzpmoJ{8p(8SS1KlsheOF`WBKmf zU#!w*p``jabkb^dy1ff6%%(TMJ$--t;lo3^;;0R32kj_gT3y-t630gz)d(LLW){YV za$L5uN^31$B~6jeS1I7@y3_r7b#VgMOu%T^ss0MwnW$$qBRo9BHxG-Sq$3HEgS@Jz zNQF>OK71h}Y?Xw3Q-Hjc1IL%QFX#-i4U)Fn5j1~ZFUoZjp-;VaH#$X2EBiV_wZYO? z6`4#4x-unDTjH`6Ll(TrC!cn>?g~z#d>^SoG#(^fhX;qa*|3y?hI5j&HyR*Vxg7jB z4Rr{Ig>FEVOt1EQL zV%xcQZB=GV!fzyt{n;oLL%-WH)$3gTJz^Q3lCPKb3eS=ACYjYWpp7f@qb~VoblnH1 zryrr2Mf=_!(qozT^IAWp;5Yo=7jQnL>k;Yn=8=_0riAD9?)5qL0!MU|^v?Z59{+=cQC;I{(09rt$zwM2f)vS1uE7~qB z$Nz<;;Ou_OLlx9)rNxuu*7`ovhr;l^?0O5n)`qb8M0~9i<&Jj)#);nIR!dFNo*TTW z_uF5b#bPUT@xD#x@yD-R%=fzTD=OT4>wPMnj^Yd@z4`~=UO6LByRisEo+$5{l>DFU!xbwe<^@=E%5KnKK% z#{n_XUPeh-3F?d!M;d$~2z(Cd;=fo0J;+EyIu;r20ppSg&U_p^W zk`E<(Cj(>5vH@^Fb6-(F8xD^<9W#q7^5jQpr@|>U@1nx?-u6CtK(4vBKns2 zy^J_{vhjC%Mj@W5Eg`9mBz|wN4J~1sRe41>0L%Czwi#2TO_cESCM?vXOv}jF9y{D5 zF7*gDSHou0$l)UrF!(f&&k*&xOg#Ayk&*1RsO7@0xix#X>$9!8Rk^OV>Znp(X0>;f zYmeuwW(k{F_8^eUh4>@1c&VJ>AXx1Q2^T#fK}fxrUEZoiP>Wu8TcXpV;_0K(So|&1 zpFcViB`q)eABAuEfxWr`c$}41Yj5I46#X22#cd*0hVlw*+cZQ`Nfr_+LXa`dMr~yc z_83oNX3)$SLbX4>cWm==oM_jIg6%oy-1mh>1!|QVEQC)l;kE-_EnpF?DZPpC#p#^K zrwO3aC^ahZ>dzN!K^fQe@Dc`GQ^`pLJ`EVB3JCWhh`Fbk;HqAN3jV=^kQ5jX1bBqQ zj6xt{#1Rdl*2~LAW4&J214*e*)r%I(x{&jR(x^qGuNs-ktypd(n}-^#+cLD8%{G8d zeYhvOijH{o_dtILPIQQtZz7Zog!JL+Upf1oMDe1&V7gBI_&PH(WFF-TRnb8zL5CE& z9`WgddC*4>w*XjCsW3)p)tiR*C=VEch$69Od=8kMg}ThNoscPr*h~_+0lYO4gA##W z6G=O;5pj|qNqwfYWV2Xf*0f1!Lr5clC1SzGyxZGKEPx1-hr7`fhEyp$yQ7>+EX+8b zMa(-04TyrJd8tASbGAu{NobSI73iDt5L3bqP=@D;^N5e~%?0}D|SLtV2dGCdP38pKi6NFW%V2G0HC)Pe5k8J@bf z-5oj49R%x8;3-|vREjN@5kqB+OA@X(=zG$UJ^S_^DczgFaNsJtO)SFD8|7b%O z#$DSP+)jsG8^%+6{5a{=PhdjnHqA*wi!!}SGxix4472G|O<1%WhG#6ZLMJ01Lb9S* zZjZ7Rx=6so=Ka1>Mgp761dW`1T06i3-~z{DEg3eE7Dmz#->Y*vKvnqpH*hGXjKVk~ z9)%iAVx!P*Hu3I`wcSO+<(zqAJK84e4ztqFi(oXH9-yKeRTY>ZmtY*1%MmbKz9_QH8JvGDo=guw#qahma!UD-tnmNBV*B zEhI;uQ|-=(qAn+kcj!lu9388VOG@veFQDfjIRQz{lA|Bx?hta&xS7i2sXKOWde{lh zqdUY;3nMLqb=V?h%gQ|`n5!$eD1R+Hy1vGv@*6AIN{N+rD`&;@n6Z+3k$`@L=4-#- zOs;7n-TG99uP1+(PRy0I+xygJGbK+mufB(wa;I6S-^VoEl!@+^&Gb*5e(eHcjVn1> zS@hNXgfSaH>2!K4>HYCQbqX4mBiA()Yl&G*xtKqE_$kN!t708*2*fSR{}fF@vRM@S zk0zoR75@K5vC`3Uf}**$4&ubCqVPN0qvcL9^=PQA9ArmL7uD`680c@bS}B~yLvqHf zCd;uBQH~lb!Th}Wqk+shex#8~6!9Q>Se9hcEGF5q*;EUHuVBej zc=jgvGCqW7v#pS(O`AFGpKpHi%`E#<`dxcJZ1ku=PuA=s=m^%Q62W2))&MT4q`nk^ zAp;Q|asj^Nf_Yt#HiFGiP+{1E;RDGX48L~w0IsQ&Hlsc?9qOY8C$2GCGz6M9l{JIA zpM~7xQoeJ3+X`uZYrJ^PZ&&4@hbCGuE(rH#w=?o}#r)(h{3w)nT;?Jf8z%y(Ni4x# zqI`pjaJXD*&(~D7a#V_W2;{}=l1ZTxl_MTLLmUcrk*3MQSOPJLX{KtjI1cAeL2r`N znxn}gnSt9&I(kdhL>%-?W@%cVGc(SZp-#=dl6*E@0r$0{ihqK^z39TQsZcxJI*ZbX zM_sHQYg5TtZ&Oj;!f$P3wugA~X^x^&2^;#HQt{ju^i?$YdZHzTQLgF>rk}C%JMT)CJSugPwDh?EHk6ZU>;ZuRc$~W_a6n*#5$j}g*6_)bSpz4(WDT0^z!tK3Cffl<0GSyI zR=0=@c%0>2dvn`3lK)%!6o{ubkz~r2oSE5Nlz7j{*ctEoResD&E|+3a5@gY)NG(al z@g@20*Nta`q+WLBYPU``6H6e_K)-%yGyrb5Si99`lVr$WvbQ}pXph2(x3l~{f`X0f zc(x%bw6^QpE%teMJqaf~h{7P-8oXp@Y4|C~Im0$vj7=uNbQ<&{&IZ9?%riDhQicuK zFvx>CYr%i)I7vAR<52>YV%CSo$t)hSAZOz|pT6AQzPr2I8l{{Md3Kv8)2$@E-p=wM z9tPwI}Y-E3?pN2qafokdo>w|FaMeH;W)^*2FYYs zH9ramJkI!#LDxKG`Ixi4K``W#aKH|rZ(V_X;%OEpG27YdV7t?lv=}8(l-z~!HOqNA z$zCejm*X&FQP@v|^q#?2cf+ynO%e1MD6;`-0tQl+OtD=PMt#pBFo9IJ+nOT<%j^)eF9?s5DKG|_ zL00d=C_-zPWqdS?JR|{?+3$y!zn)%Qvb~e{?DxI%^SzVH_dTebj}v&xKXFMaoJ^w- zC<9+<5a;(Wc42G#=Wl<7CVOuVj}9;2BL@eEmnZud7wq8lob9o*z4Ob%w^v7d=j`n2 z{Ot5%f2+nWIM-qp0~pdi{rRG~^@p>)vns{@c@&gTr_J zuTU5dqS=tMSA!%Th1Xl--TDta24k+1XIVZB6Y+=^0ZYZQ6g&&dNa1J@=aE})7K338 z-Lg?U3G%_%Eeue|d4XWe^AP^u4r6%00O3%bah{B$ZTvSYF?)QxcSc8fpKSx`#gf%1 zVT>NKfmOByY;FiR&7?ey!S`_2lxUq!tag1>o-}W5j5E@ zYrxmPG5r1#zcB&_5`{}v=+y42*;pqwM+VaB_TkgZJ z`Oo(LU_13X*zs(TGyjj_^)X2JEy}+BrOp5Za{z^rKLGE{d#Yd(#!1?%!>=s-AMWS! zFFqZNgOoAW>d!_a4pqMO>|o#RU;0;vCzsuy8$!2UG8$z(2UQ6pZnPSpUw;N2bbt2q zRsH#m=V1eB8ohot>A@_V|0l7M589>p;R%m6usO|&vtl`#?bcA@s*Y>WF z(B>veA?5ijjpaj-LA{PTEK#1t>(Oqvg~$O-8^uTL^=k$;3zBDF%0R%xXEFo4nVPmz zL!Ryh71-=)1CuR8NT8(F6J_6!nI!^?`JF#XlZlV`0L_y)%cWhku*8ppiDIyVbM~5@ zTpbHyXf%uJfpwTO>4rK~@D7uCiG*tB1(+o@&sNtYp=x@s3FcJwE5rxgS|8SJJ+>o^1H}3pPcb6Yp_vdMc2d=-(_~Lx7x3%rS7mq& z+1;xO95Z#)kao*>*3^#R+P&`C3Q3Bgz^pWLp($;V1s4UG2M|&ZSObY91s84#X(+GK zVpG;v_Gx(5CFMrF8b2BJPbjy8$FbvxUs|Jk@>)z1$iW~=AR>c8CThjIvn^SQi*sDqn=D5TJ!V7$JJ6Le0i*1gO3y~1!2Y{@OtFA#0N3S z!MuSq=~F$w$WO#$i5w152&J#N4+BqgVxiA>N>HazzgJBFh+jkKx&j55L4GV#!J)55 zq`NbRimI_9m7mL0CP8+)9+jO=Q{xj@W$3XR;T#xfHbS65gbV>axF(hQrXxalzPai8 zAkzE<>+zv6Bp``FR8LjV^+wp+rX$N;srH&ORS|O;$HfMOS*Z4GoSChl5Su*gM#aVbA!|F$Yt0S!D2dbM*cJq-vWlP&oO<)^@y*gTVRexff%?~$F zGlZHCArG9P2%v+Kyp`neSwH2$Eq?tbB>;cEDT#{Zfs|s20?dqq$<(zWtu5u*;s=i3 zqe5?r0Hue$5XHIlt%|K-C?IxJ4<)PP)B=230#6IkX?1Xl{lOSkSSdshD>`BYvcgizua5Lt+9&V(R>PO#}4ZPFBKJz>Vp z9&sDdgPj;u_oZ-S5#$J$pghEha#!Ol4+AO5h(ar%V(4m#Eb==OYQ|Ctu|yGLu~1SS zYZ9}MA&h*=L{w%oDdxG)|2YeyLIcl^Qp9^MHJ$fx1G_b`LF}C=Y;bcp;)zO7k>Y8d z>QoDaez4v}ApDHqhA>Z0rX|Fc*`n-2_^|?Pt20BSiK;gb3>GW@$7W^w2Rd+x4uKcp zU!k%N<8Pngx9zMgGXVIx8;g_~*4PzEgC3Qe}ncBBEW4Y%BwJU>Uoo?NIstwH1Xxuwt83 zEO^bMxU}w#pECT1AusDvy_uDwksMd0PB*Jk16adg1k<3QkbHZ+QwdjRu=snR{lh^GBkQs zFh&xcI{cR&{Cy$pQ5dFjvfl^8XbPrk&45v8IexvdS(ys>dyrY*Nbh`jf?*zAJIg;3 zMQ$vHtcoA=uwxb2HS%6%$x&Muha7m_Zn1;IKaTfbvXdldSCcy7r)rAj$_9kx5ROh*Nph#+^PlfIW=S4Q#Ze9!kT6w)kLFUE3Qf(FT%1o z8FCG183;f8Tu6rKY>3VN7V>%4lNQt|<(J)bNCj@P0`@VPW10W7$}(tm3dF1$iz}$k z$-~4Uj@*|F1cO{|S-OveDf#$gSzfUsg=6x=i&Ek}y=|qfr^;^)ZbVl*_|ea_?PMeezoGrt1i>J~#L)2Y&88bw%`t;h%bHq_}dv)5Lz(O$e1& zmSOOlLKG)km_Uv++jX0{F&$}!lZIomczT7{la`e=ur>Ed3Lz44fb};^3bCW4Lr9_w z&=7X@sSf@5;{1|qEkPBXRAuXatc2W+4{v=^1kq)}c5MpPD6=*h8t1Lu*ukWp)BamQ zc`-R4r9XDfA#G8w0;HD~Lm>>0+$}2`<84g8lICpKs_o9*gJ0i#uEQNvJFSSt&n6~MSCN}g}3Oz#8D)u#(_VtuV3ut^JA-VAz`_51xf_4_?C-hRKmt47skL7;yKF7!d+!;7o4v;FhN zpjoRm;9rcsp6xwDM8{vR;MadWYnsgvxeXFzgD~{-Buef8Lma=%@>DS?(+M7HiCS{k zP}CP$v>|StU}a{;-P zy<~%45q4B}OY=9{(B`3!J!-Hl<-7`@2%{qk#X8xCZs(&8+hsF!<8H^KoAsASE(PQe z1cSmCoao##^hEB3iPQ$2%Xf9qj_ctt&2pUQaLU0m!7BTnsS}d66Btp!DxBR00c+3J8Il^9mpiePo101q%*Ny4fr;f3#Ab z&7$15M~7CNgO*G}bN2{zxa*OFSU7XrqjNI5L(;YSTF3V{0vrtXthKz}`5os_mx?&a z37w}xru3BlT>N+9M{z!C*GNR~3=j#)As3R``kW5gUP5X_zfwq4hVG`iL{ke8p&^{wGQxz5B>soFj41$F8n3SG}7qdq}6!imm zEU!YXCM0@Z(iymAZa!O;r!5@Jsf7Dg(Wh3cLY`V}4(dp}pvOh#c1N6x!WNVFvM}0Q zpOMo2xnfEH*dbToTKF$u`x-l;L<1@SKR7(vm)+p6!sP>GQUhgqg6!YtJo8f?46%fc z3n4Hp@pZd~ulo-||4h%IcP;Z$w^fkD|AQ zD}|+G(PUb>L3EegvJ+uk*BOnooo^X3IxM=9x-e*iyr)=A=Lr?jKYn@VA0Hm?`I;ZA@T?@he|&cN-j4giKfE~Kf9KM{*L5@( z(4Ye(JChs?4zFPbx143ORK0wGggIdrKg*#?4)}D>`e|~@<1HrN9xGz86#CtbdGo31^x$Uqdb^^`DHm+ExzmEW|rY~=Rn+u$G2TXk)#zu2Lc71XlvEj zQy7u}ir41upe1CYeOaTz=;w${V^&>e^l{&+bX9dD-7xfJB}(62!-?BRh1J`Fu7&Mb zugC7iUj>F;kI_IBJGUd@X_}}7baUxYM*23RCb7o&N}KCTAl&k!z}wy?aY7{P+)wQM z?XF?8f%L_@6MX0>2VwYnRxNc%muQCn0`K*z>3q$pMc>U{l=N9RiPY(Bh&iZ8k;*g$ zqi9y6AhIfsgDqF>qII9q&}v)~#l8vU7jsyY`VT4Qx(xlcvO2UV}lc0O8**Czy}N;kG!8_n`` z(WS;J(#rbf6;;|RN6BU8?7iS(BvH23nP>oi`#L*lPkWIA09+qj6(BlO`$y#$HOS-e z*0Zg+L6?TL6`~rcpfgvDFgyN^FXs^x-dzym?8nA1uSNLIrO)}cn4;Lb{PqA$ z3;xf=P4|S|aWSXKNlXw-d&~5ke%7$uIV1jcoO(W7YapH7}g2+1@d?79Me{fU8s0?xE@GV}725mZm+vS9OG% zuX==<|5-OBc;Tjm(a$R9Xlyh6w|v%Ak<;f&)%giW_bVRR`BD6@PLnFBt~99>6y)@6 zVM)$2?y+gjmcBeMW6ZgSrWb}}71KlYTuw`6AfYBJbvH{#weE#2Gd(GQlI0HWIK)Ue zrtUt=9?Jt4mLq;^(^wFM$ocjb>J@9P?Hh+4q%YE1Hou~g70@wOHPjhdAF27*;5WJ{5$*uJI7^?b6Ma`XD zmz?U6p|o>8*+62&2&J_+cfLycSPA@GhMV@fh|tNc)X6PHKa4jJ{<}MWg(nq2NQSmf z-vkwJ^~DcxtX~q$mIT8g%W&}_+pr0EQ;4rt%yEltO9GyHA11!{a||&ItP79{%#Q@| zKuky?bVM>Tp`HmH%6DZNio-DFgFHd=Q)IWrUm=i43M2ylr|?H|uarejplhX5sE9s# zrK4SCi5Uy1)y!K?6hP~FBEl+D-7)QAy1DtW;s9Bt$t<4{Dru89fvJrO^D-~;W~nLY zLhr(=D?S1>@C_`}d%bt!(GI{IDjQjN*BH8RJ5Q}vLwHoN1QW16=E0Ds|K9fl6%YRh zVea?3BgoW;?m*4EF=%T%_I9wPwD=y2tygi2(1auELuxzGFe9JJ6Y2OV$Hq>xsuStD znNzcPcKdtWFm@>}xoAwQ+5^iAt{pE;@?GP*dBedR=dH+3InFK}{Q1u-ZdN_2lbt4o zA@O?5;cPOs$0n=aMFOZh?=3p+g_R+n=Ht~as?dPwu@_M^`jsw}toG8Kl_&nfJ9gH- zJRw8S2i=rt7K3R#!z08^FnpSV7{En0nB09ZzyC7W@W>4ky&pj5?*f4~`%AV_p7?1C zr-%QJ?S=@m zaH=u!;Kc~qJAW(fC3VKWdK{9Ep8K=iw~NsBNhB;XtB z=Ij=far)h;Zn&)BCaVo+ylx)DW0c$rp6-X>03kREpk9{@i@q3SeLhC<5Zp@GWrU|~ zgxz++ci#vc2clk>;#v2D!M;i835J?M5`O!Tmp$?);hn#yWx|SP!Ds)FM|l|-g$+;q zOCaUqpW1gw$8y&d}nxKZN6%nG_HZ_elQ(#GQonYkR}+jK`aP!thpz!LiT>y1bc#oGI83u+XW+{k|`XskTe+ z9KO}-;?*?g@;i3Djc29K*VB14u{4YR0EWlv=(@QFc%01}Yf~FJ^0WOb8d3?iF$R)N z-5w6vBUwneB81{`*&Io^#$y@JWjy1X8AG@%|NXjK(ny+z?bK$k&Xo$5)N1uh-L00q z-GQyn7EI%j*n`)7@VCZ6D7Mn489k^kf7($2)qm? zSvK3--oCrL>x~m3Mk4)^#j{?V+-#?r7md7Rlx{05ujAQ$65LEOXuWR3)194X0Ow)^ zZ@sJw$C2Nw1NwU$dD#S4eib50q;v!?{*?^>=7sZVZyIDhF`BJ1-G^xR2*7pG1rT6l^e@qp*Vvkml_;Aq1$mV0=$~W-VR;;xRYgoL<3+NK+hp zBO;M_A)L*JVc=V=ftSLJI@1ZVIlSkI%-V$_1&&BPUWV-TK?FF?tLGf+)fB=mpzd3! zOk^N|ct-QuNcBC0XfBDK*Q=3&VRnQz!iXpF3>ljsN@Vpe2t%@&c`C;9uuCWq7(N_d zzI}gn2?wVi;lsiC`N8Ss$36mQlNd+Et&pgK=`0KoGxC*qQFf2Cvqc`BzkZ8T4qhFf z9AADU4vvm5PY*9H;OPB19KhMZ`Q`EJtCNFsIJ-JOdw+4*YrusNTFflaDoN*JrX4XQ z!yk#v3&MOed_*;;NMtyIiFYed-M$EJkwg!CG~Vx1Wf-H85z{!wh_w&F7@`=r#a$Ah z5oIx61+m-Zkr1;Y7`K<}$!3Xmw@F!j}$bkNMK5ofA4xuJe*##Yv?ts>#0TeUb338#j<$I|Z zq-bzKhK5SLMdCY=_?lG?_>&+U^_vgoRG5s;NzbJ9D1h3$((b^JmZ67mrZoqoBrt&9JKIjBn+)H-VZZ;%oEL`Zc!3_0_6LO=gnPtZHR0)NH?Rz^;K>jYs}h1)+Vw5X!qnFxvA<#-A%U4FbiYZ zbmkbX)pk{#YubjW)Hvx0_p?8pIlxkzU0|KU{yyx$lP68&s1nx51dKX)7AjqB6W0*w z<5KS+v^8DYoK?G=jmH9$^dqqLgU(n^Bmy{2(SeeRL=fX9opD!{>@|uGl%#9iz`m`3 zD(~^VDwTqA6}wcb?jj1seu+8%62oX18^Roty;oV>LiC)ml}zQ!$^NiH}O<901{ z&>D~Hq>DI>`zSbGL*{5scD{r<+U5*l6Z z)(lgp3~677bxCgC@z`JQLW_J(+g%auPUjwN$HXiM%jdeQY{BCc9*;gnh`e@Ec}Q*m zUQUFmaFHUiT0%I`Nh0b+Tsf&LWd)nCTZ^46_j{4k9EH2xFGrDj(+wg@eFt+t{b^OJ zC?<^#oaGKN>0TLJ}66PZmo5S zsBB)USgBh0!QMq0zNDgAB5oaONz+{G(bV#pC=aISnNQ;Q3ws={n*>Q}sg#exB#fZw z3%i`1O6#T?0djmN6jD5;^0_*Td+6n5S58>1T-9I>SV$#R7-OhBay7nDa^Xt*MN!Y~ zW<$!Xv9i5bkhKQmz~~IPNPMHfy@{JLMyYW}Lv(n}XATqLeNn9k`crLROIZF6{I;Sb zk&Rqr4rdQ`lD}pxq1CdQoR`UXseJ2X+juaUAldNdrVa?~PF0?1?5rMl()!PRgl^!*T zd-SPT+eM*rTdZ=@GR0!%1H8lD52~e22O%m?c_AiE^Vxtd;s%j76|0$z_UJ|1$kEtP zCH13#7mmA<8u%08f3YVR{?vqA+UfP@g_xs(0X0X}sJafl!Xcr2DyuAV?37LvxuC95 z7+=HSj~boalLZ zGPVW7p^*=Ap{_3B_~Pp9?C`whw;PQX{!i{|<6wiVg<3DL_0NsAW?IIxrkDCbfKfY) z@6d``cC5n?sF>vDtP356V!9-}NgvZpRtIO;r=W5>?#$Hb#@^5Tx`OIw*h`h<}M7kR;X1`%(;0f2G{Cq8507X=vR(>h3m>R zPpN{gjEI){X>NMGOC>NBG8tWp;@RDCQZcO_mcoFxs2H}23f5>qu3_BysVqR=C+GG%bmR>8|*SHZM$gl!XfGYyjw4wYg{n@ zlUd=Px)7_+rj7x(#+}dkBDS~ES)<`i#xZ4myRLuvv23l$!NOt7 zy%?)!*`oMQV0GtYW_GC z#u-Q=sET3HP(ein8CthBR$`tZNaLU#SI7Zs&BjKr%}2e8S!r8zDUsZ-C_+hBWa4?1 zwK#BjB$tp@>A(bX?ZV~9lnN@$4txKd#^jQ;gv}M4@tEyyRS37VV0$hUsWA&jy7?Bi z?$9FZ{><7s!Dn@uOJ95PVA!i4&%7vS32)G78WosZ{$lt14nBWxG&ZT%sf_Hb;WqtYWq)PZ5q^ zA%J%2UDzy3bV4%q?uTL!L<2DS1bs61kp4k>8f&cs_mFz*7ps&`7-VG@N^+&JZseD#atcV{Pu&b4|GYDggtS)9mW$%wQ+80}8p@B7^t-c~3Eljl#sqaM%Kl5r>G@4fnPzEK z6(n1ZrnastOXqc27fXB-c2_U^FQAk5UImr83tdU7IrI+}X>Cv`Jqs!YmCA!<{#-^` z6kJ@MAD_OtuwT!t8FNS1RcmWi&-ly}AN-ugkSoQV>o6Qoo-WWOuRLt4GIZV-hvZ&g(ZJhK%c{&!2xb z6`h&M@|n7Q6zt47V0U3XS#P@+BNDWHCz98Hj(>Z1xQA-YR3J~iG5;hi7HPDR!Cjnu zA#6lY3iL~p8KDP1 zTR#rtsPA-`@Vo&5p+4TovW#aW9Jl#3~UIO%i<5s^{p(0{NWhhKpMA3{yo44RsR6 zCQx;0CDR+7z9lbOQswgR=53izInXB1wDNlP4u-i>@$gFEO0ZVB8y z)W=2Bg5b-tRr8K`f{;I+2y9dT084p)#U@E@aC_tSNQgU3xdSC?dv zwu{We1Q-3bH>R!b$J42&2&0djiF%#!y^u02>b&0Cm0PO2(RNWHqpAFPo5Y65iT9ZA z*6H_^1@zZX;>P1ohu58hn#CUa(PQ`ecCC^Fdr0j=rDlAXSXXXC_ z18N3r;R2pNc$}M6-cr8duOfd^lCE8OYG!&yiGr>|V&Y~VC3&XJjw+Gj0Nx`DTH#Wp zVR)RCR7-EuKoFK7L5!7Oq5nZ9H1Q9l+Xk@qLdNJ{b6DOiLS=PTf*vtya@(X(bxn#b7GSvl zIyhK2-HuoG99|~4^Y!QcY1lFzS5X}y?K&owLkS?X_h1V(8_gP0F~L%|279=@B@3vV zp$%jIYnsN7d?Ggjp&d_qqXDSR5vS4Et?g_WC0Nm+X&y>)mw>)94td&WZX2}{D2QHe zJJwYE;WNVkX?X?c>*f8H{Zc{R4vW~8*<}#`;#;b)sCt9~Vq#RU*`7?6BiUxe+xzB91ec@6L=Q zQkcF^D2^QBN%~r4+Bs_@CY%JG^dTjPI8No~hOUp9TqY(L-!m7*uhiloBE=ogmu!;Q zu{5pA91KH?s6EFcXhv6Me0h8%^q9Y-Wt5$8v=|LJv}`i~(BpGQkm?ZQP#))mE(t=1 zQN(+!xTZ~HnCg*|ZaaHHEM?DCCUt^wOQ=$8oXx#R*6jZe$4Q^ZQPG)SIwe1!=0Vjr zn5pbv>q}0gAj#24FEs$;5IouA9#JpF1jj_YWrhTWgoX}xx@07Sx@wR-aqA1`&zzJe z^4Z+;(V5kZ{fj0t)1OIHmwoCHQV*26_`d-H(VWNYP3mcQoQ+dWYZFlvB^r{x*?L*bE9m@#E151xX48(BT4h>BbwM{z+ zdHD%QUKKD9+YJG`#`K#ZNTpCk#`8|k;B7hEt<04)%aT?GYtc1~X&FGD9+w*&3GTq7 zC(WiFM@0wnEwfhQgjv++`j!QiX+QF@cwH!>Wp9eZZgz2l!|m9udOSL9rT~aqsU^D; zX+geZuL_9o5!P|`z9vS;BMmP%VmK8ll~@)$T9b36ms>iT@$Gxw{%{a877DS9iWG%% zqLxr1p)f`=3v&zNCYBreV_k~uTVpPu-Hj%i8UhVi&0@rm56P-hx=|6H}AK+F4m&y?LFgZyQ&N3ZiQQ=8<%!bsTkW}))zlsY;QlbTH-a@E8n zY&|AZRpj-U+rw6&MAi!z%gIzAZP8uSZI1cF;$mKQ?4StJi|P!W!D%llbxz$%z9_L5|9DH*Owb9MAcXz`wHA=#=mXt# zc$~W_aEgC}GAo;_Ur11-#$f+=KtLXw33JO7~DGDBmB{~Y8dC7X4Wf-HF6+E5&{o+01^$t*5Wh)78Xu_xbP(FU74nS)gk!q8(?hA_fl zA~meC5XL-KMKus3J_l$-d|FXzswTp=ij?&D+|1n6c(Bsvtcpemr8)We*`)=z6hqXc zl;##pPGA-1MG=}T!3K4X1Dl8_-1%A{c^xiJ5SX09rYH%QQP4tj$#OOW8B|9rfPn@q z2)?qZI-@%kSpkNHVC_H&pm1_VViC|vkZqF_*`*;aZDbc=0h>IFU6}_KEecxtTmT5j zl_#{M0(hM5S8a3KHVpn8{R%X_Yc0ROBz=jJ-rUqqyg5$JFKctVo=%o1i>oa9C@PNE z<-ZT4BunJV&kLWco9U$N}=4) z8fAEN7E8J$G!S+B3C&cQk(O9q7b(a(3kno#et2*P0Mko-=;!fB|P%hbO!|B2kP`cEi-E4LM#>9bZ zOH?rsyM9RNXBJq(L(d<5gmf8q;QV(!|H<;BWqnCSojB2l#L1A_BnS}|10)=TN1$t4 z4p~wg`WRuV01t$Rm?O07O=)+_a~3Z1eYU2-0+5|$c$Q#KJsN^f=iK5Oz&~Zi5HeS+ zElv#But@R4i97?%LJMbzC$S>{W50OqPMSECsWNf_eV6$uE(jk$~F zKDBeHffd3^3PTUmoNtt&N^O#a0)4qXmfS)E2*q{feVcLWEdi_o<50rQ!~{67m9*0_ z>J9i7Mwi;v53rCW>tKy2V2`aZF%Kaz)iw2fSu;^c+{mv=2vmm8gX#6{Yzp1cJ$&wt z$KBEN-auvHF)R1p2pQ z=)zrhJRMxlhTSpT&Bk}PlV1G@CWNFkD?*Ey-qMV9h8u=#Iz(91-yVj0+~yF2^d0c5 z2ZGye6Z(K5T3}=G{=2R885WsL8f`LK4WKRr43EW{Q!FCEB&0Mvw9oMYs>11em=dIn zz@2Z|1ZpseBtoatRLp;5p^(})U1+vjtyZnoX}+z(Y|@qKH8kxdb+Hw|b@$hvd3ihP z53bB>6b7~*IRwsa7Pxd#_daMZNr1(yWoyT|&f*>CZNz3pl*v{kD<)7d(jlG&_o&|; zPI}tQxDUnOj!I2E=O@;ij%S&g{Bl%!p|mqq>^uTD5@QVo*q+6~#MsP8xbMvH8(o>m zne|)y^vzeefbSYWtNLTl{}BH*M7#Q94?=XRfB&59J*Ua@1|N(2ao_0$K z3#g#B&{C6k?U;y&2chZ*LA0D>FTm~)1uM>M*%}-LZQ0mm!@4|v3M!ydY6>kw7R-$7 z@T8QFC&X@T6J3)9ykiHb+G!gorfvydKq=LQSI~TX*90AOTm)76@}JVjOcFIiiJ$P3 z_#xTR#Iubzjvzh>7TB{cplKv4yAf~_M!rbbu$iei@?o4bWfVu>wW9+6M^A~R3LsW0 z0%^w}afC;)N$fg9t5lR~t8b(lI|;NC@ss=|-4!}&J>OCDfTPZ{95vrP-_hG*M<>s7 zbn<*honl9)&vVp%zN1#Lqc{7G{t>Pir?thAzvca2$}7}rM*iyuEbiUqLwTH^XEAPt zf9_}3>F3i(Yd$?GNy*DkuDV8gil5?E;zc-;)*&7f@MpmZj#oC${3vu-@LC?acv`@j zOWx!~y##xR>?JtdVk;``p4ogqL5Kapmz&-hd}27)pf4X}4_d9zE@Vq0@S>Mql}vdv4^bnG(mI@=IF_ygp)%w#t&7(QG)};YJFSYUT<#6r9^0&)HVt zb>p?Z#mp%eU~a99eEUxpGt-JZOHX?>mS&GR;VXkkFRdb)tLi2x0+}RR&Eb4C zcGdDrXke$4M&Tiv(*R$EOopLL7G2!yxn+M#s!7rUWjSnBL2kd9OM9m^Kv{mqQ&~R! zRElww_6&4L)%Q8Vmi_8g%9a6@3f-Ng)Co(GB`c`_Z$Oa0NnZBi0^S$MTFoM1M^B-* zmGR}%m3cF`>6z2}yPi24{W7}!JThd{iYZgk$E`};bq5Tmy)Vh-Q=VS%ZfHO zDm3vwIEfI(562Mux)|BON}o#4r@1KbjE9l_qm`1WsJ zFrRKs{d9|s=KJ!HV}HoP1b0OQSq$lfL2u}d*c53xL<|)Gd}eXtMj;^IIY=CHZdi|AFL*{=* z6g?QC@;*(JL4-<1MB^I6)-L#C2qQF$``AY%N+a5m7M96b7*GrT@*i-?kYxTUs zCS1&EhnFwgob#_EG;@SL=|Ov^)9Gw>UbcU3!PP~N$lI<~fAYs8Hioyo|LzYC&Q1@H z-VEO2U^oosBL;iJC>;BDTa*3jPb@@bu3B>*5u5TkHCA(+(4>~1@x#;^-%HYwA32-Q z5Hcn^M$XC|8>SC4<_@tq4l}z2KDvyA#)w$7!*S)XcYM*W{)AuskcnTFdb?rKDBv#7 zuM8OdsMOauv;zuj0%8PrEFBK!VGs>J;jb4j%nax6oBrj&;Og}F?BKupzp8!RMfLHl z!AF3;=~IYM5|i-Y@P2f6g1kH-E}wYmaFQSCE?pC_;=!&tj)n7S^-C4t{jYBZCr2m! z!AbAU(ZS%Ne{gwpcG}9%@V^D){qys)^P=&y!|J1h#zl%w2yrMwo8yCOnWQkBcri3d zs|JK|7bj4?U>5rr+0qC4T}X9vs!1(?fM&@4z^O+>q7(~U%n_mUeAJaNRi{VeaUyn} zhlzg|axa;}XAE9!5U}troj8+%2tHjfKJ}7MxxLUa-WBdellK@d2Z{fGtepJC^a+9I zxx$$?z%ZmqoqB%^a4SyyBNrL^reV?A>Hy7uz$L|9!$52nvU{k1j{H%B9~v`EPC|^S z7>&^YIxQeN(7)DmTQ(YaWVQTAPG|9{IF&tknU)}k`T?)-tH7@mIRqp8tW}%)LP>CS zyX%Y#b;*z0`cg8B!>3or$LxGkmpD+AxDUd+EQLQXNseEa7*#TS1jy2zNOFre;t*<|QaB0m z$mOyvQiueyfRv^3yd}n9?epvubr}OCkcIQyV5v;Y1e%v-iJ3ujmc}jRkPrfYl7VGb z6G8VAyr4iG0bI#T?Zj~*F}{uBGauFQK{JA}84QOIgGl<4~Tqs6nd&C}XMn##S`hvcz1+ysOyu=^m zs&;;%SsYY8QmnPSGy-yY*r(z&PviJbQnM(%b5(1IU~WcNHv~D#f{?EOQyJ8gFV#x! zEZVwDVf1M!s715c`8HMkPP)2=+!^_Ic*(C18)}1jDDEr67C2`X?BTLRYEeC- zzg)w!%8WQ?IOy8PW7WX!Lpu{AijFnPOCNr3R6;Q3h9kHtjRL4Uo3wa3)PhdiWv(p`r>s01(hD1h|8x1Axa!|N9!Ys3&>$*e+DR5|5zNwsj${RKf3Ch(O-PAd+ zaB!pf%sC`;YPIZ0{+IiuCwdlieNlm9aomUDc;`FhWeYVlmy4Aykd-etcVFU>Wq}B8 zptfH_c6)KUDX;ytS2a-?5`eWAHQ*Qc8~X8&8ZYK-@@qLC*{F%y&!)V_G#^dk= z&xFSPrz97m4!O9x*>J0Pn(3xmT~LJl?um-hh-C%1Y~^Gr^Q<(-A;IK1-}z`ax<1Ei z{6Jn<{(zL})%p)-fp8|LRDDbDBjK#+$tf=|(G%f&afKysEUMM$bGSoUT;u*XV{9q1 zLwEu0KMoHUR_#kB_V(bHXQ$f#3SvtpHV8MthV0`G^?*WE;fi$DpQ6f9-yMM zVX3KT#;lSPSvd|V#y?6G!+!ku{j49kA>=JD4>EKUjJ#ElIhOk>7B*XfBu2m z{tTgRlnOQT#QFcHTwNmMmEm8^{%WpTVG97==5Gv!0rNtb&v*i+aA|RO2FblQoAJkj zV+g590q0^e2LN|nMeu6X#TGQDm~H}$1j zd1@f6tPtZXf_W9rpu?m0C;eScJQWF$=i*YV+O_y|SkwFlyyccZuj0>sig-ZngLR*$ zvEajAiBqRJyn|utRKSHS1IlE9V&6g7O0!-k7R{0UoxcuJdZL}poi@O4;DHyv_1+C$ z_YvyyY;cVKLcL&dF7u+*4Z~l3%P2wW&l#j%?yQ0oLUE*C?l?%P#mkV&X9a`>@-U}{ zc?Qz@g-qm0#&db77jtYYEAlUcQ=W$fIIYe?2PZu3QQ3vE-N$OqkINPdRXVncdK%6Q zTepR7RqeH~ETv=0Qxe}N)#OU+*U~kZ`gPIcWsSx#n$EnK(Q^mhno-utq?|3UoK{q` zBJVjdpC)agK}Z8oR+$eye>Yu*E%?Z5^UBX;Yady+BP${sB@r3HH#Ra|RH9GO9}O&N ziU-1W`OMkU@$LHpWp$@8Jr<>g`bE3WkHU3+T;MuC62f^Gne`CYA8+th>K=t-4Gc2e zzUuhNbeuGJvrXgrBiRN*7A-e!CC4L4XvKQuZ7fSicadQiQv6hs3n<12x{R!EC4f$L zml|0MH4zK6xyfyxXkP*Q%z_oIYpHFOT9%yW9U-}oD3S`}lMkUZ&-G&mdd6o-!jzTe z>U@jh>aN9PY@8NuSIS&6IxpO_!s+W*r6(B>jo_YzpnczyhF)0_RVgL+5Xn@DfhC4Y zmhTmt(bNr7h>ZzHqexO;5NK5ApH@^UG7b8|wr6?dzT!f@-(q#OT_Gk&l~vEt_$RNm zmdeVJ0>#zwK;ro%8JQ4m=~N5a4V%!yUQa)yCvUQC)FDvfZeXomt0z7%gr?{$S2aMr zrNo;zo)?z_%V34f-2!0d3M)CI+a&f&HZvdvmtB(~6|U`m8=4BJbZ@Eb0!@y|S`n9s zTmxg#yq9fQY1o#gi8E_?>TMmTDX19qwJA#U?bU*`;w`eLimr2Hgrj!(2GnQ0Ng!V$ zC{+4p(o_mhWIB%g|Mg`wkA)8ywZD z{aQ`#z#xh~&1VH}uGj%MKF+we0^i1i0xbGic!Bl8PjY>;WT6|~!+}{^>V~u;E_}x* zRA20ujp+Bp8>y!CsLI6ED3&4e;bpjg;8Ev=`7|#%fkfJ4$knvV>#J zp!xM{uElNNP-Q0|ntJJxC=gr7sOdp6za0i%l9*7Xrdo!DjYc*Twz->KsOtk3yE9nZ zH6eX9H)N`$!R?~c->F7R>(`bLWKohqQPH#Agy}p;eR_*?9>$E`!X3fPOH)Se)ADUm z28lOi=6t>z8?_{zO-LfRXY@kydI~8E0t^fuetY1r=K2Zv$rcr_Dp}6S7ketMCU&~+ z#Rcq}ODJwGA;u2drf{U>x?(IgydlPN))g_1{qNihG7E}1S8+F0bhvkxM<<^U1Q!Lz zRjAUY;2hk@Gt`;S_0MY;EVQ&V_nObp5SeYZE4ukbKFxh=Pq*8CSC6y8%XFIM*<{`- zFG2oWF6Gx!p`J1s#<(>r@=EFyb^&8qnZ%T{HQV;&0ZR5ZLlqjf)Qcl7N6!hr&wQD2 z>Wgm5#f&eDc!78$^j_za#SrOqrjv6mw#2@78fhk(OQ}!n=SuP1W3r zXy<=-mlI@n^ge?q$znTwTSUJ}j&kXYNzYu5zNlkSxv`HBR2LhpWKztI!~wrn({|&&J%Aodyu)HYO8MBZ~EDEF33Zi zt7_Rrn)@|+do=HB#Z#URAAS2(ro>jM0iMxer&uRA+8vJFjp(N~yf%vcC@y;Tcp zajjtrO%|*jT2vuJg2~PwaS-qL>FhY&J>o^ng16Gybcg|_UL!GWa;iVHKZLaw=)HFM zV)@Qmk&@*?gRAdF{Tbt75G5?5J&)CY0@PH{PUH-t7I>VyG=*{fM8*yGSs4{J-)G&b z!p*6mkeOGakZH}uIr*cK=;RBE9GkCdi3_N3ass6kAhHOcRg_v>no|;AP?VXk!!`M% zmBb`#*2$dK^ZBf~xD*sX!V0zu2G*1JTZ>Q5bnu;g)>v|Ktc^AcNM^FHt@vaGTSe^s zbyU@T(?5=WHr*&G0wPFvcL)edgLF!FcS#C}fC8It0qNd!O0#LDq#L9KL>kTpz3%6} zzYpKv^PIC>XRWi=VXe9N!+mW&Gw+Gl%zI`&PYB|f~4*# zLCSJ6?N9GDC3Njd+}np2jVE{}Zm}UMaUrHMD!w}xoRC@>2F;-)7HORmWH^^Wz`i2( zeZ!+*YiKcLImNd#nC!u^$8;`q%ynL2fgm5&P%0o7O`6yJ+8cLGWkQ(0fj8I*cxm$8 z!5?qoU#A-)y$_=wAo$c=lLtzx9kGZ43B)f;eiGAxR)!KaS}gVW;q7 zulzn_R?l_^$7tT~3T63-yZ_@Acudw~Zrdf_(<6V%%VVnS>e6l0GLj5wh8wgE@=H*@ z-KwRoABewY>^0s4b9lms$2&^ER}{@t)M-ZI`cPEn-)%CQq} z$uzAHhEQ_i=@GQRKDXe?420IBaxcR9N8fW#0g(f9*TqQ1NM%YOJOLD(>Ylwd1GXHF zEHUadf0p^CNQeoj2edGZdAx$+7sKqHVkOdZ@>*m$n7tK>1ZN61L+??r#l2^&R;ilc zt@_lUqB^5}Z6x4K42+I3Nqzq9h5RqqmC5bG%yv$Xk6P5YgzLsUE}hWH&8hyer@zEp zW}%BnXgX;6k-5b-O^MoB(oY{3({ibbKA~w5tfCd>E9Z4_Yzn$IHj$BfJW$Oy_)?h^ zs2ro^TSxT6g2|&fz1-vX!%znVFxTbRLF*77LPMcM`Sq?+pDZl$CD5kO=t8MN_fIV> zI`gUc^|2HgaogSvNe#%bK!;Vzs#ICa)|QG^r>t2j+X(@!G*ZD$kbf`UKN6%avWsz^ zWULID{oeR9itqgf&YmtG;C_Mn5+=YHCHEBVzUnv|@yA&`&#)1La_j)ch4?ckKRuB%YdR>^Wi)Io% zEKa4-Ze@_1TQDCWp=sV|IjYca^cvP$W&t7_{2rhqQ>wpLf(#B?b^V`;)8wj0P4TK z`Q_H>x=n+{QI*?QT`RR}5v!S~E_w{0R0reNBAS2vi$CIN{N+$`crp31 zt+0=1txDCFjgys?gH0*#h1AeMzuZ`#er-RaN$X;7?cf3fO>XOojco%>6J|1F4=ww? zTf*C!{s9&qlK1as8m4F;t31}A4chy$4b2b#V9iXZ%U`WK++t*~nf!Jng!pQ0e~9iW z7avC{f_ZI)y!d*kWi^A27K2JPQ;FW}mFROLM~)GCAe>VCWF5`#5Cs+z8e<&Vak?-i zNRrd-Y4hX>c#abrWd|q5zIjhtm&7PK z`sg`?iaAOeMg^!*M;gJ-D#}Un za2BY{MiCsRBo6LWya&dVz7J*)L<9d&d2kn6T`f%J+rVW0`y9J^R ztzimUJ)p5$;z(>%dgfU{(y+2dePu%elpCN8>|%v5{npCayR`CZ*|>66FjVA4kO-U7 zM2R35hfvltQFU@Ui$k;JSK&HnXo((FXjBrh`^jWUzsfo2Xk`a$V)5vundq2$m3v@^ z8o`p!_@Zhp>Eg@a+bFB(R9*-*%(V!3RY6O2I%tRm9>~Q(;^rD>^^!aweuvmO17B>P zOHi93{y;INUSHRAqVux`D)6jn$ik!5xW2wY`$T8{^olFIr94zcVoch)Z${EAW2$F!6B$eb*&Tpxj1KSv)o*0sAE-wxJ=D zu$zg6nYr_0rpE>bkW-E`5CoN5?+F-AlN^qn4sxbhiGVkbYh>2q;+`Uq>8Rq+t^@+G z#Nbu7KtTxqGJ%RSoi#J3cp7DX$F*jodjjsqYjjX$pad1ObQ3-Z9`?uifzE%~R#SOu zrsCX{_D75Phi(nHbsR3y++Y)s2%gIF4Ep`^p;?)UILB9UDaLi;8owa5AQuq13h{?c zPyjW|lxpG~_8xU%j-2ugEr{&#CDOf&g1&G%EbW0Yn^KE5X-fk;^o9_JQ`m>nWqF(u z5-kCMvknQtdI$4QGo7fm2_#E8n-`!sLWs$S={?796SNl zOmligt)|j(J)un%X^5hWE0dZLz>^jQ5l z;Vbpv_4Jmi!KyU<9@v`ElY*?Tqxp*VmyT7t zuvzRtNc)SSuS>U5_}WaYeJ8Iyv(+76I@^qoyMIb6a8(t&Ztb6Jz#xC;jSEp8VRw2- z#5q`c?&4j-t-U=k4h^Z-PNSCf?m$z;UD^D;wAK6L;;?4CZXDMdeDcPrRMt&4g{VJI z-w;4R>y&_EU<U*@OT+vZ@?~LjS2vm zXOP@Cf1mijYxk#}z0I)EQ=0fy`#7l*x)2P~kA=6|J;E=DPT6q?Dw3B?<* z$icgRiYkeZT2gd2tzs^XskWN-jo^*$3oD~q%v07_E^0csV$Dv-TJk;W!VIe9{bGS0 zh4kd`J>878e#S>1-fpClkcJ!eA^3!4YGw~EQCY^I1+lxl{HXuq;rV{n5rSIM3;aN> zivAP~J+t*6V!PqH86$PwCroatdtXD1m}-7pc_YSYF?$*{R(<%e==-qR3xV59Upkg8 zHX>7m)X<}2>q^G|1)|gYhiWA+qJ}MhsD>}Z)9b6sWzgXV=AriFSk8*>q>>$vw%10Y z8ZqIv_v}wUcVpYvuZ_)FjpVc3$B8AyeevDJd{1T2Q`pIk@$2)^2xp#G81N7}ns3s4 zuPT_8rx!)N`j)EYgD8mvuz5a$k(%>=xS|mW@(HFXp&U0C-Rt{-_C9QL>e2glq9$SK z7p*xeD^3cLUgCCgSBM4|Ctm9WfiRtGC<}CG=kCIk-F>U0lsa91Vw~5wM7qBTV)Zo5#1&t zPZSke?um0CMr41jtQ@5vMSLQ+1x=f|`t|Uh1o!uGAXQPh{SyGX$K{$J|0Sg{y&;Uy z6uZMxAT5#IFtoEXUxEtlA(SXoA{0smOE2ERvU4ztWrqUyDCasm=gVO@dIb=FriRmo z@pC3|gM`R{>VVK3u5WA5YiA~js1Bx#rKd!COd|s@4H&Ah?>Nn3Y#cK%LN&&UN%m`baoz z!V30~i#W>J4aGyI94gq%`JMxh#HKWeLt;}TIKV#L;o3OE#yIL6NSibD zm?6^bQ>K~Gk~ZV}_QnoRlArkRedBCJG2ln7#Sr!glu9UHKQ8_{Ef)GQy-gJOSR39{ zRV~0W`~FMrlK2l|3$rk_yTew#fWur(6Y--$pSh3ily271@J_qZ;%_PDJGMtF`%_eq zA`Z8FNYe`k2)rOJ2OoFia#3-~%EiVI>iFwV>e&UaFN$4Cju56Pg%@WSMo4kZkT~cQ z9svGg4od9pTPn*DgkU}ENi#Q%J;{YFIl8{-K2V4fZ>Uu`k9&%jQ_OxpsA~W{!5asl zj6f7!gnK9TUs>T>>SK|@SA*SK@h)hnj4N&m7fz`rt7|G?%;17&6>rHn1@=JtP@92M!{S#tQ=Hq055bqZ8bJOfK|TPD)l}8eL*gNOMg-rYIgG5?-%Zp3m4u8ND>j;7Loi(VB8u2Y5xRtp56vw zOTcQ$KiU@U>5iTem711A;UMMY^N< zY)s6o?F^aCf%%B;blQQ0BiA`!U~GGcbs7yP^bt_5i;lk~7R>3M;_`Cf9j@p-$%|GDckN01`_fMa zfA%BLXzF&bEf}yo5_HEke6VCqW0Bw-l9)EIiL-Ve?`&y+=3a~+GD~yl35syQn2-q3 zljL?q-J{p9RA1+lg|R>WoHE3@1Rdq+_hD`_RPZ@3MELLVheD*Ek%lyLmL{DgqR4_F{V8TL-*1y=db zfx_g$&Cl4EbC4zdvDBR66zylIK;EE~`y^Lh)AzM$kTZA7u1{mhMIdqV&~B>LrrXm|y=#TVK;p1xKSXD%1m7TP zE1ud)l?%#rOz*tFQHvQ^`^u~T(wzu(*%@!)jd)oDcR9bia`b)*H|+?#dS_VZx&`z{ zt4~2QnJ^=X@>nqWwVZy4&DT6(_Ct!{5%~*j;>r#=vBGIeYdOuO7dt+OLwVSOs1V76g=(jCzoJ8i8lE1^hQ7|YM}I+U=W5Fv+;P9@NIoEx9JdoUlzpW3!v|;H`QH!8Ry^C-NHZBU5*vR{yVMs z!>UDF z$MYgZF42^w&LqYT?1xBTgw1dIAY!&DERpw7blk6Gw?}!=QXc8 zFZ@b+Y|}okm3^hkbD!lIR9T>R6JvM<$i#{Bn z>W6%{+cH-jNmr^6_Lz^JI0$(n#zHpJ{X>5GFEOlN@4H2mHnjyuGgy6nW!m@C;;1o0 z4RAE)#j|>+a?7y8ylvOOYuR%{&=U}%=^n_>0p_>JfQ5hjmSo}@TFH>S&G~EA*?eZN zU{LbVaCw^*+-55_uWg7cOgfEk_D?9fFonjGIjmj7-~e_tB&9o9)tLI(ynQa4xb(ax z`B?s-fPaGTa>D3ug|A-=;Vr>iTb2R}>|q6U+ol>l^~}hC`xVbmt8kIutS&Nl4NUdF zD+kCF5Ty1%0XqN5>LOJ9C_o6H)Nc)hp^JTsN#vqLX#Wdfj_fgmN z5_c1LITDmwI{*~CcVW>)nT3;>wzJ?L0yXig>pw&84_fYfHG%5gIm@ly3;tH@eXOnl zmPD`-K-rJ@_B;F=&Hqd|?_&NY;iTwiT^+3AN%@ZE)pSZIF_75hLV25TGSU*C-N|U} zs^|Oejik0<#N3jrDc2w!fnBFAE$@fMOv9Qc`A-$y`bOS_ ze$e=68K6U|>#a+a=6f~HKj9f*gOhH*8@us7lp~M`Ulzmf>Bm~yMA0hixSe_-t8N;%^0f+Ds3O2#hRdIk>&gdkachYx=7zhl?es086H zn%5DZ@biMfhiQaaT`p0#>|#_tG}{CvJKm!I{T{3?%*`_}3yOmr_XH2grg5-}i$rmQ z0E8i0@(25cX51;puhWK)k4oi9zjlLt>dbDMuVqKV5X~|$A zt_M8x2NeeJfYMWB_id2B224pS0v&#Nc42C}@bTe)_6u{WsEV6jYpEaM0=;{RO1uE) zmjpZDEfsHumPOWeQ%z=9Zf54y(Z-m5PQ=&6(D#g)jJNYs*+MAK?sl~dxY(N_YnR0r zoq_Y~R=r~%=HmA`|5DXQ#dD*&DLwmw&8I8uM^>TRc=^HXJ_0aQ#4~C47PvhHhjr>M z=v6;KGQP%xCm=R|M8ZY50JMLD(9V%Rv$9FKFQ%P)SI)=ljmK!nEdN~C^vhyYFT(}; z{+E~rx5JT=b-$sH@&2FE`rLyib$4)ef1Rf5+dlR6!bn?|z+);K zuW{{%HPgNIq(6jnl3jPlFjaxGYu+fUcc9+_7~$_4*wc(?13k__*xkZ-gM7ohYqCo~ zVo&_HAWATF1^OH0W7Kh$E@EP20=6vR{0&TBHsmwE7JKRRz(TZAOw`_YHsk z+~4u+BL$Vv&8-7V;$npJRTJ(9-9loQ*GWVprM2)K^%LYJnbm$1ou6_1ko=b zt}KB3Asjbw0P@^OJb8G9ih`Is_gw`W9PqRZ$!P}^baQXf80j#F(S_Mnl>AzwJ(1hj zY<*?gTRKJE7*ZvliUVY3p`mVo%3#REE7wcHE0A?)<%3`a_}Br(Mz|ZdzuKdzOo#(` zSA&{v5l9R(u%W5Zoc(!}N zlU9RzLD#0yNBa2zWhZdWVssyi@<}yl40ysMqJ-Z(XPFa3(fTfMN+K`DJX~O?bQ%JVz%;VNd-tO5 zRH0iklmfx_N7?uKVKMBVEA2REw1b~}DUX)Wm)wQhsI!vI>>0P=~m81O_05p@$jQ2bA=`5zVPhqvq~wgc+LtXJgo80kO%dq2m2sqNr`j_pnH6qC8|Z`V@~EPaCJO zcv`ERY1b%BjvHFNQ9mZeSVb!|`ZX*gM61nJz+z;ZS|)l-TDO`IJ5zu0ROBs>K`Yr? zAyhrVpUfzFonh|GykN5Asx@|xz4N(a(>b2QQ=#KsuH!XRvfL`WqaEY@A8CGM)X#sI zJHqXm4(j^7+d2WMRQEjsdVJbBi*@l?8T2}GwUC$`P<&qziAs@llydqo_z-cq^3;S& z>JJk6TXE9+pl0VW&-;)UI~58(#cLPL)(P20lKe(vumxwLMg782EFF2jnR-q0kv@x- zy}dKmhf#lJrAk)aHtWToiL7w;=Gb!2>wbiP;DGy3-#9AFe6eUq4tzks90EQ6fFoBO zS)jllp@I5{FfIf)VweAdPNvEGWHG?eg6hn~ot@dL&q2sgrB_%f2(Ltw%MjtiX2;$j zzhu(TlkkYF*yLK04^KA_vX+DIscFgkohQ8wsUyG0K3Z1c9=R&vs%uUNKFWmr_*}(} zIO52SDPq4R+m)LXr4`+S?j=Tx9ET=A|BYV71!O+hl^+W4JmKywc!=X=YgSg3)E-E8 z{{wqdaZg!Cr50bF_48o8ki?~#mJ(0`vrGNMDR@=s@{LT|m`=#%py_zQR{ya|1RKCD z__F%wS(vJdcDNabJ4<#p4tMNZ`NTb(ui|mVwA;CfyhCaeoUd{G*s&!d0_4bpuSSe( zln7~;kXJJqQACc`u+PW4&s;w=;H)M^LDLv)l~EED}4_ zi0OhQ@Pi{;-}1Ze)u-pE!mfZ(PSC-FA8lS^mIQZ2{NT+zEFgdb#{lo z0O^cA0>C3nQtKQSYx`dV8T5zFRHd@N@S?BM@E%7$!$!0 zgT?3h-@3*F$&_#mDCrQd(i-Bc2<)_bjqQcjfV@IEW2~YDU^u1n{r(sBt^vXXZ~%w` z5s`Wi6sqwjcfRqfk)e3r*P4})Po|xGphmGx92%ltWlf#sslsq4-?2THK>nS=H&EzM z)u7!%STYcL_>90#9^b?W0Z_m~hQE{Fd*_g!&n3){d!NPQ^)-=KtciTEoiX@J<=k3a zBGxQ+`wG|k$zNbx>L#{mmiQ!iz_){2&+?`K;#C>GKm4*Q0v!tx1UxcBRR6cS$SuPq zcp%}39{~X@F>A3D8rV?$o`m?ks`54>xFtj^E!${47#iaV+&^>f!c?B+nRjqA1OXfj zND6m1B9zZ4d36)Gw2;oX5HtVeSfQOG?6v%#SWWm}amsrfCv-q^9->GpRSqGyCRn!` zY0(4$-(PTgS~X(+4w*yVT?0sMUKbz=bHsZa$N}0gPCbC&e>gP?ZF}|TaX^nRVr5m^ zn)f94qs^_GRCz9H{7Z5ReQAhU4UQRgV{~~^Yy3?l72+>8!0nb=1_lnYo=RZ%@VZ_# zT;5sI9(gof(qS0=*vxM{mPRY^qctJIHFyzpM%T;NwFc+^4E7wBj@Yn(FWE4n#Vcz=j_dOSGk%(mXTX=E1a$9DxJyRPY8OaQuRUV$L zQZrC!a>4^ypT2hCI?+(Kiqwr6D4Z#KGHJgo5sd-|IEBQBmdB&HjwptS>$Jw>v#}^o zKD0@i1YF2?;=i;64%0E=Hq&l4GU1#evDq6!$sXsm4+DTqT^HrOCt=*MoI%d_UV~_m z&4Ci?M<}zkMY3BNlwHAAUp;}be~it8X97`e6_#}eLO-Sy^dm~-gROY+JNWtzIF#`+ zo-$CCQ!0gofx%7(KJsiC^6gM89eFs9e0(ajYP1c$Q>lHv#7-(OdL1YAE7N#mW%&Ua zsOri8UmU!3YHZawbLu^4r9>n4)uMi^>zGsT1qoY z0{;|&Nl|(0L%h(i@Ngusa<(-kufdg{wl+y>ZZWCAX+Y(7W4R4mA6bV`s22MW;j4I) zlzv9CIzBnQNGX)er_ae*9_4sDHf8cYSF)6{P)ZYk~qcItIvYQ91ImkN}FO(q`%yRXPqp1<6-MoI2Go%(5~2C!Un zky_=E-zI+!2Rg6_<4$u90w`V}iro2#?!^uZ=kR?ZuQeN4eDny8ex2AWc1-@IV)-yF zWLficK3PyeRg8e;e8cx~XS@v(u>YD@#Hx$;x2u%LUS30IXSW3?xDaLwnf~>N!!pba zgR(aMK+sC&ef=Dr2gV*Zob|f~ePVPAXu2f2U(OuOh2qcnmIf?Bc@= zyXdK_!z^?q-z(w?Ng>a+5Spr5R5X_AXo-+Tv_z*4pAyp-rfIBg;}(Ym1xz_5B=M2) zw|S*FN^-$$#a55FB-1s8KV7jGWOk(VcNk_kZ1b$yj3@Uu?Jd1&INs&m(IZ?uwdLlH zCBjJNyP7@eP&)Q8_<`G8EYe$DkupybQozo~#s|OBQCO;%=WIt*&NvG z@Kbm>ZNL7)$kyc)oeo51 zXoI(-hFT6WxfcV8i{|=Bs*}Y?Fjv*sedS{QEatM3xu7?oBU7b}1OAg+sxa?!$E_5h z^d~}QOo>0;6$a^wq&Xhw{Zc=ZJuOhrvaISKcPj5X?j9(=0&IdvA6RC=BI=guReR;f zcTu5X=l~uA+~6w6e?t_eJ;n~hhV2G}P>B01cc1+yHk-81PN8Ig*(8epf@VDoA2lh< zSQD$_jX5pVau7{aZM{n3Z!U>2YIwiwEhR-lCsIX)DpwF3kZI2DPJQ&YJk_1rCJNO# z@XfsfQFXXbrlPzzk*2M|YO|0$eMCe5dvGxnq6Y001q)3M7gC?zk?Nf^xea+7r@8H> zeh?vl_4=7GS$VR|uR`vN=|y2z_UT5rvY&Jg4+EEA(V3d z9#xJ(hB5`VPv4pGm{d_bhUrj;z&FGohUIag$&xk(r_#f*-9padIozvOniS z*e@E6NTy5oc%DG#N+_}s2weq0O{?&{AK)_iji#Yn@TKWT|!eyxMg9W=k%J4=kz9nsWv&@_FL$QZ+-<31+b>zOv zOsL&6&XUI)hOa%zBm@x{?UKsHv8U$`#K*g-$fF?$OOd5!in9UF4ke>Y846^KBegP} zih5PlV(AnX)AzydEaNWGR?SDft5t~nmR^F*q_5wCd_Na;ioLNZBhcnj==810io0rN zfI>Pnl7B1~``cS>>w9-7m%Oboei5mEZ802!BmA&-L7#pkvQx$gX>Mr7+g489n6>vY zLvS?Df}|)Lnl$3OhNO?SR%nc`bo7AbDjSKAOyd>wvQL)pG@{L8kCDWUzg<`lOTJgh zvEaL4($3Ow`QDC&@m^?qbRvZ3$L03@&>9C5F?$Re^7ue@A|K_feeHYySh+{$I<;nq)bqg$aDVBrVB_ z?b;ld&MwP@9C}_cuEJq<{FiH&lVjX1^8LOt6}2KQ=BpcAEKC;$0$R`N?Vs8JSU{)0 zpPvex^e%a9>yq&J>Za^m5OP4EqPD?^?kNI7VdW+S%fXL648#l3YXIz8NGj`aMD8h8 ziJd2I50`^uFTjO}bu<(74f5Q}V`(}x{Z*4s{X!fLIPXsnT)+8N1Ux~;wETX*fXh9l zA@lW9tH3Ac#y-OP(AI6&r&^u|j;;*jH|yn2pxBc~G;aHS@>c@`i1-`pC@Dogp}P?Y7TimS|1sh+y4DAGHA%kT{~TBaB4^w(l8m?@)ZAzJ=fW*M?n~>eyd%aKVJYV%Hq!mIh#lfkBFT4;5NbZAp( z)JfwyDK|4X`i1)X1E2ih*hla)(N>FbruL8a8d-JDtC0 zaGh#eE0Z1nxz|Z54leaLwJyO{G%_CQXHe>?UQ61hrDWH99BFg#{_}I$loT*F0wMcD zS#C@VIKYjyjei@*U)??Byd`0ORj>>5^=(!oUox^hd7(C#U{TS?v$evinGBVB$Ixm` z%;yh%C#_A5-sfc#r>@t_>(L~#wZiMW2*sv6rD;)O0}ec>2@40+|249}^nP$;{Jmfoj)2u9k)(u~^|Y?`WCgsLnvBc2@_=UO%i6b@ z91lODo`p1$+?^Va<`V8F!;Yr|EJw@`R-z=iIWue4QzmSIo=)(@w39+wKOO&Roz(1# zW)6F@LShoTyc#Pw#k=$AdsR_?8Bv1+ai@IfqqQYPrF>}d8faT0pX!r@2O4;tUP^(0 zQ`x9+b*ZA{y6SsTFg-+2+`;7(U4J;@boRpQ>ahGN2(O)hbZ1%TOBii@K>$Q<{oeHKe7&Bv~ zLCcHU!1LvOfG!P}2bm&PPl)G=P{_tgO;NP|@vM<*iggz?RI3O;0GpL<+CSN*Ph;%- z)N^A?*f`VHovVYq9>^cAR$8pL!9#H6$SgxEH8Y;cZigu*Nh#DB7yyN-bWwD3=@0e!C@c)#liHA5i<8%1T1gR9(!?Vd7S-}PWVYZk0M1kH zr7t1+m0I2O?$oP0w-by*F^h1(A0YgYob?r&PK7nY!{7?BNpI@)3Msj{E+p_dlmNrz zvB&D~KfjI>Re%SYT4MHz;wg8fIgpdWq109%BGmf%U ziUzw>AU3S5pcYw!NxwbQWOq_trYSYXO!0oJYRJx#jLZV_h%hY2CtOVH;z&{Wa|MmN z3F=|Z4nD5%@QbxGHSlfaO-$!N1aK6H8t$&1ojYgMiOwEBC20xQ8~T+RLhmd8+UhS= zlZJ(?zSl5M)hlYoaXsGH-RQUB@;(Ei6}ZTjL38%M69;kPx02zT zPY1Zq77+^>Z?b+n*?C2V&W=vL$*0evwMD)lNPi}PH^aWdaSId@BfV?PXrAPL%B82u$p`F78){JooAA?(P}>mbAF2QzxR_bb09kSw*KIiR6F%tLZP@`F~V0?S>q* z@OZcuykXS)HFEv*9m_NZ&@akMZ0+xU%MWjjYry3icE5uwKplwadv|M;fGhpSIu7PS zKA$t?&b8y-M9;El5kB)NUYlaH2% zLUC}~z$1A?;O@eMM{)6)k=nOCXi{gQBgfI8=9Wj_gTGW8d1&G)$Z+iiHp`XnSuzp1 z#Lhmc7ytlXbZ#HZb++HyD|>2+c*HRdJeol`zPq<$!i_#4)hbPW^7JJA)8QkZCdVJA z%75wZUVNd*MEKgb#KuEq&9YrB11^UsYI~rM^#5KyH^lqu=P9rcwrpPQ_9#qUQbM*V#ak?QHG#YSjQ!av z^=1*Y`F^i=yTt}nn*9JEPeS;3_bmb2>}BlMk6^xC=@#L%qt~-|p1TTle@VL+7e{+b zPQ?@kg!}J*W3BqSKQXnOP7Mc~%JQvQZc6`l>_*VF*@wYu0GR~Bopxnuz%JE72C?tGURny#zIA( zF*b5o6xv37xOyc4g{D9FO7pxtJ&6RmLg^?oqH5ON&_g5!eOUTtul8Ed$>`7u;Pka+ z-$qGxhM^;Yi2WUvE=9%NYzd;*ZbR7`qs zF6Oe_)icQ1u{?cRvu21KoFuiHpTpe=`CNfnXBNLrgl=D$64e|ly4LtZhW;Zwrix!-Lj12aJQ7$$nSQx7o@(w!}0nCoq0lq>Z1{dJP zgG2FIz%}@!kG>Lr+dxWCh3Np_hy4?sE==T4G$QOAX@XL7uggm@INmmSL|-7V8Xbtj ze;C+`J+I41$xY_?De<6H8tdVUGJhh+HR8t}B0cu>cCL+e~s<=J4Ii5pEfWPaN`dtyv-KC}|IgnQJB2>$8#H(fN$&)LTkM(*?saG}$aq#k^(zI~WHBug?$0sD$*S)?tBx3Q-B1h4>sv zLSE&iCN03dI3&HQiEI}?SjDAsKzdzvEMDg`vt?kwt?YCjBg$=?)MdL@&Z@qap$z?fr`?tC5c z!_svHE}!}N407MCD^3-OP`<>_PEQ!toH#Y%m~J5zrfJENQt&_0&~2wqj!;m5NyK@d zF>Mh(SO9hyY{204PAsTD22?hL459}QA>+e676PY>5<}oof;hn*LUP~ zs30+<=_xDP7!Hp3I(*R0EHDqya~(^)M_D$53Vw*TNk9)n^RI5;{3~Yw$y0Fy^aTjc zcgIm~rT6FA_CM8HKa`|~ePR}V?M1zx_m|?R!K4G825+@& zZ{jm-|1_3I3WD%~TtQQ_M0GnTfwnNP#1Z7MkJp9S%>M=YNkSsugNiSfAMMnGFBUBn z%_4vG_S&@*?G*Y{Gbs9?e?^5fsG|`tsPUpvg&7eMktt~AB2y*kqB43^kTht?8&NrE zX>@ePFerc|Lo?P>pX&^Kv| zR-O?E*k|&xeWwk3B;ok|Rub4F6(!e{p?SdpY=VfzcO%zJrf|(yi>v<755%w4^BO!T zx0A2F{H061dp7O$N<2P8n8D&?ub%rB_*zwWm7)MaUOfI5aXvTh;^?sv1TYIg1&DGH zaQ8p~1pmSxZ!=88Z7#z^w9IPlP!Q`&3(Za^sVf|kC~<+#c?{cKIRBe~zzlr3&WZtr zMuEy2Q6M8IR)`QaELRLj2XO^F*q`hf#GYIm4jfN`1@0pI3Ne4uKwS-waq!g*q5_uc?7WMhMC4n? z$@tn4&TC->G9#EgS;rm$l43)uUxf3=`6Cf=#H_b2d++Sdp657RLHn_lBkSqZzvnzG zs|!&|ybr9(VT5jgT10M2P6Bi{B`3*2=!Z}I3A}tXBJnS$8=q@QJOJKmpqkvt{Er63 zmS>||;~i!dZ9#)y*<#fbuq*yn&=BtT;Z?VOU+EjM@4H{NT|6?&oZEy9Fb=0VBpCm;-eizKR4Ln>H?X6%#)9^a`vmP1^Ulrf)-Ix{vfL#fj?&d zv(Un94$y`^ds2W(LCxetnf(|UzE>50fuX!XAB4xP-aJBA`4ClhQ=LiBmxt-+hq<=Q8Ze z2~+!8I0YXt8NC1JRW;D}YoREEVor1t4`_t>*!Z4QX^bSvfH0N}aFP`gb2;R(svHw_ ztmuS2!s2#TgyJ}8Ak!xb+!bo@2NE9Ahd55`xM9n<_}2K;=ieA)ZL0{7Mg)qDxJzsJ z`gt|Sp>7AF0vu(w9$usw+06I)tkX>GIuK%FQZM?yxE~VGfT%O_4%P^n$BTfuqnA%_ zhpoIy9n~!YBNvSE$?X7A3HY-GIKLK3m^>c?^VeTvKpS9CSvDdB4XKYCoGbJQ{8O+3 zk}Jduf-DF-qVES`(ch^d`YD4|#UD3%nZvBWJbQ8}aj`XP8R>s3*;_80zFu9Cf1~qr z?bX988Ky<3OVBD1$IL5Z6+#DNDbj(~YH60|1?T z6s)_usmrA5HJ6WeG9x|SZ&+LtdY@WNzaIKazVWf!OIp*-83HI1C~P+M%3^R9?`)k3 zSWMx4Z0Yxw?stYJ*S3a~MFI~zMnMD?;ryKbiOuv`JrAqi1`~JAM_-j_`1V2aIxIGe z@skpDWwj|tU%eZZ zoK$%U;hi*lahcT1fSkJ4Pa3LB)8RR!Z3RAtA_ECHYy zj6S{x^6SL;qZ=@7&-riKo(EnKy1rHRWnrwwyQ3lnS#tXr-A^r}p`XH^2GCN$1G3qF zD>ZK;OQb0&Cn%$japSk=sN22l=6FX8Sn_f*Tl#s!*nD_QVH$8qEvYI55c?sJ!_NKn zpVetMs$NC~!rK+d`ItIak@Dk5P0Z0oqw<;ZPRuPRp_aZs{v9dcX6}q5WdEG83$tGj zjM*rbfQLto-a9Qn=x~%sQd-2SIUx|o=Hyu8M(dXIdm#lOjbbOd-5xYixCGpQcS@5> zhb||)#LPO`tFBzhD=flP%v*(!jTc^pS5ZX6<4!A^wj=-#j3z!_zq@3|#i2I&c;StA zE9nrp$+M8sk%X-IZ%un`s~e;{Y+3JHkzQ@QKhk;EJoud8AplS;bJm#OR4}~mJ3aAS zenVUj5d1`FUV!s|`ftj!c-;KX!xzt$ly~#+XPxKL^@Ec*iV4WnlUME~D{2 zM2Zud0v9cRe?ZlXFRgqz?=rQ@W$#ltk*QlH2{kBQ`#51|u|EOE)-eee;i6Pw zu>)_Ks9~|t<|T+7jTGa(SKl(w0I5)Je~U258`kaloDXHk z`?P?EQwZ(99qBC)xb-E(aClC6eaRA}VTkicQ=xjszgFrRXTIKGqlG+dls~S7HF3X( zvI|pw92{6YM&qWf5Ig*@3vAW0D%Bt8NBdt?^75626H+XUxHS7D->WKrObT;4@FYHh z@>s7-TH?QSdZ$d|%Za-RPtQWz+t1R=n2%79Xstgz(3YQ}*l=33V`2+P3qHBK^^jIZ z>zDH4?)wqzb!yYs5tjTG(C$_JzjQ}|LVv=dB6ML&j)PN+I%%FypUcmg z3RyX(MU1b(O*6~@jq?~pcVmqrrP9d_j(IaLLMNH+V{K)g94fBAm3v_cs|@P6?&%)( zGJ1@cOwe(Ra@#r}0}Q_0BNjoFw~W*4A4*d*VFHBD;YYs1`+59lZNPM(LHo7BnXu87 zWlZ-O-cxxJP|8hhU^qOqe88dV?WN!l?fCLNZru!NcIAd9y$(SE#B79#CpSPRznawe zS>EFCc?kC-;3dHW!n^POstd*PEBIk|Rx7$(nr7jr^K&bG+ZcL+vI z8xBp@sGl@+smu~j3tqkE`j1Vpa`Li+FUI=x7q|tK4(Xf9s$&E!vbsoG31>Z*@blF9ShF~8YL=?WHtM=XR-!<)ag=HygW=BeR9x(VY3?Oi^#C+ zLo4LLV3hPWUvfIg&Jx*&Y0f^)B|XifFD3o_jAn}?G;~J0?8HyJqcY#ra(mz<3699v z!7rwC5-1)LfHGwGVjDGq;Z|*UKP5Y~3lBiMxn9YSk1(e-N}qpU;n%B%y6}4n-gebc z#UkdTRilCNF~;P;IAO}muw+u1tN3P1_)WvsJxe?re2RZw%qmU+ud^(E*?4);en~z5 zHD<1;AbC*Gqr5d1nwjJe9(vF#=gM_2rBU^{Q$_fF8gS0higMCJYc#ZczRrB`@fN*Z z3C|P_2EcsEO~1#sWZ|9?6s7w@+2BDp-^eFrh8jp+@$y>X;K0UIrN`$Tcjs<3MVop? zXxW2gYu65&YSNF`nb>*BXaOyvk*|m4?u)gRm%xXiWY(kB)7HPWMQi*nyg92BCicC_ zV{!FZux0(U<-;Bux_Uxqt)A}JYtGCsZJG10(6i(|m+c4y?_7Gqe?(T_Ax|gu?(OeyTkFWIJQ1Bgd6xVtiYLPx#uk(K5L^`rJS17q4@|e&YV*SRS)m z{ev#_Hq4AsqpmMIvw3fmeprNnIKJleRv5`WHvH;~-u;A;`BZQL{+B#F-GC|N0F^9? z<}k>RnlFmpq)`m>%lj0n9X`HzDS8?+_U~AbaKGYl(<9A=DlE45otpI@yoLjmpyk!- z_%oc5v#ohKb&s4ADs6q;JaH{Mq<>Tf(+Xj&cZq#vjQ;pVqlj^?QQn*o?LInFWfcht z(d^N+;g1WVhr{nyR9g0*VEl~6c54T*HrYD=^Z}7Q>~`!4gkMC+L40CMyjhigMoU6L zMfEA$3}Vv#jQrKho{n;rDCcYoS*SOCeCuK}v5RjJMeC_OxJ9Ff3Uct1UTn&D#ChDe zJtNT2A;aIa?IR`kgNZkD2XMN2(nh`s3&rL}7n|z$`KMY)d7d1(6KM{^3DR(t6aVad zLRaAPz*{fk{QOtJ;J5pdEXw_UYvkx_ORuZgHzD^@XIHk)6+jvmY5L(H|r_t$kB&VdS>tsfzL}_GabaK@x$r>N% zS$u?6vCn`>DWem(>I!HWDnjL(+e-x}#a^a%vW#|{IR#|1WV!yHGlA<7)NQ!!9*yn| zP_bf`M+_QGSyH)IoB=3tYAQX$GcQQW6@y_}OK&|x+X5^?8U$M7ob^@0PhB)L1i6-Q zE)$OaKmA|iAwDK9uCuJGjU?sg)1r1hKqfkZURuN0%0p3z1IH#7eWvE-(-;pzG{=}Q z7H0~9&YKjQ;N#ufRqTN>GK;!yuL#zOG}@O06bB#)0?v5GSu-TB19Z9kyF@XdvdY6x zY1Jwb1>|t)QETAoXdf>rqQ!H)i!+{Pt&<_QtSFB=S?Qdj2kYYPxcu;pL+6s^*;Bme zdOBd-_!V~$l!+trO3RznW%LmK6(CM|__bJc_g_NY}CWOVIDdGQkF} zY-6vFUQ_1vdwO-N2~lK30C$38#UfVt7WsWPIyB}+#s>%^;1~BmVV?h0pGMzfFP*c- zik;466Ou}m7`gPaNw-U(h9Us<6&Mt@?_R(-{5o(_9_9ewaB0eP&d3cg93Yb2ogS^L zZ=4jGhQ$SZ$c+>9RlG;<_y7oEq)tolNJ`=wiVR3{9Um zY~p|8AL#1?WA60f9^*pZKWSMg)Rx#hEhLsN`QKU*B-zy zknlY5ehP&O$tF}1IL7cEb=b3c9ovCeslcA$zK|q`u`&(wUvfD(Xd~K>R>NQ;QJ)JUI zE;bq(5lvAeN80p9As=&cxCnCt+EyM3=MSu(y!=G%%gUPMtrh6x)SSbO`xbIqRE@K> zhKKv-aCK6IgEB*}bys(ct$yHB^#3=6@7H~Y)cw6vg)>%S$T(Xvlpd-E@wa9Q% z1D`z1mI}AmkhO}75^@GOUv#RpO!m;e*Ov5`5hZ78c_I2lxmB(8vld8v%w+l%V}d79 zYE>f0e8Z~EI+PxU!Ko``joS^!2SPNHHGwCD2zz$}zm(S;9F`6T%?giF=9MR&|3p7} zj`Fw0&74bgc#CwJN_Tdi9E*VCXC~EJTQ0c)bynWbtDqG8Ta6pN)i@~Kwl0|1gOVrA zep?+5FsMa7+5-jtQ|l8e>RE|7lq2Zk7-6S~GqYTORU11wK-g41{2mn;7QonB0R^-? zyxsct)bUWwl+E@(rkh{#AobpT({nIiR_on&yu(vcaD*U#O}^Z2nrZr%tc};Z<2d&S zZ6ktzLtDg0ZEmi)(?UuZ5DeydYI|FE*qqzoZZ)r9d2-#=KobKnL?W(jAO+d|!?X2F zun>*(HD8##w7aX)OCgDs zv@3$X%Qt_={vbuG#(_k)kv#HRFBLq@bA_DT^2)u&;h0bopetdjTn7cT%HOWWk@A80IhGYkEq!vBL8y{Dq`_e*7%Tmc%+EB{S+eb^w!7?4dAPMeW0MzSb$3saX z8kRgk0t2e@=`S=$6_-$>?a&Z7bk+`eWPzJ(8>Lq>eN2l9XPUr}@Q$}+b3 zjaf}Zz{bS%pQssk3+ z=$p+sfDa_7cduH{qx+SFUvtzqu})S$X2;&achL}8H}aSGUKk%W`IT`w%+SOaz6(yy z)t&S#JL3TEneiD~yj8xn>YYZ-clp})0h}m!?gcnM=YOxWK|y$J3jQ(Mz4{MoxtGT` zyN91=1bfbbXF*@lSnqqSg8bUNZ zTEuj^Z~E~%x4CMunOXhHdgf{ewcI!zbv{Zv78L`P4(J5?` zt<2^JoK}SUnWNEPGX)XLGD>u9O>Hf`rA$OOR}iZ+8E@t)l8+||>_Gtk1o`9=$P6aZ zkpcGtSR(Cx2}S>j&rLSEP5=)mL?AoejWwIR1kVo;O6%1l5;M`RIal9_5Iti5OZ7L# zIkvq5{^k7KdEeB~+L9{PmeQFv5TJ9-)3N}{zFEeG&pP3Q6S8V7r#3eb&)2pJ;-EqF zhMAA{f0@s#n28bXw9JQcxWvM*&Ce?IhLl{+x-6n)f$1I0oi$Jp%n?mbLTf9*4(({o zP&%=3aKow?&-st_Bsjoa1x4>}_?g0}_v6}b@{q1>Vj!K?Zl=z8Xg~EYZAe5a8~`8B zmOxKfC~@`XHgOh&uXn@70J$nYMT<|qw`{k%9x@K1Is*9Q@crN6Z&c~O%5S=O4-6e@ zw6{j=_`hG)rV*t^pEQ0zFLx*a;njsdaw6X#7)#Sd@Ceqz4{JPhF1aaP|H65wu>%Si z;`+aaInI2X#QBY<-ZPx~GD4Ik_v-GLC;K~5t?a^szS-b~Ml;cQ7f z8U(Uxn0+iTc*r$M3mgOmV;BUk z!+Hwg!=40zDRE>T{=j0oyEFW%+@)`O-s$C9X-S{u44H>QqUwI(-x?d)PE0l|l$`h4oDV-nt;~(9;^H4oA1Ef-D(ZnY@1y;f< zde{?EpbP{KgqUz2zyW=+WQ$uML)dxZI`f$awv4Xf(XmL%+lZ4Qx(K<*Z4ESh;(>ka zohizfy94II-erb8xy3|G_)ruBTHn9m2ccuKo951_I1N0`NS+-!w^n(mzat1n*!- z^4sj@qx~w6>jbSeV|}xJb5k=>Z~9~zm~pjc`PxJnpt44|+Yhj&U(Em7p&yr#A+uv@ z@c7_#I=j5(^Vj;h7-wDRTs-t_Ml!91J`rjkbBHK*;D>(j=UlZJo$x~!@4&6X)tP~eBoj7|N!GQ@HX5|dANMXL=#^9)RZsZvwLiu79%!Fn(GHCG~S>dMJr9@vcc$}}lJQdBC6Iv(zxio*NYB&?1_F#M-f9Yp>7ibZwrJ0rdJ@7d9Cbw+Y^~`GGI<`hZ!T?F#^4 zI7GsQsjZ#|WWC_c091320OGtZqTR4_Wc}w{SD!N!k z1xV`oNW&6CM@d5^Lq{pgs2u!yKd%1TpqKPuv#>*cCEJy?ou#k`GzxKzSxIr&Dz6k@ zX6qM5!jS*%41;BH1|p79rK;iwSTI$rN%Iy}64k`r4!6uRx=GAG7g+lj{2b+~<1MV? zrOB0k&fzF89~p%Zjs2+;gU_n9*Q(ABugV5(2?G_)WefocJ32x(r79V_Pj-0~m{N~P zD#&1)RFJ_0t_8e_R^k2ZV91lSg37&}g>5b6;sEN~=}bfXE(~>LH8*>6ipq?VfQmXk zn?O?`jnLwJy`^Oa=Z0p>UK9;4aMfA zAvLW(NbS~?zu?Uf=vb|PkJ1BDLX030_z%+)YwMy`BLzLjETG5_ z#$y+n))&@(UHEvEWFOzP(ARiY#P~rc6G}%}MgAxI3Y8Bsr&Tb)SmEIW>VAHe4vI2< zL>)f5WB4%lm?8np3dg|c&!@5ux5y3il~gq^Yy&~Z#x%BU?`JwvQZ9@UBL)y>MiQtQ z4lP(6<`+%Gs{C)@zOYuDB0RVR224s0I@e=UX6vXUMOZu{>u(c zomi6@IXEKO>JprYfvl8!y}R%MSthVQnKkvXevzprYW0r()^kx9!jN zrXjaR-s=#l%Ow*aXhy(XgbV&R9P&ccSH<~&Cpf-uw5Htp)TUAHyII@(06}O&~?+##Ju>+?L z+?3{EO7|2iE~~MrjxKsM00Rssv;yZR2Rk!LVEXr&b%XF$dp}oB84o+Wu0x6}doqJ2 zE9f=^b0K)(J&?5;#r?P2aG9_EOa%6Zfl9(aW$7&7G!}A@5Tu3WDLxopf*f7|4GqjK z!3`dJd=Km=!3c&(5So%; zjD2fGG#oWmJSxJjr|5v_0?)a1Ec=Z#v`g7S2RtB@=fnm8DKf&-LaMvg+o5=IQ+>_e zJ26V8N?*r=SQIu5jN7ul$@|wsp13TGU6?4#{u;XQd~dMt+Egz)w^91hQu<|>jI$Gm zlk!nC5%)Hq(%F!v^UF3!So9_xMGG0#P{bSh!WU8@^oA{860O~r@s;OCXcS7R6_WLT zILeSFWnv)7t2Pf+q|OOc?M|2c^0-_-pH~)$QNpKMGo~hhj|f}z{wcJ0wuILgwEcmq z`VqYp%L!eeoC#9kPWK#VwPTeyx#cticAtp1)x&#rAXO7jc^{nN7vw(6Cni$yM^*Ui zuhEpwuYMj>Hk&h|aXjcX(HRrjlM{u`=k~K|j5&XWsp@iY{|^C)qb{$e^&9 zg>~n`F6|ud>^NZ0NI9|9-mY~C9_#){PEvk3kBq~M3zfd<8WL3#m^Y{YmU#T$NkQiH zvR!!W&1#V5E}GCRmC2k&tSRfvSLdvy1`Ad zHmg(hG1}yiKF+y#VC<~d8<31b>aY$shdC|EVG?}-&u0pAvhw3IN+c8CdmPFQ#D zFS+f{dvk5ZM|CTmyODf)*l~`;6V72~0AQ8I6>bp)GhJ=dTDjMU$Z);`7x*V-%6yGsgb#fPi2G{ktx>Y?l%-= zeg6qdq&m^K&aG}rn$tPWN-hD1rr2GA%~E|b00&f{Jj(lylx=*Q$|;)uS1OlcmQwVYiQ|+Y z{>+%#R`c;R@mneyr;0=Qw2oqK51PoK-eq==Cm)tpNN5Lop9r23eIQS00#8^T5I!DX zha{zRt_yh(r?;(ad2fQR59Q#1BcUgE59Rcvzw}Xad*UW^T*#t{6Ms#j{fYGZ-&zrq z5Z&8cns1Rl|COd260t7FC%k+zIszE3@X}aBk=@2%1&>3x@z((W!5RYoclZFYKeg&V zI_u6 z<;MN+I7Foh`i=1RzF`I}fYNU|wnz_z+{MxQ*76zg3&8l5*`TNWNXmB?L!o>gxuuk* zACw^DGh_m}gAEOM8EUnKPj1M9jf~_eDMcE5uk_S6KS=`&<$RhJK~lHOO8Y=i zM(BM295Z;P1vo#ee^_P7dRw!Y>!~!D?b0+~r-GN8zvq5=e%uTV4Q~Oy^t=DG5%XE&K^kf@mq3X zj3QTp6?xtCWy71pB(H(?$DB*%AuKms&OEMhC&Lv1uyx=L7E%37ZkViy@(9qptfPSZ zocVUy5~oV)`t4<<_SoWe_@_Tz9#r|ARP}%QJf<#Pdky17cx`kl<(Or+qGKE6K<&*Jwr3FOJl31l`F zob>*o6HMUCIq$xOU%1fit%#pPTjR~G2!SPn-U?h52ke=tJVLDCdHRescQc_4wF+Uh zw0NK5VhC309%wj?Inwz7guv1!THrQZ`LjRxJI%}Au*?GiT!3H(kwgpuLCBCHC}7k_ z^pLjuBljW4PioM>ek?yBulPg|BE0U0?|{N?_RP>iGz`V*&P|!IJl3E(Bo$y8j}+=K z`!HM6ghS?rz2XsX38(%|5!i)MQ~&kvjeD+u64I-|AgTJMn5vv{Nj}FX}6~ zu5}WgZW9Xo1q(+3oG`1yzdy%4NFE zK^gwoZuQIL)75JSIkn+vB*0(-xo#Og!S)vK)t3H)_xfbB>+t*@7t?a7iaxp7)GmC3 zb2Uej3gg184nUx&fkLK451@nap2yuqWsSy88Y;^9ii9!wEMwQB7`n`%guj*jmB5Yg zh}bSJ)`@g~+t^ILyi{LPwMGEknYnZq?Dih zE#D&7yLT;e7IQFIt0TPCeI$?`|C8hx0Z^&oZnwxIyAh$gl%W%f!aZyNR|B478O2{5 zrb9iAH{K=S=O^5Yw!Jt!jtjoFGi@i=tF!atQ%p>Zepy+(f6oOwJYoeg3vqnOSawt^ zQ%1LJPIlHQ^D5rOIOk=i5>l>bUwn9nJvDJS`HOpb#V?C+lSY1;(Q)AyC7u6jym0

l^ZkRfrAD7q+`3TZuFEt?*YLCeOc<=gxY3C9|jjfN*>x$jsK7lQ(N_WILh7X zO6O%G9g66bv2l{=g)ef{pB{GhL1;Rf;iS;*{-rP}_H*hb_62WWtnzDmX3Uu`vaI_t zosJcRg-{|S?5OogGrx^<#+s%=8CW4mHO;RdLE}a z-XBNhO*_6kD97@^iKuaT}CtH{_}n8xoD?jee2WeXtm*8`Orny%Xu6ITcR@JnHHR8e!6n zONzpCfTKt_p^1GbMVrfE^pdtapOqWAW;`ywyAJQOPwhgLbB@5&09!z$zt^9nydh$j-1es)MCC`vMe`hxuMc+t< zS0LN=Ab`k7Z^|;Bzobq192;Jml}^L@+4wXYNjJyG&xu9tkggBnnp~9D>?feN-w!<3 zoBJ!|-Dy?R%l6x&Ck*&$9IE%eKo$5xtJ1^12)q`eKE z&y6dKR@uPHHdMM*`#8yl3&yEAQk_2btYaSsS)W$Np%jmgYq8oWxm|5A17r^TQ`^1c2{ z;ZK#)PLc+$8WOM|1+0y53|o}FxOEhI-iIz}hcf_y7y|Py=w_n==n=5^+t=peEqMGe zQ3s638z#S-_Dd}thnQ+h!`$dnDfXguC@IXT&>TE>7biJiL)<=00G=!&?BCszDZtfz zP=4C?E*G8JeR4ViM`p>WNnbLYug$EGn38 z1B$luq2=7X4nT;9paBDvCV#x4I9t|R^pX17zFt+Cd5%;AB_>MQKP!4+3YCSbA# zGj$6-LKpVoiOz46owWwlOyGdFmC0&?a5ON>G!ncNS3|_(k2Pv9!F!1na>9H4{Lol4 zj*!=MxZs?&HQo12{eYP;?%f6B6Y@xoEg7T1!C4CA2~OdiE0@-zR?y$V*m24&TT77Z z84*vnZp(`)eV)m=4FJ%w;ls74e0p18Q8#v?PG=$naHioOF2Du2|CdN!WRi;KPKAKpcHV~;)i>94 zro3|Q5a60q9=MMOcd!8W=GDKQywjZ7uANvWjvd&CjM=Vv|Ill2O&mN;R0V8YVS6rO z-V8Xy_)M9C)-H;WS!sD%N*x#rYsL;BU2MvNvk))I#gc2#uS^2ivEL=Ii{U@Q+n?HI zSnEKTSZ_RS?htuX)NabOv8A|cDy*qST^oL|!iV++ybetlzdsq)#xQxI9)ylPaQ#1{TYL^hl(l*kY2zmWKrvVYfk>Yhur?y+Wum>*A1$2T5 zS<&DCCM52{1yHr|Z3*E7=4YvB4@DLWiM zhlB*Ti5zfK2%Cbse++Vf54+bOc{99}(`HKWkpj_wrXzYKJY^IIQ9>KBMUgBW8cdxD zUMF&p)3d;1!UT_2^~n^|DwPG%D&^%bE~PM<)38tWYq&$=%Q@Cp%$2`Dk=Top&$p8j zs9T)yl6CZZdFuLSq)z!;g{xW* zo|TfZ3iP$8k@=zI2QCwbo)g*b08T%Ttwp2kt&s%UIi+VH2mm+;aC@+{Me#q=men`* z&*QR7A23!0DysLdXDKzK1l^=9T?HLiReMs84kin)p2~VP_}Y?J+@vjpwj^Ooh@Xvb z(iV2MKWPgG)#RV9f9jfjI@!Tk@FKj!!GZEimz{%`4ARsJE4YYg=%E3;N#jpDEhO^u z@8KtnC*!Zq+yBmVqy&ko7eE30up=FAyE(bQbiS-vQ(q@ZTYzU7@$S7E?q$hU^OMQB z9d6I}a~S7lTaVLauKw20e39$7UoyhV0xzZ5pp~$A)ktptf=X zDLX@;6vttR0FI4OOULUW!_5Iqkx^8<=Bz(?p1@Ohq-fz4zS$jha{#8Tv{E~u1cBS| ztnJ=T90zrqT;^#ppfgNr^qX~sV0LqNLDTt~Ku|*rn>A1X1I!*C%-}bQzKyS96yXT6 zI(TjnH6Yoz&kks3BU`S+-Rz9Mk$WCY?)($RzUW_|xGSeL3{LN?<(HFsQSkL=8QYBv zkpRqL42ipMt`jREpYp7`mMeLBu^JQ{zLi)tw?O|E0-)QjvCO(8ETq7yCJWK#Mnj>J zN`wbe+qkwZ+E{Lm;#+HzrhIK6K5#DwZe|%F0R2Bx%4dx(qI{V{r~3@FbQZ)6rBe}9 zPybs=`OC|TaD}s5?B#&jT7np^y_y=b77Po;QxTV$CBU#yvH`2AZ@Y>EfFS|5u?Uwe z@aL+z8E+q_Y#RYQi~I_*jX(hh&OjD|2%?CBz%{4>;6qfIgF#G&|4R}%`HR_f4D72- zRJt?U!!PC2iCf41zYm@yIzPU7pI#Dv`1$HuqcQ3^+rsW_NQ2xzj-IwUXY!kwl<9Y> zmUCOP-4}B%p>A-1VhewpMTg0)0tY!A(kwDD0{AWnh}MA}Hybayy+3$}k!3A*`S?l# znuTWH4c{NQJT4$t!LM6Cqg3{tD2oHj(?e|bRCj)@+-P;+DoTKM?()n$ytIbr-alVQ@?~f zLXdj3^>eGZ7h=nVSj_XzBk$c;rvtEG&dxW-R2wMV){$7ydS?QLOQvDLr^=fbT-EO2 zbqM?05UgLE{}S`pX4Dw0wNlHV@9$>-J>*?hG>^TQju#N2+eA%$r<>D$7~1|wSr@52 zg)C&iV`6U2QsalKlehSJ4Ax*bgVNY4b&eS|yc}Nfe9z;2ZC8`|7+jCtb>G^7Z+yOl zH}CFhN!!@mx%y$h+Hx9Jud&HxE8BP^i3o6`7I}XM-M2c7h1;T*KIqfJ* zFeK0Nx{jeH==8ldFZ zAD}Zmt_4YdM#fzM`4uzYj{XL_wPVFW%`}|3TMPv{cu&zo9s;_OC@FW>sysGajABwa z8{CsvrunEGNMq60egEIs53&%@z1Fwa;+}nd*1Z%V_zvW@Cp=^GPo)KuEnNZ8XIbds zHiyl-uDL$5)Sy{>fU%J`%^ZAljY};U@fvrU(-gqiflJsy3_|;}o3I={3_gllhc9ea z=EK)lPqW7jWK3$itvr}{pJ4wt$3hv*`w?w;Lu#t^`cQ6{8DyC+svXr}ikJL-M>4I@ zWrL>qP$)y+h=!1SU=+*+@+KFhEnWqE#J*91G6lPKxbcBwO{+;7njiEwXN}|<@_uF`O_V^Gz^54@I;P?T$mwbhJ{C%j1p!F`qCugpEA&{(c;rt4p}2fp z)FSJw&+c<0pjydet#CfQ&s_$fJBLcAV;lc|a{Ob{Z{6BglQxv8Dtved{ImEt(=~dUXJ?rwNu}{Q@ z)|1p(LOG_@p1w|LT+vr8BW!tYxu%Jp-jW}&KnefT`U(w5&dbzQ_h@9o*}xY!O%4Gk%~#5oGs0Bow)V**7;@q*1+|)gnjGThVwTm;E?!4Wtf||@5J>5P z`AZXm^O*xh^X<0Gte}0`>a1+m7TVR4Pi%LiT=F&@aYs17{?ru}`{{+cu42YDnyd2@ zYJ_Y2)_jB!awbUa;VPklMGORTrzyl|PDtXq=fCC~s{q6ORL0GFpImR$Z1`ghd7RRW z;?P?eQ5n!1ad!4Fe6)85BVjmBGzuo1D=&Kn6ri$&2)%O6pJ_$-{55rG@8@N5($PS8 zpKwW#qcTzrW%Ey_O2rX%$Q!Whha|ElTNL{Rh}l~fh)GG(_jtRt3`6((`C*B5L*kKt zPAH%MGhC;G!>{FoAgqz`N0UG8q&oHBM{9nMhK3{=92{I9+=aA;hW4@b{nMl55lu!S zo_Vuklk}9&g_Rx;_k87nubuKP+t@)oH?4-X687SZS+yV2?#Bnj!J&j08xt_#;jQKp zQmx6S^_us5icC(APE6GMzyoG~y) zPNH8NnV1t9|0**}Q7=Xlj`Inbad?3C{o%%ii^}MO4vNT+U@Fa+N*BBU8Bxpd2ux?Z zl!GvtgF|OLZ&G|bjBpH0Oc%@u%zk`4u|QJ)O`co`Cj_obmMU7d=j0i%qvh~8Ad^IO zjjWCiAC+Q^CK*S|Pkd_n#h92{(=;;f1vR{Df(35EI2tW2LT*lgN+4(5d5}Do!Ta}5 zxs+RJIQY0q9~4or(TK3W>I7)MLAK=U}I;zwJRNThmtcpxfCUyBbKz#3Fw zpi^LkvqbeZq~w9UWUHDvAKDkmASQkNyfd0+bAk6 ze8DEf$X1#@rf3r@AKECABixrwfO!;6)+JoOH{v%@P|)8uVB=XIl4MZmF(tL0H4e`x z$I{E;m%w6Vc)wv#K<35I%#InTZg{W`THPsKqDAb}I_Ptv)zcZ}!0fZY05`n)zH-l$R5A#P z*?)FFkDB4cm^yb2KX8odw*tV+A#Fb69nvD_kRxYldG`EcBP|5M+)}tlAF+la1GDwi zf@(EX;_(jnRO5ep{-T>k8rw8>`WvRBiPr4}m34kiX{dmKjxMRiJ2M#8V|LPZhhX>F z$OE|L@QEAuQw4A0y0@-=8xBl3GNz%#n?w$D=5&7cFCdZpFTk2o+Rw>r@v^(VeS7-6m9C|hQbgf->x7bM>*t=~Va18z zZ=ZEU$vMB>&z?)|bp3yTDm#hF+w1oe9B-k@xAC@~9xie(!$sWxi;cAZhmEBCcN-Cr zL^X|!c>vxt7NFK-6-a{mk(#zq=2XFSBaS>iRt--z8CXQGDRJ3^p1=|vz2%X2|OH;?!^szIz@wC zMr*M}ix3|$`hb}DJ1y@jVf@Pa2JHzyJ?(=BL=PWsK72@=z(D&3NdRul?!A$RS&umf zRMy++-K3B$Anl}Tw20^5tLC0!^S(*C<0)Pc6q}J5g+4DR2w7B=lnabEZna2IPtl>m zEnfjPW=)QgT3W*W_AvLJH!{Pkr$xt_*4`kFwt%2co88N1ufgNq!=;hpWPEnpWDfM5 z?k#?ypXc8K6AN`zYL(fQtuwX5ez8RvMF~6e2tl~rLK;`z;n!L(iBa+rqOvexjZ2v- zuX=}{#Lt!0_4^B*Pqp{`wU%dP*&+M~ZKJn$LX{Ib`d;F?^>0sJRcCd|Me(158?fL0 zkJD3Q|J)(J7cSF?UreH{-h!;DYVIsMsTR)t0s*5jbP$U?_8X|u7-Hgt*MNx&+)IRO zTt$gwxOtPzu4&pmaHZB0ui&=a?Bitlt5>@QzU%kt)JTjxQ59 z1OYmakPN)B9@BqIuvvXeA) zko4B`k*1FZ>44$!B>bmpd3=`>sd-OJiWXKx9FdZ%R#fYNwq=H;6|7(>_Y^BD1Mk@m zUIXH+whkNg2e1r=?MffvrBA=pH)@F1Tlpo!RPWGfeMk0ql!o5}SaW?;HYHZ^|60fg z?Mzg=8Eg3%b-N_$6KWh(PIgEZDVhpO^um(n+_BHeN-GevV6|X1X=dSZb7*0(0|al+ zo0=f<`&#Nnb0e78Sc4k^rA8^E^J`sk_n3s9x)vo1I3E#xG)%79vRN{O>$RywOGvS! z5S*xu#-!!E~^nVN!=SvXl2TBBQzn?tyU*ow@lyR#%;)9%*w;b!DGV9&C1Qr#cW~h{-1w?752l)$$9%5_Va)IhW!f%E5OFa z!_Cgh!^X+O0kE=ja&WT(k6Hh}ApjRAX9LH_j{!$JJLmtW&;3vT{{N#t*Ukz?uwQV0 z2mwY&|3+vq!hq2|7~O{vK8zl~=pl?q{t!8gp1_C_M)WXZf)NLdxM0KsBYqeO!RRTB z#9;IcMp7`6hmkUj)L^6qBOMs&!pHzdH_v1aBWoDh!N>tdZZPtKkspkLU=#|Y_b~bZ zqbL}GVH5|W1Q;d4C<#WXFiMBfM;LvAQ4WmqU{naBVi=Xes2oNWFsg=8EsPpq)B>Y6 z7Wrmrti-?M}$eKu&q7*4YS}C-k(xN17 z+K?AKmd6laG(O2An>39xgZFj z0@)zQpoW7AtR4|VuW_IPIUy3~)GeR_nIY0a1#&~|qSxK@3gm|XvP0|zbswleZirG) z%R#M}QxAg** z(Ff`iP@jYP5>y~V#1N<>paK~pfb0;H^g0bHkQw4Ls58KPfc-E4nK3Yf$_6U18wSof z71$30kRJoE9|mAI48ouSnK1yFF#wq{0C_P0+hG7QV^9GV$c#Z7)YYKsgK7XOkR8Js zP=Wn00Q+G8vSR?UV*qx<0A$AiWXAwx#{lez!IxhB=oJGhkR3x1s6ciMKz0lyP=Wjy zA|PHFGO9hozZ0Z*-hXfX}vd8gr5)t~_-zFs~Wj)Up zb>+Ogyge_sq7ISEdU9jZty9`}GEbaAnbl9%e`Xe4IrGK1{X~s|aCSzY)Q1>pY_}7W}<;X8GLgX=(W~M7p zmADwXIL`a=KAUxq^J*xatC;Ri9{(`$SV)vos|~H!xV7QjMHc3*O?)ckhXq>w?=CE< zLRokOPq8ugq@q=NUNh_%cs6hwowG~%Rc$o5-NU&b-6YNnCM9G>FDjNT5*;;PUKnVR%9pfEv|S{xcD{r0EJt~_6QN5}iV}f( zrDNH$v4?ggu~cs@e=Bi}C2cQ@>1N8o=0zQHCM-8D4ZUMzY>l>EzwqvKLx#H9o_bc- zOAl3DtH12uUgYz+>Eya=Xw6L4lI*8jl=<1#tYkE}E6$dl)^}Tl^}L71aPV=ZOfJ6T z-BT2Xhesz=*aY_NuX+^B%6NY4&B_AukOQ+;51VFt+-v`^4dHBlHPQu3UT#z5iDKu~ ztzL{?ZG)b~kngPDG;Z#;X#x9zmD_pcJoFd5%<^As@bTdBMM1X~E69Cen+{8V`IKwS zO^mJoj(!R2e8*T8Urb_Hvy1Dw*&sJs@8(vaKK<_T#aGHc2^~v$yY!vaW^-#&$ouy0 z(#4M+e_=UuSLJYQ@zD53n<0~(L&luu$qc&Vl$TA;1y+v^u&Kpu;|Z8A^^@y;`Kj%b z(p=*E8Nw?MYGm@uS`(KbSPNb;1Ql_G^caSId7l7j9Y4NA##1lh(Wc0zK5ap=*W~@|8l2z8CAnBJR3^`gkp#W&Hm;{7wH7ZQFS)F$viuOw zDV=`j6RQ&Pdft54@@~mpeV3q>WrsPFH_Ew{R({md&F$jmRP#CL*R3QcvTw{;a&n+M zXNL#3SKKBwn=-u1O}qXz*B{ye&WtXo)bAdAd)rQ3h6Y)!ys*8D# zAurtz{gBpJ%70^E_!{cc(sdH2Jp>J2eA0I^iEa{!8r!E7zm$@_rn`dGlR!H3*2z(# zu-QF4f9dFgj3cYKbi;&=&)-AGkBnXuIkt3WFHb`oi&4g_^#-E>A&XisvJEX0?AyG% zo9F!a<$a8v+3drO;*2|%X*9iKZ8=t8E;>EhVLO=Q()lTJxs{ZFUna7Vv5P63p>1@; z_mFw`@`M_QPa)#g*{pVgdDn+Ed5uM2OX2KKC! zkdQn*QTEXF>_e2REIH{3Zwo%*3F~q1hBaz8mOsA3&8Te5#V0*I*r1arsS;oFnVjzr z@f>LPbg(RJ4U1AlRmyJH`YZ`g;re0Z@2ukWK8ZKstDfzr2vHJc1F z?%SUX8Lb`K<`pZ*8n)`4bmaPl)76RHz4p`R?=1Hb`gdg6oe}1QqU764o|y!9*_z8faaTEBK;mse5I7YU^p1 z*SOs$ZjT<(>k>-O5?YP;xXf^B?DCDRZMko+TA_sYoOpGt#og^prK*DqmlHQ;am!wz z%iNyXg~@!i4yESCUt|i8yL=iJb~pSKJf!fsGaRGjbN3az&V&8hl@FHYzgy_dEsd_ex^ z7uLOBT;(Vl?95~FE<1p`#O`QQ<0@4|~!q7|H4 z@ozg7Pxl;LQnUu)S6t0ADtb+MptDY^;3aG9nJFH#jyJ9ZOkEzv)lD^|7+KrLomp8xhJpAlS9pcWJ8phqi70-ks#5+~D9_qE0xw~$) znE?}npz7{yR|zTA3ey`YZ21^2^$2gzW0~hk+a)6M^{QG&Hx=`ltqH?xY)NQ;!6H#; z#mT9ckQY~gLFDY*+`Y2pZL&o1*y44k9c72S)uxZ4RM|8(?Ms(5wy*Xhzw)%qi3+d? zo~avPzN#SU?RIpZ;PfKb$}eqQjcpMf`*h)=_jf%^!`_URdfnjL zV<(0luxbxc_^AJ^^k(=bsR;%4;&Adrd|oF@${pvtn9ImPX%YVT7;MVURc!Sof}#;4 zXIo<>rR6j|Onh$IUMy(YeYclcDPH@KlXRj**gk8{U7gSOzt(JMolH^IWt;Dva?+*B zp{A`tgy5Uc9yH%kdHC$fv1aM6s_C{uIVP`rDVfdNk_UV3L`K zK!&)7u-S8%`*(vC0Yqt@HJq^FPR zXBrrvmv!3WJ_3=pTR-Kpyo7TpneKnyC%g4PmO^@ky-#s+lJ^wh*~21!HQ9?wX?mX` ziO#1i)(hIdsNP&w7$E0)VvB<5g_H^f-iN${(XW!!Rix#1>Wi)DersG)a#CoW>`h(a zx2#v?N>A%O<`+FyKZ341b3ZCv?_${(x$@Tjbwp_q$E`Y#_Z^#N&_OOk%H92P*fAQn z&^R!&%tFxRraH=Y<9v5X&-eaK`CHdp#A45G9)4o}DYNXs$tceHUirT5ns+lf+}+H! zNC($s6}?vql~NEu3i92*ZnS|e6>RFy-(!@OtJl3Ib9#w`?-`JI`u0a*j39KnckyN z8f*13TKZcs&rXTloj&2Fr1SFL%;TWUcP1T3DZoPtDOCbzu69_!b(8eD5$sAK(Bzmh5C*cdzozkw(Mn z9jfNrwHsJIU7vBR9KA3k^rU)VGFi`?B6t5lTt zY!W*8?jm=$;3wPpUaqJiz4`ik$@9~t$GRBLDrzMcOr71Sajxzf`-Zz*?HyY_zSml zz2U=*HxE3mi@5iYrM$1LYFg_`lYSuMXL*IyohQ{-J@D@fSU0Y{ygJ_TN)<|QwZnth z6m4}yUqkl!-pi^Tt9|Z$PR6-?F3Z@S^|Bq0Fkka@Bn;j(;0 z=UlA#4&UPv)+gDp^-*RvC-+_#)jf(@+GhC_>KH3EG~;a7j`-5_S@%Td+1|K-8Sa(q zBU4Nr%!~S7R<2saeX@PzIZEZATB)(*zC@+|GrLx8uXwL?F^A<7p12Ole@`fEjfBIh zy(N#|bZ>g)SlFX{@m$x&kplv}tECYNEq2RPk~2<`uinRt+zlL5U!7_>WFbjW4qM#v z$egP--6GC>M$bgE#?Fx2>g=vdCrU1OR68yx;n5r2j$?|HY<8Bck8TluJgnj1c1&Ml z(_l-q&}}znrag5jMfVOeTF&Ud(DpvFj?Aj)#V=^Ly?l4FG?$RUYKy2n^~Z*e-RvEG z{&7pELr*KG;gTZ#r+S6wxSKy6G2QR-WJnyzIYel!bi1FtDW23}|sfBj#=C>Dn2lDc_<|i1hF%Ht< z^Gj7~e|n5pC9FQYOW)cp&N$`dqD!U6)^a|KH|BoN`RK&t^*1Iqx8*9!bIZ9GWVAfv zWO3O)-9RxRjI+JxUd}u0_pv2%Q_s|7@QG%V*GG+^8#9Ll^t0CurkW&##RO4IKGfCj z{aAo0s*DdzJm>aMj8WvBDMOWaw^+=95r+1}M1uSK>Q9ioDaS#p?LmvgdzX8r`=yd{ z?YHZ_m@jeAj4SuV(`0t`{sJ}Q+e7De-r5&cW0pSV_SA9c#HF6_TPjWaO{Z)bkD48O zT(WuZvgh4ygHa~;a*hX0lBCUUcepvK7|V&hUOg_0I7Hmv_%LS;b3-ND*2?QQgPdY_ znFcI8?DcZ{nxr(%M_Za-D;6NkGdJbjs=E+7zGlyJ)~YVMkdGUb`wl6_Zbt0wx^8~T zgW{pFkjpC~@!W|1=g-=)VFnf>0e-bDMfG}uYtCD@D&RU__efZ=Uc9CgFSw1kQX@83 z*K{? ztumIdoW-wd`y{KlNRCv);Kz?=t?!>P{9u!n?Mqoueh7-Ub#8e?&Y?P z3R!?m_wLP9S}>*?>E_$zmn>-KZZ&YTO?NfXtIMiRMp*AvQ?TiwriF1R$z zM8Grp)`AO6b`!-S%f2|~7qFfW=61Av`iZMT(jI&4eJNvTJqaoC6K zNO?SYCdA$r)y2G)-6=>B+viYrm!Ux9sJqcJUB?YMZ$~61QN3#gPF=lFz*kprdfd%2 zziju@)4^BPT3&Emtreg;qC4Y8Vo!En^ghXbZ6c4C&;8O(a-7$*I`(t33BQtkzc&A% z&CJx%UY)i5Z*e7eLdylw?Q6YGiPJna6Cp)u#$b zV)J^t)zZq(j2c7F`UX57F6_)Vl0vOdh*ZuQ5iz=dY3;G6k=VCSKdr8G_3P|dRuUh* zw(M+AwPBCn`ig}KZcSY4vo4F=+bQn5;o?&RBc0Jel;pTZ+*s zW`4?B*G%ybom%N-^-17F&c|zqPdr{Yv%JAxiF0$gm+PY~>YFpQk4RM5ge^(LWb#;L z_#%6UHkI6wPcqtFp7*G4Lt1E$tM8W$CtjN~XpYqIC0de(NsFvq<5Bt$-ctO93F4wy zO(NU+#_o1R!*RzGXL#XQ^nG>Db>?4FsYENLSt!sWBcTZF3^&t9zc*FsrsWP<$2bm+y zTQ;A3T4O!mS={+ zz`~7xSEalN@{hyLtn7A`>=_E%iA!v5|B#Z)z5NP~ZP|_`sN2k4Qc*h}NU)})T`)xA zir zHnXEI`*n3+yl485iyJ1SUd~q3IIrV)qf?kW_BHy1o`2jY8TV69EHA~0UqAlb-oiFO zR>^<2%ua1-zuo)C2qrc45s}?&$~^v^xzZ%mJ_9}u9hu<)-t#x#XG;fcR(_#eRc-a= z=;C+BPc5{uez$8Kp0qLK$?7wCI;^T};t#JlCr{NN@E5N(U$S4SAJR&W9_eJcIuzRM z9;iP2NxN*1WxNsp@S6IA?Y5^%l7nnEzGLYcF$^9Mc^1`QlF!0+A|wcR(WS!JqU=gt zkAZjkpmSW^LXDs%$9qzXLyE4W*}ha;mo@B9`@kIZR$lDv#<2R{>zNnbHRErIr0|r7 zoGddk)mCpB^^dlcl#Ds+v>@mdL3y%VF~=>k?S&gDU3YDmZgYVW!RE0v#eDSqjtU89 z{bjo!+~Q0`6MAF_b=PBhl6zh?1uZTR$+Ks{6I1(5xABE;#qRXSre4GD2`fLjmzWjV zp-{t?!1j6~khl9&>tVUIHlaJ+J<#u=R|lm|F0B2ic9MI__j6cKrDb8eU?g|>q^-=t z&3mO6P7H_TB(SIUg;p5|iP&%1ZGtpLvCM=`?ugp=33=-LC7VZL$*UeroN=`!$tVP9 zyDf;`<(F=x@>#%6{c@EtDd3j4RdmsU6IV}p$nH58sap7wofOr&I5%$Z@(FDG`gUFR;Qsbww7lo%)^n{(JokW@*3(R+&W#mrzRMYs!3s&H;wnh&(=sz4k(;qFzDq}3OPw%kU zYSEK|k%8Bqp}eE56gH3S78~`+d%6BnWn( zI)}5{VS2>4G&P$NK(>D16rEQTeZ9~Rzmqej=tYO)UfTv4t0_yf7}1wvay<8f?=jte zDbt8V$%h8n#TYCdA+&E1t#MlM!4!w{d^lY=7GuBtE%LhGsjPr;w~Do*`tPQ0UY+j- z=9n9<1Is-=S`|%?I2%@BNaKlTndZ9*GiEehqlDA$%?(xwOK;yR1J^DpzK?xzb+sM# zb_PxqpK&1PhSr4`ef>D!yp2lbXK*6NNHWsbafDHcD}r&smmln)c%D|>BwP5QF?(NM z?Qmfn*(%?=ZsOgGx7(!dLEeU6uHzfyx^&D*nR{IG2_=qMMA?PsuP>R1d(l>S+r?Q6=oL?v&3G!6?eEdOx`L(#a()A_y1Yea6ln+D2_G3GauD3P4_38Mc zh6Hrg!mX^a?{xId4|nqK<0)+o&)DcBrFDh!it$rzRu)TJB$HDA0D7b6_?5NqIW9Tb zFzLDYK}}?+3-B_^F8)Pap%&5Q}*XEwoG}6_^BC>!in|n6@B#&`DN1dmnOy} zz7T%wfEoz*8$vyO^JGVM*ef5uBq5zxJkuc!gSa>SN>%#z((WPmB#Dj8JQ>5hQHvA~ z{BZZdcv*UzWm281`#WCuBo)t;BTo`Nu9ascbZ^>h6YhXJG|9!ftDu!U&Ech9k)6zW zs_?$4OFND&ZR4RQT`mp-iJwv=mGUUn=(A;m!Y!^Y-51V6Z{$*Z(vPy6u->#>+Gff+ zk@`g|zWH&=BL}0fO8hg|N*m+jRt>Q$Vq8o%>u*kk(BYe3UO(b6*|TY-a;~@A<_I3g zovqgIBVRuH*cBHkb*X=)a(IIN-27$gjseA9?-AmDD$1GSTvDL0Sxp%rQO)b2>>&^My&oN6*=kFJ( z^Ka$qNfw7lmKHXNQJ& zi@HkDnx6dL>j{R>Um#bkShQnHH@BMLlg8`q#dUFI^?HN2r#?GculR0C^$y(RlRLmW zSXdMjb!B2_P<0u9_=as0QfUG&%{JaTYxC&k&g}x(a;M*(Y`S-N!KSw{=e?Ov2J8~4 z*{E|~6WSnn=;E=p*1;L+^{aNtw+}9G%_y}je1(dN@|jUQ%!S!yd|~7IgFM$U@q

Y7_6Nc{2{z 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 z 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 literal 0 HcmV?d00001 -- 2.39.2