mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-09 02:00:49 +00:00
Compare commits
341
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dda0634cc2 | ||
|
|
ad29a9d3dd | ||
|
|
51ecf50b42 | ||
|
|
3848a27689 | ||
|
|
d4eb802dcb | ||
|
|
9f35aed8f2 | ||
|
|
b8973a09de | ||
|
|
7d1ec21215 | ||
|
|
1ef17aeff3 | ||
|
|
dd3a5b3601 | ||
|
|
4809310fff | ||
|
|
ae187e6156 | ||
|
|
71b6eaf31f | ||
|
|
9ba128e62e | ||
|
|
58067bb307 | ||
|
|
6c9ea8b79e | ||
|
|
fe7f010291 | ||
|
|
19bab9086f | ||
|
|
985defbb69 | ||
|
|
7e8f1c0949 | ||
|
|
b5663db3b0 | ||
|
|
85fff3d38c | ||
|
|
1398c55740 | ||
|
|
2dae72bb3f | ||
|
|
cc3fcdeadd | ||
|
|
e002275c1c | ||
|
|
c6469aba17 | ||
|
|
726b96e393 | ||
|
|
183ee0ac32 | ||
|
|
8ea1dd281d | ||
|
|
ac41083b82 | ||
|
|
337036cebf | ||
|
|
3c63f4f09f | ||
|
|
5686615c47 | ||
|
|
6717af379d | ||
|
|
9b95efa9de | ||
|
|
a2cd7fd198 | ||
|
|
9906416cff | ||
|
|
ad2e304693 | ||
|
|
ac79b2ada4 | ||
|
|
fe06c9dcfd | ||
|
|
c8a15852c1 | ||
|
|
aa648fbb4d | ||
|
|
41a208da03 | ||
|
|
31aef753ba | ||
|
|
27f3e6e91b | ||
|
|
0f21d95e41 | ||
|
|
c5458b6986 | ||
|
|
3df5e260ca | ||
|
|
f1c9fd9134 | ||
|
|
7cef169b29 | ||
|
|
bf4cbc4fb0 | ||
|
|
4c2696b619 | ||
|
|
0d702db813 | ||
|
|
0a6ee73fa1 | ||
|
|
6062c27a2b | ||
|
|
1b26d02ad4 | ||
|
|
04afd0cec5 | ||
|
|
1279030cea | ||
|
|
a616ad19e0 | ||
|
|
62c5ef476d | ||
|
|
7420158d78 | ||
|
|
32aced596a | ||
|
|
ac4886ddff | ||
|
|
83da11921d | ||
|
|
e2aea0d95b | ||
|
|
4f07df5320 | ||
|
|
c9c573bc68 | ||
|
|
c4d255c334 | ||
|
|
9da0abf7f4 | ||
|
|
214949457c | ||
|
|
c3b4f2fd42 | ||
|
|
ca741c453e | ||
|
|
7b1dcaae5b | ||
|
|
5019b5e2e4 | ||
|
|
3f7c8b6a76 | ||
|
|
6d457903a1 | ||
|
|
56f160e2ce | ||
|
|
2e60ddf486 | ||
|
|
c9fd935be7 | ||
|
|
5268954068 | ||
|
|
81728b8999 | ||
|
|
91cba25cd3 | ||
|
|
890a2fc397 | ||
|
|
58feb4426a | ||
|
|
9817dbb9b0 | ||
|
|
b0f9118af0 | ||
|
|
fd9586e6ac | ||
|
|
c4dffe672a | ||
|
|
3e37d97627 | ||
|
|
bebcea5fcd | ||
|
|
6f23ab9f42 | ||
|
|
d8332e2fda | ||
|
|
7e406fd9e3 | ||
|
|
538965c2a8 | ||
|
|
28f45e4133 | ||
|
|
2414baae20 | ||
|
|
674236d9ab | ||
|
|
2e2583102c | ||
|
|
91f79200be | ||
|
|
2e97535993 | ||
|
|
2037993656 | ||
|
|
804360bf74 | ||
|
|
1a3176c4eb | ||
|
|
2daa579c04 | ||
|
|
ed71e6e085 | ||
|
|
469427bc2a | ||
|
|
f7a545b5bf | ||
|
|
b0e2954cf2 | ||
|
|
c89405f0c7 | ||
|
|
51e4e4c3f5 | ||
|
|
acbd45f0f9 | ||
|
|
65da211da3 | ||
|
|
47a0878ab4 | ||
|
|
0536df249b | ||
|
|
646da25288 | ||
|
|
292f0a29bd | ||
|
|
4dcdce3c23 | ||
|
|
32ee7c0288 | ||
|
|
2c6a999132 | ||
|
|
6b270a0bdd | ||
|
|
21bcceda8d | ||
|
|
1b7a2b100e | ||
|
|
f1e6410401 | ||
|
|
af0f90f6c2 | ||
|
|
8274a8d733 | ||
|
|
0182115dd7 | ||
|
|
a29f16dc23 | ||
|
|
3d3a67adeb | ||
|
|
2abccacfa5 | ||
|
|
70f9d2d390 | ||
|
|
4aef02ca6f | ||
|
|
8f4af759af | ||
|
|
bc26544ff3 | ||
|
|
0d4649e39b | ||
|
|
baa0ab00ad | ||
|
|
20777be394 | ||
|
|
6a1956ac37 | ||
|
|
12d6e6c660 | ||
|
|
4a58e4f4b9 | ||
|
|
c0aa935d3d | ||
|
|
4cb75f1b3a | ||
|
|
4605e3a541 | ||
|
|
7902154f46 | ||
|
|
44bf966ae7 | ||
|
|
caf18b2bfa | ||
|
|
a55d32948b | ||
|
|
f5d89321e8 | ||
|
|
201569c7f9 | ||
|
|
7e1fa145ee | ||
|
|
d5a7368d72 | ||
|
|
97073a0517 | ||
|
|
e6dd1bee42 | ||
|
|
2be36d43e8 | ||
|
|
cacba2613e | ||
|
|
b10466c3ee | ||
|
|
313ace007d | ||
|
|
8301424d57 | ||
|
|
7d96c874b9 | ||
|
|
fc4dabbbf6 | ||
|
|
10a123f2f8 | ||
|
|
490617c780 | ||
|
|
97e89bfb82 | ||
|
|
317c7ae225 | ||
|
|
a29aa6577d | ||
|
|
a07fe81c38 | ||
|
|
1b9a2471bd | ||
|
|
fd6a541974 | ||
|
|
a0207767c4 | ||
|
|
ba7a46ba54 | ||
|
|
d233c60165 | ||
|
|
093bc03fd5 | ||
|
|
450348fd7a | ||
|
|
13f4cdcca7 | ||
|
|
f4058a30fa | ||
|
|
d3b74b0ec5 | ||
|
|
ddf0954eec | ||
|
|
544beecc55 | ||
|
|
780b300fcf | ||
|
|
a82e35c290 | ||
|
|
eb43932fb1 | ||
|
|
63626d1c68 | ||
|
|
3dc32f41a9 | ||
|
|
4d83ad6282 | ||
|
|
1a3b493d9a | ||
|
|
858745ddf9 | ||
|
|
a17e5fe163 | ||
|
|
44518f05f8 | ||
|
|
d1602669bc | ||
|
|
76d392d3a9 | ||
|
|
94a2ab1990 | ||
|
|
ada89376b4 | ||
|
|
c479074f98 | ||
|
|
e5788c2eb7 | ||
|
|
4f64bc6cfe | ||
|
|
94801d1206 | ||
|
|
0cf43df604 | ||
|
|
a4ecfdb08c | ||
|
|
1a733ccbdd | ||
|
|
473e88e574 | ||
|
|
5955cb64bb | ||
|
|
0d3b976c03 | ||
|
|
a02c9cf4f1 | ||
|
|
ca66964530 | ||
|
|
b73fec0d9f | ||
|
|
1233878300 | ||
|
|
7cb6bc0d50 | ||
|
|
b57e6a484a | ||
|
|
0943b7909a | ||
|
|
6305213066 | ||
|
|
04d0a78649 | ||
|
|
64ddf44bd5 | ||
|
|
1650db955c | ||
|
|
4e03cdce32 | ||
|
|
8a6bb7e993 | ||
|
|
0031c498a3 | ||
|
|
add1f2f783 | ||
|
|
cd98638298 | ||
|
|
dd5c63bc18 | ||
|
|
50292aaff9 | ||
|
|
456eba04a2 | ||
|
|
379c4af44a | ||
|
|
e5f04e5d2f | ||
|
|
30d0600769 | ||
|
|
f0a7020898 | ||
|
|
bb9223391e | ||
|
|
f4a39b5314 | ||
|
|
75a3ee0284 | ||
|
|
4c5d775dd1 | ||
|
|
804d8f2183 | ||
|
|
e48af012eb | ||
|
|
a570698425 | ||
|
|
4ca2a45a0c | ||
|
|
0d12de2d75 | ||
|
|
180e1501bb | ||
|
|
d6597ad37d | ||
|
|
295719fa32 | ||
|
|
6e516e2214 | ||
|
|
e213ff37c3 | ||
|
|
ae85316906 | ||
|
|
79cbb4b143 | ||
|
|
fcfd9f78ab | ||
|
|
0b7fbabd80 | ||
|
|
49b5d46a76 | ||
|
|
01ee1225dc | ||
|
|
c227ea05c4 | ||
|
|
6b582b2c85 | ||
|
|
91f96ef1d7 | ||
|
|
394662b4a2 | ||
|
|
65af72474e | ||
|
|
0512d70c33 | ||
|
|
2253f7dbf7 | ||
|
|
c006bbb006 | ||
|
|
a4f461f9df | ||
|
|
681c35bc17 | ||
|
|
58ba05c901 | ||
|
|
5b6edac5bc | ||
|
|
49470fdc74 | ||
|
|
3f573827c2 | ||
|
|
2f69536e0e | ||
|
|
fbf441a447 | ||
|
|
58a6e8f921 | ||
|
|
c9a701c4d1 | ||
|
|
e000385d10 | ||
|
|
4be5f46e50 | ||
|
|
218f2b42e0 | ||
|
|
3158315a54 | ||
|
|
cc83a160ee | ||
|
|
ba9ef20412 | ||
|
|
1296a72aff | ||
|
|
3c7723a674 | ||
|
|
e3c797aed4 | ||
|
|
44a7348d22 | ||
|
|
a67ec786cc | ||
|
|
fbd807a7b8 | ||
|
|
95c6aa35c7 | ||
|
|
362db6cec6 | ||
|
|
ba4e292b20 | ||
|
|
7c33078b31 | ||
|
|
5393ff76f4 | ||
|
|
588fc6e846 | ||
|
|
1c32084d9d | ||
|
|
078f3abb05 | ||
|
|
8fe6e70d72 | ||
|
|
6567ab4932 | ||
|
|
a9c0b4eaa6 | ||
|
|
cd387e3f9a | ||
|
|
8fd7c98196 | ||
|
|
52105b88b4 | ||
|
|
0bf8ea8b03 | ||
|
|
35b7a1e3f7 | ||
|
|
89347c7c20 | ||
|
|
bd36484d85 | ||
|
|
73bc800428 | ||
|
|
6b38c14911 | ||
|
|
626d78118d | ||
|
|
a9c24d9728 | ||
|
|
9cfdc3a4da | ||
|
|
080e6fd89f | ||
|
|
7f1754653c | ||
|
|
7f84c5e32b | ||
|
|
7e4495a66f | ||
|
|
2e63e4f923 | ||
|
|
2745fef293 | ||
|
|
febe0e0caf | ||
|
|
c1e9d3433d | ||
|
|
e58545fde9 | ||
|
|
40d6477fe5 | ||
|
|
e681512beb | ||
|
|
b3acf2c5c4 | ||
|
|
2ed05398fc | ||
|
|
a5fa2525c8 | ||
|
|
4ee1f9830d | ||
|
|
3aaec591c2 | ||
|
|
5ccc67cc8a | ||
|
|
2b865616f1 | ||
|
|
03aa84f955 | ||
|
|
83b353de2c | ||
|
|
0a9d87e630 | ||
|
|
4942272466 | ||
|
|
001a39d7fb | ||
|
|
85a028b891 | ||
|
|
9a6cf59744 | ||
|
|
6dce4e78ab | ||
|
|
6f871656df | ||
|
|
a4d454fdcf | ||
|
|
782736f277 | ||
|
|
7350e8b884 | ||
|
|
34486b7aae | ||
|
|
fbdc2a9d10 | ||
|
|
a384315b3a | ||
|
|
68e170bec8 | ||
|
|
34a310de8c | ||
|
|
430b4a6531 | ||
|
|
d7d721c96c | ||
|
|
50a7757f0c | ||
|
|
e528918061 | ||
|
|
40ebf7dbc1 | ||
|
|
70a222560d | ||
|
|
71e6b9e504 | ||
|
|
8b06c5cda1 |
No files matched your search
+1
-1
@@ -71,7 +71,7 @@ clean:
|
||||
|
||||
distclean: clean
|
||||
rm -f config.cache config.log config.status Makefile.objects Makefile.fragments libtool main/php_config.h stamp-h php4.spec sapi/apache/libphp4.module buildmk.stamp
|
||||
egrep define'.*include/php' configure|sed 's/.*>//'|xargs rm -f
|
||||
egrep define'.*include/php' $(top_srcdir)/configure|sed 's/.*>//'|xargs rm -f
|
||||
find . -name Makefile | xargs rm -f
|
||||
|
||||
.PHONY: all clean install distclean test
|
||||
|
||||
@@ -1,5 +1,155 @@
|
||||
PHP 4 NEWS
|
||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
31 Oct 2005, Version 4.4.1
|
||||
|
||||
- Added missing safe_mode checks for image* functions and cURL. (Ilia)
|
||||
- Added missing safe_mode/open_basedir checks for file uploads. (Ilia)
|
||||
- Fixed a memory corruption bug regarding included files. (Derick)
|
||||
- Fixed possible INI setting leak via virtual() in Apache 2 sapi. (Ilia)
|
||||
- Fixed possible crash and/or memory corruption in import_request_variables().
|
||||
(Ilia)
|
||||
- Fixed potential GLOBALS overwrite via import_request_variables(). (Ilia)
|
||||
- Fixed possible GLOBALS variable override when register_globals are ON.
|
||||
(Ilia, Stefan)
|
||||
- Fixed possible register_globals toggle via parse_str(). (Ilia, Stefan)
|
||||
- Added "new_link" parameter to mssql_connect(). Bug #34369. (Frank)
|
||||
- Fixed bug #34850 (--program-suffix and --program-prefix not included in
|
||||
man page names). (Jani)
|
||||
- Fixed bug #34790 (preg_match_all(), named capturing groups, variable
|
||||
assignment/return => crash). (Dmitry)
|
||||
- Fixed bug #34742 (ftp wrapper failures caused from segmented command
|
||||
transfer). (Ilia)
|
||||
- Fixed bug #34704 (Infinite recursion due to corrupt JPEG). (Marcus)
|
||||
- Fixed bug #34645 (ctype corrupts memory when validating large numbers). (Ilia)
|
||||
- Fixed bug #34565 (mb_send_mail does not fetch mail.force_extra_parameters).
|
||||
(Marco, Ilia)
|
||||
- Fixed bug #34557 (php -m exits with "error" 1). (Johannes)
|
||||
- Fixed bug #34456 (Possible crash inside pspell extension). (Ilia)
|
||||
- Fixed bug #34311 (unserialize() crashes with chars above 191 dec). (Nuno)
|
||||
- Fixed bug #34307 (on_modify handler not called to set the default value if
|
||||
setting from php.ini was invalid). (Andrei)
|
||||
- Fixed bug #34302 (date('W') do not return leading zeros for week 1 to 9).
|
||||
(Derick)
|
||||
- Fixed bug #34277 (array_filter() crashes with references and objects).
|
||||
(Dmitry)
|
||||
- Fixed bug #34191 (ob_gzhandler does not enforce trailing \0). (Ilia)
|
||||
- Fixed bug #34156 (memory usage remains elevated after memory limit is
|
||||
reached). (Ilia)
|
||||
- Fixed bug #34148 (+,- and . not supported as parts of scheme). (Ilia)
|
||||
- Fixed bug #34137 (assigning array element by reference causes binary mess).
|
||||
(Dmitry)
|
||||
- Fixed bug #34068 (Numeric string as array key not cast to integer in
|
||||
wddx_deserialize()). (Ilia)
|
||||
- Fixed bug #34064 (arr[] as param to function is allowed only if function
|
||||
receives argument by reference). (Dmitry)
|
||||
- Fixed bug #33989 (extract($GLOBALS,EXTR_REFS) crashes PHP). (Dmitry)
|
||||
- Fixed bug #33987 (php script as ErrorDocument causes crash in Apache 2).
|
||||
(Ilia)
|
||||
- Fixed bug #33940 (array_map() fails to pass by reference when called
|
||||
recursively). (Dmitry)
|
||||
- Fixed bug #33690 (Crash setting some ini directives in httpd.conf). (Rasmus)
|
||||
- Fixed bug #33673 (Added detection for partially uploaded files). (Ilia)
|
||||
- Fixed bug #33648 (Using --with-regex=system causes compile failure). (Andrei)
|
||||
- Fixed bug #33558 (Warning with nested calls to functions returning by
|
||||
reference). (Dmitry, Derick)
|
||||
- Fixed bug #33383 (crash when retrieving empty LOBs). (Tony)
|
||||
- Fixed bug #33156 (cygwin version of setitimer doesn't accept ITIMER_PROF).
|
||||
(Nuno)
|
||||
- Fixed bug #32937 (open_basedir looses trailing / in the limiter). (Adam C.)
|
||||
- Fixed bug #32589 (possible crash inside imap_mail_compose() function). (Ilia)
|
||||
- Fixed bug #32179 (xmlrpc_encode() segfaults with recursive references). (Tony)
|
||||
- Fixed bug #32160 (copying a file into itself leads to data loss). (Ilia)
|
||||
- Fixed bug #31158 (array_splice on $GLOBALS crashes). (Dmitry)
|
||||
- Fixed bug #29983 (PHP does not explicitly set mime type & charset). (Ilia)
|
||||
- Fixed bug #29253 (array_diff with $GLOBALS argument fails). (Dmitry)
|
||||
- Fixed bug #21306 (ext/sesssion: catch bailouts of write handler during
|
||||
RSHUTDOWN). (Jani, Xuefer at 21cn dot com)
|
||||
|
||||
11 Jul 2005, Version 4.4.0
|
||||
- Added man pages for "phpize" and "php-config" scripts. (Jakub Vrana)
|
||||
- Added support for .cc files in extensions. (Brian)
|
||||
- Added the sorting flag SORT_LOCALE_STRING to the sort() functions which makes
|
||||
them sort based on the current locale. (Derick)
|
||||
- Changed sha1_file() and md5_file() functions to use streams instead of
|
||||
low level IO. (Uwe)
|
||||
- Fixed memory corruptions when using references in a wrong way. (Marcus,
|
||||
Dmitry, Derick)
|
||||
- Fixed memory corruption in pg_copy_from() in case the as_null parameter was
|
||||
passed. (Derick)
|
||||
- Fixed memory corruption in stristr(). (Derick)
|
||||
- Fixed bug #32685, #29423 (Segfault when using assignment by reference within
|
||||
function). (Dmitry, Derick)
|
||||
- Fixed bug #33242 (Mangled error message when stream fails). (Derick)
|
||||
- Fixed bug #33222 (segfault when CURL handle is closed in a callback). (Tony)
|
||||
- Fixed bug #33214 (odbc_next_result does not signal SQL errors with
|
||||
2-statement SQL batches). (rich at kastle dot com, Tony)
|
||||
- Fixed bug #33210 (relax jpeg recursive loop protection). (Ilia)
|
||||
- Fixed bug #33200 (preg_replace(): magic_quotes_sybase=On makes 'e' modifier
|
||||
misbehave). (Jani)
|
||||
- Fixed bug #33150 (shtool: insecure temporary file creation). (Jani)
|
||||
- Fixed bug #33072 (Add a safemode/open_basedir check for runtime save_path
|
||||
change) (Rasmus)
|
||||
- Fixed bug #33070 (Improved performance of bzdecompress() by several orders
|
||||
of magnitude). (Ilia)
|
||||
- Fixed bug #33057 (Don't send extraneous entity-headers on a 304 as per
|
||||
RFC 2616 section 10.3.5) (Rasmus, Choitel)
|
||||
- Fixed bug #33019 (socket errors cause memory leaks in php_strerror()).
|
||||
(jwozniak23 at poczta dot onet dot pl, Tony).
|
||||
- Fixed bug #33017 ("make distclean" gives an error with VPATH build). (Jani)
|
||||
- Fixed bug #33013 ("next month" was handled wrong while parsing dates).
|
||||
(Derick)
|
||||
- Fixed bug #32974 (pcntl calls malloc() from a signal handler). (Wez)
|
||||
- Fixed bug #32944 (Disabling session.use_cookies doesn't prevent reading
|
||||
session cookies). (Jani, Tony)
|
||||
- Fixed bug #32936 (http redirects URLs are not checked for control chars). (Ilia)
|
||||
- Fixed bug #32932 (Oracle LDAP: ldap_get_entries invalid pointer). (Jani)
|
||||
- Fixed bug #32904 (pg_get_notify() ignores result_type parameter). (Tony)
|
||||
- Fixed bug #32813 (parse_url() does not handle scheme-only urls properly). (Ilia)
|
||||
- Fixed bug #32810 (temporary files not using plain file wrapper). (Ilia)
|
||||
- Fixed bug #32802 (General cookie overrides more specific cookie). (Ilia)
|
||||
- Fixed bugs #32800, #32830 (ext/odbc: Problems with 64bit systems). (Jani)
|
||||
- Fixed bug #32773 (GMP functions break when second parameter is 0). (Stas)
|
||||
- Fixed bug #32742 (segmentation fault when the stream with a wrapper
|
||||
is not closed). (Tony, Dmitry)
|
||||
- Fixed bug #32730 (ext/crack.c fails to compile with cracklib-2.8.3). (Jani)
|
||||
- Fixed bug #32670 (foreach() does not issue warning on unset array arg). (Ilia)
|
||||
- Fixed bug #32699 (pg_affected_rows() was defined when it was not available).
|
||||
(Derick)
|
||||
- Fixed bug #32682 (ext/mssql: Error on module shutdown when called from
|
||||
activescript). (Frank)
|
||||
- Fixed bug #32647 (Using register_shutdown_function() with invalid callback
|
||||
can crash PHP). (Jani)
|
||||
- Fixed bug #32591 (ext/mysql: Unsatisfied symbol: ntohs with HP-UX). (Jani)
|
||||
- Fixed bug #32589 (Possible crash inside imap_mail_compose, with charsets).
|
||||
(Ilia)
|
||||
- Fixed bug #32587 (Apache2: errors sent to error_log do not include
|
||||
timestamps). (Jani)
|
||||
- Fixed bug #32567 (ext/gmp fails to compile in threadsafe mode). (Tony)
|
||||
- Fixed bug #32538 (ext/swf/swf.c does not compile with gcc-3.4.x or newer).
|
||||
(adam dot greenfield at gmail dot com)
|
||||
- Fixed bug #32530 (chunk_split() does not append endstr if chunklen is
|
||||
longer then the original string). (Ilia)
|
||||
- Fixed bug #32491 (File upload error - unable to create a temporary file).
|
||||
(Uwe Schindler)
|
||||
- Fixed bug #32311 (mb_encode_mimeheader() does not properly escape characters).
|
||||
(Moriyoshi)
|
||||
- Fixed bug #32245 (xml_parser_free() in a function assigned to the xml parser
|
||||
gives a segfault). (Rob)
|
||||
- Fixed bug #32116 (mysql compressed connection doesn't work under windows)
|
||||
(Georg)
|
||||
- Fixed bug #31887 (ISAPI: Custom 5xx error does not return correct HTTP
|
||||
response message). (Jani)
|
||||
- Fixed bug #31583 (php_std_date() uses short day names in non-y2k_compliance mode).
|
||||
(mike at php dot net)
|
||||
- Fixed bug #31213 (Sideeffects caused by fix of bug #29493). (Dmitry)
|
||||
- Fixed bug #30052 (Crash on shutdown after odbc_pconnect()). (Edin)
|
||||
- Fixed bug #29975 (memory leaks when set_error_handler() is used inside error
|
||||
handler). (Tony)
|
||||
- Fixed bug #29944 (Function defined in switch, crashes). (Dmitry)
|
||||
- Fixed bug #29338 (unencoded spaces get ignored after certain tags). (Ilia)
|
||||
- Fixed bug #28605 (Need to use -[m]ieee option for Alpha CPUs). (Jani)
|
||||
- Fixed bug #28377 (debug_backtrace is intermittently passing args). (Dmitry)
|
||||
|
||||
31 Mar 2005, Version 4.3.11
|
||||
- Added Oracle Instant Client support. (cjbj at hotmail dot com, Tony)
|
||||
- Added checks for negative values to gmp_sqrt(), gmp_powm(), gmp_sqrtrem()
|
||||
|
||||
-16
@@ -428,8 +428,6 @@ TSRM_API THREAD_T tsrm_thread_id(void)
|
||||
{
|
||||
#ifdef TSRM_WIN32
|
||||
return GetCurrentThreadId();
|
||||
#elif defined(NETWARE)
|
||||
return NXThreadGetId();
|
||||
#elif defined(GNUPTH)
|
||||
return pth_self();
|
||||
#elif defined(PTHREADS)
|
||||
@@ -450,17 +448,9 @@ TSRM_API THREAD_T tsrm_thread_id(void)
|
||||
TSRM_API MUTEX_T tsrm_mutex_alloc(void)
|
||||
{
|
||||
MUTEX_T mutexp;
|
||||
#ifdef NETWARE
|
||||
long flags = 0; /* Don't require NX_MUTEX_RECURSIVE, I guess */
|
||||
NXHierarchy_t order = 0;
|
||||
NX_LOCK_INFO_ALLOC (lockInfo, "PHP-TSRM", 0);
|
||||
#endif
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
mutexp = malloc(sizeof(CRITICAL_SECTION));
|
||||
InitializeCriticalSection(mutexp);
|
||||
#elif defined(NETWARE)
|
||||
mutexp = NXMutexAlloc(flags, order, &lockInfo); /* return value ignored for now */
|
||||
#elif defined(GNUPTH)
|
||||
mutexp = (MUTEX_T) malloc(sizeof(*mutexp));
|
||||
pth_mutex_init(mutexp);
|
||||
@@ -492,8 +482,6 @@ TSRM_API void tsrm_mutex_free(MUTEX_T mutexp)
|
||||
#ifdef TSRM_WIN32
|
||||
DeleteCriticalSection(mutexp);
|
||||
free(mutexp);
|
||||
#elif defined(NETWARE)
|
||||
NXMutexFree(mutexp);
|
||||
#elif defined(GNUPTH)
|
||||
free(mutexp);
|
||||
#elif defined(PTHREADS)
|
||||
@@ -523,8 +511,6 @@ TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp)
|
||||
#ifdef TSRM_WIN32
|
||||
EnterCriticalSection(mutexp);
|
||||
return 1;
|
||||
#elif defined(NETWARE)
|
||||
return NXLock(mutexp);
|
||||
#elif defined(GNUPTH)
|
||||
return pth_mutex_acquire(mutexp, 0, NULL);
|
||||
#elif defined(PTHREADS)
|
||||
@@ -550,8 +536,6 @@ TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp)
|
||||
#ifdef TSRM_WIN32
|
||||
LeaveCriticalSection(mutexp);
|
||||
return 1;
|
||||
#elif defined(NETWARE)
|
||||
return NXUnlock(mutexp);
|
||||
#elif defined(GNUPTH)
|
||||
return pth_mutex_release(mutexp);
|
||||
#elif defined(PTHREADS)
|
||||
|
||||
+1
-7
@@ -14,7 +14,7 @@
|
||||
#define TSRM_H
|
||||
|
||||
/* #ifndef WIN32 */
|
||||
#if !defined(WIN32) && !defined(NETWARE)
|
||||
#if !defined(WIN32)
|
||||
# include <tsrm_config.h>
|
||||
#endif
|
||||
|
||||
@@ -38,9 +38,6 @@
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
# include <windows.h>
|
||||
#elif defined(NETWARE)
|
||||
# include <nks/thread.h>
|
||||
# include <nks/synch.h>
|
||||
#elif defined(GNUPTH)
|
||||
# include <pth.h>
|
||||
#elif defined(PTHREADS)
|
||||
@@ -58,9 +55,6 @@ typedef int ts_rsrc_id;
|
||||
#ifdef TSRM_WIN32
|
||||
# define THREAD_T DWORD
|
||||
# define MUTEX_T CRITICAL_SECTION *
|
||||
#elif defined(NETWARE)
|
||||
# define THREAD_T NXThreadId_t
|
||||
# define MUTEX_T NXMutex_t *
|
||||
#elif defined(GNUPTH)
|
||||
# define THREAD_T pth_t
|
||||
# define MUTEX_T pth_mutex_t *
|
||||
|
||||
+9
-1
@@ -84,7 +84,15 @@ int main() {
|
||||
pthreads_working=yes
|
||||
], [
|
||||
pthreads_working=no
|
||||
], pthreads_working=no ) ] )dnl
|
||||
], [
|
||||
dnl For cross compiling running this test is of no use. NetWare supports pthreads
|
||||
pthreads_working=no
|
||||
case $host_alias in
|
||||
*netware*)
|
||||
pthreads_working=yes
|
||||
esac
|
||||
]
|
||||
) ] )dnl
|
||||
dnl
|
||||
dnl PTHREADS_CHECK()
|
||||
dnl
|
||||
|
||||
+32
-37
@@ -37,8 +37,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef NETWARE
|
||||
/*#include "pipe.h"*/
|
||||
#include "tsrm_nw.h"
|
||||
#include <fsio.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_REALPATH
|
||||
@@ -137,15 +136,9 @@ static int php_check_dots(const char *element, int n)
|
||||
|
||||
static int php_is_dir_ok(const cwd_state *state)
|
||||
{
|
||||
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
|
||||
struct stat buf;
|
||||
|
||||
if (stat(state->cwd, &buf) == 0 && S_ISDIR(buf.st_mode))
|
||||
#else
|
||||
struct stat_libc buf;
|
||||
|
||||
if (stat(state->cwd, (struct stat*)(&buf)) == 0 && S_ISDIR(buf.st_mode))
|
||||
#endif
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
@@ -153,15 +146,9 @@ static int php_is_dir_ok(const cwd_state *state)
|
||||
|
||||
static int php_is_file_ok(const cwd_state *state)
|
||||
{
|
||||
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
|
||||
struct stat buf;
|
||||
|
||||
if (stat(state->cwd, &buf) == 0 && S_ISREG(buf.st_mode))
|
||||
#else
|
||||
struct stat_libc buf;
|
||||
|
||||
if (stat(state->cwd, (struct stat*)(&buf)) == 0 && S_ISREG(buf.st_mode))
|
||||
#endif
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
@@ -196,8 +183,20 @@ CWD_API void virtual_cwd_startup(void)
|
||||
{
|
||||
char cwd[MAXPATHLEN];
|
||||
char *result;
|
||||
|
||||
result = getcwd(cwd, sizeof(cwd));
|
||||
#ifdef NETWARE
|
||||
result = getcwdpath(cwd, NULL, 1);
|
||||
if(result)
|
||||
{
|
||||
char *c=cwd;
|
||||
while(c = strchr(c, '\\'))
|
||||
{
|
||||
*c='/';
|
||||
++c;
|
||||
}
|
||||
}
|
||||
#else
|
||||
result = getcwd(cwd, sizeof(cwd));
|
||||
#endif
|
||||
if (!result) {
|
||||
cwd[0] = '\0';
|
||||
}
|
||||
@@ -210,7 +209,7 @@ CWD_API void virtual_cwd_startup(void)
|
||||
cwd_globals_ctor(&cwd_globals TSRMLS_CC);
|
||||
#endif
|
||||
|
||||
#if defined(TSRM_WIN32) && defined(ZTS)
|
||||
#if (defined(TSRM_WIN32) || defined(NETWARE)) && defined(ZTS)
|
||||
cwd_mutex = tsrm_mutex_alloc();
|
||||
#endif
|
||||
}
|
||||
@@ -220,7 +219,7 @@ CWD_API void virtual_cwd_shutdown(void)
|
||||
#ifndef ZTS
|
||||
cwd_globals_dtor(&cwd_globals TSRMLS_CC);
|
||||
#endif
|
||||
#if defined(TSRM_WIN32) && defined(ZTS)
|
||||
#if (defined(TSRM_WIN32) || defined(NETWARE)) && defined(ZTS)
|
||||
tsrm_mutex_free(cwd_mutex);
|
||||
#endif
|
||||
|
||||
@@ -418,8 +417,20 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
|
||||
state->cwd[state->cwd_length++] = DEFAULT_SLASH;
|
||||
}
|
||||
#elif defined(NETWARE)
|
||||
/* If the token is a volume name, it will have colon at the end -- so, no slash before it */
|
||||
if (ptr[ptr_length-1] != ':') {
|
||||
/*
|
||||
Below code keeps appending to state->cwd a File system seperator
|
||||
cases where this appending should not happen is given below,
|
||||
a) sys: should just be left as it is
|
||||
b) sys:system should just be left as it is,
|
||||
Colon is allowed only in the first token as volume names alone can have the : in their names.
|
||||
Files and Directories cannot have : in their names
|
||||
So the check goes like this,
|
||||
For second token and above simply append the DEFAULT_SLASH to the state->cwd.
|
||||
For first token check for the existence of :
|
||||
if it exists don't append the DEFAULT_SLASH to the state->cwd.
|
||||
*/
|
||||
if(((state->cwd_length == 0) && (strchr(ptr, ':') == NULL)) || (state->cwd_length > 0))
|
||||
{
|
||||
state->cwd[state->cwd_length++] = DEFAULT_SLASH;
|
||||
}
|
||||
#else
|
||||
@@ -683,7 +694,6 @@ CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC)
|
||||
return retval;
|
||||
}
|
||||
|
||||
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
|
||||
CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC)
|
||||
{
|
||||
cwd_state new_state;
|
||||
@@ -697,23 +707,8 @@ CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC)
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return retval;
|
||||
}
|
||||
#else
|
||||
CWD_API int virtual_stat(const char *path, struct stat_libc *buf TSRMLS_DC)
|
||||
{
|
||||
cwd_state new_state;
|
||||
int retval;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
virtual_file_ex(&new_state, path, NULL, 1);
|
||||
|
||||
retval = stat(new_state.cwd, (struct stat*)buf);
|
||||
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(TSRM_WIN32) && !defined(NETWARE)
|
||||
#ifndef TSRM_WIN32
|
||||
CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC)
|
||||
{
|
||||
cwd_state new_state;
|
||||
|
||||
@@ -74,10 +74,10 @@ typedef unsigned short mode_t;
|
||||
#define DEFAULT_SLASH '/'
|
||||
#define DEFAULT_DIR_SEPARATOR ';'
|
||||
#define IS_SLASH(c) ((c) == '/' || (c) == '\\')
|
||||
#define COPY_WHEN_ABSOLUTE(path) \
|
||||
(strchr(path, ':') - path + 1) /* Take the volume name which ends with a colon */
|
||||
#define IS_SLASH_P(c) IS_SLASH(*(c))
|
||||
/* Colon indicates volume name, either first character should be forward slash or backward slash */
|
||||
#define IS_ABSOLUTE_PATH(path, len) \
|
||||
(strchr(path, ':') != NULL) /* Colon indicates volume name */
|
||||
((strchr(path, ':') != NULL) || ((len >= 1) && ((path[0] == '/') || (path[0] == '\\'))))
|
||||
|
||||
#else
|
||||
#ifdef HAVE_DIRENT_H
|
||||
@@ -141,11 +141,7 @@ CWD_API FILE *virtual_fopen(const char *path, const char *mode TSRMLS_DC);
|
||||
CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...);
|
||||
CWD_API int virtual_creat(const char *path, mode_t mode TSRMLS_DC);
|
||||
CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC);
|
||||
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
|
||||
CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC);
|
||||
#else
|
||||
CWD_API int virtual_stat(const char *path, struct stat_libc *buf TSRMLS_DC);
|
||||
#endif
|
||||
#if !defined(TSRM_WIN32) && !defined(NETWARE)
|
||||
CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC);
|
||||
#endif
|
||||
@@ -217,7 +213,7 @@ typedef struct _virtual_cwd_globals {
|
||||
#define VCWD_REALPATH(path, real_path) virtual_realpath(path, real_path TSRMLS_CC)
|
||||
#define VCWD_RENAME(oldname, newname) virtual_rename(oldname, newname TSRMLS_CC)
|
||||
#define VCWD_STAT(path, buff) virtual_stat(path, buff TSRMLS_CC)
|
||||
#if !defined(TSRM_WIN32) && !defined(NETWARE)
|
||||
#ifndef TSRM_WIN32
|
||||
#define VCWD_LSTAT(path, buff) virtual_lstat(path, buff TSRMLS_CC)
|
||||
#endif
|
||||
#define VCWD_UNLINK(path) virtual_unlink(path TSRMLS_CC)
|
||||
|
||||
+37
-13
@@ -143,7 +143,7 @@ dnl append to the array which has been dynamically chosen at m4 time
|
||||
dnl choose the right compiler/flags/etc. for the source-file
|
||||
case $ac_src in
|
||||
*.c[)] ac_comp="$b_c_pre $3 $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $6$b_c_post" ;;
|
||||
*.cpp[)] ac_comp="$b_cxx_pre $3 $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $6$b_cxx_post" ;;
|
||||
*.cpp|*.cc[)] ac_comp="$b_cxx_pre $3 $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $6$b_cxx_post" ;;
|
||||
esac
|
||||
|
||||
dnl create a rule for the object/source combo
|
||||
@@ -1090,18 +1090,27 @@ AC_DEFUN([PHP_CHECK_CC_OPTION],[
|
||||
rm -rf conftest*
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN([PHP_REGEX],[
|
||||
|
||||
if test "$REGEX_TYPE" = "php"; then
|
||||
AC_DEFINE(HSREGEX,1,[ ])
|
||||
AC_DEFINE(REGEX,1,[ ])
|
||||
PHP_ADD_SOURCES(regex, regcomp.c regexec.c regerror.c regfree.c)
|
||||
elif test "$REGEX_TYPE" = "system"; then
|
||||
AC_DEFINE(REGEX,0,[ ])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([which regex library to use])
|
||||
AC_MSG_RESULT([$REGEX_TYPE])
|
||||
if test "$REGEX_TYPE" = "php"; then
|
||||
AC_DEFINE(HAVE_REGEX_T_RE_MAGIC, 1, [ ])
|
||||
AC_DEFINE(HSREGEX,1,[ ])
|
||||
AC_DEFINE(REGEX,1,[ ])
|
||||
PHP_ADD_SOURCES(regex, regcomp.c regexec.c regerror.c regfree.c)
|
||||
elif test "$REGEX_TYPE" = "system"; then
|
||||
AC_DEFINE(REGEX,0,[ ])
|
||||
dnl Check if field re_magic exists in struct regex_t
|
||||
AC_CACHE_CHECK([whether field re_magic exists in struct regex_t], ac_cv_regex_t_re_magic, [
|
||||
AC_TRY_COMPILE([#include <sys/types.h>
|
||||
#include <regex.h>], [regex_t rt; rt.re_magic;],
|
||||
[ac_cv_regex_t_re_magic=yes], [ac_cv_regex_t_re_magic=no])
|
||||
])
|
||||
if test "$ac_cv_regex_t_re_magic" = "yes"; then
|
||||
AC_DEFINE([HAVE_REGEX_T_RE_MAGIC], [ ], 1)
|
||||
fi
|
||||
fi
|
||||
AC_MSG_CHECKING([which regex library to use])
|
||||
AC_MSG_RESULT([$REGEX_TYPE])
|
||||
])
|
||||
|
||||
dnl
|
||||
@@ -1186,6 +1195,10 @@ AC_DEFUN([PHP_SHARED_MODULE],[
|
||||
suffix=so
|
||||
link_cmd='ifelse($4,,[$(CC)],[$(CXX)]) -dynamic -flat_namespace -bundle -undefined suppress $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(LDFLAGS) -o [$]@ $(EXTRA_LDFLAGS) $($2) $(translit($1,a-z_-,A-Z__)_SHARED_LIBADD)'
|
||||
;;
|
||||
*netware*[)]
|
||||
suffix=nlm
|
||||
link_cmd='$(LIBTOOL) --mode=link ifelse($4,,[$(CC)],[$(CXX)]) $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(LDFLAGS) -o [$]@ -shared -export-dynamic -avoid-version -prefer-pic -module -rpath $(phplibdir) $(EXTRA_LDFLAGS) $($2) ifelse($1, php4lib, , -L$(top_builddir)/netware -lphp4lib) $(translit(ifelse($1, php4lib, $1, m4_substr($1, 3)),a-z_-,A-Z__)_SHARED_LIBADD)'
|
||||
;;
|
||||
*[)]
|
||||
suffix=la
|
||||
link_cmd='$(LIBTOOL) --mode=link ifelse($4,,[$(CC)],[$(CXX)]) $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(LDFLAGS) -o [$]@ -export-dynamic -avoid-version -prefer-pic -module -rpath $(phplibdir) $(EXTRA_LDFLAGS) $($2) $(translit($1,a-z_-,A-Z__)_SHARED_LIBADD)'
|
||||
@@ -1274,7 +1287,14 @@ dnl ---------------------------------------------- Static module
|
||||
if test "$3" = "shared" || test "$3" = "yes"; then
|
||||
dnl ---------------------------------------------- Shared module
|
||||
PHP_ADD_SOURCES_X(PHP_EXT_DIR($1),$2,$ac_extra,shared_objects_$1,yes)
|
||||
PHP_SHARED_MODULE($1,shared_objects_$1, $ext_builddir, $6)
|
||||
case $host_alias in
|
||||
*netware*)
|
||||
PHP_SHARED_MODULE(php$1,shared_objects_$1, $ext_builddir, $6)
|
||||
;;
|
||||
*)
|
||||
PHP_SHARED_MODULE($1,shared_objects_$1, $ext_builddir, $6)
|
||||
;;
|
||||
esac
|
||||
AC_DEFINE_UNQUOTED([COMPILE_DL_]translit($1,a-z_-,A-Z__), 1, Whether to build $1 as dynamic module)
|
||||
fi
|
||||
fi
|
||||
@@ -1684,6 +1704,10 @@ AC_DEFUN([PHP_SETUP_OPENSSL],[
|
||||
unset OPENSSL_INCDIR
|
||||
unset OPENSSL_LIBDIR
|
||||
|
||||
dnl Empty variable means 'no'
|
||||
test -z "$PHP_OPENSSL" && PHP_OPENSSL=no
|
||||
test -z "$PHP_IMAP_SSL" && PHP_IMAP_SSL=no
|
||||
|
||||
dnl Fallbacks for different configure options
|
||||
if test "$PHP_OPENSSL" != "no"; then
|
||||
PHP_OPENSSL_DIR=$PHP_OPENSSL
|
||||
|
||||
+6
-3
@@ -14,7 +14,7 @@
|
||||
# | Author: Sascha Schumann <sascha@schumann.cx> |
|
||||
# +----------------------------------------------------------------------+
|
||||
#
|
||||
# $Id$
|
||||
# $Id$
|
||||
#
|
||||
|
||||
include generated_lists
|
||||
@@ -32,6 +32,9 @@ acconfig_h_SOURCES = acconfig.h.in $(config_h_files)
|
||||
|
||||
targets = $(TOUCH_FILES) configure $(config_h_in)
|
||||
|
||||
PHP_AUTOCONF ?= 'autoconf'
|
||||
PHP_AUTOHEADER ?= 'autoheader'
|
||||
|
||||
SUPPRESS_WARNINGS ?= 2>&1 | (egrep -v '(AC_TRY_RUN called without default to allow cross compiling|AC_PROG_CXXCPP was called before AC_PROG_CXX|defined in acinclude.m4 but never used|AC_PROG_LEX invoked multiple times|AC_DECL_YYTEXT is expanded from...|the top level)'||true)
|
||||
|
||||
all: $(targets)
|
||||
@@ -45,7 +48,7 @@ $(config_h_in): configure acconfig.h
|
||||
# correctly otherwise (timestamps are not updated)
|
||||
@echo rebuilding $@
|
||||
@rm -f $@
|
||||
autoheader $(SUPPRESS_WARNINGS)
|
||||
$(PHP_AUTOHEADER) $(SUPPRESS_WARNINGS)
|
||||
|
||||
$(TOUCH_FILES):
|
||||
touch $(TOUCH_FILES)
|
||||
@@ -56,5 +59,5 @@ aclocal.m4: configure.in acinclude.m4
|
||||
|
||||
configure: aclocal.m4 configure.in $(config_m4_files)
|
||||
@echo rebuilding $@
|
||||
autoconf $(SUPPRESS_WARNINGS)
|
||||
$(PHP_AUTOCONF) $(SUPPRESS_WARNINGS)
|
||||
|
||||
+10
-3
@@ -16,15 +16,20 @@
|
||||
# | Sascha Schumann <sascha@schumann.cx> |
|
||||
# +----------------------------------------------------------------------+
|
||||
#
|
||||
# $Id: buildcheck.sh,v 1.21.2.11 2005-01-20 01:43:18 sniper Exp $
|
||||
# $Id: buildcheck.sh,v 1.21.2.13 2005-04-07 23:33:50 jon Exp $
|
||||
#
|
||||
|
||||
echo "buildconf: checking installation..."
|
||||
|
||||
stamp=$1
|
||||
|
||||
# Allow the autoconf executable to be overridden by $PHP_AUTOCONF.
|
||||
if test -z "$PHP_AUTOCONF"; then
|
||||
PHP_AUTOCONF='autoconf'
|
||||
fi
|
||||
|
||||
# autoconf 2.13 or newer
|
||||
ac_version=`autoconf --version 2>/dev/null|head -n 1|sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
|
||||
ac_version=`$PHP_AUTOCONF --version 2>/dev/null|head -n 1|sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
|
||||
if test -z "$ac_version"; then
|
||||
echo "buildconf: autoconf not found."
|
||||
echo " You need autoconf version 2.13 or newer installed"
|
||||
@@ -42,7 +47,9 @@ echo "buildconf: autoconf version $ac_version (ok)"
|
||||
fi
|
||||
|
||||
if test "$1" = "2" && test "$2" -ge "50"; then
|
||||
echo "buildconf: running cvsclean."
|
||||
echo "buildconf: Your version of autoconf likely contains buggy cache code."
|
||||
echo " Running cvsclean for you."
|
||||
echo " To avoid this, install autoconf-2.13 and automake-1.5."
|
||||
./cvsclean
|
||||
stamp=
|
||||
fi
|
||||
|
||||
+228
-151
@@ -1,12 +1,12 @@
|
||||
#!/bin/sh
|
||||
##
|
||||
## GNU shtool -- The GNU Portable Shell Tool
|
||||
## Copyright (c) 1994-2002 Ralf S. Engelschall <rse@engelschall.com>
|
||||
## Copyright (c) 1994-2005 Ralf S. Engelschall <rse@engelschall.com>
|
||||
##
|
||||
## See http://www.gnu.org/software/shtool/ for more information.
|
||||
## See ftp://ftp.gnu.org/gnu/shtool/ for latest version.
|
||||
##
|
||||
## Version: 1.6.2 (02-Nov-2002)
|
||||
## Version: 2.0.2 (15-Jun-2005)
|
||||
## Contents: 4/19 available modules
|
||||
##
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
## rotate Logfile rotation
|
||||
## tarball Roll distribution tarballs
|
||||
## subst Apply sed(1) substitution operations
|
||||
## guessos Simple operating system guesser
|
||||
## platform Platform Identification Utility
|
||||
## arx Extended archive command
|
||||
## slo Separate linker options by library class
|
||||
## scpp Sharing C Pre-Processor
|
||||
@@ -66,9 +66,9 @@ if [ $# -eq 0 ]; then
|
||||
echo "$0:Hint: run \`$0 -h' for usage" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
if [ ".$1" = ".-h" -o ".$1" = ".--help" ]; then
|
||||
echo "This is GNU shtool, version 1.6.2 (02-Nov-2002)"
|
||||
echo "Copyright (c) 1994-2002 Ralf S. Engelschall <rse@engelschall.com>"
|
||||
if [ ".$1" = ".-h" ] || [ ".$1" = ".--help" ]; then
|
||||
echo "This is GNU shtool, version 2.0.2 (15-Jun-2005)"
|
||||
echo "Copyright (c) 1994-2005 Ralf S. Engelschall <rse@engelschall.com>"
|
||||
echo "Report bugs to <bug-shtool@gnu.org>"
|
||||
echo ''
|
||||
echo "Usage: shtool [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]]"
|
||||
@@ -80,7 +80,7 @@ if [ ".$1" = ".-h" -o ".$1" = ".--help" ]; then
|
||||
echo ' -r, --recreate recreate this shtool script via shtoolize'
|
||||
echo ''
|
||||
echo 'Available <cmd-name> [<cmd-options>] [<cmd-args>]:'
|
||||
echo ' echo [-n|--newline] [-e|--expand] [<str> ...]'
|
||||
echo ' echo [-n|--newline] [-e|--expand] [<string> ...]'
|
||||
echo ' install [-v|--verbose] [-t|--trace] [-d|--mkdir] [-c|--copy]'
|
||||
echo ' [-C|--compare-copy] [-s|--strip] [-m|--mode <mode>]'
|
||||
echo ' [-o|--owner <owner>] [-g|--group <group>] [-e|--exec'
|
||||
@@ -106,17 +106,21 @@ if [ ".$1" = ".-h" -o ".$1" = ".--help" ]; then
|
||||
echo ' rotate [-v|--verbose] [-t|--trace] [-f|--force] [-n|--num-files'
|
||||
echo ' <count>] [-s|--size <size>] [-c|--copy] [-r|--remove]'
|
||||
echo ' [-a|--archive-dir <dir>] [-z|--compress [<tool>:]<level>]'
|
||||
echo ' [-b|--background] [-d|--delay] [-p|--pad <len>] [-o|--owner'
|
||||
echo ' <owner>] [-g|--group <group>] [-m|--mode <mode>] [-M|--migrate'
|
||||
echo ' [-b|--background] [-d|--delay] [-p|--pad <len>] [-m|--mode'
|
||||
echo ' <mode>] [-o|--owner <owner>] [-g|--group <group>] [-M|--migrate'
|
||||
echo ' <cmd>] [-P|--prolog <cmd>] [-E|--epilog <cmd>] <file> [...]'
|
||||
echo ' tarball [-t|--trace] [-v|--verbose] [-o|--output <tarball>]'
|
||||
echo ' [-c|--compress <prog>] [-d|--directory <dir>] [-u|--user'
|
||||
echo ' <user>] [-g|--group <group>] [-e|--exclude <pattern>]'
|
||||
echo ' <path> [<path> ...]'
|
||||
echo ' subst [-v|--verbose] [-t|--trace] [-n|--nop] [-s|--stealth]'
|
||||
echo ' [-i|--interactive] [-b|--backup <ext>] [-e|--exec <cmd>]'
|
||||
echo ' [-f|--file <cmd-file>] [<file>] [...]'
|
||||
echo ' guessos '
|
||||
echo ' subst [-v|--verbose] [-t|--trace] [-n|--nop] [-w|--warning]'
|
||||
echo ' [-q|--quiet] [-s|--stealth] [-i|--interactive] [-b|--backup'
|
||||
echo ' <ext>] [-e|--exec <cmd>] [-f|--file <cmd-file>] [<file>]'
|
||||
echo ' [...]'
|
||||
echo ' platform [-F|--format <format>] [-S|--sep <string>] [-C|--conc'
|
||||
echo ' <string>] [-L|--lower] [-U|--upper] [-v|--verbose]'
|
||||
echo ' [-c|--concise] [-n|--no-newline] [-t|--type <type>]'
|
||||
echo ' [-V|--version] [-h|--help]'
|
||||
echo ' arx [-t|--trace] [-C|--command <cmd>] <op> <archive> [<file>'
|
||||
echo ' ...]'
|
||||
echo ' slo [-p|--prefix <str>] -- -L<dir> -l<lib> [-L<dir> -l<lib>'
|
||||
@@ -131,15 +135,15 @@ if [ ".$1" = ".-h" -o ".$1" = ".--help" ]; then
|
||||
echo ''
|
||||
exit 0
|
||||
fi
|
||||
if [ ".$1" = ".-v" -o ".$1" = ."--version" ]; then
|
||||
echo "GNU shtool 1.6.2 (02-Nov-2002)"
|
||||
if [ ".$1" = ".-v" ] || [ ".$1" = ".--version" ]; then
|
||||
echo "GNU shtool 2.0.2 (15-Jun-2005)"
|
||||
exit 0
|
||||
fi
|
||||
if [ ".$1" = ".-r" -o ".$1" = ."--recreate" ]; then
|
||||
if [ ".$1" = ".-r" ] || [ ".$1" = ".--recreate" ]; then
|
||||
shtoolize -oshtool echo install mkdir path
|
||||
exit 0
|
||||
fi
|
||||
if [ ".$1" = ".-d" -o ".$1" = ."--debug" ]; then
|
||||
if [ ".$1" = ".-d" ] || [ ".$1" = ".--debug" ]; then
|
||||
shift
|
||||
set -x
|
||||
fi
|
||||
@@ -166,7 +170,7 @@ gen_tmpfile=no
|
||||
case $tool in
|
||||
echo )
|
||||
str_tool="echo"
|
||||
str_usage="[-n|--newline] [-e|--expand] [<str> ...]"
|
||||
str_usage="[-n|--newline] [-e|--expand] [<string> ...]"
|
||||
arg_spec="0+"
|
||||
opt_spec="n.e."
|
||||
opt_alias="n:newline,e:expand"
|
||||
@@ -261,7 +265,7 @@ eval `echo h.$opt_spec |\
|
||||
|
||||
# parse option alias string
|
||||
eval `echo h:help,$opt_alias |\
|
||||
tr 'x-' 'x_' | sed -e 's/\([a-zA-Z0-9]\):\([^,]*\),*/opt_ALIAS_\2=\1;/g'`
|
||||
sed -e 's/-/_/g' -e 's/\([a-zA-Z0-9]\):\([^,]*\),*/opt_ALIAS_\2=\1;/g'`
|
||||
|
||||
# interate over argument line
|
||||
opt_PREV=''
|
||||
@@ -286,12 +290,12 @@ while [ $# -gt 0 ]; do
|
||||
--[a-zA-Z0-9]*=*)
|
||||
eval `echo "x$1" |\
|
||||
sed -e 's/^x--\([a-zA-Z0-9-]*\)=\(.*\)$/opt_OPT="\1";opt_ARG="\2"/'`
|
||||
opt_STR=`echo $opt_OPT | tr 'x-' 'x_'`
|
||||
opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
|
||||
eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
|
||||
;;
|
||||
--[a-zA-Z0-9]*)
|
||||
opt_OPT=`echo "x$1" | cut -c4-`
|
||||
opt_STR=`echo $opt_OPT | tr 'x-' 'x_'`
|
||||
opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
|
||||
eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
|
||||
opt_ARG=''
|
||||
;;
|
||||
@@ -315,8 +319,8 @@ while [ $# -gt 0 ]; do
|
||||
|
||||
# determine whether option needs an argument
|
||||
eval "opt_MODE=\$opt_MODE_${opt_OPT}"
|
||||
if [ ".$opt_ARG" = . -a ".$opt_ARG_OK" != .yes ]; then
|
||||
if [ ".$opt_MODE" = ".:" -o ".$opt_MODE" = ".+" ]; then
|
||||
if [ ".$opt_ARG" = . ] && [ ".$opt_ARG_OK" != .yes ]; then
|
||||
if [ ".$opt_MODE" = ".:" ] || [ ".$opt_MODE" = ".+" ]; then
|
||||
opt_PREV="$opt_OPT"
|
||||
continue
|
||||
fi
|
||||
@@ -375,6 +379,7 @@ esac
|
||||
|
||||
# establish a temporary file on request
|
||||
if [ ".$gen_tmpfile" = .yes ]; then
|
||||
# create (explicitly) secure temporary directory
|
||||
if [ ".$TMPDIR" != . ]; then
|
||||
tmpdir="$TMPDIR"
|
||||
elif [ ".$TEMPDIR" != . ]; then
|
||||
@@ -382,12 +387,40 @@ if [ ".$gen_tmpfile" = .yes ]; then
|
||||
else
|
||||
tmpdir="/tmp"
|
||||
fi
|
||||
tmpfile="$tmpdir/.shtool.$$"
|
||||
rm -f $tmpfile >/dev/null 2>&1
|
||||
touch $tmpfile
|
||||
chmod 600 $tmpfile
|
||||
tmpdir="$tmpdir/.shtool.$$"
|
||||
( umask 077
|
||||
rm -rf "$tmpdir" >/dev/null 2>&1 || true
|
||||
mkdir "$tmpdir" >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "$msgprefix:Error: failed to create temporary directory \`$tmpdir'" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
)
|
||||
|
||||
# create (implicitly) secure temporary file
|
||||
tmpfile="$tmpdir/shtool.tmp"
|
||||
touch "$tmpfile"
|
||||
fi
|
||||
|
||||
# utility function: map string to lower case
|
||||
util_lower () {
|
||||
echo "$1" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'
|
||||
}
|
||||
|
||||
# utility function: map string to upper case
|
||||
util_upper () {
|
||||
echo "$1" | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
}
|
||||
|
||||
# cleanup procedure
|
||||
shtool_exit () {
|
||||
rc="$1"
|
||||
if [ ".$gen_tmpfile" = .yes ]; then
|
||||
rm -rf "$tmpdir" >/dev/null 2>&1 || true
|
||||
fi
|
||||
exit $rc
|
||||
}
|
||||
|
||||
##
|
||||
## DISPATCH INTO SCRIPT BODY
|
||||
##
|
||||
@@ -397,12 +430,11 @@ case $tool in
|
||||
echo )
|
||||
##
|
||||
## echo -- Print string with optional construct expansion
|
||||
## Copyright (c) 1998-2002 Ralf S. Engelschall <rse@engelschall.com>
|
||||
## Originally written for WML as buildinfo
|
||||
## Copyright (c) 1998-2005 Ralf S. Engelschall <rse@engelschall.com>
|
||||
##
|
||||
|
||||
|
||||
text="$*"
|
||||
|
||||
|
||||
# check for broken escape sequence expansion
|
||||
seo=''
|
||||
bytes=`echo '\1' | wc -c | awk '{ printf("%s", $1); }'`
|
||||
@@ -412,18 +444,18 @@ echo )
|
||||
seo='-E'
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# check for existing -n option (to suppress newline)
|
||||
minusn=''
|
||||
bytes=`echo -n 123 2>/dev/null | wc -c | awk '{ printf("%s", $1); }'`
|
||||
if [ ".$bytes" = .3 ]; then
|
||||
minusn='-n'
|
||||
fi
|
||||
|
||||
|
||||
# determine terminal bold sequence
|
||||
term_bold=''
|
||||
term_norm=''
|
||||
if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[Bb]'`" != . ]; then
|
||||
if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[Bb]'`" != . ]; then
|
||||
case $TERM in
|
||||
# for the most important terminal types we directly know the sequences
|
||||
xterm|xterm*|vt220|vt220*)
|
||||
@@ -459,96 +491,139 @@ echo )
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ ".$term_bold" != . -a ".$term_norm" != . ]; then
|
||||
if [ ".$term_bold" != . ] && [ ".$term_norm" != . ]; then
|
||||
break;
|
||||
fi
|
||||
done
|
||||
;;
|
||||
esac
|
||||
if [ ".$term_bold" = . -o ".$term_norm" = . ]; then
|
||||
if [ ".$term_bold" = . ] || [ ".$term_norm" = . ]; then
|
||||
echo "$msgprefix:Warning: unable to determine terminal sequence for bold mode" 1>&2
|
||||
term_bold=''
|
||||
term_norm=''
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# determine user name
|
||||
username=''
|
||||
if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[uUgG]'`" != . ]; then
|
||||
username="$LOGNAME"
|
||||
if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[uUgG]'`" != . ]; then
|
||||
username="`(id -un) 2>/dev/null`"
|
||||
if [ ".$username" = . ]; then
|
||||
username="$USER"
|
||||
if [ ".$username" = . ]; then
|
||||
username="`(whoami) 2>/dev/null |\
|
||||
awk '{ printf("%s", $1); }'`"
|
||||
if [ ".$username" = . ]; then
|
||||
username="`(who am i) 2>/dev/null |\
|
||||
awk '{ printf("%s", $1); }'`"
|
||||
if [ ".$username" = . ]; then
|
||||
username='unknown'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# determine user id
|
||||
userid=''
|
||||
if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%U'`" != . ]; then
|
||||
userid="`(id -u) 2>/dev/null`"
|
||||
if [ ".$userid" = . ]; then
|
||||
str="`(id) 2>/dev/null`"
|
||||
if [ ".`echo $str | grep '^uid[ ]*=[ ]*[0-9]*('`" != . ]; then
|
||||
userid=`echo $str | sed -e 's/^uid[ ]*=[ ]*//' -e 's/(.*//'`
|
||||
username=`echo $str | sed -e 's/^uid[ ]*=[ ]*[0-9]*(//' -e 's/).*$//'`
|
||||
fi
|
||||
if [ ".$userid" = . ]; then
|
||||
userid=`egrep "^${username}:" /etc/passwd 2>/dev/null | \
|
||||
sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
|
||||
if [ ".$userid" = . ]; then
|
||||
userid=`(ypcat passwd) 2>/dev/null |
|
||||
egrep "^${username}:" | \
|
||||
sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
|
||||
if [ ".$userid" = . ]; then
|
||||
userid='?'
|
||||
if [ ".$username" = . ]; then
|
||||
username="$LOGNAME"
|
||||
if [ ".$username" = . ]; then
|
||||
username="$USER"
|
||||
if [ ".$username" = . ]; then
|
||||
username="`(whoami) 2>/dev/null |\
|
||||
awk '{ printf("%s", $1); }'`"
|
||||
if [ ".$username" = . ]; then
|
||||
username="`(who am i) 2>/dev/null |\
|
||||
awk '{ printf("%s", $1); }'`"
|
||||
if [ ".$username" = . ]; then
|
||||
username='unknown'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# determine user id
|
||||
userid=''
|
||||
if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%U'`" != . ]; then
|
||||
userid="`(id -u) 2>/dev/null`"
|
||||
if [ ".$userid" = . ]; then
|
||||
userid="`(id -u ${username}) 2>/dev/null`"
|
||||
if [ ".$userid" = . ]; then
|
||||
str="`(id) 2>/dev/null`"
|
||||
if [ ".`echo $str | grep '^uid[ ]*=[ ]*[0-9]*('`" != . ]; then
|
||||
userid=`echo $str | sed -e 's/^uid[ ]*=[ ]*//' -e 's/(.*$//'`
|
||||
fi
|
||||
if [ ".$userid" = . ]; then
|
||||
userid=`(getent passwd ${username}) 2>/dev/null | \
|
||||
sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
|
||||
if [ ".$userid" = . ]; then
|
||||
userid=`grep "^${username}:" /etc/passwd 2>/dev/null | \
|
||||
sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
|
||||
if [ ".$userid" = . ]; then
|
||||
userid=`(ypcat passwd) 2>/dev/null |
|
||||
grep "^${username}:" | \
|
||||
sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
|
||||
if [ ".$userid" = . ]; then
|
||||
userid='?'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# determine (primary) group id
|
||||
groupid=''
|
||||
if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[gG]'`" != . ]; then
|
||||
groupid=`egrep "^${username}:" /etc/passwd 2>/dev/null | \
|
||||
sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
|
||||
if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[gG]'`" != . ]; then
|
||||
groupid="`(id -g ${username}) 2>/dev/null`"
|
||||
if [ ".$groupid" = . ]; then
|
||||
groupid=`(ypcat passwd) 2>/dev/null | egrep "^${username}:" | \
|
||||
sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
|
||||
str="`(id) 2>/dev/null`"
|
||||
if [ ".`echo $str | grep 'gid[ ]*=[ ]*[0-9]*('`" != . ]; then
|
||||
groupid=`echo $str | sed -e 's/^.*gid[ ]*=[ ]*//' -e 's/(.*$//'`
|
||||
fi
|
||||
if [ ".$groupid" = . ]; then
|
||||
groupid='?'
|
||||
groupid=`(getent passwd ${username}) 2>/dev/null | \
|
||||
sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
|
||||
if [ ".$groupid" = . ]; then
|
||||
groupid=`grep "^${username}:" /etc/passwd 2>/dev/null | \
|
||||
sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
|
||||
if [ ".$groupid" = . ]; then
|
||||
groupid=`(ypcat passwd) 2>/dev/null | grep "^${username}:" | \
|
||||
sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
|
||||
if [ ".$groupid" = . ]; then
|
||||
groupid='?'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# determine (primary) group name
|
||||
groupname=''
|
||||
if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%g'`" != . ]; then
|
||||
groupname=`egrep "^[^:]*:[^:]*:${groupid}:" /etc/group 2>/dev/null | \
|
||||
sed -e 's/:.*$//'`
|
||||
if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%g'`" != . ]; then
|
||||
groupname="`(id -gn ${username}) 2>/dev/null`"
|
||||
if [ ".$groupname" = . ]; then
|
||||
groupname=`(ypcat group) 2>/dev/null | \
|
||||
egrep "^[^:]*:[^:]*:${groupid}:" | \
|
||||
sed -e 's/:.*$//'`
|
||||
str="`(id) 2>/dev/null`"
|
||||
if [ ".`echo $str | grep 'gid[ ]*=[ ]*[0-9]*('`" != . ]; then
|
||||
groupname=`echo $str | sed -e 's/^.*gid[ ]*=[ ]*[0-9]*(//' -e 's/).*$//'`
|
||||
fi
|
||||
if [ ".$groupname" = . ]; then
|
||||
groupname='?'
|
||||
groupname=`(getent group) 2>/dev/null | \
|
||||
grep "^[^:]*:[^:]*:${groupid}:" | \
|
||||
sed -e 's/:.*$//'`
|
||||
if [ ".$groupname" = . ]; then
|
||||
groupname=`grep "^[^:]*:[^:]*:${groupid}:" /etc/group 2>/dev/null | \
|
||||
sed -e 's/:.*$//'`
|
||||
if [ ".$groupname" = . ]; then
|
||||
groupname=`(ypcat group) 2>/dev/null | \
|
||||
grep "^[^:]*:[^:]*:${groupid}:" | \
|
||||
sed -e 's/:.*$//'`
|
||||
if [ ".$groupname" = . ]; then
|
||||
groupname='?'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# determine host and domain name
|
||||
hostname=''
|
||||
domainname=''
|
||||
if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%h'`" != . ]; then
|
||||
if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%h'`" != . ]; then
|
||||
hostname="`(uname -n) 2>/dev/null |\
|
||||
awk '{ printf("%s", $1); }'`"
|
||||
if [ ".$hostname" = . ]; then
|
||||
@@ -565,16 +640,16 @@ echo )
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%d'`" != . ]; then
|
||||
if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%d'`" != . ]; then
|
||||
if [ ".$domainname" = . ]; then
|
||||
if [ -f /etc/resolv.conf ]; then
|
||||
domainname="`egrep '^[ ]*domain' /etc/resolv.conf | sed -e 'q' |\
|
||||
domainname="`grep '^[ ]*domain' /etc/resolv.conf | sed -e 'q' |\
|
||||
sed -e 's/.*domain//' \
|
||||
-e 's/^[ ]*//' -e 's/^ *//' -e 's/^ *//' \
|
||||
-e 's/^\.//' -e 's/^/./' |\
|
||||
awk '{ printf("%s", $1); }'`"
|
||||
if [ ".$domainname" = . ]; then
|
||||
domainname="`egrep '^[ ]*search' /etc/resolv.conf | sed -e 'q' |\
|
||||
domainname="`grep '^[ ]*search' /etc/resolv.conf | sed -e 'q' |\
|
||||
sed -e 's/.*search//' \
|
||||
-e 's/^[ ]*//' -e 's/^ *//' -e 's/^ *//' \
|
||||
-e 's/ .*//' -e 's/ .*//' \
|
||||
@@ -584,13 +659,13 @@ echo )
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# determine current time
|
||||
time_day=''
|
||||
time_month=''
|
||||
time_year=''
|
||||
time_monthname=''
|
||||
if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[DMYm]'`" != . ]; then
|
||||
if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[DMYm]'`" != . ]; then
|
||||
time_day=`date '+%d'`
|
||||
time_month=`date '+%m'`
|
||||
time_year=`date '+%Y' 2>/dev/null`
|
||||
@@ -616,7 +691,7 @@ echo )
|
||||
12) time_monthname='Dec' ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
|
||||
# expand special ``%x'' constructs
|
||||
if [ ".$opt_e" = .yes ]; then
|
||||
text=`echo $seo "$text" |\
|
||||
@@ -633,7 +708,7 @@ echo )
|
||||
-e "s/%Y/${time_year}/g" \
|
||||
-e "s/%m/${time_monthname}/g" 2>/dev/null`
|
||||
fi
|
||||
|
||||
|
||||
# create output
|
||||
if [ .$opt_n = .no ]; then
|
||||
echo $seo "$text"
|
||||
@@ -646,15 +721,16 @@ echo )
|
||||
echo dummy | awk '{ printf("%s", TEXT); }' TEXT="$text"
|
||||
fi
|
||||
fi
|
||||
|
||||
shtool_exit 0
|
||||
;;
|
||||
|
||||
install )
|
||||
##
|
||||
## install -- Install a program, script or datafile
|
||||
## Copyright (c) 1997-2002 Ralf S. Engelschall <rse@engelschall.com>
|
||||
## Originally written for shtool
|
||||
## Copyright (c) 1997-2005 Ralf S. Engelschall <rse@engelschall.com>
|
||||
##
|
||||
|
||||
|
||||
# special case: "shtool install -d <dir> [...]" internally
|
||||
# maps to "shtool mkdir -f -p -m 755 <dir> [...]"
|
||||
if [ "$opt_d" = yes ]; then
|
||||
@@ -672,11 +748,11 @@ install )
|
||||
cmd="$cmd -t"
|
||||
fi
|
||||
for dir in "$@"; do
|
||||
eval "$cmd $dir" || exit $?
|
||||
eval "$cmd $dir" || shtool_exit $?
|
||||
done
|
||||
exit 0
|
||||
shtool_exit 0
|
||||
fi
|
||||
|
||||
|
||||
# determine source(s) and destination
|
||||
argc=$#
|
||||
srcs=""
|
||||
@@ -685,30 +761,30 @@ install )
|
||||
shift
|
||||
done
|
||||
dstpath="$1"
|
||||
|
||||
|
||||
# type check for destination
|
||||
dstisdir=0
|
||||
if [ -d $dstpath ]; then
|
||||
dstpath=`echo "$dstpath" | sed -e 's:/$::'`
|
||||
dstisdir=1
|
||||
fi
|
||||
|
||||
|
||||
# consistency check for destination
|
||||
if [ $argc -gt 2 -a $dstisdir = 0 ]; then
|
||||
if [ $argc -gt 2 ] && [ $dstisdir = 0 ]; then
|
||||
echo "$msgprefix:Error: multiple sources require destination to be directory" 1>&2
|
||||
exit 1
|
||||
shtool_exit 1
|
||||
fi
|
||||
|
||||
|
||||
# iterate over all source(s)
|
||||
for src in $srcs; do
|
||||
dst=$dstpath
|
||||
|
||||
|
||||
# if destination is a directory, append the input filename
|
||||
if [ $dstisdir = 1 ]; then
|
||||
dstfile=`echo "$src" | sed -e 's;.*/\([^/]*\)$;\1;'`
|
||||
dst="$dst/$dstfile"
|
||||
fi
|
||||
|
||||
|
||||
# check for correct arguments
|
||||
if [ ".$src" = ".$dst" ]; then
|
||||
echo "$msgprefix:Warning: source and destination are the same - skipped" 1>&2
|
||||
@@ -718,17 +794,17 @@ install )
|
||||
echo "$msgprefix:Warning: source \`$src' is a directory - skipped" 1>&2
|
||||
continue
|
||||
fi
|
||||
|
||||
|
||||
# make a temp file name in the destination directory
|
||||
dsttmp=`echo $dst |\
|
||||
sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;' -e 's;^$;.;' \
|
||||
-e "s;\$;/#INST@$$#;"`
|
||||
|
||||
|
||||
# verbosity
|
||||
if [ ".$opt_v" = .yes ]; then
|
||||
echo "$src -> $dst" 1>&2
|
||||
fi
|
||||
|
||||
|
||||
# copy or move the file name to the temp name
|
||||
# (because we might be not allowed to change the source)
|
||||
if [ ".$opt_C" = .yes ]; then
|
||||
@@ -738,14 +814,14 @@ install )
|
||||
if [ ".$opt_t" = .yes ]; then
|
||||
echo "cp $src $dsttmp" 1>&2
|
||||
fi
|
||||
cp $src $dsttmp || exit $?
|
||||
cp $src $dsttmp || shtool_exit $?
|
||||
else
|
||||
if [ ".$opt_t" = .yes ]; then
|
||||
echo "mv $src $dsttmp" 1>&2
|
||||
fi
|
||||
mv $src $dsttmp || exit $?
|
||||
mv $src $dsttmp || shtool_exit $?
|
||||
fi
|
||||
|
||||
|
||||
# adjust the target file
|
||||
if [ ".$opt_e" != . ]; then
|
||||
sed='sed'
|
||||
@@ -755,34 +831,35 @@ install )
|
||||
sed="$sed -e '$e'"
|
||||
done
|
||||
cp $dsttmp $dsttmp.old
|
||||
eval "$sed <$dsttmp.old >$dsttmp" || exit $?
|
||||
chmod u+w $dsttmp
|
||||
eval "$sed <$dsttmp.old >$dsttmp" || shtool_exit $?
|
||||
rm -f $dsttmp.old
|
||||
fi
|
||||
if [ ".$opt_s" = .yes ]; then
|
||||
if [ ".$opt_t" = .yes ]; then
|
||||
echo "strip $dsttmp" 1>&2
|
||||
fi
|
||||
strip $dsttmp || exit $?
|
||||
strip $dsttmp || shtool_exit $?
|
||||
fi
|
||||
if [ ".$opt_o" != . ]; then
|
||||
if [ ".$opt_t" = .yes ]; then
|
||||
echo "chown $opt_o $dsttmp" 1>&2
|
||||
fi
|
||||
chown $opt_o $dsttmp || exit $?
|
||||
chown $opt_o $dsttmp || shtool_exit $?
|
||||
fi
|
||||
if [ ".$opt_g" != . ]; then
|
||||
if [ ".$opt_t" = .yes ]; then
|
||||
echo "chgrp $opt_g $dsttmp" 1>&2
|
||||
fi
|
||||
chgrp $opt_g $dsttmp || exit $?
|
||||
chgrp $opt_g $dsttmp || shtool_exit $?
|
||||
fi
|
||||
if [ ".$opt_m" != ".-" ]; then
|
||||
if [ ".$opt_t" = .yes ]; then
|
||||
echo "chmod $opt_m $dsttmp" 1>&2
|
||||
fi
|
||||
chmod $opt_m $dsttmp || exit $?
|
||||
chmod $opt_m $dsttmp || shtool_exit $?
|
||||
fi
|
||||
|
||||
|
||||
# determine whether to do a quick install
|
||||
# (has to be done _after_ the strip was already done)
|
||||
quick=no
|
||||
@@ -793,7 +870,7 @@ install )
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# finally, install the file to the real destination
|
||||
if [ $quick = yes ]; then
|
||||
if [ ".$opt_t" = .yes ]; then
|
||||
@@ -807,21 +884,21 @@ install )
|
||||
rm -f $dst && mv $dsttmp $dst
|
||||
fi
|
||||
done
|
||||
|
||||
shtool_exit 0
|
||||
;;
|
||||
|
||||
mkdir )
|
||||
##
|
||||
## mkdir -- Make one or more directories
|
||||
## Copyright (c) 1996-2002 Ralf S. Engelschall <rse@engelschall.com>
|
||||
## Originally written for public domain by Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
## Cleaned up and enhanced for shtool
|
||||
## Copyright (c) 1996-2005 Ralf S. Engelschall <rse@engelschall.com>
|
||||
##
|
||||
|
||||
|
||||
errstatus=0
|
||||
for p in ${1+"$@"}; do
|
||||
# if the directory already exists...
|
||||
if [ -d "$p" ]; then
|
||||
if [ ".$opt_f" = .no -a ".$opt_p" = .no ]; then
|
||||
if [ ".$opt_f" = .no ] && [ ".$opt_p" = .no ]; then
|
||||
echo "$msgprefix:Error: directory already exists: $p" 1>&2
|
||||
errstatus=1
|
||||
break
|
||||
@@ -895,32 +972,32 @@ mkdir )
|
||||
done
|
||||
fi
|
||||
done
|
||||
exit $errstatus
|
||||
|
||||
shtool_exit $errstatus
|
||||
;;
|
||||
|
||||
path )
|
||||
##
|
||||
## path -- Deal with program paths
|
||||
## Copyright (c) 1998-2002 Ralf S. Engelschall <rse@engelschall.com>
|
||||
## Originally written for Apache
|
||||
## Copyright (c) 1998-2005 Ralf S. Engelschall <rse@engelschall.com>
|
||||
##
|
||||
|
||||
|
||||
namelist="$*"
|
||||
|
||||
|
||||
# check whether the test command supports the -x option
|
||||
if [ -x /bin/sh ] 2>/dev/null; then
|
||||
minusx="-x"
|
||||
else
|
||||
minusx="-r"
|
||||
fi
|
||||
|
||||
|
||||
# split path string
|
||||
paths="`echo $opt_p |\
|
||||
sed -e 's/^:/.:/' \
|
||||
-e 's/::/:.:/g' \
|
||||
-e 's/:$/:./' \
|
||||
-e 's/:/ /g'`"
|
||||
|
||||
|
||||
# SPECIAL REQUEST
|
||||
# translate forward to reverse path
|
||||
if [ ".$opt_r" = .yes ]; then
|
||||
@@ -933,25 +1010,25 @@ path )
|
||||
done
|
||||
fi
|
||||
echo $rp | sed -e 's:/$::'
|
||||
exit 0
|
||||
shtool_exit 0
|
||||
fi
|
||||
|
||||
|
||||
# SPECIAL REQUEST
|
||||
# strip out directory or base name
|
||||
if [ ".$opt_d" = .yes ]; then
|
||||
echo "$namelist" |\
|
||||
sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;'
|
||||
exit 0
|
||||
shtool_exit 0
|
||||
fi
|
||||
if [ ".$opt_b" = .yes ]; then
|
||||
echo "$namelist" |\
|
||||
sed -e 's;.*/\([^/]*\)$;\1;'
|
||||
exit 0
|
||||
shtool_exit 0
|
||||
fi
|
||||
|
||||
|
||||
# MAGIC SITUATION
|
||||
# Perl Interpreter (perl)
|
||||
if [ ".$opt_m" = .yes -a ".$namelist" = .perl ]; then
|
||||
if [ ".$opt_m" = .yes ] && [ ".$namelist" = .perl ]; then
|
||||
rm -f $tmpfile >/dev/null 2>&1
|
||||
touch $tmpfile
|
||||
found=0
|
||||
@@ -960,7 +1037,7 @@ path )
|
||||
dir=`echo $dir | sed -e 's;/*$;;'`
|
||||
nc=99
|
||||
for name in perl perl5 miniperl; do
|
||||
if [ $minusx "$dir/$name" -a ! -d "$dir/$name" ]; then
|
||||
if [ $minusx "$dir/$name" ] && [ ! -d "$dir/$name" ]; then
|
||||
perl="$dir/$name"
|
||||
pv=`$perl -e 'printf("%.3f", $]);'`
|
||||
echo "$pv:$pc:$nc:$perl" >>$tmpfile
|
||||
@@ -974,15 +1051,15 @@ path )
|
||||
perl="`cat $tmpfile | sort -r -u | sed -e 'q' | cut -d: -f4`"
|
||||
rm -f $tmpfile >/dev/null 2>&1
|
||||
echo "$perl"
|
||||
exit 0
|
||||
shtool_exit 0
|
||||
fi
|
||||
rm -f $tmpfile >/dev/null 2>&1
|
||||
exit 1
|
||||
shtool_exit 1
|
||||
fi
|
||||
|
||||
|
||||
# MAGIC SITUATION
|
||||
# C pre-processor (cpp)
|
||||
if [ ".$opt_m" = .yes -a ".$namelist" = .cpp ]; then
|
||||
if [ ".$opt_m" = .yes ] && [ ".$namelist" = .cpp ]; then
|
||||
echo >$tmpfile.c "#include <assert.h>"
|
||||
echo >>$tmpfile.c "Syntax Error"
|
||||
# 1. try the standard cc -E approach
|
||||
@@ -998,7 +1075,7 @@ path )
|
||||
# 3. try a standalone cpp command in path and lib dirs
|
||||
for path in $paths /lib /usr/lib /usr/local/lib; do
|
||||
path=`echo $path | sed -e 's;/*$;;'`
|
||||
if [ $minusx "$path/cpp" -a ! -d "$path/cpp" ]; then
|
||||
if [ $minusx "$path/cpp" ] && [ ! -d "$path/cpp" ]; then
|
||||
cpp="$path/cpp"
|
||||
break
|
||||
fi
|
||||
@@ -1017,30 +1094,30 @@ path )
|
||||
rm -f $tmpfile.c $tmpfile.out >/dev/null 2>&1
|
||||
if [ ".$cpp" != . ]; then
|
||||
echo "$cpp"
|
||||
exit 0
|
||||
shtool_exit 0
|
||||
fi
|
||||
exit 1
|
||||
shtool_exit 1
|
||||
fi
|
||||
|
||||
|
||||
# STANDARD SITUATION
|
||||
# iterate over names
|
||||
for name in $namelist; do
|
||||
# iterate over paths
|
||||
for path in $paths; do
|
||||
path=`echo $path | sed -e 's;/*$;;'`
|
||||
if [ $minusx "$path/$name" -a ! -d "$path/$name" ]; then
|
||||
if [ $minusx "$path/$name" ] && [ ! -d "$path/$name" ]; then
|
||||
if [ ".$opt_s" != .yes ]; then
|
||||
echo "$path/$name"
|
||||
fi
|
||||
exit 0
|
||||
shtool_exit 0
|
||||
fi
|
||||
done
|
||||
done
|
||||
exit 1
|
||||
|
||||
shtool_exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
exit 0
|
||||
shtool_exit 0
|
||||
|
||||
##EOF##
|
||||
+54
-8
@@ -39,8 +39,8 @@ PHP_CANONICAL_HOST
|
||||
AC_CONFIG_HEADER(main/php_config.h)
|
||||
|
||||
MAJOR_VERSION=4
|
||||
MINOR_VERSION=3
|
||||
RELEASE_VERSION=11
|
||||
MINOR_VERSION=4
|
||||
RELEASE_VERSION=1
|
||||
EXTRA_VERSION=""
|
||||
VERSION="$MAJOR_VERSION.$MINOR_VERSION.$RELEASE_VERSION$EXTRA_VERSION"
|
||||
|
||||
@@ -180,6 +180,17 @@ PHP_C_BIGENDIAN
|
||||
dnl Platform-specific compile settings.
|
||||
dnl -------------------------------------------------------------------------
|
||||
|
||||
dnl See bug #28605
|
||||
case $host_cpu in
|
||||
alpha*)
|
||||
if test "$GCC" = "yes"; then
|
||||
CFLAGS="$CFLAGS -mieee"
|
||||
else
|
||||
CFLAGS="$CFLAGS -ieee"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
case $host_alias in
|
||||
*solaris*)
|
||||
CPPFLAGS="$CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS"
|
||||
@@ -203,6 +214,15 @@ case $host_alias in
|
||||
CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE_EXTENDED"
|
||||
fi
|
||||
;;
|
||||
*netware*)
|
||||
PHP_BUILD_PROGRAM
|
||||
PHP_ADD_SOURCES(/main, internal_functions.c,,PHP_GLOBAL_OBJS)
|
||||
PHP_ADD_SOURCES(win32, sendmail.c, -I$CFLAGS, PHP_GLOBAL_OBJS)
|
||||
PHP4LIB_SHARED_LIBADD=\$\(EXTRA_LIBS\)
|
||||
EXTENSION_DIR=sys:/php$MAJOR_VERSION/ext
|
||||
PHP_SUBST(PHP4LIB_SHARED_LIBADD)
|
||||
PHP_SHARED_MODULE(php4lib, PHP_GLOBAL_OBJS, netware)
|
||||
;;
|
||||
esac
|
||||
|
||||
# Disable PIC mode by default where it is known to be safe to do so,
|
||||
@@ -425,6 +445,12 @@ PHP_TM_GMTOFF
|
||||
PHP_STRUCT_FLOCK
|
||||
PHP_SOCKLEN_T
|
||||
|
||||
AC_CHECK_SIZEOF(intmax_t, 0)
|
||||
AC_CHECK_SIZEOF(size_t, 8)
|
||||
AC_CHECK_SIZEOF(ssize_t, 8)
|
||||
AC_CHECK_SIZEOF(ptrdiff_t, 8)
|
||||
AC_CHECK_SIZEOF(long long, 8)
|
||||
AC_CHECK_SIZEOF(long long int, 8)
|
||||
AC_CHECK_SIZEOF(long, 8)
|
||||
AC_CHECK_SIZEOF(int, 4)
|
||||
|
||||
@@ -1065,10 +1091,20 @@ EXTRA_LDFLAGS_PROGRAM="$EXTRA_LDFLAGS_PROGRAM $PHP_LDFLAGS"
|
||||
|
||||
PHP_BUILD_DATE=`date '+%Y-%m-%d'`
|
||||
AC_DEFINE_UNQUOTED(PHP_BUILD_DATE,"$PHP_BUILD_DATE",[PHP build date])
|
||||
PHP_UNAME=`uname -a | xargs`
|
||||
AC_DEFINE_UNQUOTED(PHP_UNAME,"$PHP_UNAME",[uname -a output])
|
||||
PHP_OS=`uname | xargs`
|
||||
AC_DEFINE_UNQUOTED(PHP_OS,"$PHP_OS",[uname output])
|
||||
case $host_alias in
|
||||
*netware*)
|
||||
PHP_OS="NetWare"
|
||||
PHP_UNAME="NetWare"
|
||||
AC_DEFINE_UNQUOTED(PHP_OS,"$PHP_OS",[hardcode for each of the cross compiler host])
|
||||
AC_DEFINE_UNQUOTED(PHP_UNAME,"$PHP_UNAME",[hardcode for each of the cross compiler host])
|
||||
;;
|
||||
*)
|
||||
PHP_UNAME=`uname -a | xargs`
|
||||
AC_DEFINE_UNQUOTED(PHP_UNAME,"$PHP_UNAME",[uname -a output])
|
||||
PHP_OS=`uname | xargs`
|
||||
AC_DEFINE_UNQUOTED(PHP_OS,"$PHP_OS",[uname output])
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$disable_cli" != "1"; then
|
||||
PHP_CLI_TARGET="\$(SAPI_CLI_PATH)"
|
||||
@@ -1226,7 +1262,15 @@ PHP_ADD_SOURCES(main, main.c snprintf.c spprintf.c php_sprintf.c \
|
||||
streams.c network.c php_open_temporary_file.c php_logos.c \
|
||||
output.c memory_streams.c user_streams.c)
|
||||
PHP_ADD_SOURCES(/main, internal_functions.c,, sapi)
|
||||
PHP_ADD_SOURCES(/main, internal_functions_cli.c,, cli)
|
||||
case $host_alias in
|
||||
*netware*)
|
||||
PHP_ADD_BUILD_DIR(win32)
|
||||
PHP_ADD_BUILD_DIR(netware)
|
||||
;;
|
||||
*)
|
||||
PHP_ADD_SOURCES(/main, internal_functions_cli.c,, cli)
|
||||
;;
|
||||
esac
|
||||
|
||||
PHP_ADD_SOURCES(/Zend, zend_language_parser.c zend_language_scanner.c \
|
||||
zend_ini_parser.c zend_ini_scanner.c)
|
||||
@@ -1269,9 +1313,11 @@ AC_DEFINE([HAVE_BUILD_DEFS_H], 1, [ ])
|
||||
|
||||
$php_shtool mkdir -p pear/scripts
|
||||
$php_shtool mkdir -p scripts
|
||||
$php_shtool mkdir -p scripts/man1
|
||||
|
||||
ALL_OUTPUT_FILES="php4.spec main/build-defs.h \
|
||||
scripts/phpize scripts/php-config \
|
||||
scripts/phpize scripts/man1/phpize.1 \
|
||||
scripts/php-config scripts/man1/php-config.1 \
|
||||
$PHP_OUTPUT_FILES"
|
||||
|
||||
AC_OUTPUT($ALL_OUTPUT_FILES, [], [
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#if PHP_WIN32
|
||||
#include "../../../../main/config.w32.h"
|
||||
#elif defined(NETWARE)
|
||||
#include "config.nw.h"
|
||||
#else
|
||||
#include <php_config.h>
|
||||
#endif
|
||||
|
||||
+39
-45
@@ -40,9 +40,6 @@
|
||||
#define PHP_BZ_ERRSTR 1
|
||||
#define PHP_BZ_ERRBOTH 2
|
||||
|
||||
/* Blocksize of the decompression buffer */
|
||||
#define PHP_BZ_DECOMPRESS_SIZE 4096
|
||||
|
||||
function_entry bz2_functions[] = {
|
||||
PHP_FE(bzopen, NULL)
|
||||
PHP_FE(bzread, NULL)
|
||||
@@ -434,56 +431,53 @@ PHP_FUNCTION(bzcompress)
|
||||
Decompresses BZip2 compressed data */
|
||||
PHP_FUNCTION(bzdecompress)
|
||||
{
|
||||
zval **source, /* Source data to decompress */
|
||||
**zsmall; /* (Optional) user specified small */
|
||||
char *dest; /* Destination buffer, initially allocated */
|
||||
int error, /* Error container */
|
||||
iter = 1, /* Iteration count for the compression loop */
|
||||
size, /* Current size to realloc the dest buffer to */
|
||||
dest_len = PHP_BZ_DECOMPRESS_SIZE, /* Size of the destination length */
|
||||
small = 0, /* The actual small */
|
||||
argc = ZEND_NUM_ARGS(); /* Argument count */
|
||||
|
||||
if (argc < 1 || argc > 2 || zend_get_parameters_ex(argc, &source, &zsmall) == FAILURE) {
|
||||
WRONG_PARAM_COUNT;
|
||||
char *source, *dest;
|
||||
int source_len, error;
|
||||
long small = 0;
|
||||
#if defined(PHP_WIN32) && _MSC_VER < 1300
|
||||
unsigned __int64 size = 0;
|
||||
#else
|
||||
unsigned long long size = 0;
|
||||
#endif
|
||||
bz_stream bzs;
|
||||
|
||||
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &source, &source_len, &small)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
convert_to_string_ex(source);
|
||||
|
||||
/* optional small argument handling */
|
||||
if (argc > 1) {
|
||||
convert_to_long_ex(zsmall);
|
||||
small = Z_LVAL_PP(zsmall);
|
||||
bzs.bzalloc = NULL;
|
||||
bzs.bzfree = NULL;
|
||||
|
||||
if (BZ2_bzDecompressInit(&bzs, 0, small) != BZ_OK) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
/* Depending on the size of the source buffer, either allocate
|
||||
the length of the source buffer or the a default decompression
|
||||
size */
|
||||
dest = emalloc(PHP_BZ_DECOMPRESS_SIZE > Z_STRLEN_PP(source) ? PHP_BZ_DECOMPRESS_SIZE : Z_STRLEN_PP(source));
|
||||
bzs.next_in = source;
|
||||
bzs.avail_in = source_len;
|
||||
|
||||
/* (de)Compression Loop */
|
||||
do {
|
||||
/* Handle the (re)allocation of the buffer */
|
||||
size = dest_len * iter;
|
||||
if (iter > 1) {
|
||||
dest = erealloc(dest, size);
|
||||
}
|
||||
++iter;
|
||||
|
||||
/* Perform the decompression */
|
||||
error = BZ2_bzBuffToBuffDecompress(dest, &size, Z_STRVAL_PP(source), Z_STRLEN_PP(source), small, 0);
|
||||
} while (error == BZ_OUTBUFF_FULL);
|
||||
/* in most cases bz2 offers at least 2:1 compression, so we use that as our base */
|
||||
bzs.avail_out = source_len * 2;
|
||||
bzs.next_out = dest = emalloc(bzs.avail_out + 1);
|
||||
|
||||
if (error != BZ_OK) {
|
||||
efree(dest);
|
||||
RETURN_LONG(error);
|
||||
} else {
|
||||
/* we might have allocated a little to much, so erealloc the buffer
|
||||
down to size, before returning it */
|
||||
while ((error = BZ2_bzDecompress(&bzs)) == BZ_OK && bzs.avail_in > 0) {
|
||||
/* compression is better then 2:1, need to allocate more memory */
|
||||
bzs.avail_out = source_len;
|
||||
size = (bzs.total_out_hi32 * (unsigned int) -1) + bzs.total_out_lo32;
|
||||
dest = erealloc(dest, size + bzs.avail_out + 1);
|
||||
bzs.next_out = dest + size;
|
||||
}
|
||||
|
||||
if (error == BZ_STREAM_END || error == BZ_OK) {
|
||||
size = (bzs.total_out_hi32 * (unsigned int) -1) + bzs.total_out_lo32;
|
||||
dest = erealloc(dest, size + 1);
|
||||
dest[size] = 0;
|
||||
RETURN_STRINGL(dest, size, 0);
|
||||
dest[size] = '\0';
|
||||
RETVAL_STRINGL(dest, size, 0);
|
||||
} else { /* real error */
|
||||
efree(dest);
|
||||
RETVAL_LONG(error);
|
||||
}
|
||||
|
||||
BZ2_bzDecompressEnd(&bzs);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
+303
-301
@@ -14,7 +14,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Shane Caraveo <shane@caraveo.com> |
|
||||
| Colin Viebrock <colin@easydns.com> |
|
||||
| Hartmut Holzgraefe <hartmut@six.de> |
|
||||
| Hartmut Holzgraefe <hholzgra@php.net> |
|
||||
| Wez Furlong <wez@thebrainroom.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "sdncal.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
function_entry calendar_functions[] = {
|
||||
PHP_FE(jdtogregorian, NULL)
|
||||
PHP_FE(gregoriantojd, NULL)
|
||||
@@ -48,10 +48,10 @@ function_entry calendar_functions[] = {
|
||||
PHP_FE(jdmonthname, NULL)
|
||||
PHP_FE(easter_date, NULL)
|
||||
PHP_FE(easter_days, NULL)
|
||||
PHP_FE(unixtojd, NULL)
|
||||
PHP_FE(jdtounix, NULL)
|
||||
PHP_FE(cal_to_jd, NULL)
|
||||
PHP_FE(cal_from_jd, NULL)
|
||||
PHP_FE(unixtojd, NULL)
|
||||
PHP_FE(jdtounix, NULL)
|
||||
PHP_FE(cal_to_jd, NULL)
|
||||
PHP_FE(cal_from_jd, NULL)
|
||||
PHP_FE(cal_days_in_month, NULL)
|
||||
PHP_FE(cal_info, NULL)
|
||||
{NULL, NULL, NULL}
|
||||
@@ -60,8 +60,8 @@ function_entry calendar_functions[] = {
|
||||
|
||||
zend_module_entry calendar_module_entry = {
|
||||
STANDARD_MODULE_HEADER,
|
||||
"calendar",
|
||||
calendar_functions,
|
||||
"calendar",
|
||||
calendar_functions,
|
||||
PHP_MINIT(calendar),
|
||||
NULL,
|
||||
NULL,
|
||||
@@ -83,60 +83,76 @@ enum cal_name_type_t {
|
||||
CAL_FRENCH,
|
||||
CAL_NUM_CALS
|
||||
};
|
||||
typedef long int (*cal_to_jd_func_t)(int month, int day, int year);
|
||||
typedef void (*cal_from_jd_func_t)(long int jd, int* year, int* month, int* day);
|
||||
typedef char* (*cal_as_string_func_t)(int year, int month, int day);
|
||||
|
||||
typedef long int (*cal_to_jd_func_t) (int month, int day, int year);
|
||||
typedef void (*cal_from_jd_func_t) (long int jd, int *year, int *month, int *day);
|
||||
typedef char *(*cal_as_string_func_t) (int year, int month, int day);
|
||||
|
||||
struct cal_entry_t {
|
||||
char *name;
|
||||
char *symbol;
|
||||
cal_to_jd_func_t to_jd;
|
||||
cal_from_jd_func_t from_jd;
|
||||
int num_months;
|
||||
int max_days_in_month;
|
||||
char **month_name_short;
|
||||
char **month_name_long;
|
||||
char *name;
|
||||
char *symbol;
|
||||
cal_to_jd_func_t to_jd;
|
||||
cal_from_jd_func_t from_jd;
|
||||
int num_months;
|
||||
int max_days_in_month;
|
||||
char **month_name_short;
|
||||
char **month_name_long;
|
||||
};
|
||||
|
||||
static struct cal_entry_t cal_conversion_table[CAL_NUM_CALS] = {
|
||||
{ "Gregorian", "CAL_GREGORIAN", GregorianToSdn, SdnToGregorian, 12, 31, MonthNameShort, MonthNameLong },
|
||||
{ "Julian", "CAL_JULIAN", JulianToSdn, SdnToJulian, 12, 31, MonthNameShort, MonthNameLong },
|
||||
{ "Jewish", "CAL_JEWISH", JewishToSdn, SdnToJewish, 13, 30, JewishMonthName, JewishMonthName },
|
||||
{ "French", "CAL_FRENCH", FrenchToSdn, SdnToFrench, 13, 30, FrenchMonthName, FrenchMonthName }
|
||||
{"Gregorian", "CAL_GREGORIAN", GregorianToSdn, SdnToGregorian, 12, 31,
|
||||
MonthNameShort, MonthNameLong},
|
||||
{"Julian", "CAL_JULIAN", JulianToSdn, SdnToJulian, 12, 31,
|
||||
MonthNameShort, MonthNameLong},
|
||||
{"Jewish", "CAL_JEWISH", JewishToSdn, SdnToJewish, 13, 30,
|
||||
JewishMonthName, JewishMonthName},
|
||||
{"French", "CAL_FRENCH", FrenchToSdn, SdnToFrench, 13, 30,
|
||||
FrenchMonthName, FrenchMonthName}
|
||||
};
|
||||
|
||||
/* For jddayofweek */
|
||||
enum { CAL_DOW_DAYNO, CAL_DOW_SHORT, CAL_DOW_LONG };
|
||||
enum { CAL_DOW_DAYNO, CAL_DOW_SHORT, CAL_DOW_LONG };
|
||||
|
||||
/* For jdmonthname */
|
||||
enum { CAL_MONTH_GREGORIAN_SHORT, CAL_MONTH_GREGORIAN_LONG,
|
||||
enum { CAL_MONTH_GREGORIAN_SHORT, CAL_MONTH_GREGORIAN_LONG,
|
||||
CAL_MONTH_JULIAN_SHORT, CAL_MONTH_JULIAN_LONG, CAL_MONTH_JEWISH,
|
||||
CAL_MONTH_FRENCH };
|
||||
CAL_MONTH_FRENCH
|
||||
};
|
||||
|
||||
/* for heb_number_to_chars */
|
||||
static char alef_bet[25] = "0àáâãäåæçèéëìîðñòôö÷øùú";
|
||||
|
||||
|
||||
#define CAL_JEWISH_ADD_ALAFIM_GERESH 0x2
|
||||
#define CAL_JEWISH_ADD_ALAFIM 0x4
|
||||
#define CAL_JEWISH_ADD_GERESHAYIM 0x8
|
||||
|
||||
PHP_MINIT_FUNCTION(calendar)
|
||||
{
|
||||
REGISTER_LONG_CONSTANT("CAL_GREGORIAN", CAL_GREGORIAN, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_JULIAN", CAL_JULIAN, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_JEWISH", CAL_JEWISH, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_FRENCH", CAL_FRENCH, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_NUM_CALS", CAL_NUM_CALS, CONST_CS|CONST_PERSISTENT);
|
||||
/* constants for jddayofweek */
|
||||
REGISTER_LONG_CONSTANT("CAL_DOW_DAYNO", CAL_DOW_DAYNO, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_DOW_SHORT", CAL_DOW_SHORT, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_DOW_LONG", CAL_DOW_LONG, CONST_CS|CONST_PERSISTENT);
|
||||
/* constants for jdmonthname */
|
||||
REGISTER_LONG_CONSTANT("CAL_MONTH_GREGORIAN_SHORT", CAL_MONTH_GREGORIAN_SHORT, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_MONTH_GREGORIAN_LONG", CAL_MONTH_GREGORIAN_LONG, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_MONTH_JULIAN_SHORT", CAL_MONTH_JULIAN_SHORT, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_MONTH_JULIAN_LONG", CAL_MONTH_JULIAN_LONG, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_MONTH_JEWISH", CAL_MONTH_JEWISH, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_MONTH_FRENCH", CAL_MONTH_FRENCH, CONST_CS|CONST_PERSISTENT);
|
||||
/* constants for easter calculation */
|
||||
REGISTER_LONG_CONSTANT("CAL_EASTER_DEFAULT", CAL_EASTER_DEFAULT, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_EASTER_ROMAN", CAL_EASTER_ROMAN, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_EASTER_ALWAYS_GREGORIAN", CAL_EASTER_ALWAYS_GREGORIAN, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_EASTER_ALWAYS_JULIAN", CAL_EASTER_ALWAYS_JULIAN, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_GREGORIAN", CAL_GREGORIAN, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_JULIAN", CAL_JULIAN, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_JEWISH", CAL_JEWISH, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_FRENCH", CAL_FRENCH, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_NUM_CALS", CAL_NUM_CALS, CONST_CS | CONST_PERSISTENT);
|
||||
/* constants for jddayofweek */
|
||||
REGISTER_LONG_CONSTANT("CAL_DOW_DAYNO", CAL_DOW_DAYNO, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_DOW_SHORT", CAL_DOW_SHORT, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_DOW_LONG", CAL_DOW_LONG, CONST_CS | CONST_PERSISTENT);
|
||||
/* constants for jdmonthname */
|
||||
REGISTER_LONG_CONSTANT("CAL_MONTH_GREGORIAN_SHORT", CAL_MONTH_GREGORIAN_SHORT, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_MONTH_GREGORIAN_LONG", CAL_MONTH_GREGORIAN_LONG, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_MONTH_JULIAN_SHORT", CAL_MONTH_JULIAN_SHORT, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_MONTH_JULIAN_LONG", CAL_MONTH_JULIAN_LONG, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_MONTH_JEWISH", CAL_MONTH_JEWISH, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_MONTH_FRENCH", CAL_MONTH_FRENCH, CONST_CS | CONST_PERSISTENT);
|
||||
/* constants for easter calculation */
|
||||
REGISTER_LONG_CONSTANT("CAL_EASTER_DEFAULT", CAL_EASTER_DEFAULT, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_EASTER_ROMAN", CAL_EASTER_ROMAN, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_EASTER_ALWAYS_GREGORIAN", CAL_EASTER_ALWAYS_GREGORIAN, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_EASTER_ALWAYS_JULIAN", CAL_EASTER_ALWAYS_JULIAN, CONST_CS | CONST_PERSISTENT);
|
||||
/* constants for Jewish date formatting */
|
||||
REGISTER_LONG_CONSTANT("CAL_JEWISH_ADD_ALAFIM_GERESH", CAL_JEWISH_ADD_ALAFIM_GERESH, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_JEWISH_ADD_ALAFIM", CAL_JEWISH_ADD_ALAFIM, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("CAL_JEWISH_ADD_GERESHAYIM", CAL_JEWISH_ADD_GERESHAYIM, CONST_CS | CONST_PERSISTENT);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -147,42 +163,65 @@ PHP_MINFO_FUNCTION(calendar)
|
||||
php_info_print_table_end();
|
||||
}
|
||||
|
||||
/* {{{ proto array cal_info(int calendar)
|
||||
Returns information about a particular calendar */
|
||||
PHP_FUNCTION(cal_info)
|
||||
static void _php_cal_info(int cal, zval **ret)
|
||||
{
|
||||
zval ** cal;
|
||||
zval * months, *smonths;
|
||||
zval *months, *smonths;
|
||||
int i;
|
||||
struct cal_entry_t * calendar;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &cal) != SUCCESS) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
convert_to_long_ex(cal);
|
||||
if (Z_LVAL_PP(cal) < 0 || Z_LVAL_PP(cal) >= CAL_NUM_CALS) {
|
||||
zend_error(E_WARNING, "%s(): invalid calendar ID %ld", get_active_function_name(TSRMLS_C), Z_LVAL_PP(cal));
|
||||
RETURN_FALSE;
|
||||
}
|
||||
struct cal_entry_t *calendar;
|
||||
|
||||
calendar = &cal_conversion_table[Z_LVAL_PP(cal)];
|
||||
array_init(return_value);
|
||||
calendar = &cal_conversion_table[cal];
|
||||
array_init(*ret);
|
||||
|
||||
MAKE_STD_ZVAL(months);
|
||||
MAKE_STD_ZVAL(smonths);
|
||||
array_init(months);
|
||||
array_init(smonths);
|
||||
|
||||
for (i=1; i<= calendar->num_months; i++) {
|
||||
|
||||
for (i = 1; i <= calendar->num_months; i++) {
|
||||
add_index_string(months, i, calendar->month_name_long[i], 1);
|
||||
add_index_string(smonths, i, calendar->month_name_short[i], 1);
|
||||
}
|
||||
add_assoc_zval(return_value, "months", months);
|
||||
add_assoc_zval(return_value, "abbrevmonths", smonths);
|
||||
add_assoc_long(return_value, "maxdaysinmonth", calendar->max_days_in_month);
|
||||
add_assoc_string(return_value, "calname", calendar->name, 1);
|
||||
add_assoc_string(return_value, "calsymbol", calendar->symbol, 1);
|
||||
add_assoc_zval(*ret, "months", months);
|
||||
add_assoc_zval(*ret, "abbrevmonths", smonths);
|
||||
add_assoc_long(*ret, "maxdaysinmonth", calendar->max_days_in_month);
|
||||
add_assoc_string(*ret, "calname", calendar->name, 1);
|
||||
add_assoc_string(*ret, "calsymbol", calendar->symbol, 1);
|
||||
|
||||
}
|
||||
|
||||
/* {{{ proto array cal_info(int calendar)
|
||||
Returns information about a particular calendar */
|
||||
PHP_FUNCTION(cal_info)
|
||||
{
|
||||
long cal = -1;
|
||||
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &cal) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (cal == -1) {
|
||||
int i;
|
||||
zval *val;
|
||||
|
||||
array_init(return_value);
|
||||
|
||||
for (i = 0; i < CAL_NUM_CALS; i++) {
|
||||
MAKE_STD_ZVAL(val);
|
||||
_php_cal_info(i, &val);
|
||||
add_index_zval(return_value, i, val);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (cal != -1 && (cal < 0 || cal >= CAL_NUM_CALS)) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid calendar ID %ld.", cal);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
_php_cal_info(cal, &return_value);
|
||||
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -190,34 +229,35 @@ PHP_FUNCTION(cal_info)
|
||||
Returns the number of days in a month for a given year and calendar */
|
||||
PHP_FUNCTION(cal_days_in_month)
|
||||
{
|
||||
zval ** cal, **month, **year;
|
||||
struct cal_entry_t * calendar;
|
||||
long cal, month, year;
|
||||
struct cal_entry_t *calendar;
|
||||
long sdn_start, sdn_next;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &cal, &month, &year) != SUCCESS) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
|
||||
convert_to_long_ex(cal);
|
||||
convert_to_long_ex(month);
|
||||
convert_to_long_ex(year);
|
||||
|
||||
if (Z_LVAL_PP(cal) < 0 || Z_LVAL_PP(cal) >= CAL_NUM_CALS) {
|
||||
zend_error(E_WARNING, "%s(): invalid calendar ID %ld", get_active_function_name(TSRMLS_C), Z_LVAL_PP(cal));
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll", &cal, &month, &year) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
calendar = &cal_conversion_table[Z_LVAL_PP(cal)];
|
||||
|
||||
sdn_start = calendar->to_jd(Z_LVAL_PP(year), Z_LVAL_PP(month), 1);
|
||||
|
||||
sdn_next = calendar->to_jd(Z_LVAL_PP(year), 1 + Z_LVAL_PP(month), 1);
|
||||
|
||||
if (sdn_next == 0) {
|
||||
/* if invalid, try first month of the next year... */
|
||||
sdn_next = calendar->to_jd(Z_LVAL_PP(year) + 1, 1, 1);
|
||||
if (cal < 0 || cal >= CAL_NUM_CALS) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid calendar ID %ld.", cal);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
|
||||
calendar = &cal_conversion_table[cal];
|
||||
|
||||
sdn_start = calendar->to_jd(year, month, 1);
|
||||
|
||||
if (sdn_start == 0) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid date.");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
sdn_next = calendar->to_jd(year, 1 + month, 1);
|
||||
|
||||
if (sdn_next == 0) {
|
||||
/* if invalid, try first month of the next year... */
|
||||
sdn_next = calendar->to_jd(year + 1, 1, 1);
|
||||
}
|
||||
|
||||
RETURN_LONG(sdn_next - sdn_start);
|
||||
}
|
||||
/* }}} */
|
||||
@@ -226,26 +266,18 @@ PHP_FUNCTION(cal_days_in_month)
|
||||
Converts from a supported calendar to Julian Day Count */
|
||||
PHP_FUNCTION(cal_to_jd)
|
||||
{
|
||||
zval ** cal, **month, **day, **year;
|
||||
long jdate;
|
||||
long cal, month, day, year;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 4 || zend_get_parameters_ex(4, &cal, &month, &day, &year) != SUCCESS) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
|
||||
convert_to_long_ex(cal);
|
||||
convert_to_long_ex(month);
|
||||
convert_to_long_ex(day);
|
||||
convert_to_long_ex(year);
|
||||
|
||||
if (Z_LVAL_PP(cal) < 0 || Z_LVAL_PP(cal) >= CAL_NUM_CALS) {
|
||||
zend_error(E_WARNING, "%s(): invalid calendar ID %ld", get_active_function_name(TSRMLS_C), Z_LVAL_PP(cal));
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "llll", &cal, &month, &day, &year) != SUCCESS) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
jdate = cal_conversion_table[Z_LVAL_PP(cal)].to_jd(
|
||||
Z_LVAL_PP(year), Z_LVAL_PP(month), Z_LVAL_PP(day));
|
||||
RETURN_LONG(jdate);
|
||||
if (cal < 0 || cal >= CAL_NUM_CALS) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid calendar ID %ld.", cal);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
RETURN_LONG(cal_conversion_table[cal].to_jd(year, month, day));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -253,42 +285,38 @@ PHP_FUNCTION(cal_to_jd)
|
||||
Converts from Julian Day Count to a supported calendar and return extended information */
|
||||
PHP_FUNCTION(cal_from_jd)
|
||||
{
|
||||
zval ** jd, ** cal;
|
||||
long jd, cal;
|
||||
int month, day, year, dow;
|
||||
char date[16];
|
||||
struct cal_entry_t * calendar;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &jd, &cal) != SUCCESS) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
convert_to_long_ex(jd);
|
||||
convert_to_long_ex(cal);
|
||||
struct cal_entry_t *calendar;
|
||||
|
||||
if (Z_LVAL_PP(cal) < 0 || Z_LVAL_PP(cal) >= CAL_NUM_CALS) {
|
||||
zend_error(E_WARNING, "%s(): invalid calendar ID %ld", get_active_function_name(TSRMLS_C), Z_LVAL_PP(cal));
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "ll", &jd, &cal) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
calendar = &cal_conversion_table[Z_LVAL_PP(cal)];
|
||||
|
||||
if (cal < 0 || cal >= CAL_NUM_CALS) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid calendar ID %ld", cal);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
calendar = &cal_conversion_table[cal];
|
||||
|
||||
array_init(return_value);
|
||||
|
||||
calendar->from_jd(
|
||||
Z_LVAL_PP(jd),
|
||||
&year, &month, &day);
|
||||
calendar->from_jd(jd, &year, &month, &day);
|
||||
|
||||
sprintf(date, "%i/%i/%i", month, day, year);
|
||||
add_assoc_string(return_value, "date", date, 1);
|
||||
|
||||
|
||||
add_assoc_long(return_value, "month", month);
|
||||
add_assoc_long(return_value, "day", day);
|
||||
add_assoc_long(return_value, "year", year);
|
||||
|
||||
/* day of week */
|
||||
dow = DayOfWeek(Z_LVAL_PP(jd));
|
||||
/* day of week */
|
||||
dow = DayOfWeek(jd);
|
||||
add_assoc_long(return_value, "dow", dow);
|
||||
add_assoc_string(return_value, "abbrevdayname", DayNameShort[dow], 1);
|
||||
add_assoc_string(return_value, "dayname", DayNameLong[dow], 1);
|
||||
/* month name */
|
||||
/* month name */
|
||||
add_assoc_string(return_value, "abbrevmonth", calendar->month_name_short[month], 1);
|
||||
add_assoc_string(return_value, "monthname", calendar->month_name_long[month], 1);
|
||||
}
|
||||
@@ -298,16 +326,15 @@ PHP_FUNCTION(cal_from_jd)
|
||||
Converts a julian day count to a gregorian calendar date */
|
||||
PHP_FUNCTION(jdtogregorian)
|
||||
{
|
||||
pval **julday;
|
||||
long julday;
|
||||
int year, month, day;
|
||||
char date[10];
|
||||
char date[16];
|
||||
|
||||
if (zend_get_parameters_ex(1, &julday) != SUCCESS) {
|
||||
WRONG_PARAM_COUNT;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &julday) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
convert_to_long_ex(julday);
|
||||
SdnToGregorian(Z_LVAL_PP(julday), &year, &month, &day);
|
||||
SdnToGregorian(julday, &year, &month, &day);
|
||||
sprintf(date, "%i/%i/%i", month, day, year);
|
||||
|
||||
RETURN_STRING(date, 1);
|
||||
@@ -318,37 +345,29 @@ PHP_FUNCTION(jdtogregorian)
|
||||
Converts a gregorian calendar date to julian day count */
|
||||
PHP_FUNCTION(gregoriantojd)
|
||||
{
|
||||
pval **year, **month, **day;
|
||||
int jdate;
|
||||
long year, month, day;
|
||||
|
||||
if (zend_get_parameters_ex(3, &month, &day, &year) != SUCCESS) {
|
||||
WRONG_PARAM_COUNT;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll", &month, &day, &year) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
convert_to_long_ex(month);
|
||||
convert_to_long_ex(day);
|
||||
convert_to_long_ex(year);
|
||||
|
||||
jdate = GregorianToSdn(Z_LVAL_PP(year), Z_LVAL_PP(month), Z_LVAL_PP(day));
|
||||
|
||||
RETURN_LONG(jdate);
|
||||
RETURN_LONG(GregorianToSdn(year, month, day));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto string jdtojulian(int juliandaycount)
|
||||
Convert a julian day count to a julian calendar date */
|
||||
PHP_FUNCTION(jdtojulian)
|
||||
PHP_FUNCTION(jdtojulian)
|
||||
{
|
||||
pval **julday;
|
||||
long julday;
|
||||
int year, month, day;
|
||||
char date[10];
|
||||
char date[16];
|
||||
|
||||
if (zend_get_parameters_ex(1, &julday) != SUCCESS) {
|
||||
WRONG_PARAM_COUNT;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &julday) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
convert_to_long_ex(julday);
|
||||
SdnToJulian(Z_LVAL_PP(julday), &year, &month, &day);
|
||||
SdnToJulian(julday, &year, &month, &day);
|
||||
sprintf(date, "%i/%i/%i", month, day, year);
|
||||
|
||||
RETURN_STRING(date, 1);
|
||||
@@ -359,137 +378,146 @@ PHP_FUNCTION(jdtojulian)
|
||||
Converts a julian calendar date to julian day count */
|
||||
PHP_FUNCTION(juliantojd)
|
||||
{
|
||||
pval **year, **month, **day;
|
||||
int jdate;
|
||||
long year, month, day;
|
||||
|
||||
if (zend_get_parameters_ex(3, &month, &day, &year) != SUCCESS) {
|
||||
WRONG_PARAM_COUNT;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll", &month, &day, &year) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
convert_to_long_ex(month);
|
||||
convert_to_long_ex(day);
|
||||
convert_to_long_ex(year);
|
||||
|
||||
jdate = JulianToSdn(Z_LVAL_PP(year), Z_LVAL_PP(month), Z_LVAL_PP(day));
|
||||
|
||||
RETURN_LONG(jdate);
|
||||
RETURN_LONG(JulianToSdn(year, month, day));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
caution: the hebrew format product non unique result.
|
||||
for example both: year '5' and year '5000' product 'ä'.
|
||||
use the numeric one for calculations.
|
||||
/* {{{ heb_number_to_chars*/
|
||||
/*
|
||||
caution: the Hebrew format produces non unique result.
|
||||
for example both: year '5' and year '5000' produce 'ä'.
|
||||
use the numeric one for calculations.
|
||||
*/
|
||||
static char* heb_number_to_chars(int n, char **ret)
|
||||
static char *heb_number_to_chars(int n, int fl, char **ret)
|
||||
{
|
||||
char *p, *old;
|
||||
char *p, old[18], *endofalafim;
|
||||
|
||||
p = emalloc(10);
|
||||
old = p;
|
||||
|
||||
/*
|
||||
prevents the option breaking the jewish beliefs, and some other
|
||||
critical resources ;)
|
||||
*/
|
||||
p = endofalafim = old;
|
||||
/*
|
||||
prevents the option breaking the jewish beliefs, and some other
|
||||
critical resources ;)
|
||||
*/
|
||||
if (n > 9999 || n < 1) {
|
||||
efree(old);
|
||||
*ret = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* alafim case */
|
||||
/* alafim (thousands) case */
|
||||
if (n / 1000) {
|
||||
*p = alef_bet[n / 1000];
|
||||
p++;
|
||||
|
||||
if (CAL_JEWISH_ADD_ALAFIM_GERESH & fl) {
|
||||
*p = '\'';
|
||||
p++;
|
||||
}
|
||||
if (CAL_JEWISH_ADD_ALAFIM & fl) {
|
||||
strcpy(p, " àìôéí ");
|
||||
p += 7;
|
||||
}
|
||||
|
||||
endofalafim = p;
|
||||
n = n % 1000;
|
||||
}
|
||||
|
||||
/* taf-taf case */
|
||||
/* tav-tav (tav=400) case */
|
||||
while (n >= 400) {
|
||||
*p = alef_bet[22];
|
||||
p++;
|
||||
n-=400;
|
||||
n -= 400;
|
||||
}
|
||||
|
||||
/* meot case */
|
||||
if (n >= 100) {
|
||||
*p = alef_bet[18+n/100];
|
||||
/* meot (hundreads) case */
|
||||
if (n >= 100) {
|
||||
*p = alef_bet[18 + n / 100];
|
||||
p++;
|
||||
n = n % 100;
|
||||
}
|
||||
|
||||
/* tet-vav tet-zain case */
|
||||
/* tet-vav & tet-zain case (special case for 15 and 16) */
|
||||
if (n == 15 || n == 16) {
|
||||
*p = alef_bet[9];
|
||||
p++;
|
||||
*p = alef_bet[n-9];
|
||||
*p = alef_bet[n - 9];
|
||||
p++;
|
||||
} else {
|
||||
/* asarot case */
|
||||
if (n >= 10) {
|
||||
*p = alef_bet[9+n/10];
|
||||
/* asarot (tens) case */
|
||||
if (n >= 10) {
|
||||
*p = alef_bet[9 + n / 10];
|
||||
p++;
|
||||
n = n % 10;
|
||||
}
|
||||
|
||||
/* yeihot case */
|
||||
/* yehidot (ones) case */
|
||||
if (n > 0) {
|
||||
*p = alef_bet[n];
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
if (CAL_JEWISH_ADD_GERESHAYIM & fl) {
|
||||
switch (p - endofalafim) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
*p = '\'';
|
||||
p++;
|
||||
break;
|
||||
default:
|
||||
*(p) = *(p - 1);
|
||||
*(p - 1) = '"';
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
*ret = estrndup(old, (p - old) + 1);
|
||||
p = *ret;
|
||||
efree(old);
|
||||
return p;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto string jdtojewish(int juliandaycount)
|
||||
/* {{{ proto string jdtojewish(int juliandaycount [, bool hebrew [, int fl]])
|
||||
Converts a julian day count to a jewish calendar date */
|
||||
PHP_FUNCTION(jdtojewish)
|
||||
PHP_FUNCTION(jdtojewish)
|
||||
{
|
||||
long julday, fl;
|
||||
long julday, fl = 0;
|
||||
zend_bool heb = 0;
|
||||
int year, month, day;
|
||||
char date[10], hebdate[25];
|
||||
char date[16], hebdate[25];
|
||||
char *dayp, *yearp;
|
||||
|
||||
if (ZEND_NUM_ARGS() == 1) {
|
||||
if (zend_parse_parameters(1 TSRMLS_CC,"l", &julday) != SUCCESS) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
fl=0;
|
||||
} else if (ZEND_NUM_ARGS() == 2) {
|
||||
if (zend_parse_parameters(2 TSRMLS_CC,"ll", &julday, &fl) != SUCCESS) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
} else {
|
||||
WRONG_PARAM_COUNT;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|bl", &julday, &heb, &fl) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SdnToJewish(julday, &year, &month, &day);
|
||||
if(!fl) {
|
||||
if (!heb) {
|
||||
sprintf(date, "%i/%i/%i", month, day, year);
|
||||
RETURN_STRING(date, 1);
|
||||
} else {
|
||||
if (year <= 0 || year > 9999) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Out of range year.");
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Year out of range (0-9999).");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
sprintf(hebdate, "%s %s %s", heb_number_to_chars(day, &dayp), JewishMonthHebName[month], heb_number_to_chars(year, &yearp));
|
||||
|
||||
|
||||
sprintf(hebdate, "%s %s %s", heb_number_to_chars(day, fl, &dayp), JewishMonthHebName[month], heb_number_to_chars(year, fl, &yearp));
|
||||
|
||||
if (dayp) {
|
||||
efree(dayp);
|
||||
}
|
||||
if (yearp) {
|
||||
efree(yearp);
|
||||
efree(yearp);
|
||||
}
|
||||
|
||||
RETURN_STRING(hebdate, 1);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@@ -498,20 +526,13 @@ PHP_FUNCTION(jdtojewish)
|
||||
Converts a jewish calendar date to a julian day count */
|
||||
PHP_FUNCTION(jewishtojd)
|
||||
{
|
||||
pval **year, **month, **day;
|
||||
int jdate;
|
||||
long year, month, day;
|
||||
|
||||
if (zend_get_parameters_ex(3, &month, &day, &year) != SUCCESS) {
|
||||
WRONG_PARAM_COUNT;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll", &month, &day, &year) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
convert_to_long_ex(month);
|
||||
convert_to_long_ex(day);
|
||||
convert_to_long_ex(year);
|
||||
|
||||
jdate = JewishToSdn(Z_LVAL_PP(year), Z_LVAL_PP(month), Z_LVAL_PP(day));
|
||||
|
||||
RETURN_LONG(jdate);
|
||||
RETURN_LONG(JewishToSdn(year, month, day));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -519,17 +540,15 @@ PHP_FUNCTION(jewishtojd)
|
||||
Converts a julian day count to a french republic calendar date */
|
||||
PHP_FUNCTION(jdtofrench)
|
||||
{
|
||||
pval **julday;
|
||||
long julday;
|
||||
int year, month, day;
|
||||
char date[10];
|
||||
char date[16];
|
||||
|
||||
if (zend_get_parameters_ex(1, &julday) != SUCCESS) {
|
||||
WRONG_PARAM_COUNT;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &julday) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
convert_to_long_ex(julday);
|
||||
|
||||
SdnToFrench(Z_LVAL_PP(julday), &year, &month, &day);
|
||||
SdnToFrench(julday, &year, &month, &day);
|
||||
sprintf(date, "%i/%i/%i", month, day, year);
|
||||
|
||||
RETURN_STRING(date, 1);
|
||||
@@ -540,20 +559,13 @@ PHP_FUNCTION(jdtofrench)
|
||||
Converts a french republic calendar date to julian day count */
|
||||
PHP_FUNCTION(frenchtojd)
|
||||
{
|
||||
pval **year, **month, **day;
|
||||
int jdate;
|
||||
long year, month, day;
|
||||
|
||||
if (zend_get_parameters_ex(3, &month, &day, &year) != SUCCESS) {
|
||||
WRONG_PARAM_COUNT;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll", &month, &day, &year) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
convert_to_long_ex(month);
|
||||
convert_to_long_ex(day);
|
||||
convert_to_long_ex(year);
|
||||
|
||||
jdate = FrenchToSdn(Z_LVAL_PP(year), Z_LVAL_PP(month), Z_LVAL_PP(day));
|
||||
|
||||
RETURN_LONG(jdate);
|
||||
RETURN_LONG(FrenchToSdn(year, month, day));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -561,37 +573,30 @@ PHP_FUNCTION(frenchtojd)
|
||||
Returns name or number of day of week from julian day count */
|
||||
PHP_FUNCTION(jddayofweek)
|
||||
{
|
||||
pval *julday, *mode;
|
||||
long julday, mode = CAL_DOW_DAYNO;
|
||||
int day;
|
||||
char *daynamel, *daynames;
|
||||
int myargc=ZEND_NUM_ARGS(), mymode=0;
|
||||
|
||||
if ((myargc < 1) || (myargc > 2) || (zend_get_parameters(ht, myargc, &julday, &mode) != SUCCESS)) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
|
||||
convert_to_long(julday);
|
||||
if(myargc==2) {
|
||||
convert_to_long(mode);
|
||||
mymode = Z_LVAL_P(mode);
|
||||
}
|
||||
|
||||
day = DayOfWeek(Z_LVAL_P(julday));
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &julday, &mode) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
day = DayOfWeek(julday);
|
||||
daynamel = DayNameLong[day];
|
||||
daynames = DayNameShort[day];
|
||||
|
||||
switch (mymode) {
|
||||
case CAL_DOW_SHORT:
|
||||
RETURN_STRING(daynamel, 1);
|
||||
break;
|
||||
case CAL_DOW_LONG:
|
||||
RETURN_STRING(daynames, 1);
|
||||
break;
|
||||
case CAL_DOW_DAYNO:
|
||||
default:
|
||||
RETURN_LONG(day);
|
||||
break;
|
||||
}
|
||||
switch (mode) {
|
||||
case CAL_DOW_SHORT:
|
||||
RETURN_STRING(daynamel, 1);
|
||||
break;
|
||||
case CAL_DOW_LONG:
|
||||
RETURN_STRING(daynames, 1);
|
||||
break;
|
||||
case CAL_DOW_DAYNO:
|
||||
default:
|
||||
RETURN_LONG(day);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -599,43 +604,40 @@ PHP_FUNCTION(jddayofweek)
|
||||
Returns name of month for julian day count */
|
||||
PHP_FUNCTION(jdmonthname)
|
||||
{
|
||||
pval **julday, **mode;
|
||||
long julday, mode;
|
||||
char *monthname = NULL;
|
||||
int month, day, year;
|
||||
|
||||
if (zend_get_parameters_ex(2, &julday, &mode) != SUCCESS) {
|
||||
WRONG_PARAM_COUNT;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &julday, &mode) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
convert_to_long_ex(julday);
|
||||
convert_to_long_ex(mode);
|
||||
|
||||
switch(Z_LVAL_PP(mode)) {
|
||||
case CAL_MONTH_GREGORIAN_LONG: /* gregorian or julian month */
|
||||
SdnToGregorian(Z_LVAL_PP(julday), &year, &month, &day);
|
||||
monthname = MonthNameLong[month];
|
||||
break;
|
||||
case CAL_MONTH_JULIAN_SHORT: /* gregorian or julian month */
|
||||
SdnToJulian(Z_LVAL_PP(julday), &year, &month, &day);
|
||||
monthname = MonthNameShort[month];
|
||||
break;
|
||||
case CAL_MONTH_JULIAN_LONG: /* gregorian or julian month */
|
||||
SdnToJulian(Z_LVAL_PP(julday), &year, &month, &day);
|
||||
monthname = MonthNameLong[month];
|
||||
break;
|
||||
case CAL_MONTH_JEWISH: /* jewish month */
|
||||
SdnToJewish(Z_LVAL_PP(julday), &year, &month, &day);
|
||||
monthname = JewishMonthName[month];
|
||||
break;
|
||||
case CAL_MONTH_FRENCH: /* french month */
|
||||
SdnToFrench(Z_LVAL_PP(julday), &year, &month, &day);
|
||||
monthname = FrenchMonthName[month];
|
||||
break;
|
||||
default: /* default gregorian */
|
||||
case CAL_MONTH_GREGORIAN_SHORT: /* gregorian or julian month */
|
||||
SdnToGregorian(Z_LVAL_PP(julday), &year, &month, &day);
|
||||
monthname = MonthNameShort[month];
|
||||
break;
|
||||
switch (mode) {
|
||||
case CAL_MONTH_GREGORIAN_LONG: /* gregorian or julian month */
|
||||
SdnToGregorian(julday, &year, &month, &day);
|
||||
monthname = MonthNameLong[month];
|
||||
break;
|
||||
case CAL_MONTH_JULIAN_SHORT: /* gregorian or julian month */
|
||||
SdnToJulian(julday, &year, &month, &day);
|
||||
monthname = MonthNameShort[month];
|
||||
break;
|
||||
case CAL_MONTH_JULIAN_LONG: /* gregorian or julian month */
|
||||
SdnToJulian(julday, &year, &month, &day);
|
||||
monthname = MonthNameLong[month];
|
||||
break;
|
||||
case CAL_MONTH_JEWISH: /* jewish month */
|
||||
SdnToJewish(julday, &year, &month, &day);
|
||||
monthname = JewishMonthName[month];
|
||||
break;
|
||||
case CAL_MONTH_FRENCH: /* french month */
|
||||
SdnToFrench(julday, &year, &month, &day);
|
||||
monthname = FrenchMonthName[month];
|
||||
break;
|
||||
default: /* default gregorian */
|
||||
case CAL_MONTH_GREGORIAN_SHORT: /* gregorian or julian month */
|
||||
SdnToGregorian(julday, &year, &month, &day);
|
||||
monthname = MonthNameShort[month];
|
||||
break;
|
||||
}
|
||||
|
||||
RETURN_STRING(monthname, 1);
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
|
||||
#include <packer.h>
|
||||
|
||||
#ifndef STRINGSIZE
|
||||
#define STRINGSIZE 1024
|
||||
#endif
|
||||
|
||||
extern char * FascistLook(PWDICT *pwp, char *instring);
|
||||
extern int PWClose(PWDICT *pwp);
|
||||
|
||||
|
||||
+25
-20
@@ -92,34 +92,39 @@ PHP_MINFO_FUNCTION(ctype)
|
||||
/* {{{ ctype
|
||||
*/
|
||||
#define CTYPE(iswhat) \
|
||||
zval *c; \
|
||||
zval *c, tmp; \
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &c) == FAILURE) \
|
||||
return; \
|
||||
switch (Z_TYPE_P(c)) { \
|
||||
case IS_LONG: \
|
||||
if (Z_TYPE_P(c) == IS_LONG) { \
|
||||
if (Z_LVAL_P(c) <= 255 && Z_LVAL_P(c) >= 0) { \
|
||||
RETURN_BOOL(iswhat(Z_LVAL_P(c))); \
|
||||
} else if (Z_LVAL_P(c) >= -128 && Z_LVAL_P(c) < 0) { \
|
||||
RETURN_BOOL(iswhat(Z_LVAL_P(c) + 256)); \
|
||||
} \
|
||||
SEPARATE_ZVAL(&c); \
|
||||
convert_to_string(c); \
|
||||
case IS_STRING: \
|
||||
{ \
|
||||
char *p; \
|
||||
int n, len; \
|
||||
p=Z_STRVAL_P(c); \
|
||||
len = Z_STRLEN_P(c); \
|
||||
for(n=0;n<len;n++) { \
|
||||
if(!iswhat((int)*(unsigned char *)(p++))) RETURN_FALSE; \
|
||||
} \
|
||||
RETURN_TRUE; \
|
||||
} \
|
||||
default: \
|
||||
break; \
|
||||
tmp = *c; \
|
||||
zval_copy_ctor(&tmp); \
|
||||
convert_to_string(&tmp); \
|
||||
} else { \
|
||||
tmp = *c; \
|
||||
} \
|
||||
RETURN_FALSE;
|
||||
|
||||
if (Z_TYPE(tmp) == IS_STRING) { \
|
||||
char *p = Z_STRVAL(tmp), *e = Z_STRVAL(tmp) + Z_STRLEN(tmp); \
|
||||
if (e == p) { \
|
||||
if (Z_TYPE_P(c) == IS_LONG) zval_dtor(&tmp); \
|
||||
RETURN_FALSE; \
|
||||
} \
|
||||
while (p < e) { \
|
||||
if(!iswhat((int)*(unsigned char *)(p++))) { \
|
||||
if (Z_TYPE_P(c) == IS_LONG) zval_dtor(&tmp); \
|
||||
RETURN_FALSE; \
|
||||
} \
|
||||
} \
|
||||
if (Z_TYPE_P(c) == IS_LONG) zval_dtor(&tmp); \
|
||||
RETURN_TRUE; \
|
||||
} else { \
|
||||
RETURN_FALSE; \
|
||||
} \
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool ctype_alnum(mixed c)
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
--TEST--
|
||||
Bug #34645 (ctype corrupts memory when validating large numbers)
|
||||
--FILE--
|
||||
<?php
|
||||
$id = 394829384;
|
||||
var_dump(ctype_digit($id));
|
||||
var_dump($id);
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
int(394829384)
|
||||
+24
-5
@@ -66,7 +66,7 @@ static void _php_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC);
|
||||
#define CAAZ(s, v) add_assoc_zval_ex(return_value, s, sizeof(s), (zval *) v);
|
||||
|
||||
#define PHP_CURL_CHECK_OPEN_BASEDIR(str, len) \
|
||||
if (PG(open_basedir) && *PG(open_basedir) && \
|
||||
if (((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) && \
|
||||
strncasecmp(str, "file://", sizeof("file://") - 1) == 0) \
|
||||
{ \
|
||||
php_url *tmp_url; \
|
||||
@@ -76,7 +76,7 @@ static void _php_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC);
|
||||
RETURN_FALSE; \
|
||||
} \
|
||||
\
|
||||
if (php_check_open_basedir(tmp_url->path TSRMLS_CC) || \
|
||||
if (tmp_url->query || php_check_open_basedir(tmp_url->path TSRMLS_CC) || \
|
||||
(PG(safe_mode) && !php_checkuid(tmp_url->path, "rb+", CHECKUID_CHECK_MODE_PARAM)) \
|
||||
) { \
|
||||
php_url_free(tmp_url); \
|
||||
@@ -436,10 +436,12 @@ static size_t curl_write(char *data, size_t size, size_t nmemb, void *ctx)
|
||||
zend_list_addref(ch->id);
|
||||
ZVAL_STRINGL(argv[1], data, length, 1);
|
||||
|
||||
ch->in_callback = 1;
|
||||
error = call_user_function(EG(function_table),
|
||||
NULL,
|
||||
t->func,
|
||||
retval, 2, argv TSRMLS_CC);
|
||||
ch->in_callback = 0;
|
||||
if (error == FAILURE) {
|
||||
php_error(E_WARNING, "%s(): Couldn't call the CURLOPT_WRITEFUNCTION",
|
||||
get_active_function_name(TSRMLS_C));
|
||||
@@ -495,10 +497,12 @@ static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx)
|
||||
zend_list_addref(t->fd);
|
||||
ZVAL_LONG(argv[2], (int) size * nmemb);
|
||||
|
||||
ch->in_callback = 1;
|
||||
error = call_user_function(EG(function_table),
|
||||
NULL,
|
||||
t->func,
|
||||
retval, 3, argv TSRMLS_CC);
|
||||
ch->in_callback = 0;
|
||||
if (error == FAILURE) {
|
||||
php_error(E_WARNING, "%s(): Cannot call the CURLOPT_READFUNCTION",
|
||||
get_active_function_name(TSRMLS_C));
|
||||
@@ -553,10 +557,12 @@ static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx
|
||||
zend_list_addref(ch->id);
|
||||
ZVAL_STRINGL(argv[1], data, length, 1);
|
||||
|
||||
ch->in_callback = 1;
|
||||
error = call_user_function(EG(function_table),
|
||||
NULL,
|
||||
t->func,
|
||||
retval, 2, argv TSRMLS_CC);
|
||||
ch->in_callback = 0;
|
||||
if (error == FAILURE) {
|
||||
php_error(E_WARNING, "%s(): Couldn't call the CURLOPT_HEADERFUNCTION",
|
||||
get_active_function_name(TSRMLS_C));
|
||||
@@ -606,10 +612,12 @@ static size_t curl_passwd(void *ctx, char *prompt, char *buf, int buflen)
|
||||
ZVAL_STRING(argv[1], prompt, 1);
|
||||
ZVAL_LONG(argv[2], buflen);
|
||||
|
||||
ch->in_callback = 1;
|
||||
error = call_user_function(EG(function_table),
|
||||
NULL,
|
||||
func,
|
||||
retval, 2, argv TSRMLS_CC);
|
||||
ch->in_callback = 0;
|
||||
if (error == FAILURE) {
|
||||
php_error(E_WARNING, "%s(): Couldn't call the CURLOPT_PASSWDFUNCTION", get_active_function_name(TSRMLS_C));
|
||||
} else if (Z_TYPE_P(retval) == IS_STRING) {
|
||||
@@ -680,7 +688,9 @@ static void alloc_curl_handle(php_curl **ch)
|
||||
(*ch)->handlers->write_header = ecalloc(1, sizeof(php_curl_write));
|
||||
(*ch)->handlers->read = ecalloc(1, sizeof(php_curl_read));
|
||||
memset(&(*ch)->err, 0, sizeof((*ch)->err));
|
||||
|
||||
|
||||
(*ch)->in_callback = 0;
|
||||
|
||||
zend_llist_init(&(*ch)->to_free.str, sizeof(char *),
|
||||
(void(*)(void *)) curl_free_string, 0);
|
||||
zend_llist_init(&(*ch)->to_free.slist, sizeof(struct curl_slist),
|
||||
@@ -982,10 +992,15 @@ PHP_FUNCTION(curl_setopt)
|
||||
|
||||
postval = Z_STRVAL_PP(current);
|
||||
if (*postval == '@') {
|
||||
++postval;
|
||||
/* safe_mode / open_basedir check */
|
||||
if (php_check_open_basedir(postval TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(postval, "rb+", CHECKUID_CHECK_MODE_PARAM))) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
error = curl_formadd(&first, &last,
|
||||
CURLFORM_COPYNAME, string_key,
|
||||
CURLFORM_NAMELENGTH, (long)string_key_len - 1,
|
||||
CURLFORM_FILE, ++postval,
|
||||
CURLFORM_FILE, postval,
|
||||
CURLFORM_END);
|
||||
}
|
||||
else {
|
||||
@@ -1337,7 +1352,11 @@ PHP_FUNCTION(curl_close)
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
ZEND_FETCH_RESOURCE(ch, php_curl *, zid, -1, le_curl_name, le_curl);
|
||||
|
||||
|
||||
if (ch->in_callback) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempt to close CURL handle from a callback");
|
||||
return;
|
||||
}
|
||||
zend_list_delete(Z_LVAL_PP(zid));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -93,6 +93,7 @@ typedef struct {
|
||||
struct _php_curl_free to_free;
|
||||
long id;
|
||||
unsigned int uses;
|
||||
zend_bool in_callback;
|
||||
} php_curl;
|
||||
|
||||
/* streams support */
|
||||
|
||||
+1
-1
@@ -223,7 +223,7 @@ AC_ARG_WITH(db4,
|
||||
break
|
||||
fi
|
||||
done
|
||||
PHP_DBA_DB_CHECK(4, db-4.2 db-4.1 db-4.0 db-4 db4 db, [(void)db_create((DB**)0, (DB_ENV*)0, 0)])
|
||||
PHP_DBA_DB_CHECK(4, db-4.3 db-4.2 db-4.1 db-4.0 db-4 db4 db, [(void)db_create((DB**)0, (DB_ENV*)0, 0)])
|
||||
fi
|
||||
])
|
||||
AC_DBA_STD_RESULT(db4,Berkeley DB4)
|
||||
|
||||
+102
-112
@@ -118,33 +118,33 @@ static PHP_MSHUTDOWN_FUNCTION(dbase)
|
||||
Opens a dBase-format database file */
|
||||
PHP_FUNCTION(dbase_open)
|
||||
{
|
||||
pval *dbf_name, *options;
|
||||
zval **dbf_name, **options;
|
||||
dbhead_t *dbh;
|
||||
int handle;
|
||||
DBase_TLS_VARS;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 2 || getParameters(ht, 2, &dbf_name, &options)==FAILURE) {
|
||||
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &dbf_name, &options) == FAILURE) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
convert_to_string(dbf_name);
|
||||
convert_to_long(options);
|
||||
convert_to_string_ex(dbf_name);
|
||||
convert_to_long_ex(options);
|
||||
|
||||
if (Z_LVAL_P(options) == 1) {
|
||||
php_error(E_WARNING, "Cannot open %s in write-only mode", Z_STRVAL_P(dbf_name));
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (PG(safe_mode) && (!php_checkuid(Z_STRVAL_P(dbf_name), NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (php_check_open_basedir(Z_STRVAL_P(dbf_name) TSRMLS_CC)) {
|
||||
if (Z_LVAL_PP(options) == 1) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot open %s in write-only mode", Z_STRVAL_PP(dbf_name));
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
dbh = dbf_open(Z_STRVAL_P(dbf_name), Z_LVAL_P(options) TSRMLS_CC);
|
||||
if (PG(safe_mode) && (!php_checkuid(Z_STRVAL_PP(dbf_name), NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (php_check_open_basedir(Z_STRVAL_PP(dbf_name) TSRMLS_CC)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
dbh = dbf_open(Z_STRVAL_PP(dbf_name), Z_LVAL_PP(options) TSRMLS_CC);
|
||||
if (dbh == NULL) {
|
||||
php_error(E_WARNING, "unable to open database %s", Z_STRVAL_P(dbf_name));
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to open database %s", Z_STRVAL_PP(dbf_name));
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -157,22 +157,22 @@ PHP_FUNCTION(dbase_open)
|
||||
Closes an open dBase-format database file */
|
||||
PHP_FUNCTION(dbase_close)
|
||||
{
|
||||
pval *dbh_id;
|
||||
zval **dbh_id;
|
||||
dbhead_t *dbh;
|
||||
int dbh_type;
|
||||
DBase_TLS_VARS;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 1 || getParameters(ht, 1, &dbh_id)==FAILURE) {
|
||||
if (ZEND_NUM_ARGS() != 1 || (zend_get_parameters_ex(1, &dbh_id) == FAILURE)) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
convert_to_long(dbh_id);
|
||||
dbh = zend_list_find(Z_LVAL_P(dbh_id), &dbh_type);
|
||||
convert_to_long_ex(dbh_id);
|
||||
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
|
||||
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
|
||||
php_error(E_WARNING, "Unable to find database for identifier %d", Z_LVAL_P(dbh_id));
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
zend_list_delete(Z_LVAL_P(dbh_id));
|
||||
zend_list_delete(Z_LVAL_PP(dbh_id));
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -181,18 +181,18 @@ PHP_FUNCTION(dbase_close)
|
||||
Returns the number of records in the database */
|
||||
PHP_FUNCTION(dbase_numrecords)
|
||||
{
|
||||
pval *dbh_id;
|
||||
zval **dbh_id;
|
||||
dbhead_t *dbh;
|
||||
int dbh_type;
|
||||
DBase_TLS_VARS;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 1 || getParameters(ht, 1, &dbh_id)==FAILURE) {
|
||||
if (ZEND_NUM_ARGS() != 1 || (zend_get_parameters_ex(1, &dbh_id) == FAILURE)) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
convert_to_long(dbh_id);
|
||||
dbh = zend_list_find(Z_LVAL_P(dbh_id), &dbh_type);
|
||||
convert_to_long_ex(dbh_id);
|
||||
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
|
||||
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
|
||||
php_error(E_WARNING, "Unable to find database for identifier %d", Z_LVAL_P(dbh_id));
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -204,18 +204,18 @@ PHP_FUNCTION(dbase_numrecords)
|
||||
Returns the number of fields (columns) in the database */
|
||||
PHP_FUNCTION(dbase_numfields)
|
||||
{
|
||||
pval *dbh_id;
|
||||
zval **dbh_id;
|
||||
dbhead_t *dbh;
|
||||
int dbh_type;
|
||||
DBase_TLS_VARS;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 1 || getParameters(ht, 1, &dbh_id)==FAILURE) {
|
||||
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &dbh_id) == FAILURE) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
convert_to_long(dbh_id);
|
||||
dbh = zend_list_find(Z_LVAL_P(dbh_id), &dbh_type);
|
||||
convert_to_long_ex(dbh_id);
|
||||
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
|
||||
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
|
||||
php_error(E_WARNING, "Unable to find database for identifier %d", Z_LVAL_P(dbh_id));
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -227,18 +227,18 @@ PHP_FUNCTION(dbase_numfields)
|
||||
Packs the database (deletes records marked for deletion) */
|
||||
PHP_FUNCTION(dbase_pack)
|
||||
{
|
||||
pval *dbh_id;
|
||||
zval **dbh_id;
|
||||
dbhead_t *dbh;
|
||||
int dbh_type;
|
||||
DBase_TLS_VARS;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 1 || getParameters(ht, 1, &dbh_id)==FAILURE) {
|
||||
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &dbh_id) == FAILURE) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
convert_to_long(dbh_id);
|
||||
dbh = zend_list_find(Z_LVAL_P(dbh_id), &dbh_type);
|
||||
convert_to_long_ex(dbh_id);
|
||||
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
|
||||
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
|
||||
php_error(E_WARNING, "Unable to find database for identifier %d", Z_LVAL_P(dbh_id));
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -252,7 +252,7 @@ PHP_FUNCTION(dbase_pack)
|
||||
Adds a record to the database */
|
||||
PHP_FUNCTION(dbase_add_record)
|
||||
{
|
||||
pval *dbh_id, *fields, **field;
|
||||
zval **dbh_id, **fields, **field;
|
||||
dbhead_t *dbh;
|
||||
int dbh_type;
|
||||
|
||||
@@ -262,40 +262,36 @@ PHP_FUNCTION(dbase_add_record)
|
||||
int i;
|
||||
DBase_TLS_VARS;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 2 || getParameters(ht, 2, &dbh_id, &fields)==FAILURE) {
|
||||
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &dbh_id, &fields) == FAILURE) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
convert_to_long(dbh_id);
|
||||
if (Z_TYPE_P(fields) != IS_ARRAY) {
|
||||
php_error(E_WARNING, "Expected array as second parameter");
|
||||
convert_to_long_ex(dbh_id);
|
||||
if (Z_TYPE_PP(fields) != IS_ARRAY) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected array as second parameter");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
dbh = zend_list_find(Z_LVAL_P(dbh_id), &dbh_type);
|
||||
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
|
||||
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
|
||||
php_error(E_WARNING, "Unable to find database for identifier %d", Z_LVAL_P(dbh_id));
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
num_fields = zend_hash_num_elements(Z_ARRVAL_P(fields));
|
||||
num_fields = zend_hash_num_elements(Z_ARRVAL_PP(fields));
|
||||
|
||||
if (num_fields != dbh->db_nfields) {
|
||||
php_error(E_WARNING, "Wrong number of fields specified");
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong number of fields specified");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
cp = t_cp = (char *)emalloc(dbh->db_rlen + 1);
|
||||
if (!cp) {
|
||||
php_error(E_WARNING, "unable to allocate memory");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
*t_cp++ = VALID_RECORD;
|
||||
|
||||
dbf = dbh->db_fields;
|
||||
for (i = 0, cur_f = dbf; cur_f < &dbf[num_fields]; i++, cur_f++) {
|
||||
zval tmp;
|
||||
if (zend_hash_index_find(Z_ARRVAL_P(fields), i, (void **)&field) == FAILURE) {
|
||||
php_error(E_WARNING, "unexpected error");
|
||||
if (zend_hash_index_find(Z_ARRVAL_PP(fields), i, (void **)&field) == FAILURE) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unexpected error");
|
||||
efree(cp);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@@ -310,7 +306,7 @@ PHP_FUNCTION(dbase_add_record)
|
||||
|
||||
dbh->db_records++;
|
||||
if (put_dbf_record(dbh, dbh->db_records, cp) < 0) {
|
||||
php_error(E_WARNING, "unable to put record at %ld", dbh->db_records);
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to put record at %ld", dbh->db_records);
|
||||
efree(cp);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@@ -326,7 +322,7 @@ PHP_FUNCTION(dbase_add_record)
|
||||
Replaces a record to the database */
|
||||
PHP_FUNCTION(dbase_replace_record)
|
||||
{
|
||||
pval *dbh_id, *fields, **field, *recnum;
|
||||
zval **dbh_id, **fields, **field, **recnum;
|
||||
dbhead_t *dbh;
|
||||
int dbh_type;
|
||||
|
||||
@@ -336,40 +332,36 @@ PHP_FUNCTION(dbase_replace_record)
|
||||
int i;
|
||||
DBase_TLS_VARS;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 3 || getParameters(ht, 3, &dbh_id, &fields, &recnum)==FAILURE) {
|
||||
if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &dbh_id, &fields, &recnum) == FAILURE) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
convert_to_long(dbh_id);
|
||||
convert_to_long(recnum);
|
||||
if (Z_TYPE_P(fields) != IS_ARRAY) {
|
||||
php_error(E_WARNING, "Expected array as second parameter");
|
||||
convert_to_long_ex(dbh_id);
|
||||
convert_to_long_ex(recnum);
|
||||
if (Z_TYPE_PP(fields) != IS_ARRAY) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected array as second parameter");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
dbh = zend_list_find(Z_LVAL_P(dbh_id), &dbh_type);
|
||||
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
|
||||
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
|
||||
php_error(E_WARNING, "Unable to find database for identifier %d", Z_LVAL_P(dbh_id));
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
num_fields = zend_hash_num_elements(Z_ARRVAL_P(fields));
|
||||
num_fields = zend_hash_num_elements(Z_ARRVAL_PP(fields));
|
||||
|
||||
if (num_fields != dbh->db_nfields) {
|
||||
php_error(E_WARNING, "Wrong number of fields specified");
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong number of fields specified");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
cp = t_cp = (char *)emalloc(dbh->db_rlen + 1);
|
||||
if (!cp) {
|
||||
php_error(E_WARNING, "unable to allocate memory");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
*t_cp++ = VALID_RECORD;
|
||||
|
||||
dbf = dbh->db_fields;
|
||||
for (i = 0, cur_f = dbf; cur_f < &dbf[num_fields]; i++, cur_f++) {
|
||||
if (zend_hash_index_find(Z_ARRVAL_P(fields), i, (void **)&field) == FAILURE) {
|
||||
php_error(E_WARNING, "unexpected error");
|
||||
if (zend_hash_index_find(Z_ARRVAL_PP(fields), i, (void **)&field) == FAILURE) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unexpected error");
|
||||
efree(cp);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@@ -378,8 +370,8 @@ PHP_FUNCTION(dbase_replace_record)
|
||||
t_cp += cur_f->db_flen;
|
||||
}
|
||||
|
||||
if (put_dbf_record(dbh, Z_LVAL_P(recnum), cp) < 0) {
|
||||
php_error(E_WARNING, "unable to put record at %ld", dbh->db_records);
|
||||
if (put_dbf_record(dbh, Z_LVAL_PP(recnum), cp) < 0) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to put record at %ld", dbh->db_records);
|
||||
efree(cp);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@@ -395,28 +387,28 @@ PHP_FUNCTION(dbase_replace_record)
|
||||
Marks a record to be deleted */
|
||||
PHP_FUNCTION(dbase_delete_record)
|
||||
{
|
||||
pval *dbh_id, *record;
|
||||
zval **dbh_id, **record;
|
||||
dbhead_t *dbh;
|
||||
int dbh_type;
|
||||
DBase_TLS_VARS;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 2 || getParameters(ht, 2, &dbh_id, &record)==FAILURE) {
|
||||
if (ZEND_NUM_ARGS() != 2 || (zend_get_parameters_ex(2, &dbh_id, &record) == FAILURE)) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
convert_to_long(dbh_id);
|
||||
convert_to_long(record);
|
||||
convert_to_long_ex(dbh_id);
|
||||
convert_to_long_ex(record);
|
||||
|
||||
dbh = zend_list_find(Z_LVAL_P(dbh_id), &dbh_type);
|
||||
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
|
||||
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
|
||||
php_error(E_WARNING, "Unable to find database for identifier %d", Z_LVAL_P(dbh_id));
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (del_dbf_record(dbh, Z_LVAL_P(record)) < 0) {
|
||||
if (Z_LVAL_P(record) > dbh->db_records) {
|
||||
php_error(E_WARNING, "record %d out of bounds", Z_LVAL_P(record));
|
||||
if (del_dbf_record(dbh, Z_LVAL_PP(record)) < 0) {
|
||||
if (Z_LVAL_PP(record) > dbh->db_records) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "record %ld out of bounds", Z_LVAL_PP(record));
|
||||
} else {
|
||||
php_error(E_WARNING, "unable to delete record %d", Z_LVAL_P(record));
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to delete record %ld", Z_LVAL_PP(record));
|
||||
}
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@@ -430,7 +422,7 @@ PHP_FUNCTION(dbase_delete_record)
|
||||
*/
|
||||
static void php_dbase_get_record(INTERNAL_FUNCTION_PARAMETERS, int assoc)
|
||||
{
|
||||
pval *dbh_id, *record;
|
||||
zval **dbh_id, **record;
|
||||
dbhead_t *dbh;
|
||||
int dbh_type;
|
||||
dbfield_t *dbf, *cur_f;
|
||||
@@ -440,28 +432,26 @@ static void php_dbase_get_record(INTERNAL_FUNCTION_PARAMETERS, int assoc)
|
||||
int errno_save;
|
||||
DBase_TLS_VARS;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 2 || getParameters(ht, 2, &dbh_id, &record)==FAILURE) {
|
||||
if (ZEND_NUM_ARGS() != 2 || (zend_get_parameters_ex(2, &dbh_id, &record) == FAILURE)) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
convert_to_long(dbh_id);
|
||||
convert_to_long(record);
|
||||
convert_to_long_ex(dbh_id);
|
||||
convert_to_long_ex(record);
|
||||
|
||||
dbh = zend_list_find(Z_LVAL_P(dbh_id), &dbh_type);
|
||||
dbh = zend_list_find(Z_LVAL_PP(dbh_id), &dbh_type);
|
||||
if (!dbh || dbh_type != DBase_GLOBAL(le_dbhead)) {
|
||||
php_error(E_WARNING, "Unable to find database for identifier %d", Z_LVAL_P(dbh_id));
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find database for identifier %ld", Z_LVAL_PP(dbh_id));
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if ((data = get_dbf_record(dbh, Z_LVAL_P(record))) == NULL) {
|
||||
php_error(E_WARNING, "Tried to read bad record %d", Z_LVAL_P(record));
|
||||
if ((data = get_dbf_record(dbh, Z_LVAL_PP(record))) == NULL) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Tried to read bad record %ld", Z_LVAL_PP(record));
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
dbf = dbh->db_fields;
|
||||
|
||||
if (array_init(return_value) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
array_init(return_value);
|
||||
|
||||
fnp = NULL;
|
||||
for (cur_f = dbf; cur_f < &dbf[dbh->db_nfields]; cur_f++) {
|
||||
@@ -582,7 +572,7 @@ PHP_FUNCTION(dbase_get_record_with_names)
|
||||
Creates a new dBase-format database file */
|
||||
PHP_FUNCTION(dbase_create)
|
||||
{
|
||||
pval *filename, *fields, **field, **value;
|
||||
zval **filename, **fields, **field, **value;
|
||||
int fd;
|
||||
dbhead_t *dbh;
|
||||
|
||||
@@ -591,37 +581,37 @@ PHP_FUNCTION(dbase_create)
|
||||
int i, rlen, handle;
|
||||
DBase_TLS_VARS;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 2 || getParameters(ht, 2, &filename, &fields)==FAILURE) {
|
||||
if (ZEND_NUM_ARGS() != 2 || (zend_get_parameters_ex(2, &filename, &fields) == FAILURE)) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
convert_to_string(filename);
|
||||
convert_to_string_ex(filename);
|
||||
|
||||
if (Z_TYPE_P(fields) != IS_ARRAY) {
|
||||
php_error(E_WARNING, "Expected array as second parameter");
|
||||
if (Z_TYPE_PP(fields) != IS_ARRAY) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected array as second parameter");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (PG(safe_mode) && (!php_checkuid(Z_STRVAL_P(filename), NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
|
||||
if (PG(safe_mode) && (!php_checkuid(Z_STRVAL_PP(filename), NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (php_check_open_basedir(Z_STRVAL_P(filename) TSRMLS_CC)) {
|
||||
if (php_check_open_basedir(Z_STRVAL_PP(filename) TSRMLS_CC)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if ((fd = VCWD_OPEN_MODE(Z_STRVAL_P(filename), O_BINARY|O_RDWR|O_CREAT, 0644)) < 0) {
|
||||
php_error(E_WARNING, "Unable to create database (%d): %s", errno, strerror(errno));
|
||||
if ((fd = VCWD_OPEN_MODE(Z_STRVAL_PP(filename), O_BINARY|O_RDWR|O_CREAT, 0644)) < 0) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create database (%d): %s", errno, strerror(errno));
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
num_fields = zend_hash_num_elements(Z_ARRVAL_P(fields));
|
||||
num_fields = zend_hash_num_elements(Z_ARRVAL_PP(fields));
|
||||
|
||||
/* have to use regular malloc() because this gets free()d by
|
||||
code in the dbase library */
|
||||
dbh = (dbhead_t *)malloc(sizeof(dbhead_t));
|
||||
dbf = (dbfield_t *)malloc(sizeof(dbfield_t) * num_fields);
|
||||
if (!dbh || !dbf) {
|
||||
php_error(E_WARNING, "Unable to allocate memory for header info");
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to allocate memory for header info");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -651,27 +641,27 @@ PHP_FUNCTION(dbase_create)
|
||||
|
||||
for (i = 0, cur_f = dbf; i < num_fields; i++, cur_f++) {
|
||||
/* look up the first field */
|
||||
if (zend_hash_index_find(Z_ARRVAL_P(fields), i, (void **)&field) == FAILURE) {
|
||||
php_error(E_WARNING, "unable to find field %d", i);
|
||||
if (zend_hash_index_find(Z_ARRVAL_PP(fields), i, (void **)&field) == FAILURE) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to find field %d", i);
|
||||
free_dbf_head(dbh);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (Z_TYPE_PP (field) != IS_ARRAY) {
|
||||
php_error(E_WARNING, "second parameter must be array of arrays");
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "second parameter must be array of arrays");
|
||||
free_dbf_head(dbh);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
/* field name */
|
||||
if (zend_hash_index_find(Z_ARRVAL_PP(field), 0, (void **)&value) == FAILURE) {
|
||||
php_error(E_WARNING, "expected field name as first element of list in field %d", i);
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "expected field name as first element of list in field %d", i);
|
||||
free_dbf_head(dbh);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
convert_to_string_ex(value);
|
||||
if (Z_STRLEN_PP(value) > 10 || Z_STRLEN_PP(value) == 0) {
|
||||
php_error(E_WARNING, "invalid field name '%s' (must be non-empty and less than or equal to 10 characters)", Z_STRVAL_PP(value));
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid field name '%s' (must be non-empty and less than or equal to 10 characters)", Z_STRVAL_PP(value));
|
||||
free_dbf_head(dbh);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@@ -679,7 +669,7 @@ PHP_FUNCTION(dbase_create)
|
||||
|
||||
/* field type */
|
||||
if (zend_hash_index_find(Z_ARRVAL_PP (field), 1, (void **)&value) == FAILURE) {
|
||||
php_error(E_WARNING, "expected field type as second element of list in field %d", i);
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "expected field type as second element of list in field %d", i);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
convert_to_string_ex(value);
|
||||
@@ -704,7 +694,7 @@ PHP_FUNCTION(dbase_create)
|
||||
case 'C':
|
||||
/* field length */
|
||||
if (zend_hash_index_find(Z_ARRVAL_PP (field), 2, (void **)&value) == FAILURE) {
|
||||
php_error(E_WARNING, "expected field length as third element of list in field %d", i);
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "expected field length as third element of list in field %d", i);
|
||||
free_dbf_head(dbh);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@@ -713,7 +703,7 @@ PHP_FUNCTION(dbase_create)
|
||||
|
||||
if (cur_f->db_type == 'N') {
|
||||
if (zend_hash_index_find(Z_ARRVAL_PP (field), 3, (void **)&value) == FAILURE) {
|
||||
php_error(E_WARNING, "expected field precision as fourth element of list in field %d", i);
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "expected field precision as fourth element of list in field %d", i);
|
||||
free_dbf_head(dbh);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@@ -722,7 +712,7 @@ PHP_FUNCTION(dbase_create)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
php_error(E_WARNING, "unknown field type '%c'", cur_f->db_type);
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unknown field type '%c'", cur_f->db_type);
|
||||
}
|
||||
cur_f->db_foffset = rlen;
|
||||
rlen += cur_f->db_flen;
|
||||
|
||||
+10
-9
@@ -136,7 +136,8 @@ void pack_dbf(dbhead_t *dbh)
|
||||
|
||||
/* Try to truncate the file to the right size. */
|
||||
if (ftruncate(dbh->db_fd, out_off) != 0) {
|
||||
php_error(E_WARNING, "dbase_pack() couldn't truncate the file to the right size. Some deleted records may still be left in there.");
|
||||
TSRMLS_FETCH();
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "dbase_pack() couldn't truncate the file to the right size. Some deleted records may still be left in there.");
|
||||
}
|
||||
|
||||
if (rec_cnt == 0)
|
||||
@@ -167,16 +168,16 @@ void put_field_val(char *rp, dbfield_t *fldp, char *cp)
|
||||
*/
|
||||
void out_rec(dbhead_t *dbh, dbfield_t *dbf, char *cp)
|
||||
{
|
||||
dbfield_t *cur_f;
|
||||
int nfields = dbh->db_nfields;
|
||||
char *fnp = (char *)malloc(dbh->db_rlen);
|
||||
dbfield_t *cur_f;
|
||||
int nfields = dbh->db_nfields;
|
||||
char *fnp = (char *)malloc(dbh->db_rlen);
|
||||
|
||||
printf("%c", *cp);
|
||||
for (cur_f = dbf; cur_f < &dbf[nfields] ; cur_f++) {
|
||||
printf(" ");
|
||||
printf("%c", *cp);
|
||||
for (cur_f = dbf; cur_f < &dbf[nfields] ; cur_f++) {
|
||||
printf(" ");
|
||||
printf(cur_f->db_format, get_field_val(cp, cur_f, fnp));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
free(fnp);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
--TEST--
|
||||
Bug #31754: (dbase_open() fails for mode = 1)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('dbase')) {
|
||||
die('skip dbase extension not available');
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
// database "definition"
|
||||
$def = array(
|
||||
array("foo", "L")
|
||||
);
|
||||
|
||||
// creation
|
||||
$dbh = dbase_create('/tmp/bug31754.dbf', array(array('foo', 'L')));
|
||||
dbase_close($dbh);
|
||||
|
||||
$dbh = dbase_open('/tmp/bug31754.dbf', 1);
|
||||
unlink('/tmp/bug31754.dbf');
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: dbase_open(): Cannot open /tmp/bug31754.dbf in write-only mode in %sbug31754.php on line %d
|
||||
+37
-6
@@ -33,6 +33,8 @@ typedef struct {
|
||||
int cflags;
|
||||
} reg_cache;
|
||||
|
||||
static int reg_magic = 0;
|
||||
|
||||
/* {{{ _php_regcomp
|
||||
*/
|
||||
static int _php_regcomp(regex_t *preg, const char *pattern, int cflags)
|
||||
@@ -42,8 +44,39 @@ static int _php_regcomp(regex_t *preg, const char *pattern, int cflags)
|
||||
reg_cache *rc = NULL;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if(zend_hash_find(®(ht_rc), (char *) pattern, patlen+1, (void **) &rc) == FAILURE ||
|
||||
rc->cflags != cflags) {
|
||||
if(zend_hash_find(®(ht_rc), (char *) pattern, patlen+1, (void **) &rc) == SUCCESS
|
||||
&& rc->cflags == cflags) {
|
||||
#ifdef HAVE_REGEX_T_RE_MAGIC
|
||||
/*
|
||||
* We use a saved magic number to see whether cache is corrupted, and if it
|
||||
* is, we flush it and compile the pattern from scratch.
|
||||
*/
|
||||
if (rc->preg.re_magic != reg_magic) {
|
||||
zend_hash_clean(®(ht_rc));
|
||||
} else {
|
||||
memcpy(preg, &rc->preg, sizeof(*preg));
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
r = regcomp(preg, pattern, cflags);
|
||||
if(!r) {
|
||||
reg_cache rcp;
|
||||
|
||||
rcp.cflags = cflags;
|
||||
memcpy(&rcp.preg, preg, sizeof(*preg));
|
||||
/*
|
||||
* Since we don't have access to the actual MAGIC1 definition in the private
|
||||
* header file, we save the magic value immediately after compilation. Hopefully,
|
||||
* it's good.
|
||||
*/
|
||||
if (!reg_magic) reg_magic = preg->re_magic;
|
||||
zend_hash_update(®(ht_rc), (char *) pattern, patlen+1,
|
||||
(void *) &rcp, sizeof(rcp), NULL);
|
||||
}
|
||||
#else
|
||||
memcpy(preg, &rc->preg, sizeof(*preg));
|
||||
} else {
|
||||
r = regcomp(preg, pattern, cflags);
|
||||
if(!r) {
|
||||
reg_cache rcp;
|
||||
@@ -51,12 +84,10 @@ static int _php_regcomp(regex_t *preg, const char *pattern, int cflags)
|
||||
rcp.cflags = cflags;
|
||||
memcpy(&rcp.preg, preg, sizeof(*preg));
|
||||
zend_hash_update(®(ht_rc), (char *) pattern, patlen+1,
|
||||
(void *) &rcp, sizeof(rcp), NULL);
|
||||
(void *) &rcp, sizeof(rcp), NULL);
|
||||
}
|
||||
} else {
|
||||
memcpy(preg, &rc->preg, sizeof(*preg));
|
||||
}
|
||||
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -3013,6 +3013,12 @@ static int exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *dir_start,
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Ignore IFD2 if it purportedly exists
|
||||
*/
|
||||
if (section_index == SECTION_THUMBNAIL) {
|
||||
return TRUE;
|
||||
}
|
||||
/*
|
||||
* Hack to make it process IDF1 I hope
|
||||
* There are 2 IDFs, the second one holds the keys (0x0201 and 0x0202) to the thumbnail
|
||||
@@ -3722,7 +3728,11 @@ static int exif_read_file(image_info_type *ImageInfo, char *FileName, int read_t
|
||||
if (php_stream_is(ImageInfo->infile, PHP_STREAM_IS_STDIO)) {
|
||||
if (VCWD_STAT(FileName, &st) >= 0) {
|
||||
/* Store file date/time. */
|
||||
#ifdef NETWARE
|
||||
ImageInfo->FileDateTime = st.st_mtime.tv_sec;
|
||||
#else
|
||||
ImageInfo->FileDateTime = st.st_mtime;
|
||||
#endif
|
||||
ImageInfo->FileSize = st.st_size;
|
||||
/*exif_error_docref(NULL TSRMLS_CC, ImageInfo, E_NOTICE, "open stream is file: %d", ImageInfo->FileSize);*/
|
||||
}
|
||||
|
||||
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 9.7 KiB |
Executable
+43
@@ -0,0 +1,43 @@
|
||||
--TEST--
|
||||
Bug #34704 (Infinite recursion due to corrupt JPEG)
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
|
||||
--INI--
|
||||
magic_quotes_runtime=0
|
||||
output_handler=
|
||||
zlib.output_compression=0
|
||||
--FILE--
|
||||
<?php
|
||||
$infile = dirname(__FILE__).'/bug34704.jpg';
|
||||
var_dump(exif_read_data($infile));
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
array(7) {
|
||||
["FileName"]=>
|
||||
string(12) "bug34704.jpg"
|
||||
["FileDateTime"]=>
|
||||
int(%d)
|
||||
["FileSize"]=>
|
||||
int(9976)
|
||||
["FileType"]=>
|
||||
int(2)
|
||||
["MimeType"]=>
|
||||
string(10) "image/jpeg"
|
||||
["SectionsFound"]=>
|
||||
string(4) "IFD0"
|
||||
["COMPUTED"]=>
|
||||
array(5) {
|
||||
["html"]=>
|
||||
string(24) "width="386" height="488""
|
||||
["Height"]=>
|
||||
int(488)
|
||||
["Width"]=>
|
||||
int(386)
|
||||
["IsColor"]=>
|
||||
int(1)
|
||||
["ByteOrderMotorola"]=>
|
||||
int(0)
|
||||
}
|
||||
}
|
||||
===DONE===
|
||||
@@ -311,6 +311,7 @@ dnl These are always available with bundled library
|
||||
AC_DEFINE(HAVE_GD_IMAGEELLIPSE, 1, [ ])
|
||||
AC_DEFINE(HAVE_GD_FONTCACHESHUTDOWN,1, [ ])
|
||||
AC_DEFINE(HAVE_GD_DYNAMIC_CTX_EX, 1, [ ])
|
||||
AC_DEFINE(HAVE_GD_GIF_CTX, 1, [ ])
|
||||
|
||||
dnl Make sure the libgd/ is first in the include path
|
||||
GDLIB_CFLAGS="-DHAVE_LIBPNG"
|
||||
|
||||
+4
-3
@@ -1644,7 +1644,7 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char
|
||||
}
|
||||
|
||||
if ((argc == 2) || (argc > 2 && Z_STRLEN_PP(file))) {
|
||||
if (!fn || fn == empty_string || php_check_open_basedir(fn TSRMLS_CC)) {
|
||||
if (!fn || fn == empty_string || php_check_open_basedir(fn TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(fn, "rb+", CHECKUID_CHECK_FILE_AND_DIR))) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid filename '%s'", fn);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@@ -1699,7 +1699,7 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char
|
||||
char buf[4096];
|
||||
char *path;
|
||||
|
||||
tmp = php_open_temporary_file("", "", &path TSRMLS_CC);
|
||||
tmp = php_open_temporary_file(NULL, NULL, &path TSRMLS_CC);
|
||||
if (tmp == NULL) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open temporary file");
|
||||
RETURN_FALSE;
|
||||
@@ -3017,7 +3017,8 @@ static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int mode, int
|
||||
{
|
||||
zval *IM, *EXT = NULL;
|
||||
gdImagePtr im=NULL;
|
||||
int col = -1, x = -1, y = -1, str_len, fontname_len, i, brect[8];
|
||||
long col = -1, x = -1, y = -1;
|
||||
int str_len, fontname_len, i, brect[8];
|
||||
double ptsize, angle;
|
||||
unsigned char *str = NULL, *fontname = NULL;
|
||||
char *error = NULL;
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type,
|
||||
}
|
||||
|
||||
if ((argc == 2) || (argc > 2 && Z_STRLEN_PP(file))) {
|
||||
if (!fn || fn == empty_string || php_check_open_basedir(fn TSRMLS_CC)) {
|
||||
if (!fn || fn == empty_string || php_check_open_basedir(fn TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(fn, "rb+", CHECKUID_CHECK_FILE_AND_DIR))) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid filename '%s'", fn);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
+5
-5
@@ -1737,8 +1737,8 @@ void gdImageFilledEllipse (gdImagePtr im, int mx, int my, int w, int h, int c)
|
||||
rx = r << 1;
|
||||
ry = 0;
|
||||
x = a;
|
||||
old_y2=-1;
|
||||
old_y1=-1;
|
||||
old_y2=-2;
|
||||
old_y1=-2;
|
||||
while (x > 0){
|
||||
if (r > 0) {
|
||||
my1++;my2--;
|
||||
@@ -2304,9 +2304,9 @@ void gdImageCopyMergeGray (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, i
|
||||
dc = gdImageGetPixel(dst, tox, toy);
|
||||
g = (0.29900f * gdImageRed(dst, dc)) + (0.58700f * gdImageGreen(dst, dc)) + (0.11400f * gdImageBlue(dst, dc));
|
||||
|
||||
ncR = (int)(gdImageRed (src, c) * (pct / 100.0f) + gdImageRed(dst, dc) * g * ((100 - pct) / 100.0f));
|
||||
ncG = (int)(gdImageGreen (src, c) * (pct / 100.0f) + gdImageGreen(dst, dc) * g * ((100 - pct) / 100.0f));
|
||||
ncB = (int)(gdImageBlue (src, c) * (pct / 100.0f) + gdImageBlue(dst, dc) * g * ((100 - pct) / 100.0f));
|
||||
ncR = (int)(gdImageRed (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0));
|
||||
ncG = (int)(gdImageGreen (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0));
|
||||
ncB = (int)(gdImageBlue (src, c) * (pct / 100.0f) + g * ((100 - pct) / 100.0));
|
||||
|
||||
/* First look for an exact match */
|
||||
nc = gdImageColorExact(dst, ncR, ncG, ncB);
|
||||
|
||||
@@ -259,13 +259,13 @@ DoExtension(gdIOCtx *fd, int label, int *Transparent)
|
||||
if ((buf[0] & 0x1) != 0)
|
||||
*Transparent = buf[3];
|
||||
|
||||
while (GetDataBlock(fd, (unsigned char*) buf) != 0)
|
||||
while (GetDataBlock(fd, (unsigned char*) buf) > 0)
|
||||
;
|
||||
return FALSE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
while (GetDataBlock(fd, (unsigned char*) buf) != 0)
|
||||
while (GetDataBlock(fd, (unsigned char*) buf) > 0)
|
||||
;
|
||||
|
||||
return FALSE;
|
||||
@@ -337,7 +337,7 @@ GetCode_(gdIOCtx *fd, int code_size, int flag)
|
||||
buf[0] = buf[last_byte-2];
|
||||
buf[1] = buf[last_byte-1];
|
||||
|
||||
if ((count = GetDataBlock(fd, &buf[2])) == 0)
|
||||
if ((count = GetDataBlock(fd, &buf[2])) <= 0)
|
||||
done = TRUE;
|
||||
|
||||
last_byte = 2 + count;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
gdimagefill() function (Bug #19366 (fixed in bundled libgd))
|
||||
Bug #19366 (gdimagefill() function crashes (fixed in bundled libgd))
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('gd')) die("skip gd extension not available\n");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
gdimagefill() function (Bug #19366 (fixed in bundled libgd))
|
||||
Bug #27582 (ImageFillToBorder() on alphablending image looses alpha on fill color)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('gd')) die("skip gd extension not available\n");
|
||||
|
||||
+46
-24
@@ -205,7 +205,7 @@ ZEND_MODULE_INFO_D(gmp)
|
||||
if(Z_TYPE_PP(zval) == IS_RESOURCE) { \
|
||||
ZEND_FETCH_RESOURCE(gmpnumber, mpz_t *, zval, -1, GMP_RESOURCE_NAME, le_gmp);\
|
||||
} else {\
|
||||
if(convert_to_gmp(&gmpnumber, zval, 0) == FAILURE) {\
|
||||
if(convert_to_gmp(&gmpnumber, zval, 0 TSRMLS_CC) == FAILURE) {\
|
||||
RETURN_FALSE;\
|
||||
}\
|
||||
ZEND_REGISTER_RESOURCE(NULL, gmpnumber, le_gmp);\
|
||||
@@ -217,7 +217,7 @@ if(Z_TYPE_PP(zval) == IS_RESOURCE) { \
|
||||
|
||||
/* {{{ convert_to_gmp
|
||||
* Convert zval to be gmp number */
|
||||
static int convert_to_gmp(mpz_t * *gmpnumber, zval **val, int base)
|
||||
static int convert_to_gmp(mpz_t * *gmpnumber, zval **val, int base TSRMLS_DC)
|
||||
{
|
||||
int ret = 0;
|
||||
int skip_lead = 0;
|
||||
@@ -280,8 +280,8 @@ typedef void (*gmp_binary_op2_t)(mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr);
|
||||
typedef unsigned long (*gmp_binary_ui_op2_t)(mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long);
|
||||
/* }}} */
|
||||
|
||||
#define gmp_zval_binary_ui_op(r, a, b, o, u) gmp_zval_binary_ui_op_ex(r, a, b, o, u, 0 TSRMLS_CC)
|
||||
#define gmp_zval_binary_ui_op2(r, a, b, o, u) gmp_zval_binary_ui_op2_ex(r, a, b, o, u, 0 TSRMLS_CC)
|
||||
#define gmp_zval_binary_ui_op(r, a, b, o, u) gmp_zval_binary_ui_op_ex(r, a, b, o, u, 0, 0 TSRMLS_CC)
|
||||
#define gmp_zval_binary_ui_op2(r, a, b, o, u) gmp_zval_binary_ui_op2_ex(r, a, b, o, u, 0, 0 TSRMLS_CC)
|
||||
|
||||
#define gmp_binary_ui_op(op, uop) _gmp_binary_ui_op(INTERNAL_FUNCTION_PARAM_PASSTHRU, op, uop)
|
||||
#define gmp_binary_op(op) _gmp_binary_ui_op(INTERNAL_FUNCTION_PARAM_PASSTHRU, op, NULL)
|
||||
@@ -296,7 +296,7 @@ typedef unsigned long (*gmp_binary_ui_op2_t)(mpz_ptr, mpz_ptr, mpz_srcptr, unsig
|
||||
Execute GMP binary operation.
|
||||
May return GMP resource or long if operation allows this
|
||||
*/
|
||||
static inline void gmp_zval_binary_ui_op_ex(zval *return_value, zval **a_arg, zval **b_arg, gmp_binary_op_t gmp_op, gmp_binary_ui_op_t gmp_ui_op, int allow_ui_return TSRMLS_DC)
|
||||
static inline void gmp_zval_binary_ui_op_ex(zval *return_value, zval **a_arg, zval **b_arg, gmp_binary_op_t gmp_op, gmp_binary_ui_op_t gmp_ui_op, int allow_ui_return, int check_b_zero TSRMLS_DC)
|
||||
{
|
||||
mpz_t *gmpnum_a, *gmpnum_b, *gmpnum_result;
|
||||
unsigned long long_result=0;
|
||||
@@ -309,10 +309,20 @@ static inline void gmp_zval_binary_ui_op_ex(zval *return_value, zval **a_arg, zv
|
||||
FETCH_GMP_ZVAL(gmpnum_b, b_arg);
|
||||
}
|
||||
|
||||
if (!Z_LVAL_PP(b_arg)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
if(check_b_zero) {
|
||||
int b_is_zero = 0;
|
||||
if(use_ui) {
|
||||
b_is_zero = (Z_LVAL_PP(b_arg) == 0);
|
||||
} else {
|
||||
b_is_zero = !mpz_cmp_ui(*gmpnum_b, 0);
|
||||
}
|
||||
|
||||
if(b_is_zero) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Zero operand not allowed");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
INIT_GMP_NUM(gmpnum_result);
|
||||
if(use_ui && gmp_ui_op) {
|
||||
if(allow_ui_return) {
|
||||
@@ -337,7 +347,7 @@ static inline void gmp_zval_binary_ui_op_ex(zval *return_value, zval **a_arg, zv
|
||||
Execute GMP binary operation which returns 2 values.
|
||||
May return GMP resources or longs if operation allows this.
|
||||
*/
|
||||
static inline void gmp_zval_binary_ui_op2_ex(zval *return_value, zval **a_arg, zval **b_arg, gmp_binary_op2_t gmp_op, gmp_binary_ui_op2_t gmp_ui_op, int allow_ui_return TSRMLS_DC)
|
||||
static inline void gmp_zval_binary_ui_op2_ex(zval *return_value, zval **a_arg, zval **b_arg, gmp_binary_op2_t gmp_op, gmp_binary_ui_op2_t gmp_ui_op, int allow_ui_return, int check_b_zero TSRMLS_DC)
|
||||
{
|
||||
mpz_t *gmpnum_a, *gmpnum_b, *gmpnum_result1, *gmpnum_result2;
|
||||
zval r;
|
||||
@@ -352,10 +362,20 @@ static inline void gmp_zval_binary_ui_op2_ex(zval *return_value, zval **a_arg, z
|
||||
FETCH_GMP_ZVAL(gmpnum_b, b_arg);
|
||||
}
|
||||
|
||||
if (!Z_LVAL_PP(b_arg)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
if(check_b_zero) {
|
||||
int b_is_zero = 0;
|
||||
if(use_ui) {
|
||||
b_is_zero = (Z_LVAL_PP(b_arg) == 0);
|
||||
} else {
|
||||
b_is_zero = !mpz_cmp_ui(*gmpnum_b, 0);
|
||||
}
|
||||
|
||||
if(b_is_zero) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Zero operand not allowed");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
INIT_GMP_NUM(gmpnum_result1);
|
||||
INIT_GMP_NUM(gmpnum_result2);
|
||||
|
||||
@@ -509,7 +529,7 @@ ZEND_FUNCTION(gmp_init)
|
||||
}
|
||||
}
|
||||
|
||||
if(convert_to_gmp(&gmpnumber, number_arg, base) == FAILURE) {
|
||||
if(convert_to_gmp(&gmpnumber, number_arg, base TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -642,13 +662,13 @@ ZEND_FUNCTION(gmp_div_qr)
|
||||
|
||||
switch(round) {
|
||||
case GMP_ROUND_ZERO:
|
||||
gmp_zval_binary_ui_op2(return_value, a_arg, b_arg, mpz_tdiv_qr, (gmp_binary_ui_op2_t)mpz_tdiv_qr_ui);
|
||||
gmp_zval_binary_ui_op2_ex(return_value, a_arg, b_arg, mpz_tdiv_qr, (gmp_binary_ui_op2_t)mpz_tdiv_qr_ui, 0, 1 TSRMLS_CC);
|
||||
break;
|
||||
case GMP_ROUND_PLUSINF:
|
||||
gmp_zval_binary_ui_op2(return_value, a_arg, b_arg, mpz_cdiv_qr, (gmp_binary_ui_op2_t)mpz_cdiv_qr_ui);
|
||||
gmp_zval_binary_ui_op2_ex(return_value, a_arg, b_arg, mpz_cdiv_qr, (gmp_binary_ui_op2_t)mpz_cdiv_qr_ui, 0, 1 TSRMLS_CC);
|
||||
break;
|
||||
case GMP_ROUND_MINUSINF:
|
||||
gmp_zval_binary_ui_op2(return_value, a_arg, b_arg, mpz_fdiv_qr, (gmp_binary_ui_op2_t)mpz_fdiv_qr_ui);
|
||||
gmp_zval_binary_ui_op2_ex(return_value, a_arg, b_arg, mpz_fdiv_qr, (gmp_binary_ui_op2_t)mpz_fdiv_qr_ui, 0, 1 TSRMLS_CC);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -677,15 +697,17 @@ ZEND_FUNCTION(gmp_div_r)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
switch(round) {
|
||||
case GMP_ROUND_ZERO:
|
||||
gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_tdiv_r, (gmp_binary_ui_op_t)mpz_tdiv_r_ui, 1 TSRMLS_CC);
|
||||
gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_tdiv_r, (gmp_binary_ui_op_t)mpz_tdiv_r_ui, 1, 1 TSRMLS_CC);
|
||||
break;
|
||||
case GMP_ROUND_PLUSINF:
|
||||
gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_cdiv_r, (gmp_binary_ui_op_t)mpz_cdiv_r_ui, 1 TSRMLS_CC);
|
||||
gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_cdiv_r, (gmp_binary_ui_op_t)mpz_cdiv_r_ui, 1, 1 TSRMLS_CC);
|
||||
break;
|
||||
case GMP_ROUND_MINUSINF:
|
||||
gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_fdiv_r, (gmp_binary_ui_op_t)mpz_fdiv_r_ui, 1 TSRMLS_CC);
|
||||
gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_fdiv_r, (gmp_binary_ui_op_t)mpz_fdiv_r_ui, 1, 1 TSRMLS_CC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -715,13 +737,13 @@ ZEND_FUNCTION(gmp_div_q)
|
||||
|
||||
switch(round) {
|
||||
case GMP_ROUND_ZERO:
|
||||
gmp_zval_binary_ui_op(return_value, a_arg, b_arg, mpz_tdiv_q, (gmp_binary_ui_op_t)mpz_tdiv_q_ui);
|
||||
gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_tdiv_q, (gmp_binary_ui_op_t)mpz_tdiv_q_ui, 0, 1 TSRMLS_CC);
|
||||
break;
|
||||
case GMP_ROUND_PLUSINF:
|
||||
gmp_zval_binary_ui_op(return_value, a_arg, b_arg, mpz_cdiv_q, (gmp_binary_ui_op_t)mpz_cdiv_q_ui);
|
||||
gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_cdiv_q, (gmp_binary_ui_op_t)mpz_cdiv_q_ui, 0, 1 TSRMLS_CC);
|
||||
break;
|
||||
case GMP_ROUND_MINUSINF:
|
||||
gmp_zval_binary_ui_op(return_value, a_arg, b_arg, mpz_fdiv_q, (gmp_binary_ui_op_t)mpz_fdiv_q_ui);
|
||||
gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_fdiv_q, (gmp_binary_ui_op_t)mpz_fdiv_q_ui, 0, 1 TSRMLS_CC);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -738,7 +760,7 @@ ZEND_FUNCTION(gmp_mod)
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
|
||||
gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_mod, (gmp_binary_ui_op_t)mpz_mod_ui, 1 TSRMLS_CC);
|
||||
gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_mod, (gmp_binary_ui_op_t)mpz_mod_ui, 1, 1 TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -984,7 +1006,7 @@ ZEND_FUNCTION(gmp_gcd)
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
|
||||
gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_gcd, (gmp_binary_ui_op_t)mpz_gcd_ui, 1 TSRMLS_CC);
|
||||
gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_gcd, (gmp_binary_ui_op_t)mpz_gcd_ui, 1, 0 TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
--TEST--
|
||||
Bug #32773 binary GMP functions returns unexpected value, when second parameter is int(0)
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("gmp")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
echo '10 + 0 = ', gmp_strval(gmp_add(10, 0)), "\n";
|
||||
echo '10 + "0" = ', gmp_strval(gmp_add(10, '0')), "\n";
|
||||
|
||||
echo gmp_strval(gmp_div(10, 0))."\n";
|
||||
echo gmp_strval(gmp_div_qr(10, 0))."\n";
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
10 + 0 = 10
|
||||
10 + "0" = 10
|
||||
|
||||
Warning: gmp_div(): Zero operand not allowed in %s on line %d
|
||||
0
|
||||
|
||||
Warning: gmp_div_qr(): Zero operand not allowed in %s on line %d
|
||||
0
|
||||
+4
-4
@@ -97,7 +97,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IMAP_EXPORTS" /FR /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\\" /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D "ZTS" /D "_DEBUG" /D "IMAP_EXPORTS" /D "COMPILE_DL_IMAP" /D HAVE_IMAP=1 /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZEND_WIN32" /D "PHP_WIN32" /D ZEND_DEBUG=1 /FR /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\\" /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D "ZTS" /D "_DEBUG" /D "IMAP_EXPORTS" /D "COMPILE_DL_IMAP" /D HAVE_IMAP=1 /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZEND_WIN32" /D "PHP_WIN32" /D ZEND_DEBUG=1 /D HAVE_IMAP2004=1 /D HAVE_IMAP_SSL=1 /FR /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x40d /d "_DEBUG"
|
||||
@@ -107,7 +107,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts_debug.lib wsock32.lib winmm.lib cclient.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug_TS/php_imap.dll" /pdbtype:sept /libpath:"..\..\..\\" /libpath:"..\..\Debug_TS"
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts_debug.lib wsock32.lib winmm.lib cclient.lib crypt32.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug_TS/php_imap.dll" /pdbtype:sept /libpath:"..\..\..\\" /libpath:"..\..\Debug_TS"
|
||||
|
||||
!ELSEIF "$(CFG)" == "imap - Win32 Release_TS"
|
||||
|
||||
@@ -123,7 +123,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IMAP_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\\" /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /I "..\..\..\php_build\imap\c-client" /D "ZTS" /D "NDEBUG" /D "IMAP_EXPORTS" /D "COMPILE_DL_IMAP" /D HAVE_IMAP=1 /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZEND_WIN32" /D "PHP_WIN32" /D ZEND_DEBUG=0 /D HAVE_IMAP2001=1 /FR /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\\" /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /I "..\..\..\php_build\imap\c-client" /D "ZTS" /D "NDEBUG" /D "IMAP_EXPORTS" /D "COMPILE_DL_IMAP" /D HAVE_IMAP=1 /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZEND_WIN32" /D "PHP_WIN32" /D ZEND_DEBUG=0 /D HAVE_IMAP2001=1 /D HAVE_IMAP2004=1 /D HAVE_IMAP_SSL=1 /FR /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x40d /d "NDEBUG"
|
||||
@@ -133,7 +133,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib wsock32.lib winmm.lib cclient.lib Secur32.lib CertIdl.Lib /nologo /dll /machine:I386 /nodefaultlib:"LIBCMT" /out:"..\..\Release_TS/php_imap.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline" /libpath:"..\..\..\php_build\imap"
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib wsock32.lib winmm.lib cclient.lib Secur32.lib CertIdl.Lib crypt32.lib /nologo /dll /machine:I386 /nodefaultlib:"LIBCMT" /out:"..\..\Release_TS/php_imap.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline" /libpath:"..\..\..\php_build\imap"
|
||||
# SUBTRACT LINK32 /nodefaultlib
|
||||
|
||||
!ENDIF
|
||||
|
||||
+2
-1
@@ -3015,7 +3015,8 @@ PHP_FUNCTION(imap_mail_compose)
|
||||
if (zend_hash_find(Z_ARRVAL_PP(data), "charset", sizeof("charset"), (void **) &pvalue)== SUCCESS) {
|
||||
convert_to_string_ex(pvalue);
|
||||
tmp_param = mail_newbody_parameter();
|
||||
tmp_param->value = cpystr(Z_STRVAL_PP(pvalue));
|
||||
tmp_param->value = (char *) fs_get(Z_STRLEN_PP(pvalue) + 1);
|
||||
memcpy(tmp_param->value, Z_STRVAL_PP(pvalue), Z_STRLEN_PP(pvalue) + 1);
|
||||
tmp_param->attribute = "CHARSET";
|
||||
tmp_param->next = bod->parameter;
|
||||
bod->parameter = tmp_param;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
OVERALL_TARGET += $(srcdir)/ifx.c
|
||||
|
||||
$(srcdir)/ifx.c: $(srcdir)/ifx.ec $(builddir)/libphpifx.a
|
||||
|
||||
+13
-1
@@ -44,8 +44,20 @@ if test "$PHP_INFORMIX" != "no"; then
|
||||
esac
|
||||
|
||||
AC_MSG_CHECKING([Informix version])
|
||||
IFX_IBM_VERSION=[`$INFORMIXDIR/bin/esql -V | grep "IBM Informix-ESQL Version" | sed -ne '1 s/\(.*\)ESQL Version \([0-9]*\)\.\([0-9]*\).*/\2\3/p'`]
|
||||
IFX_VERSION=[`$INFORMIXDIR/bin/esql -V | grep "ESQL Version" | sed -ne '1 s/\(.*\)ESQL Version \([0-9]*\)\.\([0-9]*\).*/\2\3/p'`]
|
||||
AC_MSG_RESULT($IFX_VERSION)
|
||||
|
||||
if test "$IFX_IBM_VERSION"; then
|
||||
if test $IFX_IBM_VERSION -ge "290" && test $IFX_IBM_VERSION -lt "300"; then
|
||||
IFX_VERSION=960
|
||||
else
|
||||
IFX_VERSION=$IFX_IBM_VERSION
|
||||
fi
|
||||
AC_MSG_RESULT([IBM: $IFX_VERSION])
|
||||
else
|
||||
AC_MSG_RESULT([$IFX_VERSION])
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED(IFX_VERSION, $IFX_VERSION, [ ])
|
||||
|
||||
if test $IFX_VERSION -ge "900"; then
|
||||
|
||||
@@ -29,7 +29,9 @@ if test "$PHP_INGRES" != "no"; then
|
||||
AC_MSG_ERROR(Cannot find libiiapi.a under $II_DIR/lib)
|
||||
fi
|
||||
|
||||
PHP_ADD_LIBRARY_WITH_PATH(iiapi, $II_LIB_DIR, II_SHARED_LIBADD)
|
||||
PHP_ADD_LIBRARY_WITH_PATH(ingres, $II_LIB_DIR, II_SHARED_LIBADD)
|
||||
PHP_ADD_LIBRARY_WITH_PATH(iiapi.1, $II_LIB_DIR, II_SHARED_LIBADD)
|
||||
PHP_ADD_LIBRARY_WITH_PATH(q.1, $II_LIB_DIR, II_SHARED_LIBADD)
|
||||
PHP_ADD_LIBRARY_WITH_PATH(frame.1, $II_LIB_DIR, II_SHARED_LIBADD)
|
||||
PHP_ADD_LIBRARY_WITH_PATH(compat.1, $II_LIB_DIR, II_SHARED_LIBADD)
|
||||
PHP_ADD_INCLUDE($II_INC_DIR)
|
||||
fi
|
||||
+14
-4
@@ -99,7 +99,9 @@ if test "$PHP_LDAP" != "no"; then
|
||||
elif test -f $LDAP_LIBDIR/libclntsh.$SHLIB_SUFFIX_NAME; then
|
||||
PHP_ADD_LIBRARY_WITH_PATH(clntsh, $LDAP_LIBDIR, LDAP_SHARED_LIBADD)
|
||||
AC_DEFINE(HAVE_ORALDAP,1,[ ])
|
||||
|
||||
if test -f $LDAP_LIBDIR/libclntsh.$SHLIB_SUFFIX_NAME.10.1; then
|
||||
AC_DEFINE(HAVE_ORALDAP_10,1,[ ])
|
||||
fi
|
||||
else
|
||||
AC_MSG_ERROR(Cannot find ldap libraries in $LDAP_LIBDIR.)
|
||||
fi
|
||||
@@ -112,8 +114,6 @@ if test "$PHP_LDAP" != "no"; then
|
||||
_SAVE_CPPFLAGS=$CPPFLAGS
|
||||
_SAVE_LDFLAGS=$LDFLAGS
|
||||
CPPFLAGS="$CPPFLAGS -I$LDAP_INCDIR"
|
||||
LDFLAGS="$LDFLAGS $LDAP_SHARED_LIBADD"
|
||||
|
||||
AC_CACHE_CHECK([for 3 arg ldap_set_rebind_proc], ac_cv_3arg_setrebindproc,
|
||||
[AC_TRY_COMPILE([#include <ldap.h>], [ldap_set_rebind_proc(0,0,0)],
|
||||
ac_cv_3arg_setrebindproc=yes, ac_cv_3arg_setrebindproc=no)])
|
||||
@@ -124,6 +124,16 @@ if test "$PHP_LDAP" != "no"; then
|
||||
|
||||
dnl Solaris 2.8 claims to be 2004 API, but doesn't have
|
||||
dnl ldap_parse_reference() nor ldap_start_tls_s()
|
||||
AC_CHECK_FUNCS([ldap_parse_reference ldap_start_tls_s])
|
||||
AC_CHECK_FUNCS([ldap_parse_result ldap_parse_reference ldap_start_tls_s])
|
||||
LDFLAGS=$_SAVE_LDFLAGS
|
||||
|
||||
dnl
|
||||
dnl Sanity check
|
||||
dnl
|
||||
_SAVE_LDFLAGS=$LDFLAGS
|
||||
LDFLAGS="$LDFLAGS $LDAP_SHARED_LIBADD"
|
||||
AC_CHECK_FUNC(ldap_bind_s, [], [
|
||||
AC_MSG_ERROR([LDAP build check failed. Please check config.log for more information.])
|
||||
])
|
||||
LDFLAGS=$_SAVE_LDFLAGS
|
||||
fi
|
||||
+35
-26
@@ -121,16 +121,18 @@ function_entry ldap_functions[] = {
|
||||
PHP_FE(ldap_compare, NULL)
|
||||
PHP_FE(ldap_sort, NULL)
|
||||
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10
|
||||
PHP_FE(ldap_rename, NULL)
|
||||
PHP_FE(ldap_get_option, third_argument_force_ref)
|
||||
PHP_FE(ldap_set_option, NULL)
|
||||
PHP_FE(ldap_parse_result, arg3to6of6_force_ref)
|
||||
PHP_FE(ldap_first_reference, NULL)
|
||||
PHP_FE(ldap_next_reference, NULL)
|
||||
#ifdef HAVE_LDAP_PARSE_REFERENCE
|
||||
PHP_FE(ldap_parse_reference, third_argument_force_ref)
|
||||
#endif
|
||||
PHP_FE(ldap_rename, NULL)
|
||||
#ifdef HAVE_LDAP_PARSE_RESULT
|
||||
PHP_FE(ldap_parse_result, arg3to6of6_force_ref)
|
||||
#endif
|
||||
#ifdef HAVE_LDAP_START_TLS_S
|
||||
PHP_FE(ldap_start_tls, NULL)
|
||||
#endif
|
||||
@@ -223,7 +225,7 @@ PHP_MINIT_FUNCTION(ldap)
|
||||
REGISTER_LONG_CONSTANT("LDAP_DEREF_FINDING", LDAP_DEREF_FINDING, CONST_PERSISTENT | CONST_CS);
|
||||
REGISTER_LONG_CONSTANT("LDAP_DEREF_ALWAYS", LDAP_DEREF_ALWAYS, CONST_PERSISTENT | CONST_CS);
|
||||
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10
|
||||
/* LDAP options */
|
||||
REGISTER_LONG_CONSTANT("LDAP_OPT_DEREF", LDAP_OPT_DEREF, CONST_PERSISTENT | CONST_CS);
|
||||
REGISTER_LONG_CONSTANT("LDAP_OPT_SIZELIMIT", LDAP_OPT_SIZELIMIT, CONST_PERSISTENT | CONST_CS);
|
||||
@@ -234,7 +236,9 @@ PHP_MINIT_FUNCTION(ldap)
|
||||
#ifdef LDAP_OPT_RESTART
|
||||
REGISTER_LONG_CONSTANT("LDAP_OPT_RESTART", LDAP_OPT_RESTART, CONST_PERSISTENT | CONST_CS);
|
||||
#endif
|
||||
#ifdef LDAP_OPT_HOST_NAME
|
||||
REGISTER_LONG_CONSTANT("LDAP_OPT_HOST_NAME", LDAP_OPT_HOST_NAME, CONST_PERSISTENT | CONST_CS);
|
||||
#endif
|
||||
REGISTER_LONG_CONSTANT("LDAP_OPT_ERROR_STRING", LDAP_OPT_ERROR_STRING, CONST_PERSISTENT | CONST_CS);
|
||||
#ifdef LDAP_OPT_MATCHED_DN
|
||||
REGISTER_LONG_CONSTANT("LDAP_OPT_MATCHED_DN", LDAP_OPT_MATCHED_DN, CONST_PERSISTENT | CONST_CS);
|
||||
@@ -414,7 +418,7 @@ PHP_FUNCTION(ldap_connect)
|
||||
static int _get_lderrno(LDAP *ldap)
|
||||
{
|
||||
#if !HAVE_NSLDAP
|
||||
#if LDAP_API_VERSION > 2000
|
||||
#if LDAP_API_VERSION > 2000 || HAVE_ORALDAP_10
|
||||
int lderr;
|
||||
|
||||
/* New versions of OpenLDAP do it this way */
|
||||
@@ -478,7 +482,7 @@ static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref)
|
||||
{
|
||||
/* sizelimit */
|
||||
if (sizelimit > -1) {
|
||||
#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP
|
||||
#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP_10
|
||||
ldap_set_option(ldap, LDAP_OPT_SIZELIMIT, &sizelimit);
|
||||
#else
|
||||
ldap->ld_sizelimit = sizelimit;
|
||||
@@ -487,7 +491,7 @@ static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref)
|
||||
|
||||
/* timelimit */
|
||||
if (timelimit > -1) {
|
||||
#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP
|
||||
#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP_10
|
||||
ldap_set_option(ldap, LDAP_OPT_TIMELIMIT, &timelimit);
|
||||
#else
|
||||
ldap->ld_timelimit = timelimit;
|
||||
@@ -496,7 +500,7 @@ static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref)
|
||||
|
||||
/* deref */
|
||||
if (deref > -1) {
|
||||
#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP
|
||||
#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP_10
|
||||
ldap_set_option(ldap, LDAP_OPT_DEREF, &deref);
|
||||
#else
|
||||
ldap->ld_deref = deref;
|
||||
@@ -915,12 +919,12 @@ PHP_FUNCTION(ldap_get_entries)
|
||||
add_index_string(tmp1, num_attrib, attribute, 1);
|
||||
|
||||
num_attrib++;
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || WINDOWS
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
|
||||
ldap_memfree(attribute);
|
||||
#endif
|
||||
attribute = ldap_next_attribute(ldap, ldap_result_entry, ber);
|
||||
}
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || WINDOWS
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
|
||||
if (ber != NULL)
|
||||
ber_free(ber, 0);
|
||||
#endif
|
||||
@@ -928,7 +932,7 @@ PHP_FUNCTION(ldap_get_entries)
|
||||
add_assoc_long(tmp1, "count", num_attrib);
|
||||
dn = ldap_get_dn(ldap, ldap_result_entry);
|
||||
add_assoc_string(tmp1, "dn", dn, 1);
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || WINDOWS
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
|
||||
ldap_memfree(dn);
|
||||
#else
|
||||
free(dn);
|
||||
@@ -968,7 +972,7 @@ PHP_FUNCTION(ldap_first_attribute)
|
||||
ZEND_REGISTER_RESOURCE(*berp, ber, le_ber_entry);
|
||||
|
||||
RETVAL_STRING(attribute, 1);
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || WINDOWS
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
|
||||
ldap_memfree(attribute);
|
||||
#endif
|
||||
}
|
||||
@@ -999,7 +1003,7 @@ PHP_FUNCTION(ldap_next_attribute)
|
||||
ZEND_REGISTER_RESOURCE(*berp, ber, le_ber_entry);
|
||||
|
||||
RETVAL_STRING(attribute, 1);
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || WINDOWS
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
|
||||
ldap_memfree(attribute);
|
||||
#endif
|
||||
}
|
||||
@@ -1046,12 +1050,12 @@ PHP_FUNCTION(ldap_get_attributes)
|
||||
add_index_string(return_value, num_attrib, attribute, 1);
|
||||
|
||||
num_attrib++;
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || WINDOWS
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
|
||||
ldap_memfree(attribute);
|
||||
#endif
|
||||
attribute = ldap_next_attribute(ld->link, resultentry->data, ber);
|
||||
}
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || WINDOWS
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
|
||||
if (ber != NULL) {
|
||||
ber_free(ber, 0);
|
||||
}
|
||||
@@ -1159,7 +1163,7 @@ PHP_FUNCTION(ldap_get_dn)
|
||||
text = ldap_get_dn(ld->link, resultentry->data);
|
||||
if (text != NULL) {
|
||||
RETVAL_STRING(text, 1);
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || WINDOWS
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
|
||||
ldap_memfree(text);
|
||||
#else
|
||||
free(text);
|
||||
@@ -1222,7 +1226,7 @@ PHP_FUNCTION(ldap_dn2ufn)
|
||||
|
||||
if (ufn !=NULL) {
|
||||
RETVAL_STRING(ufn, 1);
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || WINDOWS
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
|
||||
ldap_memfree(ufn);
|
||||
#endif
|
||||
} else {
|
||||
@@ -1542,8 +1546,7 @@ PHP_FUNCTION(ldap_sort)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10
|
||||
/* {{{ proto bool ldap_get_option(resource link, int option, mixed retval)
|
||||
Get the current value of various session-wide parameters */
|
||||
PHP_FUNCTION(ldap_get_option)
|
||||
@@ -1581,8 +1584,10 @@ PHP_FUNCTION(ldap_get_option)
|
||||
ZVAL_LONG(*retval, val);
|
||||
} break;
|
||||
/* options with string value */
|
||||
case LDAP_OPT_HOST_NAME:
|
||||
case LDAP_OPT_ERROR_STRING:
|
||||
#ifdef LDAP_OPT_HOST_NAME
|
||||
case LDAP_OPT_HOST_NAME:
|
||||
#endif
|
||||
#ifdef LDAP_OPT_MATCHED_DN
|
||||
case LDAP_OPT_MATCHED_DN:
|
||||
#endif
|
||||
@@ -1636,7 +1641,7 @@ PHP_FUNCTION(ldap_set_option)
|
||||
opt = Z_LVAL_PP(option);
|
||||
|
||||
switch (opt) {
|
||||
/* options with int value */
|
||||
/* options with int value */
|
||||
case LDAP_OPT_DEREF:
|
||||
case LDAP_OPT_SIZELIMIT:
|
||||
case LDAP_OPT_TIMELIMIT:
|
||||
@@ -1653,9 +1658,11 @@ PHP_FUNCTION(ldap_set_option)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
} break;
|
||||
/* options with string value */
|
||||
case LDAP_OPT_HOST_NAME:
|
||||
/* options with string value */
|
||||
case LDAP_OPT_ERROR_STRING:
|
||||
#ifdef LDAP_OPT_HOST_NAME
|
||||
case LDAP_OPT_HOST_NAME:
|
||||
#endif
|
||||
#ifdef LDAP_OPT_MATCHED_DN
|
||||
case LDAP_OPT_MATCHED_DN:
|
||||
#endif
|
||||
@@ -1751,6 +1758,7 @@ PHP_FUNCTION(ldap_set_option)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#ifdef HAVE_LDAP_PARSE_RESULT
|
||||
/* {{{ proto bool ldap_parse_result(resource link, resource result, int errcode, string matcheddn, string errmsg, array referrals)
|
||||
Extract information from result */
|
||||
PHP_FUNCTION(ldap_parse_result)
|
||||
@@ -1816,6 +1824,7 @@ PHP_FUNCTION(ldap_parse_result)
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
#endif
|
||||
|
||||
/* {{{ proto resource ldap_first_reference(resource link, resource result)
|
||||
Return first reference */
|
||||
@@ -1928,7 +1937,7 @@ PHP_FUNCTION(ldap_rename)
|
||||
convert_to_string_ex(newparent);
|
||||
convert_to_boolean_ex(deleteoldrdn);
|
||||
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10
|
||||
rc = ldap_rename_s(ld->link, Z_STRVAL_PP(dn), Z_STRVAL_PP(newrdn), Z_STRVAL_PP(newparent), Z_BVAL_PP(deleteoldrdn), NULL, NULL);
|
||||
#else
|
||||
if (Z_STRLEN_PP(newparent) != 0) {
|
||||
@@ -1972,10 +1981,10 @@ PHP_FUNCTION(ldap_start_tls)
|
||||
}
|
||||
/* }}} */
|
||||
#endif
|
||||
#endif /* (LDAP_API_VERSION > 2000) || HAVE_NSLDAP */
|
||||
#endif /* (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 */
|
||||
|
||||
#if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
|
||||
/* {{{ proto _ldap_rebind_proc()
|
||||
/* {{{ _ldap_rebind_proc()
|
||||
*/
|
||||
int _ldap_rebind_proc(LDAP *ldap, const char *url, ber_tag_t req, ber_int_t msgid, void *params)
|
||||
{
|
||||
|
||||
+7
-15
@@ -34,59 +34,51 @@ extern zend_module_entry ldap_module_entry;
|
||||
/* LDAP functions */
|
||||
PHP_MINIT_FUNCTION(ldap);
|
||||
PHP_MSHUTDOWN_FUNCTION(ldap);
|
||||
|
||||
PHP_MINFO_FUNCTION(ldap);
|
||||
|
||||
PHP_FUNCTION(ldap_connect);
|
||||
|
||||
PHP_FUNCTION(ldap_bind);
|
||||
PHP_FUNCTION(ldap_unbind);
|
||||
|
||||
PHP_FUNCTION(ldap_read);
|
||||
PHP_FUNCTION(ldap_list);
|
||||
PHP_FUNCTION(ldap_search);
|
||||
|
||||
PHP_FUNCTION(ldap_free_result);
|
||||
PHP_FUNCTION(ldap_count_entries);
|
||||
|
||||
PHP_FUNCTION(ldap_first_entry);
|
||||
PHP_FUNCTION(ldap_next_entry);
|
||||
PHP_FUNCTION(ldap_get_entries);
|
||||
PHP_FUNCTION(ldap_first_attribute);
|
||||
PHP_FUNCTION(ldap_next_attribute);
|
||||
PHP_FUNCTION(ldap_get_attributes);
|
||||
|
||||
PHP_FUNCTION(ldap_get_values);
|
||||
PHP_FUNCTION(ldap_get_values_len);
|
||||
|
||||
PHP_FUNCTION(ber_free);
|
||||
PHP_FUNCTION(ldap_get_dn);
|
||||
PHP_FUNCTION(ldap_explode_dn);
|
||||
PHP_FUNCTION(ldap_dn2ufn);
|
||||
|
||||
PHP_FUNCTION(ldap_add);
|
||||
PHP_FUNCTION(ldap_delete);
|
||||
|
||||
PHP_FUNCTION(ldap_mod_add);
|
||||
PHP_FUNCTION(ldap_mod_replace);
|
||||
PHP_FUNCTION(ldap_mod_del);
|
||||
|
||||
PHP_FUNCTION(ldap_errno);
|
||||
PHP_FUNCTION(ldap_err2str);
|
||||
PHP_FUNCTION(ldap_error);
|
||||
|
||||
PHP_FUNCTION(ldap_compare);
|
||||
|
||||
PHP_FUNCTION(ldap_sort);
|
||||
|
||||
#if ( LDAP_API_VERSION > 2000 ) || HAVE_NSLDAP
|
||||
#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10
|
||||
PHP_FUNCTION(ldap_get_option);
|
||||
PHP_FUNCTION(ldap_set_option);
|
||||
PHP_FUNCTION(ldap_parse_result);
|
||||
PHP_FUNCTION(ldap_first_reference);
|
||||
PHP_FUNCTION(ldap_next_reference);
|
||||
PHP_FUNCTION(ldap_parse_reference);
|
||||
PHP_FUNCTION(ldap_rename);
|
||||
#ifdef HAVE_LDAP_PARSE_RESULT
|
||||
PHP_FUNCTION(ldap_parse_result);
|
||||
#endif
|
||||
#ifdef HAVE_LDAP_PARSE_REFERENCE
|
||||
PHP_FUNCTION(ldap_parse_reference);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LDAP_API_VERSION > 2000
|
||||
|
||||
@@ -405,16 +405,16 @@ mbfl_encoding_detector_feed(mbfl_encoding_detector *identd, mbfl_string *string)
|
||||
num = identd->filter_list_size;
|
||||
n = string->len;
|
||||
p = string->val;
|
||||
bad = 0;
|
||||
while (n > 0) {
|
||||
i = 0;
|
||||
bad = 0;
|
||||
while (i < num) {
|
||||
for (i = 0; i < num; i++) {
|
||||
filter = identd->filter_list[i];
|
||||
(*filter->filter_function)(*p, filter);
|
||||
if (filter->flag) {
|
||||
bad++;
|
||||
if (!filter->flag) {
|
||||
(*filter->filter_function)(*p, filter);
|
||||
if (filter->flag) {
|
||||
bad++;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if ((num - 1) <= bad) {
|
||||
res = 1;
|
||||
@@ -555,9 +555,11 @@ mbfl_identify_encoding(mbfl_string *string, enum mbfl_no_encoding *elist, int el
|
||||
while (n > 0) {
|
||||
for (i = 0; i < num; i++) {
|
||||
filter = &flist[i];
|
||||
(*filter->filter_function)(*p, filter);
|
||||
if (filter->flag) {
|
||||
bad++;
|
||||
if (!filter->flag) {
|
||||
(*filter->filter_function)(*p, filter);
|
||||
if (filter->flag) {
|
||||
bad++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((num - 1) <= bad && !strict) {
|
||||
@@ -1960,6 +1962,25 @@ mime_header_encoder_block_collector(int c, void *data)
|
||||
static int
|
||||
mime_header_encoder_collector(int c, void *data)
|
||||
{
|
||||
static int qp_table[256] = {
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00 */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00 */
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
|
||||
0, 0, 0, 0, 0, 0, 0 ,0, 0, 0, 0, 0, 0, 1, 0, 1, /* 0x10 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 0x50 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 0x70 */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80 */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x90 */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xA0 */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xB0 */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xC0 */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xD0 */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xE0 */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* 0xF0 */
|
||||
};
|
||||
|
||||
int n;
|
||||
struct mime_header_encoder_data *pe = (struct mime_header_encoder_data *)data;
|
||||
|
||||
@@ -1969,7 +1990,7 @@ mime_header_encoder_collector(int c, void *data)
|
||||
break;
|
||||
|
||||
default: /* ASCII */
|
||||
if (c >= 0x21 && c < 0x7f) { /* ASCII exclude SPACE and CTLs */
|
||||
if (!qp_table[(c & 0xff)]) { /* ordinary characters */
|
||||
mbfl_memory_device_output(c, &pe->tmpdev);
|
||||
pe->status1 = 1;
|
||||
} else if (pe->status1 == 0 && c == 0x20) { /* repeat SPACE */
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#include "mbstring.h"
|
||||
#include "ext/standard/php_string.h"
|
||||
#include "ext/standard/php_mail.h"
|
||||
#include "ext/standard/exec.h"
|
||||
#include "ext/standard/url.h"
|
||||
#include "main/php_output.h"
|
||||
#include "ext/standard/info.h"
|
||||
@@ -3473,6 +3474,7 @@ PHP_FUNCTION(mb_send_mail)
|
||||
body_enc; /* body transfar encoding */
|
||||
mbfl_memory_device device; /* automatic allocateable buffer for additional header */
|
||||
const mbfl_language *lang;
|
||||
char *force_extra_parameters = INI_STR("mail.force_extra_parameters");
|
||||
int err = 0;
|
||||
|
||||
/* initialize */
|
||||
@@ -3594,12 +3596,21 @@ PHP_FUNCTION(mb_send_mail)
|
||||
extra_cmd = Z_STRVAL_PP(argv[4]);
|
||||
}
|
||||
|
||||
if (force_extra_parameters) {
|
||||
extra_cmd = estrdup(force_extra_parameters);
|
||||
} else if (extra_cmd) {
|
||||
extra_cmd = php_escape_shell_cmd(extra_cmd);
|
||||
}
|
||||
|
||||
if (!err && php_mail(to, subject, message, headers, extra_cmd TSRMLS_CC)) {
|
||||
RETVAL_TRUE;
|
||||
} else {
|
||||
RETVAL_FALSE;
|
||||
}
|
||||
|
||||
if (extra_cmd) {
|
||||
efree(extra_cmd);
|
||||
}
|
||||
if (subject_buf) {
|
||||
efree((void *)subject_buf);
|
||||
}
|
||||
|
||||
@@ -4,28 +4,16 @@ php-users@php.gr.jp #16242
|
||||
<?php
|
||||
extension_loaded('mbstring') or die('skip mbstring not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$ini = <<< HERE
|
||||
--INI--
|
||||
mbstring.language=Japanese
|
||||
mbstring.internal_encoding=UTF-8
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
HERE;
|
||||
var_dump(ini_get('mbstring.language'));
|
||||
var_dump(ini_get('mbstring.internal_encoding'));
|
||||
var_dump(mb_internal_encoding());
|
||||
|
||||
$tmpfile = tempnam(dirname(__FILE__), "t");
|
||||
$fp = fopen($tmpfile, 'w');
|
||||
fwrite($fp, $ini);
|
||||
fclose($fp);
|
||||
|
||||
$cmd = 'echo "<?php ';
|
||||
$cmd .= "var_dump(ini_get('mbstring.language'));";
|
||||
$cmd .= "var_dump(ini_get('mbstring.internal_encoding'));";
|
||||
$cmd .= 'var_dump(mb_internal_encoding());';
|
||||
$cmd .= ' ?>" |'.getenv("TEST_PHP_EXECUTABLE").' -c '.$tmpfile;
|
||||
|
||||
system($cmd);
|
||||
|
||||
unlink($tmpfile);
|
||||
?>
|
||||
--EXPECT--
|
||||
string(8) "Japanese"
|
||||
|
||||
@@ -27,8 +27,6 @@
|
||||
|
||||
#if PHP_WIN32
|
||||
#include "config.w32.h"
|
||||
#elif defined NETWARE
|
||||
#include "config.nw.h"
|
||||
#else
|
||||
#include <php_config.h>
|
||||
#endif
|
||||
|
||||
+2
-2
@@ -43,7 +43,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MING_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /I "..\..\win32" /I "..\..\..\bindlib_w32" /D "WIN32" /D "MING_EXPORTS" /D "COMPILE_DL_MING" /D "HAVE_MING" /D ZEND_DEBUG=0 /D "NDEBUG" /D "_WINDOWS" /D "ZEND_WIN32" /D "PHP_WIN32" /D ZTS=1 /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /I "..\..\win32" /I "..\..\..\bindlib_w32" /D "WIN32" /D "MING_EXPORTS" /D "COMPILE_DL_MING" /D "HAVE_MING" /D ZEND_DEBUG=0 /D "NDEBUG" /D "_WINDOWS" /D "ZEND_WIN32" /D "PHP_WIN32" /D ZTS=1 /D HAVE_NEW_MING=1 /D HAVE_SWFPREBUILTCLIP=1 /D HAVE_MING_ZLIB=1 /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x407 /d "NDEBUG"
|
||||
@@ -53,7 +53,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 php4ts.lib libming.lib zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_ming.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline"
|
||||
# ADD LINK32 php4ts.lib libming.lib zlib.lib libungif.lib libpng.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_ming.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline"
|
||||
|
||||
!ELSEIF "$(CFG)" == "ming - Win32 Debug_TS"
|
||||
|
||||
|
||||
+28
-5
@@ -317,7 +317,11 @@ PHP_MINIT_FUNCTION(mssql)
|
||||
PHP_MSHUTDOWN_FUNCTION(mssql)
|
||||
{
|
||||
UNREGISTER_INI_ENTRIES();
|
||||
#ifndef HAVE_FREETDS
|
||||
dbwinexit();
|
||||
#else
|
||||
dbexit();
|
||||
#endif
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -372,7 +376,7 @@ static void php_mssql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
|
||||
{
|
||||
char *user, *passwd, *host;
|
||||
char *hashed_details;
|
||||
int hashed_details_length;
|
||||
int hashed_details_length, new_link = 0;
|
||||
mssql_link mssql, *mssql_ptr;
|
||||
char buffer[32];
|
||||
|
||||
@@ -430,6 +434,25 @@ static void php_mssql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
|
||||
sprintf(hashed_details,"mssql_%s_%s_%s",Z_STRVAL_PP(yyhost),Z_STRVAL_PP(yyuser),Z_STRVAL_PP(yypasswd)); /* SAFE */
|
||||
}
|
||||
break;
|
||||
case 4: {
|
||||
zval **yyhost,**yyuser,**yypasswd, **yynew_link;
|
||||
|
||||
if (zend_get_parameters_ex(4, &yyhost, &yyuser, &yypasswd, &yynew_link) == FAILURE) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
convert_to_string_ex(yyhost);
|
||||
convert_to_string_ex(yyuser);
|
||||
convert_to_string_ex(yypasswd);
|
||||
convert_to_long_ex(yynew_link);
|
||||
host = Z_STRVAL_PP(yyhost);
|
||||
user = Z_STRVAL_PP(yyuser);
|
||||
passwd = Z_STRVAL_PP(yypasswd);
|
||||
new_link = Z_LVAL_PP(yynew_link);
|
||||
hashed_details_length = Z_STRLEN_PP(yyhost)+Z_STRLEN_PP(yyuser)+Z_STRLEN_PP(yypasswd)+5+3;
|
||||
hashed_details = (char *) emalloc(hashed_details_length+1);
|
||||
sprintf(hashed_details,"mssql_%s_%s_%s",Z_STRVAL_PP(yyhost),Z_STRVAL_PP(yyuser),Z_STRVAL_PP(yypasswd)); /* SAFE */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WRONG_PARAM_COUNT;
|
||||
break;
|
||||
@@ -479,7 +502,7 @@ static void php_mssql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
|
||||
list_entry *le;
|
||||
|
||||
/* try to find if we already have this link in our persistent list */
|
||||
if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_length + 1, (void **) &le)==FAILURE) { /* we don't */
|
||||
if (new_link || zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_length + 1, (void **) &le)==FAILURE) { /* we don't */
|
||||
list_entry new_le;
|
||||
|
||||
if (MS_SQL_G(max_links) != -1 && MS_SQL_G(num_links) >= MS_SQL_G(max_links)) {
|
||||
@@ -592,7 +615,7 @@ static void php_mssql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
|
||||
* if it doesn't, open a new mssql link, add it to the resource list,
|
||||
* and add a pointer to it with hashed_details as the key.
|
||||
*/
|
||||
if (zend_hash_find(&EG(regular_list), hashed_details, hashed_details_length + 1,(void **) &index_ptr)==SUCCESS) {
|
||||
if (!new_link && zend_hash_find(&EG(regular_list), hashed_details, hashed_details_length + 1,(void **) &index_ptr)==SUCCESS) {
|
||||
int type,link;
|
||||
void *ptr;
|
||||
|
||||
@@ -682,7 +705,7 @@ static int php_mssql_get_default_link(INTERNAL_FUNCTION_PARAMETERS)
|
||||
return MS_SQL_G(default_link);
|
||||
}
|
||||
|
||||
/* {{{ proto int mssql_connect([string servername [, string username [, string password]]])
|
||||
/* {{{ proto int mssql_connect([string servername [, string username [, string password [, bool new_link]]]])
|
||||
Establishes a connection to a MS-SQL server */
|
||||
PHP_FUNCTION(mssql_connect)
|
||||
{
|
||||
@@ -691,7 +714,7 @@ PHP_FUNCTION(mssql_connect)
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto int mssql_pconnect([string servername [, string username [, string password]]])
|
||||
/* {{{ proto int mssql_pconnect([string servername [, string username [, string password [, bool new_link]]]])
|
||||
Establishes a persistent connection to a MS-SQL server */
|
||||
PHP_FUNCTION(mssql_pconnect)
|
||||
{
|
||||
|
||||
+14
-7
@@ -8,7 +8,7 @@ sinclude(libmysql/acinclude.m4)
|
||||
sinclude(libmysql/mysql.m4)
|
||||
|
||||
AC_DEFUN([MYSQL_LIB_CHK], [
|
||||
str="$MYSQL_DIR/$1/libmysqlclient.*"
|
||||
str="$MYSQL_DIR/$1/lib$MY_LIBNAME.*"
|
||||
for j in `echo $str`; do
|
||||
if test -r $j; then
|
||||
MYSQL_LIB_DIR=$MYSQL_DIR/$1
|
||||
@@ -114,19 +114,26 @@ elif test "$PHP_MYSQL" != "no"; then
|
||||
|
||||
MYSQL_MODULE_TYPE=external
|
||||
|
||||
MY_LIBNAME=mysqlclient
|
||||
case $host_alias in
|
||||
*netware*[)]
|
||||
MY_LIBNAME=mysql
|
||||
;;
|
||||
esac
|
||||
|
||||
for i in lib lib/mysql; do
|
||||
MYSQL_LIB_CHK($i)
|
||||
done
|
||||
|
||||
if test -z "$MYSQL_LIB_DIR"; then
|
||||
AC_MSG_ERROR(Cannot find mysqlclient library under $MYSQL_DIR)
|
||||
AC_MSG_ERROR(Cannot find lib$MY_LIBNAME library under $MYSQL_DIR)
|
||||
fi
|
||||
|
||||
PHP_CHECK_LIBRARY(mysqlclient, mysql_close, [ ],
|
||||
PHP_CHECK_LIBRARY($MY_LIBNAME, mysql_close, [ ],
|
||||
[
|
||||
if test "$PHP_ZLIB_DIR" != "no"; then
|
||||
PHP_ADD_LIBRARY_WITH_PATH(z, $PHP_ZLIB_DIR, MYSQL_SHARED_LIBADD)
|
||||
PHP_CHECK_LIBRARY(mysqlclient, mysql_error, [], [
|
||||
PHP_CHECK_LIBRARY($MY_LIBNAME, mysql_error, [], [
|
||||
AC_MSG_ERROR([mysql configure failed. Please check config.log for more information.])
|
||||
], [
|
||||
-L$PHP_ZLIB_DIR/lib -L$MYSQL_LIB_DIR
|
||||
@@ -134,7 +141,7 @@ elif test "$PHP_MYSQL" != "no"; then
|
||||
MYSQL_LIBS="-L$PHP_ZLIB_DIR/lib -lz"
|
||||
else
|
||||
PHP_ADD_LIBRARY(z,, MYSQL_SHARED_LIBADD)
|
||||
PHP_CHECK_LIBRARY(mysqlclient, mysql_errno, [], [
|
||||
PHP_CHECK_LIBRARY($MY_LIBNAME, mysql_errno, [], [
|
||||
AC_MSG_ERROR([Try adding --with-zlib-dir=<DIR>. Please check config.log for more information.])
|
||||
], [
|
||||
-L$MYSQL_LIB_DIR
|
||||
@@ -145,8 +152,8 @@ elif test "$PHP_MYSQL" != "no"; then
|
||||
-L$MYSQL_LIB_DIR
|
||||
])
|
||||
|
||||
PHP_ADD_LIBRARY_WITH_PATH(mysqlclient, $MYSQL_LIB_DIR, MYSQL_SHARED_LIBADD)
|
||||
MYSQL_LIBS="-L$MYSQL_LIB_DIR -lmysqlclient $MYSQL_LIBS"
|
||||
PHP_ADD_LIBRARY_WITH_PATH($MY_LIBNAME, $MYSQL_LIB_DIR, MYSQL_SHARED_LIBADD)
|
||||
MYSQL_LIBS="-L$MYSQL_LIB_DIR -l$MY_LIBNAME $MYSQL_LIBS"
|
||||
|
||||
PHP_ADD_INCLUDE($MYSQL_INC_DIR)
|
||||
MYSQL_INCLUDE=-I$MYSQL_INC_DIR
|
||||
|
||||
@@ -239,7 +239,7 @@ inline double ulonglong2double(ulonglong value)
|
||||
#define HAVE_ALLOCA
|
||||
#define HAVE_STRPBRK
|
||||
#define HAVE_STRSTR
|
||||
/* #define HAVE_COMPRESS -- not with PHP, please */
|
||||
#define HAVE_COMPRESS
|
||||
|
||||
#ifdef NOT_USED
|
||||
#define HAVE_SNPRINTF /* Gave link error */
|
||||
|
||||
@@ -51,6 +51,9 @@
|
||||
# endif
|
||||
# include <netdb.h>
|
||||
# include <netinet/in.h>
|
||||
# if HAVE_ARPA_INET_H
|
||||
# include <arpa/inet.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <mysql.h>
|
||||
|
||||
+29
-9
@@ -836,18 +836,18 @@ _oci_conn_list_dtor(oci_connection *connection TSRMLS_DC)
|
||||
(ub4) OCI_HTYPE_SVCCTX));
|
||||
}
|
||||
|
||||
if (connection->session && connection->session->exclusive) {
|
||||
/* exclusive connection created via OCINLogon() close their
|
||||
associated session when destructed */
|
||||
zend_list_delete(connection->session->num);
|
||||
}
|
||||
|
||||
if (connection->pError) {
|
||||
CALL_OCI(OCIHandleFree(
|
||||
(dvoid *) connection->pError,
|
||||
(ub4) OCI_HTYPE_ERROR));
|
||||
}
|
||||
|
||||
if (connection->session && connection->session->exclusive) {
|
||||
/* exclusive connection created via OCINLogon() close their
|
||||
associated session when destructed */
|
||||
zend_list_delete(connection->session->num);
|
||||
}
|
||||
|
||||
oci_debug("END _oci_conn_list_dtor: id=%d",connection->id);
|
||||
|
||||
efree(connection);
|
||||
@@ -1285,7 +1285,12 @@ _oci_make_zval(zval *value,oci_statement *statement,oci_out_column *column, char
|
||||
if (oci_loadlob(statement->conn,descr,&buffer,&loblen)) {
|
||||
ZVAL_FALSE(value);
|
||||
} else {
|
||||
ZVAL_STRINGL(value,buffer,loblen,0);
|
||||
if (loblen > 0) {
|
||||
ZVAL_STRINGL(value,buffer,loblen,0);
|
||||
}
|
||||
else {
|
||||
ZVAL_EMPTY_STRING(value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* return the locator */
|
||||
@@ -1912,6 +1917,10 @@ oci_loadlob(oci_connection *connection, oci_descriptor *mydescr, char **buffer,u
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (readlen == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
buf = emalloc(readlen + 1);
|
||||
|
||||
while (readlen > 0) { /* thies loop should not be entered on readlen == 0 */
|
||||
@@ -2527,7 +2536,7 @@ static oci_server *_oci_open_server(char *dbname,int persistent)
|
||||
/* breakthru to open */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
server = calloc(1,sizeof(oci_server));
|
||||
|
||||
server->persistent = persistent;
|
||||
@@ -2975,6 +2984,12 @@ break;
|
||||
}
|
||||
value_sz = sizeof(void*);
|
||||
break;
|
||||
case SQLT_CHR:
|
||||
break;
|
||||
default:
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or unsupported datatype given: %u", ocitype);
|
||||
RETURN_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ocitype == SQLT_CHR) && (value_sz == -1)) {
|
||||
@@ -3280,7 +3295,12 @@ PHP_FUNCTION(ociloadlob)
|
||||
}
|
||||
|
||||
if (!oci_loadlob(descr->conn,descr,&buffer,&loblen)) {
|
||||
RETURN_STRINGL(buffer,loblen,0);
|
||||
if (loblen > 0) {
|
||||
RETURN_STRINGL(buffer,loblen,0);
|
||||
}
|
||||
else {
|
||||
RETURN_EMPTY_STRING();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+30
-3
@@ -223,7 +223,7 @@ AC_MSG_CHECKING(for Empress support)
|
||||
AC_ARG_WITH(empress,
|
||||
[ --with-empress[=DIR] Include Empress support. DIR is the Empress base
|
||||
install directory, defaults to \$EMPRESSPATH.
|
||||
From PHP4, this option only supports Empress Version
|
||||
From PHP 4, this option only supports Empress Version
|
||||
8.60 and above],
|
||||
[
|
||||
PHP_WITH_SHARED
|
||||
@@ -255,7 +255,7 @@ AC_ARG_WITH(empress-bcs,
|
||||
[ --with-empress-bcs[=DIR]
|
||||
Include Empress Local Access support. DIR is the
|
||||
Empress base install directory, defaults to
|
||||
\$EMPRESSPATH. From PHP4, this option only supports
|
||||
\$EMPRESSPATH. From PHP 4, this option only supports
|
||||
Empress Version 8.60 and above.],
|
||||
[
|
||||
PHP_WITH_SHARED
|
||||
@@ -313,10 +313,35 @@ AC_ARG_WITH(birdstep,
|
||||
ODBC_INCDIR=$withval/include
|
||||
ODBC_LIBDIR=$withval/lib
|
||||
fi
|
||||
|
||||
case $host_alias in
|
||||
*aix*[)]
|
||||
AC_DEFINE(AIX,1,[ ]);;
|
||||
*hpux*[)]
|
||||
AC_DEFINE(HPUX,1,[ ]);;
|
||||
*linux*[)]
|
||||
AC_DEFINE(LINUX,1,[ ]);;
|
||||
*qnx*[)]
|
||||
AC_DEFINE(NEUTRINO,1,[ ]);;
|
||||
i?86-*-solaris*[)]
|
||||
AC_DEFINE(ISOLARIS,1,[ ]);;
|
||||
sparc-*-solaris*[)]
|
||||
AC_DEFINE(SOLARIS,1,[ ]);;
|
||||
*unixware*[)]
|
||||
AC_DEFINE(UNIXWARE,1,[ ]);;
|
||||
esac
|
||||
|
||||
ODBC_INCLUDE=-I$ODBC_INCDIR
|
||||
ODBC_TYPE=birdstep
|
||||
ODBC_LFLAGS=-L$ODBC_LIBDIR
|
||||
ODBC_LIBS="-lCadm -lCdict -lCenc -lCrdm -lCrpc -lCrdbc -lCrm -lCuapi -lutil"
|
||||
|
||||
if test -e "$ODBC_LIBDIR/libCrdbc32.$SHLIB_SUFFIX_NAME"; then
|
||||
ODBC_LIBS="-lCrdbc32 -lCadm32 -lCncp32 -lCrm32 -lCsql32 -lCdict32 -lCrdm32 -lCrpc32 -lutil"
|
||||
elif test -e "$ODBC_LIBDIR/libCrdbc.$SHLIB_SUFFIX_NAME"; then
|
||||
ODBC_LIBS="-lCrdbc -lCadm -lCncp -lCrm -lCsql -lCdict -lCrdm -lCrpc -lutil"
|
||||
fi
|
||||
|
||||
AC_DEFINE(HAVE_BIRDSTEP,1,[ ])
|
||||
|
||||
AC_MSG_RESULT(yes)
|
||||
@@ -514,7 +539,9 @@ if test -n "$ODBC_TYPE"; then
|
||||
if test "$ODBC_TYPE" != "dbmaker"; then
|
||||
ext_shared=$shared
|
||||
PHP_EVAL_LIBLINE([$ODBC_LFLAGS $ODBC_LIBS], ODBC_SHARED_LIBADD)
|
||||
AC_DEFINE(HAVE_SQLDATASOURCES,1,[ ])
|
||||
if test "$ODBC_TYPE" != "birdstep"; then
|
||||
AC_DEFINE(HAVE_SQLDATASOURCES,1,[ ])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_DEFINE(HAVE_UODBC,1,[ ])
|
||||
|
||||
+5
-3
@@ -245,7 +245,7 @@ static void _close_odbc_pconn(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
||||
odbc_result *res;
|
||||
odbc_connection *conn = (odbc_connection *)rsrc->ptr;
|
||||
|
||||
nument = zend_hash_next_free_element(&EG(regular_list));
|
||||
nument = zend_hash_next_free_element(&EG(persistent_list));
|
||||
for(i = 1; i < nument; i++) {
|
||||
ptr = zend_list_find(i, &type);
|
||||
if (ptr && (type == le_result)) {
|
||||
@@ -2436,8 +2436,10 @@ PHP_FUNCTION(odbc_next_result)
|
||||
result->values = NULL;
|
||||
}
|
||||
RETURN_TRUE;
|
||||
}
|
||||
else {
|
||||
} else if (rc == SQL_NO_DATA_FOUND) {
|
||||
RETURN_FALSE;
|
||||
} else {
|
||||
odbc_sql_error(result->conn_ptr, result->stmt, "SQLMoreResults");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@
|
||||
extern zend_module_entry odbc_module_entry;
|
||||
#define odbc_module_ptr &odbc_module_entry
|
||||
|
||||
#if defined(HAVE_DBMAKER) || defined(PHP_WIN32) || defined(HAVE_IBMDB2) || defined(HAVE_UNIXODBC)
|
||||
#if defined(HAVE_DBMAKER) || defined(PHP_WIN32) || defined(HAVE_IBMDB2) || defined(HAVE_UNIXODBC) || defined(HAVE_BIRDSTEP)
|
||||
# define PHP_ODBC_HAVE_FETCH_HASH 1
|
||||
#endif
|
||||
|
||||
|
||||
@@ -216,7 +216,7 @@ typedef struct odbc_connection {
|
||||
typedef struct odbc_result_value {
|
||||
char name[32];
|
||||
char *value;
|
||||
long int vallen;
|
||||
SDWORD vallen;
|
||||
SDWORD coltype;
|
||||
} odbc_result_value;
|
||||
|
||||
|
||||
@@ -2510,7 +2510,7 @@ PHP_FUNCTION(openssl_private_encrypt)
|
||||
cryptedlen = EVP_PKEY_size(pkey);
|
||||
cryptedbuf = emalloc(cryptedlen + 1);
|
||||
|
||||
switch (Z_TYPE_P(pkey)) {
|
||||
switch (pkey->type) {
|
||||
case EVP_PKEY_RSA:
|
||||
case EVP_PKEY_RSA2:
|
||||
successful = (RSA_private_encrypt(data_len,
|
||||
@@ -2566,7 +2566,7 @@ PHP_FUNCTION(openssl_private_decrypt)
|
||||
cryptedlen = EVP_PKEY_size(pkey);
|
||||
crypttemp = emalloc(cryptedlen + 1);
|
||||
|
||||
switch (Z_TYPE_P(pkey)) {
|
||||
switch (pkey->type) {
|
||||
case EVP_PKEY_RSA:
|
||||
case EVP_PKEY_RSA2:
|
||||
cryptedlen = RSA_private_decrypt(data_len,
|
||||
@@ -2629,7 +2629,7 @@ PHP_FUNCTION(openssl_public_encrypt)
|
||||
cryptedlen = EVP_PKEY_size(pkey);
|
||||
cryptedbuf = emalloc(cryptedlen + 1);
|
||||
|
||||
switch (Z_TYPE_P(pkey)) {
|
||||
switch (pkey->type) {
|
||||
case EVP_PKEY_RSA:
|
||||
case EVP_PKEY_RSA2:
|
||||
successful = (RSA_public_encrypt(data_len,
|
||||
@@ -2686,7 +2686,7 @@ PHP_FUNCTION(openssl_public_decrypt)
|
||||
cryptedlen = EVP_PKEY_size(pkey);
|
||||
crypttemp = emalloc(cryptedlen + 1);
|
||||
|
||||
switch (Z_TYPE_P(pkey)) {
|
||||
switch (pkey->type) {
|
||||
case EVP_PKEY_RSA:
|
||||
case EVP_PKEY_RSA2:
|
||||
cryptedlen = RSA_public_decrypt(data_len,
|
||||
|
||||
+64
-36
@@ -139,17 +139,13 @@ void php_register_signal_constants(INIT_FUNC_ARGS)
|
||||
|
||||
static void php_pcntl_init_globals(zend_pcntl_globals *pcntl_globals)
|
||||
{
|
||||
/* Just in case ... */
|
||||
memset(&pcntl_globals->php_signal_queue,0,sizeof(pcntl_globals->php_signal_queue));
|
||||
|
||||
zend_llist_init(&pcntl_globals->php_signal_queue, sizeof (long), NULL, 1);
|
||||
pcntl_globals->signal_queue_ready = 0;
|
||||
pcntl_globals->processing_signal_queue = 0;
|
||||
memset(pcntl_globals, 0, sizeof(*pcntl_globals));
|
||||
}
|
||||
|
||||
PHP_RINIT_FUNCTION(pcntl)
|
||||
{
|
||||
zend_hash_init(&PCNTL_G(php_signal_table), 16, NULL, ZVAL_PTR_DTOR, 1);
|
||||
zend_hash_init(&PCNTL_G(php_signal_table), 16, NULL, ZVAL_PTR_DTOR, 0);
|
||||
PCNTL_G(head) = PCNTL_G(tail) = PCNTL_G(spares) = NULL;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -164,13 +160,26 @@ PHP_MINIT_FUNCTION(pcntl)
|
||||
|
||||
PHP_MSHUTDOWN_FUNCTION(pcntl)
|
||||
{
|
||||
zend_llist_destroy(&PCNTL_G(php_signal_queue));
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
PHP_RSHUTDOWN_FUNCTION(pcntl)
|
||||
{
|
||||
struct php_pcntl_pending_signal *sig;
|
||||
|
||||
/* FIXME: if a signal is delivered after this point, things will go pear shaped;
|
||||
* need to remove signal handlers */
|
||||
zend_hash_destroy(&PCNTL_G(php_signal_table));
|
||||
while (PCNTL_G(head)) {
|
||||
sig = PCNTL_G(head);
|
||||
PCNTL_G(head) = sig->next;
|
||||
efree(sig);
|
||||
}
|
||||
while (PCNTL_G(spares)) {
|
||||
sig = PCNTL_G(spares);
|
||||
PCNTL_G(spares) = sig->next;
|
||||
efree(sig);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -467,6 +476,19 @@ PHP_FUNCTION(pcntl_signal)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PCNTL_G(spares)) {
|
||||
/* since calling malloc() from within a signal handler is not portable,
|
||||
* pre-allocate a few records for recording signals */
|
||||
int i;
|
||||
for (i = 0; i < 32; i++) {
|
||||
struct php_pcntl_pending_signal *psig;
|
||||
|
||||
psig = emalloc(sizeof(*psig));
|
||||
psig->next = PCNTL_G(spares);
|
||||
PCNTL_G(spares) = psig;
|
||||
}
|
||||
}
|
||||
|
||||
/* Special long value case for SIG_DFL and SIG_IGN */
|
||||
if (Z_TYPE_P(handle)==IS_LONG) {
|
||||
if (Z_LVAL_P(handle)!= (long) SIG_DFL && Z_LVAL_P(handle) != (long) SIG_IGN) {
|
||||
@@ -501,57 +523,63 @@ PHP_FUNCTION(pcntl_signal)
|
||||
/* Our custom signal handler that calls the appropriate php_function */
|
||||
static void pcntl_signal_handler(int signo)
|
||||
{
|
||||
long signal_num = signo;
|
||||
struct php_pcntl_pending_signal *psig;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
IF_DEBUG(DEBUG_OUT("Caught signo %d\n", signo));
|
||||
if (! PCNTL_G(processing_signal_queue)) {
|
||||
zend_llist_add_element(&PCNTL_G(php_signal_queue), &signal_num);
|
||||
PCNTL_G(signal_queue_ready) = 1;
|
||||
IF_DEBUG(DEBUG_OUT("Added queue entry\n"));
|
||||
psig = PCNTL_G(spares);
|
||||
if (!psig) {
|
||||
/* oops, too many signals for us to track, so we'll forget about this one */
|
||||
return;
|
||||
}
|
||||
return;
|
||||
PCNTL_G(spares) = psig->next;
|
||||
|
||||
psig->signo = signo;
|
||||
psig->next = NULL;
|
||||
|
||||
/* the head check is important, as the tick handler cannot atomically clear both
|
||||
* the head and tail */
|
||||
if (PCNTL_G(head) && PCNTL_G(tail)) {
|
||||
PCNTL_G(tail)->next = psig;
|
||||
} else {
|
||||
PCNTL_G(head) = psig;
|
||||
}
|
||||
PCNTL_G(tail) = psig;
|
||||
}
|
||||
|
||||
void pcntl_tick_handler()
|
||||
{
|
||||
zend_llist_element *element;
|
||||
zval *param, **handle, *retval;
|
||||
struct php_pcntl_pending_signal *queue, *next;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
/* Bail if the queue is empty or if we are already playing the queue*/
|
||||
if (! PCNTL_G(signal_queue_ready) || PCNTL_G(processing_signal_queue))
|
||||
if (! PCNTL_G(head) || PCNTL_G(processing_signal_queue))
|
||||
return;
|
||||
|
||||
/* Mark our queue empty */
|
||||
PCNTL_G(signal_queue_ready) = 0;
|
||||
|
||||
/* If for some reason our signal queue is empty then return */
|
||||
if (zend_llist_count(&PCNTL_G(php_signal_queue)) <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Prevent reentrant handler calls */
|
||||
PCNTL_G(processing_signal_queue) = 1;
|
||||
|
||||
queue = PCNTL_G(head);
|
||||
PCNTL_G(head) = NULL; /* simple stores are atomic */
|
||||
|
||||
/* Allocate */
|
||||
MAKE_STD_ZVAL(param);
|
||||
MAKE_STD_ZVAL(retval);
|
||||
|
||||
/* Traverse through our signal queue and call the appropriate php functions */
|
||||
for (element = (&PCNTL_G(php_signal_queue))->head; element; element = element->next) {
|
||||
long *signal_num = (long *)&element->data;
|
||||
if (zend_hash_index_find(&PCNTL_G(php_signal_table), *signal_num, (void **) &handle)==FAILURE) {
|
||||
continue;
|
||||
while (queue) {
|
||||
if (zend_hash_index_find(&PCNTL_G(php_signal_table), queue->signo, (void **) &handle)==SUCCESS) {
|
||||
ZVAL_LONG(param, queue->signo);
|
||||
|
||||
/* Call php signal handler - Note that we do not report errors, and we ignore the return value */
|
||||
/* FIXME: this is probably broken when multiple signals are handled in this while loop (retval) */
|
||||
call_user_function(EG(function_table), NULL, *handle, retval, 1, ¶m TSRMLS_CC);
|
||||
}
|
||||
|
||||
ZVAL_LONG(param, *signal_num);
|
||||
|
||||
/* Call php signal handler - Note that we do not report errors, and we ignore the eturn value */
|
||||
call_user_function(EG(function_table), NULL, *handle, retval, 1, ¶m TSRMLS_CC);
|
||||
next = queue->next;
|
||||
queue->next = PCNTL_G(spares);
|
||||
PCNTL_G(spares) = queue;
|
||||
queue = next;
|
||||
}
|
||||
/* Clear */
|
||||
zend_llist_clean(&PCNTL_G(php_signal_queue));
|
||||
|
||||
/* Re-enable queue */
|
||||
PCNTL_G(processing_signal_queue) = 0;
|
||||
|
||||
@@ -51,12 +51,17 @@ PHP_FUNCTION(pcntl_wstopsig);
|
||||
PHP_FUNCTION(pcntl_signal);
|
||||
PHP_FUNCTION(pcntl_exec);
|
||||
|
||||
struct php_pcntl_pending_signal {
|
||||
struct php_pcntl_pending_signal *next;
|
||||
long signo;
|
||||
};
|
||||
|
||||
ZEND_BEGIN_MODULE_GLOBALS(pcntl)
|
||||
HashTable php_signal_table;
|
||||
zend_llist php_signal_queue;
|
||||
int signal_queue_ready;
|
||||
int processing_signal_queue;
|
||||
struct php_pcntl_pending_signal *head, *tail, *spares;
|
||||
ZEND_END_MODULE_GLOBALS(pcntl)
|
||||
|
||||
#ifdef ZTS
|
||||
#define PCNTL_G(v) TSRMG(pcntl_globals_id, zend_pcntl_globals *, v)
|
||||
#else
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
declare(ticks=1);
|
||||
|
||||
function alarm_handle($signal){
|
||||
if ($signal==SIGALRM) print "Caught SIGALRM!!!\n";
|
||||
if ($signal==SIGALRM) print "Child: Caught SIGALRM!!!\n";
|
||||
}
|
||||
|
||||
function usr1_handle($signal){
|
||||
if ($signal==SIGUSR1) print "Caught SIGUSR1!!!\n";
|
||||
if ($signal==SIGUSR1) print "Child: Caught SIGUSR1!!!\n";
|
||||
}
|
||||
|
||||
print "This test will demonstrate a fork followed by ipc via signals.\n";
|
||||
@@ -23,6 +23,7 @@ if ($pid==0) {
|
||||
sleep(100);
|
||||
print "Child: Resetting Alarm handler to Ignore....\n";
|
||||
pcntl_signal(SIGALRM, SIG_IGN);
|
||||
print "Child: sleeping for 10 seconds....\n";
|
||||
sleep(10);
|
||||
print "Done\n";
|
||||
} else {
|
||||
@@ -33,7 +34,7 @@ if ($pid==0) {
|
||||
sleep(1);
|
||||
print "Parent: Senging SIGUSR1 to Child\n";
|
||||
posix_kill($pid,SIGUSR1);
|
||||
sleep(1);
|
||||
sleep(2);
|
||||
print "Parent: Sending SIGALRM to Child\n";
|
||||
pcntl_waitpid($pid, &$status, $options);
|
||||
}
|
||||
+2
-2
@@ -13,7 +13,7 @@ PHP_ARG_WITH(pcre-regex,for PCRE support,
|
||||
|
||||
if test "$PHP_PCRE_REGEX" != "no"; then
|
||||
if test "$PHP_PCRE_REGEX" = "yes"; then
|
||||
PHP_NEW_EXTENSION(pcre, pcrelib/maketables.c pcrelib/get.c pcrelib/study.c pcrelib/pcre.c php_pcre.c, $ext_shared,,-DSUPPORT_UTF8 -DLINK_SIZE=2 -DPOSIX_MALLOC_THRESHOLD=10 -I@ext_srcdir@/pcrelib)
|
||||
PHP_NEW_EXTENSION(pcre, pcrelib/pcre_chartables.c pcrelib/pcre_compile.c pcrelib/pcre_config.c pcrelib/pcre_dfa_exec.c pcrelib/pcre_exec.c pcrelib/pcre_fullinfo.c pcrelib/pcre_get.c pcrelib/pcre_globals.c pcrelib/pcre_info.c pcrelib/pcre_maketables.c pcrelib/pcre_ord2utf8.c pcrelib/pcre_printint.c pcrelib/pcre_refcount.c pcrelib/pcre_study.c pcrelib/pcre_tables.c pcrelib/pcre_try_flipped.c pcrelib/pcre_ucp_findchar.c pcrelib/pcre_valid_utf8.c pcrelib/pcre_version.c pcrelib/pcre_xclass.c php_pcre.c, $ext_shared,,-DEXPORT= -DNEWLINE=10 -DSUPPORT_UTF8 -DSUPPORT_UCP -DLINK_SIZE=2 -DPOSIX_MALLOC_THRESHOLD=10 -DMATCH_LIMIT=10000000 -I@ext_srcdir@/pcrelib)
|
||||
PHP_ADD_BUILD_DIR($ext_builddir/pcrelib)
|
||||
AC_DEFINE(HAVE_BUNDLED_PCRE, 1, [ ])
|
||||
else
|
||||
@@ -50,7 +50,7 @@ if test "$PHP_PCRE_REGEX" != "no"; then
|
||||
|
||||
AC_DEFINE(HAVE_PCRE, 1, [ ])
|
||||
PHP_ADD_INCLUDE($PCRE_INCDIR)
|
||||
PHP_NEW_EXTENSION(pcre, php_pcre.c, $ext_shared,,-DSUPPORT_UTF8 -DLINK_SIZE=2 -DPOSIX_MALLOC_THRESHOLD=10)
|
||||
PHP_NEW_EXTENSION(pcre, php_pcre.c, $ext_shared,,-DEXPORT= -DNEWLINE=10 -DSUPPORT_UTF8 -DSUPPORT_UCP -DLINK_SIZE=2 -DPOSIX_MALLOC_THRESHOLD=10 -DMATCH_LIMIT=10000000)
|
||||
fi
|
||||
PHP_SUBST(PCRE_SHARED_LIBADD)
|
||||
fi
|
||||
@@ -1,6 +1,23 @@
|
||||
Written by: Philip Hazel <ph10@cam.ac.uk>
|
||||
THE MAIN PCRE LIBRARY
|
||||
---------------------
|
||||
|
||||
Written by: Philip Hazel
|
||||
Email local part: ph10
|
||||
Email domain: cam.ac.uk
|
||||
|
||||
University of Cambridge Computing Service,
|
||||
Cambridge, England. Phone: +44 1223 334714.
|
||||
|
||||
Copyright (c) 1997-2003 University of Cambridge
|
||||
Copyright (c) 1997-2005 University of Cambridge
|
||||
All rights reserved
|
||||
|
||||
|
||||
THE C++ WRAPPER LIBRARY
|
||||
-----------------------
|
||||
|
||||
Written by: Google Inc.
|
||||
|
||||
Copyright (c) 2005 Google Inc
|
||||
All rights reserved
|
||||
|
||||
####
|
||||
+46
-32
@@ -4,51 +4,65 @@ PCRE LICENCE
|
||||
PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by: Philip Hazel <ph10@cam.ac.uk>
|
||||
Release 6 of PCRE is distributed under the terms of the "BSD" licence, as
|
||||
specified below. The documentation for PCRE, supplied in the "doc"
|
||||
directory, is distributed under the same terms as the software itself.
|
||||
|
||||
The basic library functions are written in C and are freestanding. Also
|
||||
included in the distribution is a set of C++ wrapper functions.
|
||||
|
||||
|
||||
THE BASIC LIBRARY FUNCTIONS
|
||||
---------------------------
|
||||
|
||||
Written by: Philip Hazel
|
||||
Email local part: ph10
|
||||
Email domain: cam.ac.uk
|
||||
|
||||
University of Cambridge Computing Service,
|
||||
Cambridge, England. Phone: +44 1223 334714.
|
||||
|
||||
Copyright (c) 1997-2003 University of Cambridge
|
||||
Copyright (c) 1997-2005 University of Cambridge
|
||||
All rights reserved.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose on any
|
||||
computer system, and to redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
|
||||
1. This software 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.
|
||||
THE C++ WRAPPER FUNCTIONS
|
||||
-------------------------
|
||||
|
||||
2. The origin of this software must not be misrepresented, either by
|
||||
explicit claim or by omission. In practice, this means that if you use
|
||||
PCRE in software that you distribute to others, commercially or
|
||||
otherwise, you must put a sentence like this
|
||||
Contributed by: Google Inc.
|
||||
|
||||
Regular expression support is provided by the PCRE library package,
|
||||
which is open source software, written by Philip Hazel, and copyright
|
||||
by the University of Cambridge, England.
|
||||
Copyright (c) 2005, Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
somewhere reasonably visible in your documentation and in any relevant
|
||||
files or online help data or similar. A reference to the ftp site for
|
||||
the source, that is, to
|
||||
|
||||
ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
|
||||
THE "BSD" LICENCE
|
||||
-----------------
|
||||
|
||||
should also be given in the documentation. However, this condition is not
|
||||
intended to apply to whole chains of software. If package A includes PCRE,
|
||||
it must acknowledge it, but if package B is software that includes package
|
||||
A, the condition is not imposed on package B (unless it uses PCRE
|
||||
independently).
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
3. Altered versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
4. If PCRE is embedded in any software that is released under the GNU
|
||||
General Purpose Licence (GPL), or Lesser General Purpose Licence (LGPL),
|
||||
then the terms of that licence shall supersede any condition above with
|
||||
which it is incompatible.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
The documentation for PCRE, supplied in the "doc" directory, is distributed
|
||||
under the same terms as the software itself.
|
||||
* Neither the name of the University of Cambridge nor the name of Google
|
||||
Inc. nor the names of their contributors may be used to endorse or
|
||||
promote products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
End
|
||||
@@ -1,6 +1,357 @@
|
||||
ChangeLog for PCRE
|
||||
------------------
|
||||
|
||||
Version 6.2 01-Aug-05
|
||||
---------------------
|
||||
|
||||
1. There was no test for integer overflow of quantifier values. A construction
|
||||
such as {1111111111111111} would give undefined results. What is worse, if
|
||||
a minimum quantifier for a parenthesized subpattern overflowed and became
|
||||
negative, the calculation of the memory size went wrong. This could have
|
||||
led to memory overwriting.
|
||||
|
||||
2. Building PCRE using VPATH was broken. Hopefully it is now fixed.
|
||||
|
||||
3. Added "b" to the 2nd argument of fopen() in dftables.c, for non-Unix-like
|
||||
operating environments where this matters.
|
||||
|
||||
4. Applied Giuseppe Maxia's patch to add additional features for controlling
|
||||
PCRE options from within the C++ wrapper.
|
||||
|
||||
5. Named capturing subpatterns were not being correctly counted when a pattern
|
||||
was compiled. This caused two problems: (a) If there were more than 100
|
||||
such subpatterns, the calculation of the memory needed for the whole
|
||||
compiled pattern went wrong, leading to an overflow error. (b) Numerical
|
||||
back references of the form \12, where the number was greater than 9, were
|
||||
not recognized as back references, even though there were sufficient
|
||||
previous subpatterns.
|
||||
|
||||
6. Two minor patches to pcrecpp.cc in order to allow it to compile on older
|
||||
versions of gcc, e.g. 2.95.4.
|
||||
|
||||
|
||||
Version 6.1 21-Jun-05
|
||||
---------------------
|
||||
|
||||
1. There was one reference to the variable "posix" in pcretest.c that was not
|
||||
surrounded by "#if !defined NOPOSIX".
|
||||
|
||||
2. Make it possible to compile pcretest without DFA support, UTF8 support, or
|
||||
the cross-check on the old pcre_info() function, for the benefit of the
|
||||
cut-down version of PCRE that is currently imported into Exim.
|
||||
|
||||
3. A (silly) pattern starting with (?i)(?-i) caused an internal space
|
||||
allocation error. I've done the easy fix, which wastes 2 bytes for sensible
|
||||
patterns that start (?i) but I don't think that matters. The use of (?i) is
|
||||
just an example; this all applies to the other options as well.
|
||||
|
||||
4. Since libtool seems to echo the compile commands it is issuing, the output
|
||||
from "make" can be reduced a bit by putting "@" in front of each libtool
|
||||
compile command.
|
||||
|
||||
5. Patch from the folks at Google for configure.in to be a bit more thorough
|
||||
in checking for a suitable C++ installation before trying to compile the
|
||||
C++ stuff. This should fix a reported problem when a compiler was present,
|
||||
but no suitable headers.
|
||||
|
||||
6. The man pages all had just "PCRE" as their title. I have changed them to
|
||||
be the relevant file name. I have also arranged that these names are
|
||||
retained in the file doc/pcre.txt, which is a concatenation in text format
|
||||
of all the man pages except the little individual ones for each function.
|
||||
|
||||
7. The NON-UNIX-USE file had not been updated for the different set of source
|
||||
files that come with release 6. I also added a few comments about the C++
|
||||
wrapper.
|
||||
|
||||
|
||||
Version 6.0 07-Jun-05
|
||||
---------------------
|
||||
|
||||
1. Some minor internal re-organization to help with my DFA experiments.
|
||||
|
||||
2. Some missing #ifdef SUPPORT_UCP conditionals in pcretest and printint that
|
||||
didn't matter for the library itself when fully configured, but did matter
|
||||
when compiling without UCP support, or within Exim, where the ucp files are
|
||||
not imported.
|
||||
|
||||
3. Refactoring of the library code to split up the various functions into
|
||||
different source modules. The addition of the new DFA matching code (see
|
||||
below) to a single monolithic source would have made it really too
|
||||
unwieldy, quite apart from causing all the code to be include in a
|
||||
statically linked application, when only some functions are used. This is
|
||||
relevant even without the DFA addition now that patterns can be compiled in
|
||||
one application and matched in another.
|
||||
|
||||
The downside of splitting up is that there have to be some external
|
||||
functions and data tables that are used internally in different modules of
|
||||
the library but which are not part of the API. These have all had their
|
||||
names changed to start with "_pcre_" so that they are unlikely to clash
|
||||
with other external names.
|
||||
|
||||
4. Added an alternate matching function, pcre_dfa_exec(), which matches using
|
||||
a different (DFA) algorithm. Although it is slower than the original
|
||||
function, it does have some advantages for certain types of matching
|
||||
problem.
|
||||
|
||||
5. Upgrades to pcretest in order to test the features of pcre_dfa_exec(),
|
||||
including restarting after a partial match.
|
||||
|
||||
6. A patch for pcregrep that defines INVALID_FILE_ATTRIBUTES if it is not
|
||||
defined when compiling for Windows was sent to me. I have put it into the
|
||||
code, though I have no means of testing or verifying it.
|
||||
|
||||
7. Added the pcre_refcount() auxiliary function.
|
||||
|
||||
8. Added the PCRE_FIRSTLINE option. This constrains an unanchored pattern to
|
||||
match before or at the first newline in the subject string. In pcretest,
|
||||
the /f option on a pattern can be used to set this.
|
||||
|
||||
9. A repeated \w when used in UTF-8 mode with characters greater than 256
|
||||
would behave wrongly. This has been present in PCRE since release 4.0.
|
||||
|
||||
10. A number of changes to the pcregrep command:
|
||||
|
||||
(a) Refactored how -x works; insert ^(...)$ instead of setting
|
||||
PCRE_ANCHORED and checking the length, in preparation for adding
|
||||
something similar for -w.
|
||||
|
||||
(b) Added the -w (match as a word) option.
|
||||
|
||||
(c) Refactored the way lines are read and buffered so as to have more
|
||||
than one at a time available.
|
||||
|
||||
(d) Implemented a pcregrep test script.
|
||||
|
||||
(e) Added the -M (multiline match) option. This allows patterns to match
|
||||
over several lines of the subject. The buffering ensures that at least
|
||||
8K, or the rest of the document (whichever is the shorter) is available
|
||||
for matching (and similarly the previous 8K for lookbehind assertions).
|
||||
|
||||
(f) Changed the --help output so that it now says
|
||||
|
||||
-w, --word-regex(p)
|
||||
|
||||
instead of two lines, one with "regex" and the other with "regexp"
|
||||
because that confused at least one person since the short forms are the
|
||||
same. (This required a bit of code, as the output is generated
|
||||
automatically from a table. It wasn't just a text change.)
|
||||
|
||||
(g) -- can be used to terminate pcregrep options if the next thing isn't an
|
||||
option but starts with a hyphen. Could be a pattern or a path name
|
||||
starting with a hyphen, for instance.
|
||||
|
||||
(h) "-" can be given as a file name to represent stdin.
|
||||
|
||||
(i) When file names are being printed, "(standard input)" is used for
|
||||
the standard input, for compatibility with GNU grep. Previously
|
||||
"<stdin>" was used.
|
||||
|
||||
(j) The option --label=xxx can be used to supply a name to be used for
|
||||
stdin when file names are being printed. There is no short form.
|
||||
|
||||
(k) Re-factored the options decoding logic because we are going to add
|
||||
two more options that take data. Such options can now be given in four
|
||||
different ways, e.g. "-fname", "-f name", "--file=name", "--file name".
|
||||
|
||||
(l) Added the -A, -B, and -C options for requesting that lines of context
|
||||
around matches be printed.
|
||||
|
||||
(m) Added the -L option to print the names of files that do not contain
|
||||
any matching lines, that is, the complement of -l.
|
||||
|
||||
(n) The return code is 2 if any file cannot be opened, but pcregrep does
|
||||
continue to scan other files.
|
||||
|
||||
(o) The -s option was incorrectly implemented. For compatibility with other
|
||||
greps, it now suppresses the error message for a non-existent or non-
|
||||
accessible file (but not the return code). There is a new option called
|
||||
-q that suppresses the output of matching lines, which was what -s was
|
||||
previously doing.
|
||||
|
||||
(p) Added --include and --exclude options to specify files for inclusion
|
||||
and exclusion when recursing.
|
||||
|
||||
11. The Makefile was not using the Autoconf-supported LDFLAGS macro properly.
|
||||
Hopefully, it now does.
|
||||
|
||||
12. Missing cast in pcre_study().
|
||||
|
||||
13. Added an "uninstall" target to the makefile.
|
||||
|
||||
14. Replaced "extern" in the function prototypes in Makefile.in with
|
||||
"PCRE_DATA_SCOPE", which defaults to 'extern' or 'extern "C"' in the Unix
|
||||
world, but is set differently for Windows.
|
||||
|
||||
15. Added a second compiling function called pcre_compile2(). The only
|
||||
difference is that it has an extra argument, which is a pointer to an
|
||||
integer error code. When there is a compile-time failure, this is set
|
||||
non-zero, in addition to the error test pointer being set to point to an
|
||||
error message. The new argument may be NULL if no error number is required
|
||||
(but then you may as well call pcre_compile(), which is now just a
|
||||
wrapper). This facility is provided because some applications need a
|
||||
numeric error indication, but it has also enabled me to tidy up the way
|
||||
compile-time errors are handled in the POSIX wrapper.
|
||||
|
||||
16. Added VPATH=.libs to the makefile; this should help when building with one
|
||||
prefix path and installing with another. (Or so I'm told by someone who
|
||||
knows more about this stuff than I do.)
|
||||
|
||||
17. Added a new option, REG_DOTALL, to the POSIX function regcomp(). This
|
||||
passes PCRE_DOTALL to the pcre_compile() function, making the "." character
|
||||
match everything, including newlines. This is not POSIX-compatible, but
|
||||
somebody wanted the feature. From pcretest it can be activated by using
|
||||
both the P and the s flags.
|
||||
|
||||
18. AC_PROG_LIBTOOL appeared twice in Makefile.in. Removed one.
|
||||
|
||||
19. libpcre.pc was being incorrectly installed as executable.
|
||||
|
||||
20. A couple of places in pcretest check for end-of-line by looking for '\n';
|
||||
it now also looks for '\r' so that it will work unmodified on Windows.
|
||||
|
||||
21. Added Google's contributed C++ wrapper to the distribution.
|
||||
|
||||
22. Added some untidy missing memory free() calls in pcretest, to keep
|
||||
Electric Fence happy when testing.
|
||||
|
||||
|
||||
|
||||
Version 5.0 13-Sep-04
|
||||
---------------------
|
||||
|
||||
1. Internal change: literal characters are no longer packed up into items
|
||||
containing multiple characters in a single byte-string. Each character
|
||||
is now matched using a separate opcode. However, there may be more than one
|
||||
byte in the character in UTF-8 mode.
|
||||
|
||||
2. The pcre_callout_block structure has two new fields: pattern_position and
|
||||
next_item_length. These contain the offset in the pattern to the next match
|
||||
item, and its length, respectively.
|
||||
|
||||
3. The PCRE_AUTO_CALLOUT option for pcre_compile() requests the automatic
|
||||
insertion of callouts before each pattern item. Added the /C option to
|
||||
pcretest to make use of this.
|
||||
|
||||
4. On the advice of a Windows user, the lines
|
||||
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
_setmode( _fileno( stdout ), 0x8000 );
|
||||
#endif /* defined(_WIN32) || defined(WIN32) */
|
||||
|
||||
have been added to the source of pcretest. This apparently does useful
|
||||
magic in relation to line terminators.
|
||||
|
||||
5. Changed "r" and "w" in the calls to fopen() in pcretest to "rb" and "wb"
|
||||
for the benefit of those environments where the "b" makes a difference.
|
||||
|
||||
6. The icc compiler has the same options as gcc, but "configure" doesn't seem
|
||||
to know about it. I have put a hack into configure.in that adds in code
|
||||
to set GCC=yes if CC=icc. This seems to end up at a point in the
|
||||
generated configure script that is early enough to affect the setting of
|
||||
compiler options, which is what is needed, but I have no means of testing
|
||||
whether it really works. (The user who reported this had patched the
|
||||
generated configure script, which of course I cannot do.)
|
||||
|
||||
LATER: After change 22 below (new libtool files), the configure script
|
||||
seems to know about icc (and also ecc). Therefore, I have commented out
|
||||
this hack in configure.in.
|
||||
|
||||
7. Added support for pkg-config (2 patches were sent in).
|
||||
|
||||
8. Negated POSIX character classes that used a combination of internal tables
|
||||
were completely broken. These were [[:^alpha:]], [[:^alnum:]], and
|
||||
[[:^ascii]]. Typically, they would match almost any characters. The other
|
||||
POSIX classes were not broken in this way.
|
||||
|
||||
9. Matching the pattern "\b.*?" against "ab cd", starting at offset 1, failed
|
||||
to find the match, as PCRE was deluded into thinking that the match had to
|
||||
start at the start point or following a newline. The same bug applied to
|
||||
patterns with negative forward assertions or any backward assertions
|
||||
preceding ".*" at the start, unless the pattern required a fixed first
|
||||
character. This was a failing pattern: "(?!.bcd).*". The bug is now fixed.
|
||||
|
||||
10. In UTF-8 mode, when moving forwards in the subject after a failed match
|
||||
starting at the last subject character, bytes beyond the end of the subject
|
||||
string were read.
|
||||
|
||||
11. Renamed the variable "class" as "classbits" to make life easier for C++
|
||||
users. (Previously there was a macro definition, but it apparently wasn't
|
||||
enough.)
|
||||
|
||||
12. Added the new field "tables" to the extra data so that tables can be passed
|
||||
in at exec time, or the internal tables can be re-selected. This allows
|
||||
a compiled regex to be saved and re-used at a later time by a different
|
||||
program that might have everything at different addresses.
|
||||
|
||||
13. Modified the pcre-config script so that, when run on Solaris, it shows a
|
||||
-R library as well as a -L library.
|
||||
|
||||
14. The debugging options of pcretest (-d on the command line or D on a
|
||||
pattern) showed incorrect output for anything following an extended class
|
||||
that contained multibyte characters and which was followed by a quantifier.
|
||||
|
||||
15. Added optional support for general category Unicode character properties
|
||||
via the \p, \P, and \X escapes. Unicode property support implies UTF-8
|
||||
support. It adds about 90K to the size of the library. The meanings of the
|
||||
inbuilt class escapes such as \d and \s have NOT been changed.
|
||||
|
||||
16. Updated pcredemo.c to include calls to free() to release the memory for the
|
||||
compiled pattern.
|
||||
|
||||
17. The generated file chartables.c was being created in the source directory
|
||||
instead of in the building directory. This caused the build to fail if the
|
||||
source directory was different from the building directory, and was
|
||||
read-only.
|
||||
|
||||
18. Added some sample Win commands from Mark Tetrode into the NON-UNIX-USE
|
||||
file. No doubt somebody will tell me if they don't make sense... Also added
|
||||
Dan Mooney's comments about building on OpenVMS.
|
||||
|
||||
19. Added support for partial matching via the PCRE_PARTIAL option for
|
||||
pcre_exec() and the \P data escape in pcretest.
|
||||
|
||||
20. Extended pcretest with 3 new pattern features:
|
||||
|
||||
(i) A pattern option of the form ">rest-of-line" causes pcretest to
|
||||
write the compiled pattern to the file whose name is "rest-of-line".
|
||||
This is a straight binary dump of the data, with the saved pointer to
|
||||
the character tables forced to be NULL. The study data, if any, is
|
||||
written too. After writing, pcretest reads a new pattern.
|
||||
|
||||
(ii) If, instead of a pattern, "<rest-of-line" is given, pcretest reads a
|
||||
compiled pattern from the given file. There must not be any
|
||||
occurrences of "<" in the file name (pretty unlikely); if there are,
|
||||
pcretest will instead treat the initial "<" as a pattern delimiter.
|
||||
After reading in the pattern, pcretest goes on to read data lines as
|
||||
usual.
|
||||
|
||||
(iii) The F pattern option causes pcretest to flip the bytes in the 32-bit
|
||||
and 16-bit fields in a compiled pattern, to simulate a pattern that
|
||||
was compiled on a host of opposite endianness.
|
||||
|
||||
21. The pcre-exec() function can now cope with patterns that were compiled on
|
||||
hosts of opposite endianness, with this restriction:
|
||||
|
||||
As for any compiled expression that is saved and used later, the tables
|
||||
pointer field cannot be preserved; the extra_data field in the arguments
|
||||
to pcre_exec() should be used to pass in a tables address if a value
|
||||
other than the default internal tables were used at compile time.
|
||||
|
||||
22. Calling pcre_exec() with a negative value of the "ovecsize" parameter is
|
||||
now diagnosed as an error. Previously, most of the time, a negative number
|
||||
would have been treated as zero, but if in addition "ovector" was passed as
|
||||
NULL, a crash could occur.
|
||||
|
||||
23. Updated the files ltmain.sh, config.sub, config.guess, and aclocal.m4 with
|
||||
new versions from the libtool 1.5 distribution (the last one is a copy of
|
||||
a file called libtool.m4). This seems to have fixed the need to patch
|
||||
"configure" to support Darwin 1.3 (which I used to do). However, I still
|
||||
had to patch ltmain.sh to ensure that ${SED} is set (it isn't on my
|
||||
workstation).
|
||||
|
||||
24. Changed the PCRE licence to be the more standard "BSD" licence.
|
||||
|
||||
|
||||
Version 4.5 01-Dec-03
|
||||
---------------------
|
||||
|
||||
|
||||
+46
-32
@@ -4,51 +4,65 @@ PCRE LICENCE
|
||||
PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by: Philip Hazel <ph10@cam.ac.uk>
|
||||
Release 6 of PCRE is distributed under the terms of the "BSD" licence, as
|
||||
specified below. The documentation for PCRE, supplied in the "doc"
|
||||
directory, is distributed under the same terms as the software itself.
|
||||
|
||||
The basic library functions are written in C and are freestanding. Also
|
||||
included in the distribution is a set of C++ wrapper functions.
|
||||
|
||||
|
||||
THE BASIC LIBRARY FUNCTIONS
|
||||
---------------------------
|
||||
|
||||
Written by: Philip Hazel
|
||||
Email local part: ph10
|
||||
Email domain: cam.ac.uk
|
||||
|
||||
University of Cambridge Computing Service,
|
||||
Cambridge, England. Phone: +44 1223 334714.
|
||||
|
||||
Copyright (c) 1997-2003 University of Cambridge
|
||||
Copyright (c) 1997-2005 University of Cambridge
|
||||
All rights reserved.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose on any
|
||||
computer system, and to redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
|
||||
1. This software 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.
|
||||
THE C++ WRAPPER FUNCTIONS
|
||||
-------------------------
|
||||
|
||||
2. The origin of this software must not be misrepresented, either by
|
||||
explicit claim or by omission. In practice, this means that if you use
|
||||
PCRE in software that you distribute to others, commercially or
|
||||
otherwise, you must put a sentence like this
|
||||
Contributed by: Google Inc.
|
||||
|
||||
Regular expression support is provided by the PCRE library package,
|
||||
which is open source software, written by Philip Hazel, and copyright
|
||||
by the University of Cambridge, England.
|
||||
Copyright (c) 2005, Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
somewhere reasonably visible in your documentation and in any relevant
|
||||
files or online help data or similar. A reference to the ftp site for
|
||||
the source, that is, to
|
||||
|
||||
ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
|
||||
THE "BSD" LICENCE
|
||||
-----------------
|
||||
|
||||
should also be given in the documentation. However, this condition is not
|
||||
intended to apply to whole chains of software. If package A includes PCRE,
|
||||
it must acknowledge it, but if package B is software that includes package
|
||||
A, the condition is not imposed on package B (unless it uses PCRE
|
||||
independently).
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
3. Altered versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
4. If PCRE is embedded in any software that is released under the GNU
|
||||
General Purpose Licence (GPL), or Lesser General Purpose Licence (LGPL),
|
||||
then the terms of that licence shall supersede any condition above with
|
||||
which it is incompatible.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
The documentation for PCRE, supplied in the "doc" directory, is distributed
|
||||
under the same terms as the software itself.
|
||||
* Neither the name of the University of Cambridge nor the name of Google
|
||||
Inc. nor the names of their contributors may be used to endorse or
|
||||
promote products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
End
|
||||
@@ -1,6 +1,85 @@
|
||||
News about PCRE releases
|
||||
------------------------
|
||||
|
||||
Release 6.0 07-Jun-05
|
||||
---------------------
|
||||
|
||||
The release number has been increased to 6.0 because of the addition of several
|
||||
major new pieces of functionality.
|
||||
|
||||
A new function, pcre_dfa_exec(), which implements pattern matching using a DFA
|
||||
algorithm, has been added. This has a number of advantages for certain cases,
|
||||
though it does run more slowly, and lacks the ability to capture substrings. On
|
||||
the other hand, it does find all matches, not just the first, and it works
|
||||
better for partial matching. The pcrematching man page discusses the
|
||||
differences.
|
||||
|
||||
The pcretest program has been enhanced so that it can make use of the new
|
||||
pcre_dfa_exec() matching function and the extra features it provides.
|
||||
|
||||
The distribution now includes a C++ wrapper library. This is built
|
||||
automatically if a C++ compiler is found. The pcrecpp man page discusses this
|
||||
interface.
|
||||
|
||||
The code itself has been re-organized into many more files, one for each
|
||||
function, so it no longer requires everything to be linked in when static
|
||||
linkage is used. As a consequence, some internal functions have had to have
|
||||
their names exposed. These functions all have names starting with _pcre_. They
|
||||
are undocumented, and are not intended for use by outside callers.
|
||||
|
||||
The pcregrep program has been enhanced with new functionality such as
|
||||
multiline-matching and options for output more matching context. See the
|
||||
ChangeLog for a complete list of changes to the library and the utility
|
||||
programs.
|
||||
|
||||
|
||||
Release 5.0 13-Sep-04
|
||||
---------------------
|
||||
|
||||
The licence under which PCRE is released has been changed to the more
|
||||
conventional "BSD" licence.
|
||||
|
||||
In the code, some bugs have been fixed, and there are also some major changes
|
||||
in this release (which is why I've increased the number to 5.0). Some changes
|
||||
are internal rearrangements, and some provide a number of new facilities. The
|
||||
new features are:
|
||||
|
||||
1. There's an "automatic callout" feature that inserts callouts before every
|
||||
item in the regex, and there's a new callout field that gives the position
|
||||
in the pattern - useful for debugging and tracing.
|
||||
|
||||
2. The extra_data structure can now be used to pass in a set of character
|
||||
tables at exec time. This is useful if compiled regex are saved and re-used
|
||||
at a later time when the tables may not be at the same address. If the
|
||||
default internal tables are used, the pointer saved with the compiled
|
||||
pattern is now set to NULL, which means that you don't need to do anything
|
||||
special unless you are using custom tables.
|
||||
|
||||
3. It is possible, with some restrictions on the content of the regex, to
|
||||
request "partial" matching. A special return code is given if all of the
|
||||
subject string matched part of the regex. This could be useful for testing
|
||||
an input field as it is being typed.
|
||||
|
||||
4. There is now some optional support for Unicode character properties, which
|
||||
means that the patterns items such as \p{Lu} and \X can now be used. Only
|
||||
the general category properties are supported. If PCRE is compiled with this
|
||||
support, an additional 90K data structure is include, which increases the
|
||||
size of the library dramatically.
|
||||
|
||||
5. There is support for saving compiled patterns and re-using them later.
|
||||
|
||||
6. There is support for running regular expressions that were compiled on a
|
||||
different host with the opposite endianness.
|
||||
|
||||
7. The pcretest program has been extended to accommodate the new features.
|
||||
|
||||
The main internal rearrangement is that sequences of literal characters are no
|
||||
longer handled as strings. Instead, each character is handled on its own. This
|
||||
makes some UTF-8 handling easier, and makes the support of partial matching
|
||||
possible. Compiled patterns containing long literal strings will be larger as a
|
||||
result of this change; I hope that performance will not be much affected.
|
||||
|
||||
|
||||
Release 4.5 01-Dec-03
|
||||
---------------------
|
||||
|
||||
|
||||
+170
-15
@@ -1,19 +1,25 @@
|
||||
Compiling PCRE on non-Unix systems
|
||||
----------------------------------
|
||||
|
||||
See below for comments on Cygwin or MinGW usage. I (Philip Hazel) have no
|
||||
knowledge of Windows sytems and how their libraries work. The items in the
|
||||
PCRE Makefile that relate to anything other than Unix-like systems have been
|
||||
contributed by PCRE users. There are some other comments and files in the
|
||||
Contrib directory on the ftp site that you may find useful.
|
||||
See below for comments on Cygwin or MinGW and OpenVMS usage. I (Philip Hazel)
|
||||
have no knowledge of Windows or VMS sytems and how their libraries work. The
|
||||
items in the PCRE Makefile that relate to anything other than Unix-like systems
|
||||
have been contributed by PCRE users. There are some other comments and files in
|
||||
the Contrib directory on the ftp site that you may find useful. See
|
||||
|
||||
The following are generic comments about building PCRE:
|
||||
ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/Contrib
|
||||
|
||||
If you want to compile PCRE for a non-Unix system (or perhaps, more strictly,
|
||||
for a system that does not support "configure" and make files), note that PCRE
|
||||
consists entirely of code written in Standard C, and so should compile
|
||||
successfully on any machine with a Standard C compiler and library, using
|
||||
normal compiling commands to do the following:
|
||||
for a system that does not support "configure" and "make" files), note that
|
||||
PCRE consists entirely of code written in Standard C, and so should compile
|
||||
successfully on any system that has a Standard C compiler and library.
|
||||
|
||||
|
||||
GENERIC INSTRUCTIONS FOR THE C LIBRARY
|
||||
|
||||
The following are generic comments about building PCRE. The interspersed
|
||||
indented commands are suggestions from Mark Tetrode as to which commands you
|
||||
might use on a Windows system to build a static library.
|
||||
|
||||
(1) Copy or rename the file config.in as config.h, and change the macros that
|
||||
define HAVE_STRERROR and HAVE_MEMMOVE to define them as 1 rather than 0.
|
||||
@@ -23,32 +29,116 @@ particular, if you want to force a specific value for newline, you can define
|
||||
the NEWLINE macro. The default is to use '\n', thereby using whatever value
|
||||
your compiler gives to '\n'.
|
||||
|
||||
rem Mark Tetrode's commands
|
||||
copy config.in config.h
|
||||
rem Use write, because notepad cannot handle UNIX files. Change values.
|
||||
write config.h
|
||||
|
||||
(2) Copy or rename the file pcre.in as pcre.h, and change the macro definitions
|
||||
for PCRE_MAJOR, PCRE_MINOR, and PCRE_DATE near its start to the values set in
|
||||
configure.in.
|
||||
|
||||
rem Mark Tetrode's commands
|
||||
copy pcre.in pcre.h
|
||||
rem Read values from configure.in
|
||||
write configure.in
|
||||
rem Change values
|
||||
write pcre.h
|
||||
|
||||
(3) Compile dftables.c as a stand-alone program, and then run it with
|
||||
the single argument "chartables.c". This generates a set of standard
|
||||
character tables and writes them to that file.
|
||||
|
||||
(4) Compile maketables.c, get.c, study.c and pcre.c and link them all
|
||||
together into an object library in whichever form your system keeps such
|
||||
libraries. This is the pcre library (chartables.c is included by means of an
|
||||
#include directive). If your system has static and shared libraries, you may
|
||||
have to do this once for each type.
|
||||
rem Mark Tetrode's commands
|
||||
rem Compile & run
|
||||
cl -DSUPPORT_UTF8 -DSUPPORT_UCP dftables.c
|
||||
dftables.exe chartables.c
|
||||
|
||||
(4) Compile the following source files:
|
||||
|
||||
pcre_chartables.c
|
||||
pcre_compile.c
|
||||
pcre_config.c
|
||||
pcre_dfa_exec.c
|
||||
pcre_exec.c
|
||||
pcre_fullinfo.c
|
||||
pcre_get.c
|
||||
pcre_globals.c
|
||||
pcre_info.c
|
||||
pcre_maketables.c
|
||||
pcre_ord2utf8.c
|
||||
pcre_printint.c
|
||||
pcre_refcount.c
|
||||
pcre_study.c
|
||||
pcre_tables.c
|
||||
pcre_try_flipped.c
|
||||
pcre_ucp_findchar.c
|
||||
pcre_valid_utf8.c
|
||||
pcre_version.c
|
||||
pcre_xclass.c
|
||||
|
||||
and link them all together into an object library in whichever form your system
|
||||
keeps such libraries. This is the pcre C library. If your system has static and
|
||||
shared libraries, you may have to do this once for each type.
|
||||
|
||||
rem These comments are out-of-date, referring to a previous release which
|
||||
rem had fewer source files. Replace with the file names from above.
|
||||
rem Mark Tetrode's commands, for a static library
|
||||
rem Compile & lib
|
||||
cl -DSUPPORT_UTF8 -DSUPPORT_UCP -DPOSIX_MALLOC_THRESHOLD=10 /c maketables.c get.c study.c pcre.c
|
||||
lib /OUT:pcre.lib maketables.obj get.obj study.obj pcre.obj
|
||||
|
||||
(5) Similarly, compile pcreposix.c and link it (on its own) as the pcreposix
|
||||
library.
|
||||
|
||||
rem Mark Tetrode's commands, for a static library
|
||||
rem Compile & lib
|
||||
cl -DSUPPORT_UTF8 -DSUPPORT_UCP -DPOSIX_MALLOC_THRESHOLD=10 /c pcreposix.c
|
||||
lib /OUT:pcreposix.lib pcreposix.obj
|
||||
|
||||
(6) Compile the test program pcretest.c. This needs the functions in the
|
||||
pcre and pcreposix libraries when linking.
|
||||
|
||||
rem Mark Tetrode's commands
|
||||
rem compile & link
|
||||
cl /F0x400000 pcretest.c pcre.lib pcreposix.lib
|
||||
|
||||
(7) Run pcretest on the testinput files in the testdata directory, and check
|
||||
that the output matches the corresponding testoutput files. You must use the
|
||||
-i option when checking testinput2. Note that the supplied files are in Unix
|
||||
format, with just LF characters as line terminators. You may need to edit them
|
||||
to change this if your system uses a different convention.
|
||||
|
||||
rem Mark Tetrode's commands
|
||||
pcretest testdata\testinput1 testdata\myoutput1
|
||||
windiff testdata\testoutput1 testdata\myoutput1
|
||||
pcretest -i testdata\testinput2 testdata\myoutput2
|
||||
windiff testdata\testoutput2 testdata\myoutput2
|
||||
pcretest testdata\testinput3 testdata\myoutput3
|
||||
windiff testdata\testoutput3 testdata\myoutput3
|
||||
pcretest testdata\testinput4 testdata\myoutput4
|
||||
windiff testdata\testoutput4 testdata\myoutput4
|
||||
pcretest testdata\testinput5 testdata\myoutput5
|
||||
windiff testdata\testoutput5 testdata\myoutput5
|
||||
pcretest testdata\testinput6 testdata\myoutput6
|
||||
windiff testdata\testoutput6 testdata\myoutput6
|
||||
|
||||
Note that there are now three more tests (7, 8, 9) that did not exist when Mark
|
||||
wrote those comments. The test the new pcre_dfa_exec() function.
|
||||
|
||||
|
||||
THE C++ WRAPPER FUNCTIONS
|
||||
|
||||
The PCRE distribution now contains some C++ wrapper functions and tests,
|
||||
contributed by Google Inc. On a system that can use "configure" and "make",
|
||||
the functions are automatically built into a library called pcrecpp. It should
|
||||
be straightforward to compile the .cc files manually on other systems. The
|
||||
files called xxx_unittest.cc are test programs for each of the corresponding
|
||||
xxx.cc files.
|
||||
|
||||
|
||||
FURTHER REMARKS
|
||||
|
||||
If you have a system without "configure" but where you can use a Makefile, edit
|
||||
Makefile.in to create Makefile, substituting suitable values for the variables
|
||||
at the head of the file.
|
||||
@@ -119,4 +209,69 @@ void (*pcre_free)(void *) = free;
|
||||
#endif
|
||||
=========================
|
||||
|
||||
|
||||
BUILDING PCRE ON OPENVMS
|
||||
|
||||
Dan Mooney sent the following comments about building PCRE on OpenVMS. They
|
||||
relate to an older version of PCRE that used fewer source files, so the exact
|
||||
commands will need changing. See the current list of source files above.
|
||||
|
||||
"It was quite easy to compile and link the library. I don't have a formal
|
||||
make file but the attached file [reproduced below] contains the OpenVMS DCL
|
||||
commands I used to build the library. I had to add #define
|
||||
POSIX_MALLOC_THRESHOLD 10 to pcre.h since it was not defined anywhere.
|
||||
|
||||
The library was built on:
|
||||
O/S: HP OpenVMS v7.3-1
|
||||
Compiler: Compaq C v6.5-001-48BCD
|
||||
Linker: vA13-01
|
||||
|
||||
The test results did not match 100% due to the issues you mention in your
|
||||
documentation regarding isprint(), iscntrl(), isgraph() and ispunct(). I
|
||||
modified some of the character tables temporarily and was able to get the
|
||||
results to match. Tests using the fr locale did not match since I don't have
|
||||
that locale loaded. The study size was always reported to be 3 less than the
|
||||
value in the standard test output files."
|
||||
|
||||
=========================
|
||||
$! This DCL procedure builds PCRE on OpenVMS
|
||||
$!
|
||||
$! I followed the instructions in the non-unix-use file in the distribution.
|
||||
$!
|
||||
$ COMPILE == "CC/LIST/NOMEMBER_ALIGNMENT/PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES
|
||||
$ COMPILE DFTABLES.C
|
||||
$ LINK/EXE=DFTABLES.EXE DFTABLES.OBJ
|
||||
$ RUN DFTABLES.EXE/OUTPUT=CHARTABLES.C
|
||||
$ COMPILE MAKETABLES.C
|
||||
$ COMPILE GET.C
|
||||
$ COMPILE STUDY.C
|
||||
$! I had to set POSIX_MALLOC_THRESHOLD to 10 in PCRE.H since the symbol
|
||||
$! did not seem to be defined anywhere.
|
||||
$! I edited pcre.h and added #DEFINE SUPPORT_UTF8 to enable UTF8 support.
|
||||
$ COMPILE PCRE.C
|
||||
$ LIB/CREATE PCRE MAKETABLES.OBJ, GET.OBJ, STUDY.OBJ, PCRE.OBJ
|
||||
$! I had to set POSIX_MALLOC_THRESHOLD to 10 in PCRE.H since the symbol
|
||||
$! did not seem to be defined anywhere.
|
||||
$ COMPILE PCREPOSIX.C
|
||||
$ LIB/CREATE PCREPOSIX PCREPOSIX.OBJ
|
||||
$ COMPILE PCRETEST.C
|
||||
$ LINK/EXE=PCRETEST.EXE PCRETEST.OBJ, PCRE/LIB, PCREPOSIX/LIB
|
||||
$! C programs that want access to command line arguments must be
|
||||
$! defined as a symbol
|
||||
$ PCRETEST :== "$ SYS$ROADSUSERS:[DMOONEY.REGEXP]PCRETEST.EXE"
|
||||
$! Arguments must be enclosed in quotes.
|
||||
$ PCRETEST "-C"
|
||||
$! Test results:
|
||||
$!
|
||||
$! The test results did not match 100%. The functions isprint(), iscntrl(),
|
||||
$! isgraph() and ispunct() on OpenVMS must not produce the same results
|
||||
$! as the system that built the test output files provided with the
|
||||
$! distribution.
|
||||
$!
|
||||
$! The study size did not match and was always 3 less on OpenVMS.
|
||||
$!
|
||||
$! Locale could not be set to fr
|
||||
$!
|
||||
=========================
|
||||
|
||||
****
|
||||
+190
-66
@@ -7,14 +7,22 @@ The latest release of PCRE is always available from
|
||||
|
||||
Please read the NEWS file if you are upgrading from a previous release.
|
||||
|
||||
PCRE has its own native API, but a set of "wrapper" functions that are based on
|
||||
the POSIX API are also supplied in the library libpcreposix. Note that this
|
||||
just provides a POSIX calling interface to PCRE: the regular expressions
|
||||
themselves still follow Perl syntax and semantics. The header file
|
||||
for the POSIX-style functions is called pcreposix.h. The official POSIX name is
|
||||
regex.h, but I didn't want to risk possible problems with existing files of
|
||||
that name by distributing it that way. To use it with an existing program that
|
||||
uses the POSIX API, it will have to be renamed or pointed at by a link.
|
||||
|
||||
The PCRE APIs
|
||||
-------------
|
||||
|
||||
PCRE is written in C, and it has its own API. The distribution now includes a
|
||||
set of C++ wrapper functions, courtesy of Google Inc. (see the pcrecpp man page
|
||||
for details).
|
||||
|
||||
Also included are a set of C wrapper functions that are based on the POSIX
|
||||
API. These end up in the library called libpcreposix. Note that this just
|
||||
provides a POSIX calling interface to PCRE: the regular expressions themselves
|
||||
still follow Perl syntax and semantics. The header file for the POSIX-style
|
||||
functions is called pcreposix.h. The official POSIX name is regex.h, but I
|
||||
didn't want to risk possible problems with existing files of that name by
|
||||
distributing it that way. To use it with an existing program that uses the
|
||||
POSIX API, it will have to be renamed or pointed at by a link.
|
||||
|
||||
If you are using the POSIX interface to PCRE and there is already a POSIX regex
|
||||
library installed on your system, you must take care when linking programs to
|
||||
@@ -22,6 +30,28 @@ ensure that they link with PCRE's libpcreposix library. Otherwise they may pick
|
||||
up the "real" POSIX functions of the same name.
|
||||
|
||||
|
||||
Documentation for PCRE
|
||||
----------------------
|
||||
|
||||
If you install PCRE in the normal way, you will end up with an installed set of
|
||||
man pages whose names all start with "pcre". The one that is called "pcre"
|
||||
lists all the others. In addition to these man pages, the PCRE documentation is
|
||||
supplied in two other forms; however, as there is no standard place to install
|
||||
them, they are left in the doc directory of the unpacked source distribution.
|
||||
These forms are:
|
||||
|
||||
1. Files called doc/pcre.txt, doc/pcregrep.txt, and doc/pcretest.txt. The
|
||||
first of these is a concatenation of the text forms of all the section 3
|
||||
man pages except those that summarize individual functions. The other two
|
||||
are the text forms of the section 1 man pages for the pcregrep and
|
||||
pcretest commands. Text forms are provided for ease of scanning with text
|
||||
editors or similar tools.
|
||||
|
||||
2. A subdirectory called doc/html contains all the documentation in HTML
|
||||
form, hyperlinked in various ways, and rooted in a file called
|
||||
doc/index.html.
|
||||
|
||||
|
||||
Contributions by users of PCRE
|
||||
------------------------------
|
||||
|
||||
@@ -46,7 +76,7 @@ INSTALL.
|
||||
|
||||
Most commonly, people build PCRE within its own distribution directory, and in
|
||||
this case, on many systems, just running "./configure" is sufficient, but the
|
||||
usual methods of changing standard defaults are available. For example,
|
||||
usual methods of changing standard defaults are available. For example:
|
||||
|
||||
CFLAGS='-O2 -Wall' ./configure --prefix=/opt/local
|
||||
|
||||
@@ -69,6 +99,13 @@ library. You can read more about them in the pcrebuild man page.
|
||||
for handling UTF-8 is not included in the library. (Even when included, it
|
||||
still has to be enabled by an option at run time.)
|
||||
|
||||
. If, in addition to support for UTF-8 character strings, you want to include
|
||||
support for the \P, \p, and \X sequences that recognize Unicode character
|
||||
properties, you must add --enable-unicode-properties to the "configure"
|
||||
command. This adds about 90K to the size of the library (in the form of a
|
||||
property table); only the basic two-letter properties such as Lu are
|
||||
supported.
|
||||
|
||||
. You can build PCRE to recognized CR or NL as the newline character, instead
|
||||
of whatever your compiler uses for "\n", by adding --newline-is-cr or
|
||||
--newline-is-nl to the "configure" command, respectively. Only do this if you
|
||||
@@ -83,7 +120,7 @@ library. You can read more about them in the pcrebuild man page.
|
||||
|
||||
on the "configure" command.
|
||||
|
||||
. PCRE has a counter which can be set to limit the amount of resources it uses.
|
||||
. PCRE has a counter that can be set to limit the amount of resources it uses.
|
||||
If the limit is exceeded during a match, the match fails. The default is ten
|
||||
million. You can change the default by setting, for example,
|
||||
|
||||
@@ -101,51 +138,91 @@ library. You can read more about them in the pcrebuild man page.
|
||||
is a representation of the compiled pattern, and this changes with the link
|
||||
size.
|
||||
|
||||
. You can build PCRE so that its match() function does not call itself
|
||||
recursively. Instead, it uses blocks of data from the heap via special
|
||||
functions pcre_stack_malloc() and pcre_stack_free() to save data that would
|
||||
otherwise be saved on the stack. To build PCRE like this, use
|
||||
. You can build PCRE so that its internal match() function that is called from
|
||||
pcre_exec() does not call itself recursively. Instead, it uses blocks of data
|
||||
from the heap via special functions pcre_stack_malloc() and pcre_stack_free()
|
||||
to save data that would otherwise be saved on the stack. To build PCRE like
|
||||
this, use
|
||||
|
||||
--disable-stack-for-recursion
|
||||
|
||||
on the "configure" command. PCRE runs more slowly in this mode, but it may be
|
||||
necessary in environments with limited stack sizes.
|
||||
necessary in environments with limited stack sizes. This applies only to the
|
||||
pcre_exec() function; it does not apply to pcre_dfa_exec(), which does not
|
||||
use deeply nested recursion.
|
||||
|
||||
The "configure" script builds five files:
|
||||
The "configure" script builds eight files for the basic C library:
|
||||
|
||||
. pcre.h is the header file for C programs that call PCRE
|
||||
. Makefile is the makefile that builds the library
|
||||
. config.h contains build-time configuration options for the library
|
||||
. pcre-config is a script that shows the settings of "configure" options
|
||||
. libpcre.pc is data for the pkg-config command
|
||||
. libtool is a script that builds shared and/or static libraries
|
||||
. Makefile is built by copying Makefile.in and making substitutions.
|
||||
. config.h is built by copying config.in and making substitutions.
|
||||
. pcre-config is built by copying pcre-config.in and making substitutions.
|
||||
. RunTest is a script for running tests
|
||||
. RunTest is a script for running tests on the library
|
||||
. RunGrepTest is a script for running tests on the pcregrep command
|
||||
|
||||
Once "configure" has run, you can run "make". It builds two libraries called
|
||||
In addition, if a C++ compiler is found, the following are also built:
|
||||
|
||||
. pcrecpp.h is the header file for programs that call PCRE via the C++ wrapper
|
||||
. pcre_stringpiece.h is the header for the C++ "stringpiece" functions
|
||||
|
||||
The "configure" script also creates config.status, which is an executable
|
||||
script that can be run to recreate the configuration, and config.log, which
|
||||
contains compiler output from tests that "configure" runs.
|
||||
|
||||
Once "configure" has run, you can run "make". It builds two libraries, called
|
||||
libpcre and libpcreposix, a test program called pcretest, and the pcregrep
|
||||
command. You can use "make install" to copy these, the public header files
|
||||
pcre.h and pcreposix.h, and the man pages to appropriate live directories on
|
||||
your system, in the normal way.
|
||||
command. If a C++ compiler was found on your system, it also builds the C++
|
||||
wrapper library, which is called libpcrecpp, and some test programs called
|
||||
pcrecpp_unittest, pcre_scanner_unittest, and pcre_stringpiece_unittest.
|
||||
|
||||
The command "make test" runs all the appropriate tests. Details of the PCRE
|
||||
tests are given in a separate section of this document, below.
|
||||
|
||||
You can use "make install" to copy the libraries, the public header files
|
||||
pcre.h, pcreposix.h, pcrecpp.h, and pcre_stringpiece.h (the last two only if
|
||||
the C++ wrapper was built), and the man pages to appropriate live directories
|
||||
on your system, in the normal way.
|
||||
|
||||
If you want to remove PCRE from your system, you can run "make uninstall".
|
||||
This removes all the files that "make install" installed. However, it does not
|
||||
remove any directories, because these are often shared with other programs.
|
||||
|
||||
|
||||
Retrieving configuration information on Unix-like systems
|
||||
---------------------------------------------------------
|
||||
|
||||
Running "make install" also installs the command pcre-config, which can be used
|
||||
to recall information about the PCRE configuration and installation. For
|
||||
example,
|
||||
example:
|
||||
|
||||
pcre-config --version
|
||||
|
||||
prints the version number, and
|
||||
|
||||
pcre-config --libs
|
||||
pcre-config --libs
|
||||
|
||||
outputs information about where the library is installed. This command can be
|
||||
included in makefiles for programs that use PCRE, saving the programmer from
|
||||
having to remember too many details.
|
||||
|
||||
The pkg-config command is another system for saving and retrieving information
|
||||
about installed libraries. Instead of separate commands for each library, a
|
||||
single command is used. For example:
|
||||
|
||||
pkg-config --cflags pcre
|
||||
|
||||
The data is held in *.pc files that are installed in a directory called
|
||||
pkgconfig.
|
||||
|
||||
|
||||
Shared libraries on Unix-like systems
|
||||
-------------------------------------
|
||||
|
||||
The default distribution builds PCRE as two shared libraries and two static
|
||||
libraries, as long as the operating system supports shared libraries. Shared
|
||||
library support relies on the "libtool" script which is built as part of the
|
||||
The default distribution builds PCRE as shared libraries and static libraries,
|
||||
as long as the operating system supports shared libraries. Shared library
|
||||
support relies on the "libtool" script which is built as part of the
|
||||
"configure" process.
|
||||
|
||||
The libtool script is used to compile and link both shared and static
|
||||
@@ -158,7 +235,7 @@ installed themselves. However, the versions left in the source directory still
|
||||
use the uninstalled libraries.
|
||||
|
||||
To build PCRE using static libraries only you must use --disable-shared when
|
||||
configuring it. For example
|
||||
configuring it. For example:
|
||||
|
||||
./configure --prefix=/usr/gnu --disable-shared
|
||||
|
||||
@@ -174,7 +251,8 @@ order to cross-compile PCRE for some other host. However, during the building
|
||||
process, the dftables.c source file is compiled *and run* on the local host, in
|
||||
order to generate the default character tables (the chartables.c file). It
|
||||
therefore needs to be compiled with the local compiler, not the cross compiler.
|
||||
You can do this by specifying CC_FOR_BUILD (and if necessary CFLAGS_FOR_BUILD)
|
||||
You can do this by specifying CC_FOR_BUILD (and if necessary CFLAGS_FOR_BUILD;
|
||||
there are also CXX_FOR_BUILD and CXXFLAGS_FOR_BUILD for the C++ wrapper)
|
||||
when calling the "configure" command. If they are not specified, they default
|
||||
to the values of CC and CFLAGS.
|
||||
|
||||
@@ -196,15 +274,21 @@ Testing PCRE
|
||||
------------
|
||||
|
||||
To test PCRE on a Unix system, run the RunTest script that is created by the
|
||||
configuring process. (This can also be run by "make runtest", "make check", or
|
||||
"make test".) For other systems, see the instructions in NON-UNIX-USE.
|
||||
configuring process. There is also a script called RunGrepTest that tests the
|
||||
options of the pcregrep command. If the C++ wrapper library is build, three
|
||||
test programs called pcrecpp_unittest, pcre_scanner_unittest, and
|
||||
pcre_stringpiece_unittest are provided.
|
||||
|
||||
The script runs the pcretest test program (which is documented in its own man
|
||||
page) on each of the testinput files (in the testdata directory) in turn,
|
||||
and compares the output with the contents of the corresponding testoutput file.
|
||||
A file called testtry is used to hold the output from pcretest. To run pcretest
|
||||
on just one of the test files, give its number as an argument to RunTest, for
|
||||
example:
|
||||
Both the scripts and all the program tests are run if you obey "make runtest",
|
||||
"make check", or "make test". For other systems, see the instructions in
|
||||
NON-UNIX-USE.
|
||||
|
||||
The RunTest script runs the pcretest test program (which is documented in its
|
||||
own man page) on each of the testinput files (in the testdata directory) in
|
||||
turn, and compares the output with the contents of the corresponding testoutput
|
||||
file. A file called testtry is used to hold the main output from pcretest
|
||||
(testsavedregex is also used as a working file). To run pcretest on just one of
|
||||
the test files, give its number as an argument to RunTest, for example:
|
||||
|
||||
RunTest 2
|
||||
|
||||
@@ -247,19 +331,28 @@ running "configure". This file can be also fed directly to the perltest script,
|
||||
provided you are running Perl 5.8 or higher. (For Perl 5.6, a small patch,
|
||||
commented in the script, can be be used.)
|
||||
|
||||
The fifth and final file tests error handling with UTF-8 encoding, and internal
|
||||
UTF-8 features of PCRE that are not relevant to Perl.
|
||||
The fifth test checks error handling with UTF-8 encoding, and internal UTF-8
|
||||
features of PCRE that are not relevant to Perl.
|
||||
|
||||
The sixth and test checks the support for Unicode character properties. It it
|
||||
not run automatically unless PCRE is built with Unicode property support. To to
|
||||
this you must set --enable-unicode-properties when running "configure".
|
||||
|
||||
The seventh, eighth, and ninth tests check the pcre_dfa_exec() alternative
|
||||
matching function, in non-UTF-8 mode, UTF-8 mode, and UTF-8 mode with Unicode
|
||||
property support, respectively. The eighth and ninth tests are not run
|
||||
automatically unless PCRE is build with the relevant support.
|
||||
|
||||
|
||||
Character tables
|
||||
----------------
|
||||
|
||||
PCRE uses four tables for manipulating and identifying characters. The final
|
||||
argument of the pcre_compile() function is a pointer to a block of memory
|
||||
containing the concatenated tables. A call to pcre_maketables() can be used to
|
||||
generate a set of tables in the current locale. If the final argument for
|
||||
pcre_compile() is passed as NULL, a set of default tables that is built into
|
||||
the binary is used.
|
||||
PCRE uses four tables for manipulating and identifying characters whose values
|
||||
are less than 256. The final argument of the pcre_compile() function is a
|
||||
pointer to a block of memory containing the concatenated tables. A call to
|
||||
pcre_maketables() can be used to generate a set of tables in the current
|
||||
locale. If the final argument for pcre_compile() is passed as NULL, a set of
|
||||
default tables that is built into the binary is used.
|
||||
|
||||
The source file called chartables.c contains the default set of tables. This is
|
||||
not supplied in the distribution, but is built by the program dftables
|
||||
@@ -299,18 +392,47 @@ The distribution should contain the following files:
|
||||
headers:
|
||||
|
||||
dftables.c auxiliary program for building chartables.c
|
||||
get.c )
|
||||
maketables.c )
|
||||
study.c ) source of
|
||||
pcre.c ) the functions
|
||||
|
||||
pcreposix.c )
|
||||
printint.c )
|
||||
pcre_compile.c )
|
||||
pcre_config.c )
|
||||
pcre_dfa_exec.c )
|
||||
pcre_exec.c )
|
||||
pcre_fullinfo.c )
|
||||
pcre_get.c ) sources for the functions in the library,
|
||||
pcre_globals.c ) and some internal functions that they use
|
||||
pcre_info.c )
|
||||
pcre_maketables.c )
|
||||
pcre_ord2utf8.c )
|
||||
pcre_printint.c )
|
||||
pcre_study.c )
|
||||
pcre_tables.c )
|
||||
pcre_try_flipped.c )
|
||||
pcre_ucp_findchar.c )
|
||||
pcre_valid_utf8.c )
|
||||
pcre_version.c )
|
||||
pcre_xclass.c )
|
||||
|
||||
ucp_findchar.c )
|
||||
ucp.h ) source for the code that is used for
|
||||
ucpinternal.h ) Unicode property handling
|
||||
ucptable.c )
|
||||
ucptypetable.c )
|
||||
|
||||
pcre.in "source" for the header for the external API; pcre.h
|
||||
is built from this by "configure"
|
||||
pcreposix.h header for the external POSIX wrapper API
|
||||
internal.h header for internal use
|
||||
pcre_internal.h header for internal use
|
||||
config.in template for config.h, which is built by configure
|
||||
|
||||
pcrecpp.h.in "source" for the header file for the C++ wrapper
|
||||
pcrecpp.cc )
|
||||
pcre_scanner.cc ) source for the C++ wrapper library
|
||||
|
||||
pcre_stringpiece.h.in "source" for pcre_stringpiece.h, the header for the
|
||||
C++ stringpiece functions
|
||||
pcre_stringpiece.cc source for the C++ stringpiece functions
|
||||
|
||||
(B) Auxiliary files:
|
||||
|
||||
AUTHORS information about the author of PCRE
|
||||
@@ -323,6 +445,7 @@ The distribution should contain the following files:
|
||||
NON-UNIX-USE notes on building PCRE on non-Unix systems
|
||||
README this file
|
||||
RunTest.in template for a Unix shell script for running tests
|
||||
RunGrepTest.in template for a Unix shell script for pcregrep tests
|
||||
config.guess ) files used by libtool,
|
||||
config.sub ) used only when building a shared library
|
||||
configure a configuring shell script (built by autoconf)
|
||||
@@ -335,31 +458,32 @@ The distribution should contain the following files:
|
||||
doc/pcretest.txt plain text documentation of test program
|
||||
doc/perltest.txt plain text documentation of Perl test program
|
||||
install-sh a shell script for installing files
|
||||
libpcre.pc.in "source" for libpcre.pc for pkg-config
|
||||
ltmain.sh file used to build a libtool script
|
||||
mkinstalldirs script for making install directories
|
||||
pcretest.c comprehensive test program
|
||||
pcredemo.c simple demonstration of coding calls to PCRE
|
||||
perltest Perl test program
|
||||
pcregrep.c source of a grep utility that uses PCRE
|
||||
pcre-config.in source of script which retains PCRE information
|
||||
testdata/testinput1 test data, compatible with Perl
|
||||
testdata/testinput2 test data for error messages and non-Perl things
|
||||
testdata/testinput3 test data for locale-specific tests
|
||||
testdata/testinput4 test data for UTF-8 tests compatible with Perl
|
||||
testdata/testinput5 test data for other UTF-8 tests
|
||||
testdata/testoutput1 test results corresponding to testinput1
|
||||
testdata/testoutput2 test results corresponding to testinput2
|
||||
testdata/testoutput3 test results corresponding to testinput3
|
||||
testdata/testoutput4 test results corresponding to testinput4
|
||||
testdata/testoutput5 test results corresponding to testinput5
|
||||
pcrecpp_unittest.c )
|
||||
pcre_scanner_unittest.c ) test programs for the C++ wrapper
|
||||
pcre_stringpiece_unittest.c )
|
||||
testdata/testinput* test data for main library tests
|
||||
testdata/testoutput* expected test results
|
||||
testdata/grep* input and output for pcregrep tests
|
||||
|
||||
(C) Auxiliary files for Win32 DLL
|
||||
|
||||
dll.mk
|
||||
libpcre.def
|
||||
libpcreposix.def
|
||||
pcre.def
|
||||
|
||||
(D) Auxiliary file for VPASCAL
|
||||
|
||||
makevp.bat
|
||||
|
||||
Philip Hazel <ph10@cam.ac.uk>
|
||||
December 2003
|
||||
Philip Hazel
|
||||
Email local part: ph10
|
||||
Email domain: cam.ac.uk
|
||||
June 2005
|
||||
+38
-33
@@ -2,52 +2,55 @@
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/*
|
||||
PCRE is a library of functions to support regular expressions whose syntax
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by: Philip Hazel <ph10@cam.ac.uk>
|
||||
|
||||
Copyright (c) 1997-2003 University of Cambridge
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2005 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Permission is granted to anyone to use this software for any purpose on any
|
||||
computer system, and to redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. This software 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.
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. The origin of this software must not be misrepresented, either by
|
||||
explicit claim or by omission.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Altered versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
4. If PCRE is embedded in any software that is released under the GNU
|
||||
General Purpose Licence (GPL), then the terms of that licence shall
|
||||
supersede any condition above with which it is incompatible.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
See the file Tech.Notes for some information on the internals.
|
||||
*/
|
||||
|
||||
|
||||
/* This is a support program to generate the file chartables.c, containing
|
||||
character tables of various kinds. They are built according to the default C
|
||||
locale and used as the default tables by PCRE. Now that pcre_maketables is
|
||||
a function visible to the outside world, we make use of its code from here in
|
||||
order to be consistent. */
|
||||
/* This is a freestanding support program to generate a file containing default
|
||||
character tables for PCRE. The tables are built according to the default C
|
||||
locale. Now that pcre_maketables is a function visible to the outside world, we
|
||||
make use of its code from here in order to be consistent. */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "pcre_internal.h"
|
||||
|
||||
#define DFTABLES /* maketables.c notices this */
|
||||
#include "maketables.c"
|
||||
#define DFTABLES /* pcre_maketables.c notices this */
|
||||
#include "pcre_maketables.c"
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
@@ -55,6 +58,7 @@ int main(int argc, char **argv)
|
||||
int i;
|
||||
FILE *f;
|
||||
const unsigned char *tables = pcre_maketables();
|
||||
const unsigned char *base_of_tables = tables;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
@@ -62,7 +66,7 @@ if (argc != 2)
|
||||
return 1;
|
||||
}
|
||||
|
||||
f = fopen(argv[1], "w");
|
||||
f = fopen(argv[1], "wb");
|
||||
if (f == NULL)
|
||||
{
|
||||
fprintf(stderr, "dftables: failed to open %s for writing\n", argv[1]);
|
||||
@@ -80,10 +84,10 @@ fprintf(f,
|
||||
"program. If you edit it by hand, you might like to edit the Makefile to \n"
|
||||
"prevent its ever being regenerated.\n\n");
|
||||
fprintf(f,
|
||||
"This file is #included in the compilation of pcre.c to build the default\n"
|
||||
"character tables which are used when no tables are passed to the compile\n"
|
||||
"function. */\n\n"
|
||||
"static unsigned char pcre_default_tables[] = {\n\n"
|
||||
"This file contains the default tables for characters with codes less than\n"
|
||||
"128 (ASCII characters). These tables are used when no external tables are\n"
|
||||
"passed to PCRE. */\n\n"
|
||||
"const unsigned char _pcre_default_tables[] = {\n\n"
|
||||
"/* This table is a lower casing table. */\n\n");
|
||||
|
||||
fprintf(f, " ");
|
||||
@@ -161,6 +165,7 @@ if (isprint(i-1)) fprintf(f, " %c ", i-1);
|
||||
fprintf(f, " */\n\n/* End of chartables.c */\n");
|
||||
|
||||
fclose(f);
|
||||
free((void *)base_of_tables);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+106
-48
@@ -1,6 +1,9 @@
|
||||
Technical Notes about PCRE
|
||||
--------------------------
|
||||
|
||||
Historical note 1
|
||||
-----------------
|
||||
|
||||
Many years ago I implemented some regular expression functions to an algorithm
|
||||
suggested by Martin Richards. These were not Unix-like in form, and were quite
|
||||
restricted in what they could do by comparison with Perl. The interesting part
|
||||
@@ -9,12 +12,15 @@ form of an expression was known in advance. The code to apply an expression did
|
||||
not operate by backtracking, as the original Henry Spencer code and current
|
||||
Perl code does, but instead checked all possibilities simultaneously by keeping
|
||||
a list of current states and checking all of them as it advanced through the
|
||||
subject string. (In the terminology of Jeffrey Friedl's book, it was a "DFA
|
||||
algorithm".) When the pattern was all used up, all remaining states were
|
||||
subject string. In the terminology of Jeffrey Friedl's book, it was a "DFA
|
||||
algorithm". When the pattern was all used up, all remaining states were
|
||||
possible matches, and the one matching the longest subset of the subject string
|
||||
was chosen. This did not necessarily maximize the individual wild portions of
|
||||
the pattern, as is expected in Unix and Perl-style regular expressions.
|
||||
|
||||
Historical note 2
|
||||
-----------------
|
||||
|
||||
By contrast, the code originally written by Henry Spencer and subsequently
|
||||
heavily modified for Perl actually compiles the expression twice: once in a
|
||||
dummy mode in order to find out how much store will be needed, and then for
|
||||
@@ -23,23 +29,58 @@ optionally, minimizing in Perl) the amount of the subject that matches
|
||||
individual wild portions of the pattern. This is an "NFA algorithm" in Friedl's
|
||||
terminology.
|
||||
|
||||
For the set of functions that forms PCRE (which are unrelated to those
|
||||
mentioned above), I tried at first to invent an algorithm that used an amount
|
||||
of store bounded by a multiple of the number of characters in the pattern, to
|
||||
save on compiling time. However, because of the greater complexity in Perl
|
||||
regular expressions, I couldn't do this. In any case, a first pass through the
|
||||
pattern is needed, for a number of reasons. PCRE works by running a very
|
||||
degenerate first pass to calculate a maximum store size, and then a second pass
|
||||
to do the real compile - which may use a bit less than the predicted amount of
|
||||
store. The idea is that this is going to turn out faster because the first pass
|
||||
is degenerate and the second pass can just store stuff straight into the
|
||||
vector. It does make the compiling functions bigger, of course, but they have
|
||||
got quite big anyway to handle all the Perl stuff.
|
||||
OK, here's the real stuff
|
||||
-------------------------
|
||||
|
||||
For the set of functions that form the "basic" PCRE library (which are
|
||||
unrelated to those mentioned above), I tried at first to invent an algorithm
|
||||
that used an amount of store bounded by a multiple of the number of characters
|
||||
in the pattern, to save on compiling time. However, because of the greater
|
||||
complexity in Perl regular expressions, I couldn't do this. In any case, a
|
||||
first pass through the pattern is needed, for a number of reasons. PCRE works
|
||||
by running a very degenerate first pass to calculate a maximum store size, and
|
||||
then a second pass to do the real compile - which may use a bit less than the
|
||||
predicted amount of store. The idea is that this is going to turn out faster
|
||||
because the first pass is degenerate and the second pass can just store stuff
|
||||
straight into the vector, which it knows is big enough. It does make the
|
||||
compiling functions bigger, of course, but they have got quite big anyway to
|
||||
handle all the Perl stuff.
|
||||
|
||||
Traditional matching function
|
||||
-----------------------------
|
||||
|
||||
The "traditional", and original, matching function is called pcre_exec(), and
|
||||
it implements an NFA algorithm, similar to the original Henry Spencer algorithm
|
||||
and the way that Perl works. Not surprising, since it is intended to be as
|
||||
compatible with Perl as possible. This is the function most users of PCRE will
|
||||
use most of the time.
|
||||
|
||||
Supplementary matching function
|
||||
-------------------------------
|
||||
|
||||
From PCRE 6.0, there is also a supplementary matching function called
|
||||
pcre_dfa_exec(). This implements a DFA matching algorithm that searches
|
||||
simultaneously for all possible matches that start at one point in the subject
|
||||
string. (Going back to my roots: see Historical Note 1 above.) This function
|
||||
intreprets the same compiled pattern data as pcre_exec(); however, not all the
|
||||
facilities are available, and those that are don't always work in quite the
|
||||
same way. See the user documentation for details.
|
||||
|
||||
Format of compiled patterns
|
||||
---------------------------
|
||||
|
||||
The compiled form of a pattern is a vector of bytes, containing items of
|
||||
variable length. The first byte in an item is an opcode, and the length of the
|
||||
item is either implicit in the opcode or contained in the data bytes which
|
||||
follow it. A list of all the opcodes follows:
|
||||
item is either implicit in the opcode or contained in the data bytes that
|
||||
follow it.
|
||||
|
||||
In many cases below "two-byte" data values are specified. This is in fact just
|
||||
a default. PCRE can be compiled to use 3-byte or 4-byte values (impairing the
|
||||
performance). This is necessary only when patterns whose compiled length is
|
||||
greater than 64K are going to be processed. In this description, we assume the
|
||||
"normal" compilation options.
|
||||
|
||||
A list of all the opcodes follows:
|
||||
|
||||
Opcodes with no following data
|
||||
------------------------------
|
||||
@@ -48,7 +89,7 @@ These items are all just one byte long
|
||||
|
||||
OP_END end of pattern
|
||||
OP_ANY match any character
|
||||
OP_ANYBYTE match any single byte, even in UTF-8 mode
|
||||
OP_ANYBYTE match any single byte, even in UTF-8 mode
|
||||
OP_SOD match start of data: \A
|
||||
OP_SOM, start of match (subject + offset): \G
|
||||
OP_CIRC ^ (start of data, or after \n in multiline)
|
||||
@@ -63,13 +104,14 @@ These items are all just one byte long
|
||||
OP_EODN match end of data or \n at end: \Z
|
||||
OP_EOD match end of data: \z
|
||||
OP_DOLL $ (end of data, or before \n in multiline)
|
||||
|
||||
OP_EXTUNI match an extended Unicode character
|
||||
|
||||
|
||||
Repeating single characters
|
||||
---------------------------
|
||||
|
||||
The common repeats (*, +, ?) when applied to a single character appear as
|
||||
two-byte items using the following opcodes:
|
||||
The common repeats (*, +, ?) when applied to a single character use the
|
||||
following opcodes:
|
||||
|
||||
OP_STAR
|
||||
OP_MINSTAR
|
||||
@@ -78,6 +120,7 @@ two-byte items using the following opcodes:
|
||||
OP_QUERY
|
||||
OP_MINQUERY
|
||||
|
||||
In ASCII mode, these are two-byte items; in UTF-8 mode, the length is variable.
|
||||
Those with "MIN" in their name are the minimizing versions. Each is followed by
|
||||
the character that is to be repeated. Other repeats make use of
|
||||
|
||||
@@ -109,39 +152,52 @@ byte. The opcodes are:
|
||||
OP_TYPEEXACT
|
||||
|
||||
|
||||
Matching a character string
|
||||
Match by Unicode property
|
||||
-------------------------
|
||||
|
||||
OP_PROP and OP_NOTPROP are used for positive and negative matches of a
|
||||
character by testing its Unicode property (the \p and \P escape sequences).
|
||||
Each is followed by a single byte that encodes the desired property value.
|
||||
|
||||
Repeats of these items use the OP_TYPESTAR etc. set of opcodes, followed by two
|
||||
bytes: OP_PROP or OP_NOTPROP and then the desired property value.
|
||||
|
||||
|
||||
Matching literal characters
|
||||
---------------------------
|
||||
|
||||
The OP_CHARS opcode is followed by a one-byte count and then that number of
|
||||
characters. If there are more than 255 characters in sequence, successive
|
||||
instances of OP_CHARS are used.
|
||||
The OP_CHAR opcode is followed by a single character that is to be matched
|
||||
casefully. For caseless matching, OP_CHARNC is used. In UTF-8 mode, the
|
||||
character may be more than one byte long. (Earlier versions of PCRE used
|
||||
multi-character strings, but this was changed to allow some new features to be
|
||||
added.)
|
||||
|
||||
|
||||
Character classes
|
||||
-----------------
|
||||
|
||||
If there is only one character, OP_CHARS is used for a positive class,
|
||||
and OP_NOT for a negative one (that is, for something like [^a]). However, in
|
||||
UTF-8 mode, this applies only to characters with values < 128, because OP_NOT
|
||||
is confined to single bytes.
|
||||
If there is only one character, OP_CHAR or OP_CHARNC is used for a positive
|
||||
class, and OP_NOT for a negative one (that is, for something like [^a]).
|
||||
However, in UTF-8 mode, the use of OP_NOT applies only to characters with
|
||||
values < 128, because OP_NOT is confined to single bytes.
|
||||
|
||||
Another set of repeating opcodes (OP_NOTSTAR etc.) are used for a repeated,
|
||||
negated, single-character class. The normal ones (OP_STAR etc.) are used for a
|
||||
repeated positive single-character class.
|
||||
|
||||
When there's more than one character in a class and all the characters are less
|
||||
than 256, OP_CLASS is used for a positive class, and OP_NCLASS for a negative
|
||||
than 256, OP_CLASS is used for a positive class, and OP_NCLASS for a negative
|
||||
one. In either case, the opcode is followed by a 32-byte bit map containing a 1
|
||||
bit for every character that is acceptable. The bits are counted from the least
|
||||
significant end of each byte.
|
||||
|
||||
The reason for having both OP_CLASS and OP_NCLASS is so that, in UTF-8 mode,
|
||||
subject characters with values greater than 256 can be handled correctly. For
|
||||
The reason for having both OP_CLASS and OP_NCLASS is so that, in UTF-8 mode,
|
||||
subject characters with values greater than 256 can be handled correctly. For
|
||||
OP_CLASS they don't match, whereas for OP_NCLASS they do.
|
||||
|
||||
For classes containing characters with values > 255, OP_XCLASS is used. It
|
||||
optionally uses a bit map (if any characters lie within it), followed by a list
|
||||
of pairs and single characters. There is a flag character than indicates
|
||||
of pairs and single characters. There is a flag character than indicates
|
||||
whether it's a positive or a negative class.
|
||||
|
||||
|
||||
@@ -191,15 +247,15 @@ number. This opcode is ignored while matching, but is fished out when handling
|
||||
the bracket itself. (They could have all been done like this, but I was making
|
||||
minimal changes.)
|
||||
|
||||
A bracket opcode is followed by two bytes which give the offset to the next
|
||||
alternative OP_ALT or, if there aren't any branches, to the matching KET
|
||||
opcode. Each OP_ALT is followed by two bytes giving the offset to the next one,
|
||||
or to the KET opcode.
|
||||
A bracket opcode is followed by LINK_SIZE bytes which give the offset to the
|
||||
next alternative OP_ALT or, if there aren't any branches, to the matching
|
||||
OP_KET opcode. Each OP_ALT is followed by LINK_SIZE bytes giving the offset to
|
||||
the next one, or to the OP_KET opcode.
|
||||
|
||||
OP_KET is used for subpatterns that do not repeat indefinitely, while
|
||||
OP_KETRMIN and OP_KETRMAX are used for indefinite repetitions, minimally or
|
||||
maximally respectively. All three are followed by two bytes giving (as a
|
||||
positive number) the offset back to the matching BRA opcode.
|
||||
maximally respectively. All three are followed by LINK_SIZE bytes giving (as a
|
||||
positive number) the offset back to the matching OP_BRA opcode.
|
||||
|
||||
If a subpattern is quantified such that it is permitted to match zero times, it
|
||||
is preceded by one of OP_BRAZERO or OP_BRAMINZERO. These are single-byte
|
||||
@@ -207,15 +263,14 @@ opcodes which tell the matcher that skipping this subpattern entirely is a
|
||||
valid branch.
|
||||
|
||||
A subpattern with an indefinite maximum repetition is replicated in the
|
||||
compiled data its minimum number of times (or once with a BRAZERO if the
|
||||
minimum is zero), with the final copy terminating with a KETRMIN or KETRMAX as
|
||||
appropriate.
|
||||
compiled data its minimum number of times (or once with OP_BRAZERO if the
|
||||
minimum is zero), with the final copy terminating with OP_KETRMIN or OP_KETRMAX
|
||||
as appropriate.
|
||||
|
||||
A subpattern with a bounded maximum repetition is replicated in a nested
|
||||
fashion up to the maximum number of times, with BRAZERO or BRAMINZERO before
|
||||
each replication after the minimum, so that, for example, (abc){2,5} is
|
||||
compiled as (abc)(abc)((abc)((abc)(abc)?)?)?. The 99 and 200 bracket limits do
|
||||
not apply to these internally generated brackets.
|
||||
fashion up to the maximum number of times, with OP_BRAZERO or OP_BRAMINZERO
|
||||
before each replication after the minimum, so that, for example, (abc){2,5} is
|
||||
compiled as (abc)(abc)((abc)((abc)(abc)?)?)?.
|
||||
|
||||
|
||||
Assertions
|
||||
@@ -260,8 +315,11 @@ from the start of the whole pattern.
|
||||
Callout
|
||||
-------
|
||||
|
||||
OP_CALLOUT is followed by one byte of data that holds a callout number in the
|
||||
range 0 to 255.
|
||||
OP_CALLOUT is followed by one byte of data that holds a callout number in the
|
||||
range 0 to 254 for manual callouts, or 255 for an automatic callout. In both
|
||||
cases there follows a two-byte value giving the offset in the pattern to the
|
||||
start of the following item, and another two-byte item giving the length of the
|
||||
next item.
|
||||
|
||||
|
||||
Changing options
|
||||
@@ -278,4 +336,4 @@ at compile time, and so does not cause anything to be put into the compiled
|
||||
data.
|
||||
|
||||
Philip Hazel
|
||||
August 2003
|
||||
March 2005
|
||||
+2475
-934
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,20 @@
|
||||
LIBRARY libpcre
|
||||
EXPORTS
|
||||
pcre_malloc
|
||||
pcre_free
|
||||
pcre_config
|
||||
pcre_callout
|
||||
pcre_compile
|
||||
pcre_copy_substring
|
||||
pcre_dfa_exec
|
||||
pcre_exec
|
||||
pcre_get_substring
|
||||
pcre_get_stringnumber
|
||||
pcre_get_substring_list
|
||||
pcre_free_substring
|
||||
pcre_free_substring_list
|
||||
pcre_info
|
||||
pcre_fullinfo
|
||||
pcre_maketables
|
||||
pcre_study
|
||||
pcre_version
|
||||
@@ -0,0 +1,25 @@
|
||||
LIBRARY libpcreposix
|
||||
EXPORTS
|
||||
pcre_malloc
|
||||
pcre_free
|
||||
pcre_config
|
||||
pcre_callout
|
||||
pcre_compile
|
||||
pcre_copy_substring
|
||||
pcre_dfa_exec
|
||||
pcre_exec
|
||||
pcre_get_substring
|
||||
pcre_get_stringnumber
|
||||
pcre_get_substring_list
|
||||
pcre_free_substring
|
||||
pcre_free_substring_list
|
||||
pcre_info
|
||||
pcre_fullinfo
|
||||
pcre_maketables
|
||||
pcre_study
|
||||
pcre_version
|
||||
|
||||
regcomp
|
||||
regexec
|
||||
regerror
|
||||
regfree
|
||||
File diff suppressed because it is too large.
Load diff
@@ -5,6 +5,7 @@ pcre_free DATA
|
||||
|
||||
pcre_compile
|
||||
pcre_copy_substring
|
||||
pcre_dfa_exec
|
||||
pcre_exec
|
||||
pcre_get_substring
|
||||
pcre_get_substring_list
|
||||
|
||||
+119
-54
@@ -2,7 +2,39 @@
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* Copyright (c) 1997-2003 University of Cambridge */
|
||||
/* In its original form, this is the .in file that is transformed by
|
||||
"configure" into pcre.h.
|
||||
|
||||
Copyright (c) 1997-2005 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _PCRE_H
|
||||
#define _PCRE_H
|
||||
@@ -12,11 +44,11 @@ make changes to pcre.in. */
|
||||
|
||||
#include "php_compat.h"
|
||||
|
||||
#define PCRE_MAJOR 4
|
||||
#define PCRE_MINOR 5
|
||||
#define PCRE_DATE 01-December-2003
|
||||
#define PCRE_MAJOR 6
|
||||
#define PCRE_MINOR 2
|
||||
#define PCRE_DATE 01-Aug-2005
|
||||
|
||||
/* Win32 uses DLL by default */
|
||||
/* Win32 uses DLL by default; it needs special stuff for exported functions. */
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef PCRE_DEFINITION
|
||||
@@ -29,8 +61,15 @@ make changes to pcre.in. */
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* For other operating systems, we use the standard "extern". */
|
||||
|
||||
#ifndef PCRE_DATA_SCOPE
|
||||
# define PCRE_DATA_SCOPE extern
|
||||
# ifdef __cplusplus
|
||||
# define PCRE_DATA_SCOPE extern "C"
|
||||
# else
|
||||
# define PCRE_DATA_SCOPE extern
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Have to include stdlib.h in order to ensure that size_t is defined;
|
||||
@@ -46,20 +85,25 @@ extern "C" {
|
||||
|
||||
/* Options */
|
||||
|
||||
#define PCRE_CASELESS 0x0001
|
||||
#define PCRE_MULTILINE 0x0002
|
||||
#define PCRE_DOTALL 0x0004
|
||||
#define PCRE_EXTENDED 0x0008
|
||||
#define PCRE_ANCHORED 0x0010
|
||||
#define PCRE_DOLLAR_ENDONLY 0x0020
|
||||
#define PCRE_EXTRA 0x0040
|
||||
#define PCRE_NOTBOL 0x0080
|
||||
#define PCRE_NOTEOL 0x0100
|
||||
#define PCRE_UNGREEDY 0x0200
|
||||
#define PCRE_NOTEMPTY 0x0400
|
||||
#define PCRE_UTF8 0x0800
|
||||
#define PCRE_NO_AUTO_CAPTURE 0x1000
|
||||
#define PCRE_NO_UTF8_CHECK 0x2000
|
||||
#define PCRE_CASELESS 0x00000001
|
||||
#define PCRE_MULTILINE 0x00000002
|
||||
#define PCRE_DOTALL 0x00000004
|
||||
#define PCRE_EXTENDED 0x00000008
|
||||
#define PCRE_ANCHORED 0x00000010
|
||||
#define PCRE_DOLLAR_ENDONLY 0x00000020
|
||||
#define PCRE_EXTRA 0x00000040
|
||||
#define PCRE_NOTBOL 0x00000080
|
||||
#define PCRE_NOTEOL 0x00000100
|
||||
#define PCRE_UNGREEDY 0x00000200
|
||||
#define PCRE_NOTEMPTY 0x00000400
|
||||
#define PCRE_UTF8 0x00000800
|
||||
#define PCRE_NO_AUTO_CAPTURE 0x00001000
|
||||
#define PCRE_NO_UTF8_CHECK 0x00002000
|
||||
#define PCRE_AUTO_CALLOUT 0x00004000
|
||||
#define PCRE_PARTIAL 0x00008000
|
||||
#define PCRE_DFA_SHORTEST 0x00010000
|
||||
#define PCRE_DFA_RESTART 0x00020000
|
||||
#define PCRE_FIRSTLINE 0x00040000
|
||||
|
||||
/* Exec-time and get/set-time error codes */
|
||||
|
||||
@@ -74,6 +118,15 @@ extern "C" {
|
||||
#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */
|
||||
#define PCRE_ERROR_BADUTF8 (-10)
|
||||
#define PCRE_ERROR_BADUTF8_OFFSET (-11)
|
||||
#define PCRE_ERROR_PARTIAL (-12)
|
||||
#define PCRE_ERROR_BADPARTIAL (-13)
|
||||
#define PCRE_ERROR_INTERNAL (-14)
|
||||
#define PCRE_ERROR_BADCOUNT (-15)
|
||||
#define PCRE_ERROR_DFA_UITEM (-16)
|
||||
#define PCRE_ERROR_DFA_UCOND (-17)
|
||||
#define PCRE_ERROR_DFA_UMLIMIT (-18)
|
||||
#define PCRE_ERROR_DFA_WSSIZE (-19)
|
||||
#define PCRE_ERROR_DFA_RECURSE (-20)
|
||||
|
||||
/* Request types for pcre_fullinfo() */
|
||||
|
||||
@@ -89,6 +142,7 @@ extern "C" {
|
||||
#define PCRE_INFO_NAMECOUNT 8
|
||||
#define PCRE_INFO_NAMETABLE 9
|
||||
#define PCRE_INFO_STUDYSIZE 10
|
||||
#define PCRE_INFO_DEFAULT_TABLES 11
|
||||
|
||||
/* Request types for pcre_config() */
|
||||
|
||||
@@ -98,12 +152,14 @@ extern "C" {
|
||||
#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3
|
||||
#define PCRE_CONFIG_MATCH_LIMIT 4
|
||||
#define PCRE_CONFIG_STACKRECURSE 5
|
||||
#define PCRE_CONFIG_UNICODE_PROPERTIES 6
|
||||
|
||||
/* Bit flags for the pcre_extra structure */
|
||||
|
||||
#define PCRE_EXTRA_STUDY_DATA 0x0001
|
||||
#define PCRE_EXTRA_MATCH_LIMIT 0x0002
|
||||
#define PCRE_EXTRA_CALLOUT_DATA 0x0004
|
||||
#define PCRE_EXTRA_TABLES 0x0008
|
||||
|
||||
/* Types */
|
||||
|
||||
@@ -111,13 +167,15 @@ struct real_pcre; /* declaration; the definition is private */
|
||||
typedef struct real_pcre pcre;
|
||||
|
||||
/* The structure for passing additional data to pcre_exec(). This is defined in
|
||||
such as way as to be extensible. */
|
||||
such as way as to be extensible. Always add new fields at the end, in order to
|
||||
remain compatible. */
|
||||
|
||||
typedef struct pcre_extra {
|
||||
unsigned long int flags; /* Bits for which fields are set */
|
||||
void *study_data; /* Opaque data from pcre_study() */
|
||||
unsigned long int match_limit; /* Maximum number of calls to match() */
|
||||
void *callout_data; /* Data passed back in callouts */
|
||||
const unsigned char *tables; /* Pointer to character tables */
|
||||
} pcre_extra;
|
||||
|
||||
/* The structure for passing out data via the pcre_callout_function. We use a
|
||||
@@ -133,19 +191,21 @@ typedef struct pcre_callout_block {
|
||||
const char *subject; /* The subject being matched */
|
||||
int subject_length; /* The length of the subject */
|
||||
int start_match; /* Offset to start of this match attempt */
|
||||
int current_position; /* Where we currently are */
|
||||
int current_position; /* Where we currently are in the subject */
|
||||
int capture_top; /* Max current capture */
|
||||
int capture_last; /* Most recently closed capture */
|
||||
void *callout_data; /* Data passed in with the call */
|
||||
/* ------------------- Added for Version 1 -------------------------- */
|
||||
int pattern_position; /* Offset to next item in the pattern */
|
||||
int next_item_length; /* Length of next item in the pattern */
|
||||
/* ------------------------------------------------------------------ */
|
||||
} pcre_callout_block;
|
||||
|
||||
/* Indirection for store get and free functions. These can be set to
|
||||
alternative malloc/free functions if required. Special ones are used in the
|
||||
non-recursive case for "frames". There is also an optional callout function
|
||||
that is triggered by the (?) regex item. Some magic is required for Win32 DLL;
|
||||
it is null on other OS. For Virtual Pascal, these have to be different again.
|
||||
*/
|
||||
that is triggered by the (?) regex item. For Virtual Pascal, these definitions
|
||||
have to take another form. */
|
||||
|
||||
#ifndef VPCOMPAT
|
||||
PCRE_DATA_SCOPE void *(*pcre_malloc)(size_t);
|
||||
@@ -154,39 +214,44 @@ PCRE_DATA_SCOPE void *(*pcre_stack_malloc)(size_t);
|
||||
PCRE_DATA_SCOPE void (*pcre_stack_free)(void *);
|
||||
PCRE_DATA_SCOPE int (*pcre_callout)(pcre_callout_block *);
|
||||
#else /* VPCOMPAT */
|
||||
extern void *pcre_malloc(size_t);
|
||||
extern void pcre_free(void *);
|
||||
extern void *pcre_stack_malloc(size_t);
|
||||
extern void pcre_stack_free(void *);
|
||||
extern int pcre_callout(pcre_callout_block *);
|
||||
PCRE_DATA_SCOPE void *pcre_malloc(size_t);
|
||||
PCRE_DATA_SCOPE void pcre_free(void *);
|
||||
PCRE_DATA_SCOPE void *pcre_stack_malloc(size_t);
|
||||
PCRE_DATA_SCOPE void pcre_stack_free(void *);
|
||||
PCRE_DATA_SCOPE int pcre_callout(pcre_callout_block *);
|
||||
#endif /* VPCOMPAT */
|
||||
|
||||
/* Exported PCRE functions */
|
||||
|
||||
extern pcre *pcre_compile(const char *, int, const char **,
|
||||
int *, const unsigned char *);
|
||||
extern int pcre_config(int, void *);
|
||||
extern int pcre_copy_named_substring(const pcre *, const char *,
|
||||
int *, int, const char *, char *, int);
|
||||
extern int pcre_copy_substring(const char *, int *, int, int,
|
||||
char *, int);
|
||||
extern int pcre_exec(const pcre *, const pcre_extra *,
|
||||
const char *, int, int, int, int *, int);
|
||||
extern void pcre_free_substring(const char *);
|
||||
extern void pcre_free_substring_list(const char **);
|
||||
extern int pcre_fullinfo(const pcre *, const pcre_extra *, int,
|
||||
void *);
|
||||
extern int pcre_get_named_substring(const pcre *, const char *,
|
||||
int *, int, const char *, const char **);
|
||||
extern int pcre_get_stringnumber(const pcre *, const char *);
|
||||
extern int pcre_get_substring(const char *, int *, int, int,
|
||||
const char **);
|
||||
extern int pcre_get_substring_list(const char *, int *, int,
|
||||
const char ***);
|
||||
extern int pcre_info(const pcre *, int *, int *);
|
||||
extern const unsigned char *pcre_maketables(void);
|
||||
extern pcre_extra *pcre_study(const pcre *, int, const char **);
|
||||
extern const char *pcre_version(void);
|
||||
PCRE_DATA_SCOPE pcre *pcre_compile(const char *, int, const char **, int *,
|
||||
const unsigned char *);
|
||||
PCRE_DATA_SCOPE pcre *pcre_compile2(const char *, int, int *, const char **,
|
||||
int *, const unsigned char *);
|
||||
PCRE_DATA_SCOPE int pcre_config(int, void *);
|
||||
PCRE_DATA_SCOPE int pcre_copy_named_substring(const pcre *, const char *,
|
||||
int *, int, const char *, char *, int);
|
||||
PCRE_DATA_SCOPE int pcre_copy_substring(const char *, int *, int, int, char *,
|
||||
int);
|
||||
PCRE_DATA_SCOPE int pcre_dfa_exec(const pcre *, const pcre_extra *,
|
||||
const char *, int, int, int, int *, int , int *, int);
|
||||
PCRE_DATA_SCOPE int pcre_exec(const pcre *, const pcre_extra *, const char *,
|
||||
int, int, int, int *, int);
|
||||
PCRE_DATA_SCOPE void pcre_free_substring(const char *);
|
||||
PCRE_DATA_SCOPE void pcre_free_substring_list(const char **);
|
||||
PCRE_DATA_SCOPE int pcre_fullinfo(const pcre *, const pcre_extra *, int,
|
||||
void *);
|
||||
PCRE_DATA_SCOPE int pcre_get_named_substring(const pcre *, const char *,
|
||||
int *, int, const char *, const char **);
|
||||
PCRE_DATA_SCOPE int pcre_get_stringnumber(const pcre *, const char *);
|
||||
PCRE_DATA_SCOPE int pcre_get_substring(const char *, int *, int, int,
|
||||
const char **);
|
||||
PCRE_DATA_SCOPE int pcre_get_substring_list(const char *, int *, int,
|
||||
const char ***);
|
||||
PCRE_DATA_SCOPE int pcre_info(const pcre *, int *, int *);
|
||||
PCRE_DATA_SCOPE const unsigned char *pcre_maketables(void);
|
||||
PCRE_DATA_SCOPE int pcre_refcount(pcre *, int);
|
||||
PCRE_DATA_SCOPE pcre_extra *pcre_study(const pcre *, int, const char **);
|
||||
PCRE_DATA_SCOPE const char *pcre_version(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
program. If you edit it by hand, you might like to edit the Makefile to
|
||||
prevent its ever being regenerated.
|
||||
|
||||
This file is #included in the compilation of pcre.c to build the default
|
||||
character tables which are used when no tables are passed to the compile
|
||||
function. */
|
||||
This file contains the default tables for characters with codes less than
|
||||
128 (ASCII characters). These tables are used when no external tables are
|
||||
passed to PCRE. */
|
||||
|
||||
static unsigned char pcre_default_tables[] = {
|
||||
const unsigned char _pcre_default_tables[] = {
|
||||
|
||||
/* This table is a lower casing table. */
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,112 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2005 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains the external function pcre_config(). */
|
||||
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Return info about what features are configured *
|
||||
*************************************************/
|
||||
|
||||
/* This function has an extensible interface so that additional items can be
|
||||
added compatibly.
|
||||
|
||||
Arguments:
|
||||
what what information is required
|
||||
where where to put the information
|
||||
|
||||
Returns: 0 if data returned, negative on error
|
||||
*/
|
||||
|
||||
EXPORT int
|
||||
pcre_config(int what, void *where)
|
||||
{
|
||||
switch (what)
|
||||
{
|
||||
case PCRE_CONFIG_UTF8:
|
||||
#ifdef SUPPORT_UTF8
|
||||
*((int *)where) = 1;
|
||||
#else
|
||||
*((int *)where) = 0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case PCRE_CONFIG_UNICODE_PROPERTIES:
|
||||
#ifdef SUPPORT_UCP
|
||||
*((int *)where) = 1;
|
||||
#else
|
||||
*((int *)where) = 0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case PCRE_CONFIG_NEWLINE:
|
||||
*((int *)where) = NEWLINE;
|
||||
break;
|
||||
|
||||
case PCRE_CONFIG_LINK_SIZE:
|
||||
*((int *)where) = LINK_SIZE;
|
||||
break;
|
||||
|
||||
case PCRE_CONFIG_POSIX_MALLOC_THRESHOLD:
|
||||
*((int *)where) = POSIX_MALLOC_THRESHOLD;
|
||||
break;
|
||||
|
||||
case PCRE_CONFIG_MATCH_LIMIT:
|
||||
*((unsigned int *)where) = MATCH_LIMIT;
|
||||
break;
|
||||
|
||||
case PCRE_CONFIG_STACKRECURSE:
|
||||
#ifdef NO_RECURSE
|
||||
*((int *)where) = 0;
|
||||
#else
|
||||
*((int *)where) = 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default: return PCRE_ERROR_BADOPTION;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* End of pcre_config.c */
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,149 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/*PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2005 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains the external function pcre_fullinfo(), which returns
|
||||
information about a compiled pattern. */
|
||||
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Return info about compiled pattern *
|
||||
*************************************************/
|
||||
|
||||
/* This is a newer "info" function which has an extensible interface so
|
||||
that additional items can be added compatibly.
|
||||
|
||||
Arguments:
|
||||
argument_re points to compiled code
|
||||
extra_data points extra data, or NULL
|
||||
what what information is required
|
||||
where where to put the information
|
||||
|
||||
Returns: 0 if data returned, negative on error
|
||||
*/
|
||||
|
||||
EXPORT int
|
||||
pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data, int what,
|
||||
void *where)
|
||||
{
|
||||
real_pcre internal_re;
|
||||
pcre_study_data internal_study;
|
||||
const real_pcre *re = (const real_pcre *)argument_re;
|
||||
const pcre_study_data *study = NULL;
|
||||
|
||||
if (re == NULL || where == NULL) return PCRE_ERROR_NULL;
|
||||
|
||||
if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0)
|
||||
study = (const pcre_study_data *)extra_data->study_data;
|
||||
|
||||
if (re->magic_number != MAGIC_NUMBER)
|
||||
{
|
||||
re = _pcre_try_flipped(re, &internal_re, study, &internal_study);
|
||||
if (re == NULL) return PCRE_ERROR_BADMAGIC;
|
||||
if (study != NULL) study = &internal_study;
|
||||
}
|
||||
|
||||
switch (what)
|
||||
{
|
||||
case PCRE_INFO_OPTIONS:
|
||||
*((unsigned long int *)where) = re->options & PUBLIC_OPTIONS;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_SIZE:
|
||||
*((size_t *)where) = re->size;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_STUDYSIZE:
|
||||
*((size_t *)where) = (study == NULL)? 0 : study->size;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_CAPTURECOUNT:
|
||||
*((int *)where) = re->top_bracket;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_BACKREFMAX:
|
||||
*((int *)where) = re->top_backref;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_FIRSTBYTE:
|
||||
*((int *)where) =
|
||||
((re->options & PCRE_FIRSTSET) != 0)? re->first_byte :
|
||||
((re->options & PCRE_STARTLINE) != 0)? -1 : -2;
|
||||
break;
|
||||
|
||||
/* Make sure we pass back the pointer to the bit vector in the external
|
||||
block, not the internal copy (with flipped integer fields). */
|
||||
|
||||
case PCRE_INFO_FIRSTTABLE:
|
||||
*((const uschar **)where) =
|
||||
(study != NULL && (study->options & PCRE_STUDY_MAPPED) != 0)?
|
||||
((const pcre_study_data *)extra_data->study_data)->start_bits : NULL;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_LASTLITERAL:
|
||||
*((int *)where) =
|
||||
((re->options & PCRE_REQCHSET) != 0)? re->req_byte : -1;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_NAMEENTRYSIZE:
|
||||
*((int *)where) = re->name_entry_size;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_NAMECOUNT:
|
||||
*((int *)where) = re->name_count;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_NAMETABLE:
|
||||
*((const uschar **)where) = (const uschar *)re + re->name_table_offset;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_DEFAULT_TABLES:
|
||||
*((const uschar **)where) = (const uschar *)(_pcre_default_tables);
|
||||
break;
|
||||
|
||||
default: return PCRE_ERROR_BADOPTION;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* End of pcre_fullinfo.c */
|
||||
@@ -2,45 +2,48 @@
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/*
|
||||
This is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language. See
|
||||
the file Tech.Notes for some information on the internals.
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by: Philip Hazel <ph10@cam.ac.uk>
|
||||
|
||||
Copyright (c) 1997-2003 University of Cambridge
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2005 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Permission is granted to anyone to use this software for any purpose on any
|
||||
computer system, and to redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. This software 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.
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. The origin of this software must not be misrepresented, either by
|
||||
explicit claim or by omission.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Altered versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
4. If PCRE is embedded in any software that is released under the GNU
|
||||
General Purpose Licence (GPL), then the terms of that licence shall
|
||||
supersede any condition above with which it is incompatible.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains some convenience functions for extracting substrings
|
||||
from the subject string after a regex match has succeeded. The original idea
|
||||
for these functions came from Scott Wimer <scottw@cgibuilder.com>. */
|
||||
for these functions came from Scott Wimer. */
|
||||
|
||||
|
||||
/* Include the internals header, which itself includes Standard C headers plus
|
||||
the external pcre header. */
|
||||
|
||||
#include "internal.h"
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
/*************************************************
|
||||
@@ -346,4 +349,4 @@ pcre_free_substring(const char *pointer)
|
||||
(pcre_free)((void *)pointer);
|
||||
}
|
||||
|
||||
/* End of get.c */
|
||||
/* End of pcre_get.c */
|
||||
@@ -0,0 +1,69 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2005 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains global variables that are exported by the PCRE library.
|
||||
PCRE is thread-clean and doesn't use any global variables in the normal sense.
|
||||
However, it calls memory allocation and freeing functions via the four
|
||||
indirections below, and it can optionally do callouts, using the fifth
|
||||
indirection. These values can be changed by the caller, but are shared between
|
||||
all threads. However, when compiling for Virtual Pascal, things are done
|
||||
differently, and global variables are not used (see pcre.in). */
|
||||
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
#ifndef VPCOMPAT
|
||||
#ifdef __cplusplus
|
||||
extern "C" void *(*pcre_malloc)(size_t) = malloc;
|
||||
extern "C" void (*pcre_free)(void *) = free;
|
||||
extern "C" void *(*pcre_stack_malloc)(size_t) = malloc;
|
||||
extern "C" void (*pcre_stack_free)(void *) = free;
|
||||
extern "C" int (*pcre_callout)(pcre_callout_block *) = NULL;
|
||||
#else
|
||||
void *(*pcre_malloc)(size_t) = malloc;
|
||||
void (*pcre_free)(void *) = free;
|
||||
void *(*pcre_stack_malloc)(size_t) = malloc;
|
||||
void (*pcre_stack_free)(void *) = free;
|
||||
int (*pcre_callout)(pcre_callout_block *) = NULL;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* End of pcre_globals.c */
|
||||
@@ -0,0 +1,89 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2005 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains the external function pcre_info(), which gives some
|
||||
information about a compiled pattern. However, use of this function is now
|
||||
deprecated, as it has been superseded by pcre_fullinfo(). */
|
||||
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
/*************************************************
|
||||
* (Obsolete) Return info about compiled pattern *
|
||||
*************************************************/
|
||||
|
||||
/* This is the original "info" function. It picks potentially useful data out
|
||||
of the private structure, but its interface was too rigid. It remains for
|
||||
backwards compatibility. The public options are passed back in an int - though
|
||||
the re->options field has been expanded to a long int, all the public options
|
||||
at the low end of it, and so even on 16-bit systems this will still be OK.
|
||||
Therefore, I haven't changed the API for pcre_info().
|
||||
|
||||
Arguments:
|
||||
argument_re points to compiled code
|
||||
optptr where to pass back the options
|
||||
first_byte where to pass back the first character,
|
||||
or -1 if multiline and all branches start ^,
|
||||
or -2 otherwise
|
||||
|
||||
Returns: number of capturing subpatterns
|
||||
or negative values on error
|
||||
*/
|
||||
|
||||
EXPORT int
|
||||
pcre_info(const pcre *argument_re, int *optptr, int *first_byte)
|
||||
{
|
||||
real_pcre internal_re;
|
||||
const real_pcre *re = (const real_pcre *)argument_re;
|
||||
if (re == NULL) return PCRE_ERROR_NULL;
|
||||
if (re->magic_number != MAGIC_NUMBER)
|
||||
{
|
||||
re = _pcre_try_flipped(re, &internal_re, NULL, NULL);
|
||||
if (re == NULL) return PCRE_ERROR_BADMAGIC;
|
||||
}
|
||||
if (optptr != NULL) *optptr = (int)(re->options & PUBLIC_OPTIONS);
|
||||
if (first_byte != NULL)
|
||||
*first_byte = ((re->options & PCRE_FIRSTSET) != 0)? re->first_byte :
|
||||
((re->options & PCRE_STARTLINE) != 0)? -1 : -2;
|
||||
return re->top_bracket;
|
||||
}
|
||||
|
||||
/* End of pcre_info.c */
|
||||
@@ -3,80 +3,129 @@
|
||||
*************************************************/
|
||||
|
||||
|
||||
/* This is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language. See
|
||||
the file Tech.Notes for some information on the internals.
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by: Philip Hazel <ph10@cam.ac.uk>
|
||||
|
||||
Copyright (c) 1997-2003 University of Cambridge
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2005 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Permission is granted to anyone to use this software for any purpose on any
|
||||
computer system, and to redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. This software 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.
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. The origin of this software must not be misrepresented, either by
|
||||
explicit claim or by omission.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Altered versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
4. If PCRE is embedded in any software that is released under the GNU
|
||||
General Purpose Licence (GPL), then the terms of that licence shall
|
||||
supersede any condition above with which it is incompatible.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* This header contains definitions that are shared between the different
|
||||
modules, but which are not relevant to the outside. */
|
||||
modules, but which are not relevant to the exported API. This includes some
|
||||
functions whose names all begin with "_pcre_". */
|
||||
|
||||
|
||||
/* Define DEBUG to get debugging output on stdout. */
|
||||
|
||||
/****
|
||||
#define DEBUG
|
||||
****/
|
||||
|
||||
/* Use a macro for debugging printing, 'cause that eliminates the use of #ifdef
|
||||
inline, and there are *still* stupid compilers about that don't like indented
|
||||
pre-processor statements, or at least there were when I first wrote this. After
|
||||
all, it had only been about 10 years then... */
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DPRINTF(p) printf p
|
||||
#else
|
||||
#define DPRINTF(p) /*nothing*/
|
||||
#endif
|
||||
|
||||
|
||||
/* Get the definitions provided by running "configure" */
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
# include "config.w32.h"
|
||||
#elif defined(NETWARE)
|
||||
# include "config.nw.h"
|
||||
#else
|
||||
# include <php_config.h>
|
||||
#endif
|
||||
|
||||
/* Standard C headers plus the external interface definition. The only time
|
||||
setjmp and stdarg are used is when NO_RECURSE is set. */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef PCRE_SPY
|
||||
#define PCRE_DEFINITION /* Win32 __declspec(export) trigger for .dll */
|
||||
#endif
|
||||
|
||||
/* The value of NEWLINE determines the newline character. The default is to
|
||||
leave it up to the compiler, but some sites want to force a particular value.
|
||||
On Unix systems, "configure" can be used to override this default. */
|
||||
/* We need to have types that specify unsigned 16-bit and 32-bit integers. We
|
||||
cannot determine these outside the compilation (e.g. by running a program as
|
||||
part of "configure") because PCRE is often cross-compiled for use on other
|
||||
systems. Instead we make use of the maximum sizes that are available at
|
||||
preprocessor time in standard C environments. */
|
||||
|
||||
#ifndef NEWLINE
|
||||
#define NEWLINE '\n'
|
||||
#if USHRT_MAX == 65535
|
||||
typedef unsigned short pcre_uint16;
|
||||
#elif UINT_MAX == 65535
|
||||
typedef unsigned int pcre_uint16;
|
||||
#else
|
||||
#error Cannot determine a type for 16-bit unsigned integers
|
||||
#endif
|
||||
|
||||
/* The value of MATCH_LIMIT determines the default number of times the match()
|
||||
function can be called during a single execution of pcre_exec(). (There is a
|
||||
runtime method of setting a different limit.) The limit exists in order to
|
||||
catch runaway regular expressions that take for ever to determine that they do
|
||||
not match. The default is set very large so that it does not accidentally catch
|
||||
legitimate cases. On Unix systems, "configure" can be used to override this
|
||||
default default. */
|
||||
|
||||
#ifndef MATCH_LIMIT
|
||||
#define MATCH_LIMIT 10000000
|
||||
#if UINT_MAX == 4294967295
|
||||
typedef unsigned int pcre_uint32;
|
||||
#elif ULONG_MAX == 4294967295
|
||||
typedef unsigned long int pcre_uint32;
|
||||
#else
|
||||
#error Cannot determine a type for 32-bit unsigned integers
|
||||
#endif
|
||||
|
||||
/* If you are compiling for a system that needs some magic to be inserted
|
||||
* before the definition of an exported function, define this macro to contain
|
||||
* the relevant magic. It apears at the start of every exported function. */
|
||||
|
||||
#define EXPORT
|
||||
/* All character handling must be done as unsigned characters. Otherwise there
|
||||
are problems with top-bit-set characters and functions such as isspace().
|
||||
However, we leave the interface to the outside world as char *, because that
|
||||
should make things easier for callers. We define a short type for unsigned char
|
||||
to save lots of typing. I tried "uchar", but it causes problems on Digital
|
||||
Unix, where it is defined in sys/types, so use "uschar" instead. */
|
||||
|
||||
typedef unsigned char uschar;
|
||||
|
||||
/* Include the public PCRE header */
|
||||
|
||||
#include "pcre.h"
|
||||
|
||||
/* Include the (copy of) the public ucp header, changing the external name into
|
||||
a private one. This does no harm, even if we aren't compiling UCP support. */
|
||||
|
||||
#define ucp_findchar _pcre_ucp_findchar
|
||||
#include "ucp.h"
|
||||
|
||||
/* When compiling for use with the Virtual Pascal compiler, these functions
|
||||
need to have their names changed. PCRE must be compiled with the -DVPCOMPAT
|
||||
option on the command line. */
|
||||
@@ -95,18 +144,6 @@ neither (there some non-Unix environments where this is the case). This assumes
|
||||
that all calls to memmove are moving strings upwards in store, which is the
|
||||
case in PCRE. */
|
||||
|
||||
/* Standard C headers plus the external interface definition. The only time
|
||||
setjmp and stdarg are used is when NO_RECURSE is set. */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if ! HAVE_MEMMOVE
|
||||
#undef memmove /* some systems may have a macro */
|
||||
#if HAVE_BCOPY
|
||||
@@ -126,13 +163,14 @@ for (i = 0; i < n; ++i) *(--dest) = *(--src);
|
||||
#endif /* not VPCOMPAT */
|
||||
|
||||
|
||||
/* PCRE keeps offsets in its compiled code as 2-byte quantities by default.
|
||||
These are used, for example, to link from the start of a subpattern to its
|
||||
alternatives and its end. The use of 2 bytes per offset limits the size of the
|
||||
compiled regex to around 64K, which is big enough for almost everybody.
|
||||
However, I received a request for an even bigger limit. For this reason, and
|
||||
also to make the code easier to maintain, the storing and loading of offsets
|
||||
from the byte string is now handled by the macros that are defined here.
|
||||
/* PCRE keeps offsets in its compiled code as 2-byte quantities (always stored
|
||||
in big-endian order) by default. These are used, for example, to link from the
|
||||
start of a subpattern to its alternatives and its end. The use of 2 bytes per
|
||||
offset limits the size of the compiled regex to around 64K, which is big enough
|
||||
for almost everybody. However, I received a request for an even bigger limit.
|
||||
For this reason, and also to make the code easier to maintain, the storing and
|
||||
loading of offsets from the byte string is now handled by the macros that are
|
||||
defined here.
|
||||
|
||||
The macros are controlled by the value of LINK_SIZE. This defaults to 2 in
|
||||
the config.h file, but can be overridden by using -D on the command line. This
|
||||
@@ -201,6 +239,116 @@ capturing parenthesis numbers in back references. */
|
||||
#define PUT2INC(a,n,d) PUT2(a,n,d), a += 2
|
||||
|
||||
|
||||
/* When UTF-8 encoding is being used, a character is no longer just a single
|
||||
byte. The macros for character handling generate simple sequences when used in
|
||||
byte-mode, and more complicated ones for UTF-8 characters. */
|
||||
|
||||
#ifndef SUPPORT_UTF8
|
||||
#define GETCHAR(c, eptr) c = *eptr;
|
||||
#define GETCHARTEST(c, eptr) c = *eptr;
|
||||
#define GETCHARINC(c, eptr) c = *eptr++;
|
||||
#define GETCHARINCTEST(c, eptr) c = *eptr++;
|
||||
#define GETCHARLEN(c, eptr, len) c = *eptr;
|
||||
#define BACKCHAR(eptr)
|
||||
|
||||
#else /* SUPPORT_UTF8 */
|
||||
|
||||
/* Get the next UTF-8 character, not advancing the pointer. This is called when
|
||||
we know we are in UTF-8 mode. */
|
||||
|
||||
#define GETCHAR(c, eptr) \
|
||||
c = *eptr; \
|
||||
if ((c & 0xc0) == 0xc0) \
|
||||
{ \
|
||||
int gcii; \
|
||||
int gcaa = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */ \
|
||||
int gcss = 6*gcaa; \
|
||||
c = (c & _pcre_utf8_table3[gcaa]) << gcss; \
|
||||
for (gcii = 1; gcii <= gcaa; gcii++) \
|
||||
{ \
|
||||
gcss -= 6; \
|
||||
c |= (eptr[gcii] & 0x3f) << gcss; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Get the next UTF-8 character, testing for UTF-8 mode, and not advancing the
|
||||
pointer. */
|
||||
|
||||
#define GETCHARTEST(c, eptr) \
|
||||
c = *eptr; \
|
||||
if (utf8 && (c & 0xc0) == 0xc0) \
|
||||
{ \
|
||||
int gcii; \
|
||||
int gcaa = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */ \
|
||||
int gcss = 6*gcaa; \
|
||||
c = (c & _pcre_utf8_table3[gcaa]) << gcss; \
|
||||
for (gcii = 1; gcii <= gcaa; gcii++) \
|
||||
{ \
|
||||
gcss -= 6; \
|
||||
c |= (eptr[gcii] & 0x3f) << gcss; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Get the next UTF-8 character, advancing the pointer. This is called when we
|
||||
know we are in UTF-8 mode. */
|
||||
|
||||
#define GETCHARINC(c, eptr) \
|
||||
c = *eptr++; \
|
||||
if ((c & 0xc0) == 0xc0) \
|
||||
{ \
|
||||
int gcaa = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */ \
|
||||
int gcss = 6*gcaa; \
|
||||
c = (c & _pcre_utf8_table3[gcaa]) << gcss; \
|
||||
while (gcaa-- > 0) \
|
||||
{ \
|
||||
gcss -= 6; \
|
||||
c |= (*eptr++ & 0x3f) << gcss; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Get the next character, testing for UTF-8 mode, and advancing the pointer */
|
||||
|
||||
#define GETCHARINCTEST(c, eptr) \
|
||||
c = *eptr++; \
|
||||
if (utf8 && (c & 0xc0) == 0xc0) \
|
||||
{ \
|
||||
int gcaa = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */ \
|
||||
int gcss = 6*gcaa; \
|
||||
c = (c & _pcre_utf8_table3[gcaa]) << gcss; \
|
||||
while (gcaa-- > 0) \
|
||||
{ \
|
||||
gcss -= 6; \
|
||||
c |= (*eptr++ & 0x3f) << gcss; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Get the next UTF-8 character, not advancing the pointer, incrementing length
|
||||
if there are extra bytes. This is called when we know we are in UTF-8 mode. */
|
||||
|
||||
#define GETCHARLEN(c, eptr, len) \
|
||||
c = *eptr; \
|
||||
if ((c & 0xc0) == 0xc0) \
|
||||
{ \
|
||||
int gcii; \
|
||||
int gcaa = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */ \
|
||||
int gcss = 6*gcaa; \
|
||||
c = (c & _pcre_utf8_table3[gcaa]) << gcss; \
|
||||
for (gcii = 1; gcii <= gcaa; gcii++) \
|
||||
{ \
|
||||
gcss -= 6; \
|
||||
c |= (eptr[gcii] & 0x3f) << gcss; \
|
||||
} \
|
||||
len += gcaa; \
|
||||
}
|
||||
|
||||
/* If the pointer is not at the start of a character, move it back until
|
||||
it is. Called only in UTF-8 mode. */
|
||||
|
||||
#define BACKCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr--;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* In case there is no definition of offsetof() provided - though any proper
|
||||
Standard C system should have one. */
|
||||
|
||||
@@ -208,6 +356,7 @@ Standard C system should have one. */
|
||||
#define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field))
|
||||
#endif
|
||||
|
||||
|
||||
/* These are the public options that can change during matching. */
|
||||
|
||||
#define PCRE_IMS (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL)
|
||||
@@ -215,32 +364,38 @@ Standard C system should have one. */
|
||||
/* Private options flags start at the most significant end of the four bytes,
|
||||
but skip the top bit so we can use ints for convenience without getting tangled
|
||||
with negative values. The public options defined in pcre.h start at the least
|
||||
significant end. Make sure they don't overlap, though now that we have expanded
|
||||
to four bytes there is plenty of space. */
|
||||
significant end. Make sure they don't overlap! */
|
||||
|
||||
#define PCRE_FIRSTSET 0x40000000 /* first_byte is set */
|
||||
#define PCRE_REQCHSET 0x20000000 /* req_byte is set */
|
||||
#define PCRE_STARTLINE 0x10000000 /* start after \n for multiline */
|
||||
#define PCRE_ICHANGED 0x08000000 /* i option changes within regex */
|
||||
#define PCRE_NOPARTIAL 0x04000000 /* can't use partial with this regex */
|
||||
|
||||
/* Options for the "extra" block produced by pcre_study(). */
|
||||
|
||||
#define PCRE_STUDY_MAPPED 0x01 /* a map of starting chars exists */
|
||||
|
||||
/* Masks for identifying the public options which are permitted at compile
|
||||
time, run time or study time, respectively. */
|
||||
/* Masks for identifying the public options that are permitted at compile
|
||||
time, run time, or study time, respectively. */
|
||||
|
||||
#define PUBLIC_OPTIONS \
|
||||
(PCRE_CASELESS|PCRE_EXTENDED|PCRE_ANCHORED|PCRE_MULTILINE| \
|
||||
PCRE_DOTALL|PCRE_DOLLAR_ENDONLY|PCRE_EXTRA|PCRE_UNGREEDY|PCRE_UTF8| \
|
||||
PCRE_NO_AUTO_CAPTURE|PCRE_NO_UTF8_CHECK)
|
||||
PCRE_NO_AUTO_CAPTURE|PCRE_NO_UTF8_CHECK|PCRE_AUTO_CALLOUT|PCRE_FIRSTLINE)
|
||||
|
||||
#define PUBLIC_EXEC_OPTIONS \
|
||||
(PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NO_UTF8_CHECK)
|
||||
(PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NO_UTF8_CHECK| \
|
||||
PCRE_PARTIAL)
|
||||
|
||||
#define PUBLIC_DFA_EXEC_OPTIONS \
|
||||
(PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NO_UTF8_CHECK| \
|
||||
PCRE_PARTIAL|PCRE_DFA_SHORTEST|PCRE_DFA_RESTART)
|
||||
|
||||
#define PUBLIC_STUDY_OPTIONS 0 /* None defined */
|
||||
|
||||
/* Magic number to provide a small check against being handed junk. */
|
||||
/* Magic number to provide a small check against being handed junk. Also used
|
||||
to detect whether a pattern was compiled on a host of different endianness. */
|
||||
|
||||
#define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */
|
||||
|
||||
@@ -249,6 +404,11 @@ time, run time or study time, respectively. */
|
||||
#define REQ_UNSET (-2)
|
||||
#define REQ_NONE (-1)
|
||||
|
||||
/* The maximum remaining length of subject we are prepared to search for a
|
||||
req_byte match. */
|
||||
|
||||
#define REQ_BYTE_MAX 1000
|
||||
|
||||
/* Flags added to firstbyte or reqbyte; a "non-literal" item is either a
|
||||
variable-length repeat, or a anything other than literal characters. */
|
||||
|
||||
@@ -296,12 +456,13 @@ definitions below, up to ESC_z. There's a dummy for OP_ANY because it
|
||||
corresponds to "." rather than an escape sequence. The final one must be
|
||||
ESC_REF as subsequent values are used for \1, \2, \3, etc. There is are two
|
||||
tests in the code for an escape greater than ESC_b and less than ESC_Z to
|
||||
detect the types that may be repeated. These are the types that consume a
|
||||
character. If any new escapes are put in between that don't consume a
|
||||
detect the types that may be repeated. These are the types that consume
|
||||
characters. If any new escapes are put in between that don't consume a
|
||||
character, that code will have to change. */
|
||||
|
||||
enum { ESC_A = 1, ESC_G, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W,
|
||||
ESC_w, ESC_dum1, ESC_C, ESC_Z, ESC_z, ESC_E, ESC_Q, ESC_REF };
|
||||
ESC_w, ESC_dum1, ESC_C, ESC_P, ESC_p, ESC_X, ESC_Z, ESC_z, ESC_E,
|
||||
ESC_Q, ESC_REF };
|
||||
|
||||
/* Flag bits and data types for the extended class (OP_XCLASS) for classes that
|
||||
contain UTF-8 characters with values greater than 255. */
|
||||
@@ -312,6 +473,8 @@ contain UTF-8 characters with values greater than 255. */
|
||||
#define XCL_END 0 /* Marks end of individual items */
|
||||
#define XCL_SINGLE 1 /* Single item (one multibyte char) follows */
|
||||
#define XCL_RANGE 2 /* A range (two multibyte chars) follows */
|
||||
#define XCL_PROP 3 /* Unicode property (one property code) follows */
|
||||
#define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */
|
||||
|
||||
|
||||
/* Opcode table: OP_BRA must be last, as all values >= it are used for brackets
|
||||
@@ -337,110 +500,123 @@ enum {
|
||||
OP_WORDCHAR, /* 10 \w */
|
||||
OP_ANY, /* 11 Match any character */
|
||||
OP_ANYBYTE, /* 12 Match any byte (\C); different to OP_ANY for UTF-8 */
|
||||
OP_EODN, /* 13 End of data or \n at end of data: \Z. */
|
||||
OP_EOD, /* 14 End of data: \z */
|
||||
OP_NOTPROP, /* 13 \P (not Unicode property) */
|
||||
OP_PROP, /* 14 \p (Unicode property) */
|
||||
OP_EXTUNI, /* 15 \X (extended Unicode sequence */
|
||||
OP_EODN, /* 16 End of data or \n at end of data: \Z. */
|
||||
OP_EOD, /* 17 End of data: \z */
|
||||
|
||||
OP_OPT, /* 15 Set runtime options */
|
||||
OP_CIRC, /* 16 Start of line - varies with multiline switch */
|
||||
OP_DOLL, /* 17 End of line - varies with multiline switch */
|
||||
OP_CHARS, /* 18 Match string of characters */
|
||||
OP_NOT, /* 19 Match anything but the following char */
|
||||
OP_OPT, /* 18 Set runtime options */
|
||||
OP_CIRC, /* 19 Start of line - varies with multiline switch */
|
||||
OP_DOLL, /* 20 End of line - varies with multiline switch */
|
||||
OP_CHAR, /* 21 Match one character, casefully */
|
||||
OP_CHARNC, /* 22 Match one character, caselessly */
|
||||
OP_NOT, /* 23 Match anything but the following char */
|
||||
|
||||
OP_STAR, /* 20 The maximizing and minimizing versions of */
|
||||
OP_MINSTAR, /* 21 all these opcodes must come in pairs, with */
|
||||
OP_PLUS, /* 22 the minimizing one second. */
|
||||
OP_MINPLUS, /* 23 This first set applies to single characters */
|
||||
OP_QUERY, /* 24 */
|
||||
OP_MINQUERY, /* 25 */
|
||||
OP_UPTO, /* 26 From 0 to n matches */
|
||||
OP_MINUPTO, /* 27 */
|
||||
OP_EXACT, /* 28 Exactly n matches */
|
||||
OP_STAR, /* 24 The maximizing and minimizing versions of */
|
||||
OP_MINSTAR, /* 25 all these opcodes must come in pairs, with */
|
||||
OP_PLUS, /* 26 the minimizing one second. */
|
||||
OP_MINPLUS, /* 27 This first set applies to single characters */
|
||||
OP_QUERY, /* 28 */
|
||||
OP_MINQUERY, /* 29 */
|
||||
OP_UPTO, /* 30 From 0 to n matches */
|
||||
OP_MINUPTO, /* 31 */
|
||||
OP_EXACT, /* 32 Exactly n matches */
|
||||
|
||||
OP_NOTSTAR, /* 29 The maximizing and minimizing versions of */
|
||||
OP_NOTMINSTAR, /* 30 all these opcodes must come in pairs, with */
|
||||
OP_NOTPLUS, /* 31 the minimizing one second. */
|
||||
OP_NOTMINPLUS, /* 32 This set applies to "not" single characters */
|
||||
OP_NOTQUERY, /* 33 */
|
||||
OP_NOTMINQUERY, /* 34 */
|
||||
OP_NOTUPTO, /* 35 From 0 to n matches */
|
||||
OP_NOTMINUPTO, /* 36 */
|
||||
OP_NOTEXACT, /* 37 Exactly n matches */
|
||||
OP_NOTSTAR, /* 33 The maximizing and minimizing versions of */
|
||||
OP_NOTMINSTAR, /* 34 all these opcodes must come in pairs, with */
|
||||
OP_NOTPLUS, /* 35 the minimizing one second. */
|
||||
OP_NOTMINPLUS, /* 36 This set applies to "not" single characters */
|
||||
OP_NOTQUERY, /* 37 */
|
||||
OP_NOTMINQUERY, /* 38 */
|
||||
OP_NOTUPTO, /* 39 From 0 to n matches */
|
||||
OP_NOTMINUPTO, /* 40 */
|
||||
OP_NOTEXACT, /* 41 Exactly n matches */
|
||||
|
||||
OP_TYPESTAR, /* 38 The maximizing and minimizing versions of */
|
||||
OP_TYPEMINSTAR, /* 39 all these opcodes must come in pairs, with */
|
||||
OP_TYPEPLUS, /* 40 the minimizing one second. These codes must */
|
||||
OP_TYPEMINPLUS, /* 41 be in exactly the same order as those above. */
|
||||
OP_TYPEQUERY, /* 42 This set applies to character types such as \d */
|
||||
OP_TYPEMINQUERY, /* 43 */
|
||||
OP_TYPEUPTO, /* 44 From 0 to n matches */
|
||||
OP_TYPEMINUPTO, /* 45 */
|
||||
OP_TYPEEXACT, /* 46 Exactly n matches */
|
||||
OP_TYPESTAR, /* 42 The maximizing and minimizing versions of */
|
||||
OP_TYPEMINSTAR, /* 43 all these opcodes must come in pairs, with */
|
||||
OP_TYPEPLUS, /* 44 the minimizing one second. These codes must */
|
||||
OP_TYPEMINPLUS, /* 45 be in exactly the same order as those above. */
|
||||
OP_TYPEQUERY, /* 46 This set applies to character types such as \d */
|
||||
OP_TYPEMINQUERY, /* 47 */
|
||||
OP_TYPEUPTO, /* 48 From 0 to n matches */
|
||||
OP_TYPEMINUPTO, /* 49 */
|
||||
OP_TYPEEXACT, /* 50 Exactly n matches */
|
||||
|
||||
OP_CRSTAR, /* 47 The maximizing and minimizing versions of */
|
||||
OP_CRMINSTAR, /* 48 all these opcodes must come in pairs, with */
|
||||
OP_CRPLUS, /* 49 the minimizing one second. These codes must */
|
||||
OP_CRMINPLUS, /* 50 be in exactly the same order as those above. */
|
||||
OP_CRQUERY, /* 51 These are for character classes and back refs */
|
||||
OP_CRMINQUERY, /* 52 */
|
||||
OP_CRRANGE, /* 53 These are different to the three seta above. */
|
||||
OP_CRMINRANGE, /* 54 */
|
||||
OP_CRSTAR, /* 51 The maximizing and minimizing versions of */
|
||||
OP_CRMINSTAR, /* 52 all these opcodes must come in pairs, with */
|
||||
OP_CRPLUS, /* 53 the minimizing one second. These codes must */
|
||||
OP_CRMINPLUS, /* 54 be in exactly the same order as those above. */
|
||||
OP_CRQUERY, /* 55 These are for character classes and back refs */
|
||||
OP_CRMINQUERY, /* 56 */
|
||||
OP_CRRANGE, /* 57 These are different to the three sets above. */
|
||||
OP_CRMINRANGE, /* 58 */
|
||||
|
||||
OP_CLASS, /* 55 Match a character class, chars < 256 only */
|
||||
OP_NCLASS, /* 56 Same, but the bitmap was created from a negative
|
||||
OP_CLASS, /* 59 Match a character class, chars < 256 only */
|
||||
OP_NCLASS, /* 60 Same, but the bitmap was created from a negative
|
||||
class - the difference is relevant only when a UTF-8
|
||||
character > 255 is encountered. */
|
||||
|
||||
OP_XCLASS, /* 57 Extended class for handling UTF-8 chars within the
|
||||
OP_XCLASS, /* 61 Extended class for handling UTF-8 chars within the
|
||||
class. This does both positive and negative. */
|
||||
|
||||
OP_REF, /* 58 Match a back reference */
|
||||
OP_RECURSE, /* 59 Match a numbered subpattern (possibly recursive) */
|
||||
OP_CALLOUT, /* 60 Call out to external function if provided */
|
||||
OP_REF, /* 62 Match a back reference */
|
||||
OP_RECURSE, /* 63 Match a numbered subpattern (possibly recursive) */
|
||||
OP_CALLOUT, /* 64 Call out to external function if provided */
|
||||
|
||||
OP_ALT, /* 61 Start of alternation */
|
||||
OP_KET, /* 62 End of group that doesn't have an unbounded repeat */
|
||||
OP_KETRMAX, /* 63 These two must remain together and in this */
|
||||
OP_KETRMIN, /* 64 order. They are for groups the repeat for ever. */
|
||||
OP_ALT, /* 65 Start of alternation */
|
||||
OP_KET, /* 66 End of group that doesn't have an unbounded repeat */
|
||||
OP_KETRMAX, /* 67 These two must remain together and in this */
|
||||
OP_KETRMIN, /* 68 order. They are for groups the repeat for ever. */
|
||||
|
||||
/* The assertions must come before ONCE and COND */
|
||||
|
||||
OP_ASSERT, /* 65 Positive lookahead */
|
||||
OP_ASSERT_NOT, /* 66 Negative lookahead */
|
||||
OP_ASSERTBACK, /* 67 Positive lookbehind */
|
||||
OP_ASSERTBACK_NOT, /* 68 Negative lookbehind */
|
||||
OP_REVERSE, /* 69 Move pointer back - used in lookbehind assertions */
|
||||
OP_ASSERT, /* 69 Positive lookahead */
|
||||
OP_ASSERT_NOT, /* 70 Negative lookahead */
|
||||
OP_ASSERTBACK, /* 71 Positive lookbehind */
|
||||
OP_ASSERTBACK_NOT, /* 72 Negative lookbehind */
|
||||
OP_REVERSE, /* 73 Move pointer back - used in lookbehind assertions */
|
||||
|
||||
/* ONCE and COND must come after the assertions, with ONCE first, as there's
|
||||
a test for >= ONCE for a subpattern that isn't an assertion. */
|
||||
|
||||
OP_ONCE, /* 70 Once matched, don't back up into the subpattern */
|
||||
OP_COND, /* 71 Conditional group */
|
||||
OP_CREF, /* 72 Used to hold an extraction string number (cond ref) */
|
||||
OP_ONCE, /* 74 Once matched, don't back up into the subpattern */
|
||||
OP_COND, /* 75 Conditional group */
|
||||
OP_CREF, /* 76 Used to hold an extraction string number (cond ref) */
|
||||
|
||||
OP_BRAZERO, /* 73 These two must remain together and in this */
|
||||
OP_BRAMINZERO, /* 74 order. */
|
||||
OP_BRAZERO, /* 77 These two must remain together and in this */
|
||||
OP_BRAMINZERO, /* 78 order. */
|
||||
|
||||
OP_BRANUMBER, /* 75 Used for extracting brackets whose number is greater
|
||||
OP_BRANUMBER, /* 79 Used for extracting brackets whose number is greater
|
||||
than can fit into an opcode. */
|
||||
|
||||
OP_BRA /* 76 This and greater values are used for brackets that
|
||||
extract substrings up to a basic limit. After that,
|
||||
use is made of OP_BRANUMBER. */
|
||||
OP_BRA /* 80 This and greater values are used for brackets that
|
||||
extract substrings up to EXTRACT_BASIC_MAX. After
|
||||
that, use is made of OP_BRANUMBER. */
|
||||
};
|
||||
|
||||
/* WARNING: There is an implicit assumption in study.c that all opcodes are
|
||||
less than 128 in value. This makes handling UTF-8 character sequences easier.
|
||||
*/
|
||||
/* WARNING WARNING WARNING: There is an implicit assumption in pcre.c and
|
||||
study.c that all opcodes are less than 128 in value. This makes handling UTF-8
|
||||
character sequences easier. */
|
||||
|
||||
/* The highest extraction number before we have to start using additional
|
||||
bytes. (Originally PCRE didn't have support for extraction counts highter than
|
||||
this number.) The value is limited by the number of opcodes left after OP_BRA,
|
||||
i.e. 255 - OP_BRA. We actually set it a bit lower to leave room for additional
|
||||
opcodes. */
|
||||
|
||||
#define EXTRACT_BASIC_MAX 100
|
||||
|
||||
|
||||
/* This macro defines textual names for all the opcodes. There are used only
|
||||
for debugging, in pcre.c when DEBUG is defined, and also in pcretest.c. The
|
||||
macro is referenced only in printint.c. */
|
||||
/* This macro defines textual names for all the opcodes. These are used only
|
||||
for debugging. The macro is referenced only in pcre_printint.c. */
|
||||
|
||||
#define OP_NAME_LIST \
|
||||
"End", "\\A", "\\G", "\\B", "\\b", "\\D", "\\d", \
|
||||
"\\S", "\\s", "\\W", "\\w", "Any", "Anybyte", "\\Z", "\\z", \
|
||||
"Opt", "^", "$", "chars", "not", \
|
||||
"\\S", "\\s", "\\W", "\\w", "Any", "Anybyte", \
|
||||
"notprop", "prop", "extuni", \
|
||||
"\\Z", "\\z", \
|
||||
"Opt", "^", "$", "char", "charnc", "not", \
|
||||
"*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
|
||||
"*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
|
||||
"*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
|
||||
@@ -454,7 +630,7 @@ macro is referenced only in printint.c. */
|
||||
/* This macro defines the length of fixed length operations in the compiled
|
||||
regex. The lengths are used when searching for specific things, and also in the
|
||||
debugging printing of a compiled regex. We use a macro so that it can be
|
||||
incorporated both into pcre.c and pcretest.c without being publicly exposed.
|
||||
defined close to the definitions of the opcodes themselves.
|
||||
|
||||
As things have been extended, some of these are no longer fixed lenths, but are
|
||||
minima instead. For example, the length of a single-character repeat may vary
|
||||
@@ -463,8 +639,11 @@ in UTF-8 mode. The code that uses this table must know about such things. */
|
||||
#define OP_LENGTHS \
|
||||
1, /* End */ \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* \A, \G, \B, \B, \D, \d, \S, \s, \W, \w */ \
|
||||
1, 1, 1, 1, 2, 1, 1, /* Any, Anybyte, \Z, \z, Opt, ^, $ */ \
|
||||
2, /* Chars - the minimum length */ \
|
||||
1, 1, /* Any, Anybyte */ \
|
||||
2, 2, 1, /* NOTPROP, PROP, EXTUNI */ \
|
||||
1, 1, 2, 1, 1, /* \Z, \z, Opt, ^, $ */ \
|
||||
2, /* Char - the minimum length */ \
|
||||
2, /* Charnc - the minimum length */ \
|
||||
2, /* not */ \
|
||||
/* Positive single-char repeats ** These are */ \
|
||||
2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \
|
||||
@@ -483,7 +662,7 @@ in UTF-8 mode. The code that uses this table must know about such things. */
|
||||
0, /* XCLASS - variable length */ \
|
||||
3, /* REF */ \
|
||||
1+LINK_SIZE, /* RECURSE */ \
|
||||
2, /* CALLOUT */ \
|
||||
2+2*LINK_SIZE, /* CALLOUT */ \
|
||||
1+LINK_SIZE, /* Alt */ \
|
||||
1+LINK_SIZE, /* Ket */ \
|
||||
1+LINK_SIZE, /* KetRmax */ \
|
||||
@@ -501,98 +680,61 @@ in UTF-8 mode. The code that uses this table must know about such things. */
|
||||
1+LINK_SIZE /* BRA */ \
|
||||
|
||||
|
||||
/* The highest extraction number before we have to start using additional
|
||||
bytes. (Originally PCRE didn't have support for extraction counts highter than
|
||||
this number.) The value is limited by the number of opcodes left after OP_BRA,
|
||||
i.e. 255 - OP_BRA. We actually set it a bit lower to leave room for additional
|
||||
opcodes. */
|
||||
|
||||
#define EXTRACT_BASIC_MAX 150
|
||||
|
||||
/* A magic value for OP_CREF to indicate the "in recursion" condition. */
|
||||
|
||||
#define CREF_RECURSE 0xffff
|
||||
|
||||
/* The texts of compile-time error messages are defined as macros here so that
|
||||
they can be accessed by the POSIX wrapper and converted into error codes. Yes,
|
||||
I could have used error codes in the first place, but didn't feel like changing
|
||||
just to accommodate the POSIX wrapper. */
|
||||
/* Error code numbers. They are given names so that they can more easily be
|
||||
tracked. */
|
||||
|
||||
#define ERR1 "\\ at end of pattern"
|
||||
#define ERR2 "\\c at end of pattern"
|
||||
#define ERR3 "unrecognized character follows \\"
|
||||
#define ERR4 "numbers out of order in {} quantifier"
|
||||
#define ERR5 "number too big in {} quantifier"
|
||||
#define ERR6 "missing terminating ] for character class"
|
||||
#define ERR7 "invalid escape sequence in character class"
|
||||
#define ERR8 "range out of order in character class"
|
||||
#define ERR9 "nothing to repeat"
|
||||
#define ERR10 "operand of unlimited repeat could match the empty string"
|
||||
#define ERR11 "internal error: unexpected repeat"
|
||||
#define ERR12 "unrecognized character after (?"
|
||||
#define ERR13 "POSIX named classes are supported only within a class"
|
||||
#define ERR14 "missing )"
|
||||
#define ERR15 "reference to non-existent subpattern"
|
||||
#define ERR16 "erroffset passed as NULL"
|
||||
#define ERR17 "unknown option bit(s) set"
|
||||
#define ERR18 "missing ) after comment"
|
||||
#define ERR19 "parentheses nested too deeply"
|
||||
#define ERR20 "regular expression too large"
|
||||
#define ERR21 "failed to get memory"
|
||||
#define ERR22 "unmatched parentheses"
|
||||
#define ERR23 "internal error: code overflow"
|
||||
#define ERR24 "unrecognized character after (?<"
|
||||
#define ERR25 "lookbehind assertion is not fixed length"
|
||||
#define ERR26 "malformed number after (?("
|
||||
#define ERR27 "conditional group contains more than two branches"
|
||||
#define ERR28 "assertion expected after (?("
|
||||
#define ERR29 "(?R or (?digits must be followed by )"
|
||||
#define ERR30 "unknown POSIX class name"
|
||||
#define ERR31 "POSIX collating elements are not supported"
|
||||
#define ERR32 "this version of PCRE is not compiled with PCRE_UTF8 support"
|
||||
#define ERR33 "spare error"
|
||||
#define ERR34 "character value in \\x{...} sequence is too large"
|
||||
#define ERR35 "invalid condition (?(0)"
|
||||
#define ERR36 "\\C not allowed in lookbehind assertion"
|
||||
#define ERR37 "PCRE does not support \\L, \\l, \\N, \\P, \\p, \\U, \\u, or \\X"
|
||||
#define ERR38 "number after (?C is > 255"
|
||||
#define ERR39 "closing ) for (?C expected"
|
||||
#define ERR40 "recursive call could loop indefinitely"
|
||||
#define ERR41 "unrecognized character after (?P"
|
||||
#define ERR42 "syntax error after (?P"
|
||||
#define ERR43 "two named groups have the same name"
|
||||
#define ERR44 "invalid UTF-8 string"
|
||||
|
||||
/* All character handling must be done as unsigned characters. Otherwise there
|
||||
are problems with top-bit-set characters and functions such as isspace().
|
||||
However, we leave the interface to the outside world as char *, because that
|
||||
should make things easier for callers. We define a short type for unsigned char
|
||||
to save lots of typing. I tried "uchar", but it causes problems on Digital
|
||||
Unix, where it is defined in sys/types, so use "uschar" instead. */
|
||||
|
||||
typedef unsigned char uschar;
|
||||
enum { ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9,
|
||||
ERR10, ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19,
|
||||
ERR20, ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29,
|
||||
ERR30, ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39,
|
||||
ERR40, ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47 };
|
||||
|
||||
/* The real format of the start of the pcre block; the index of names and the
|
||||
code vector run on as long as necessary after the end. */
|
||||
code vector run on as long as necessary after the end. We store an explicit
|
||||
offset to the name table so that if a regex is compiled on one host, saved, and
|
||||
then run on another where the size of pointers is different, all might still
|
||||
be well. For the case of compiled-on-4 and run-on-8, we include an extra
|
||||
pointer that is always NULL. For future-proofing, a few dummy fields were
|
||||
originally included - even though you can never get this planning right - but
|
||||
there is only one left now.
|
||||
|
||||
NOTE NOTE NOTE:
|
||||
Because people can now save and re-use compiled patterns, any additions to this
|
||||
structure should be made at the end, and something earlier (e.g. a new
|
||||
flag in the options or one of the dummy fields) should indicate that the new
|
||||
fields are present. Currently PCRE always sets the dummy fields to zero.
|
||||
NOTE NOTE NOTE:
|
||||
*/
|
||||
|
||||
typedef struct real_pcre {
|
||||
unsigned long int magic_number;
|
||||
size_t size; /* Total that was malloced */
|
||||
const unsigned char *tables; /* Pointer to tables */
|
||||
unsigned long int options;
|
||||
unsigned short int top_bracket;
|
||||
unsigned short int top_backref;
|
||||
unsigned short int first_byte;
|
||||
unsigned short int req_byte;
|
||||
unsigned short int name_entry_size; /* Size of any name items; 0 => none */
|
||||
unsigned short int name_count; /* Number of name items */
|
||||
pcre_uint32 magic_number;
|
||||
pcre_uint32 size; /* Total that was malloced */
|
||||
pcre_uint32 options;
|
||||
pcre_uint32 dummy1; /* For future use, maybe */
|
||||
|
||||
pcre_uint16 top_bracket;
|
||||
pcre_uint16 top_backref;
|
||||
pcre_uint16 first_byte;
|
||||
pcre_uint16 req_byte;
|
||||
pcre_uint16 name_table_offset; /* Offset to name table that follows */
|
||||
pcre_uint16 name_entry_size; /* Size of any name items */
|
||||
pcre_uint16 name_count; /* Number of name items */
|
||||
pcre_uint16 ref_count; /* Reference count */
|
||||
|
||||
const unsigned char *tables; /* Pointer to tables or NULL for std */
|
||||
const unsigned char *nullpad; /* NULL padding */
|
||||
} real_pcre;
|
||||
|
||||
/* The format of the block used to store data from pcre_study(). */
|
||||
/* The format of the block used to store data from pcre_study(). The same
|
||||
remark (see NOTE above) about extending this structure applies. */
|
||||
|
||||
typedef struct pcre_study_data {
|
||||
size_t size; /* Total that was malloced */
|
||||
uschar options;
|
||||
pcre_uint32 size; /* Total that was malloced */
|
||||
pcre_uint32 options;
|
||||
uschar start_bits[32];
|
||||
} pcre_study_data;
|
||||
|
||||
@@ -605,12 +747,14 @@ typedef struct compile_data {
|
||||
const uschar *cbits; /* Points to character type table */
|
||||
const uschar *ctypes; /* Points to table of type maps */
|
||||
const uschar *start_code; /* The start of the compiled code */
|
||||
const uschar *start_pattern; /* The start of the pattern */
|
||||
uschar *name_table; /* The name/number table */
|
||||
int names_found; /* Number of entries so far */
|
||||
int name_entry_size; /* Size of each entry */
|
||||
int top_backref; /* Maximum back reference */
|
||||
unsigned int backref_map; /* Bitmap of low back refs */
|
||||
int req_varyopt; /* "After variable item" flag for reqbyte */
|
||||
BOOL nopartial; /* Set TRUE if partial won't work */
|
||||
} compile_data;
|
||||
|
||||
/* Structure for maintaining a chain of pointers to the currently incomplete
|
||||
@@ -644,7 +788,7 @@ NOTE: This isn't used for a "normal" compilation of pcre. */
|
||||
struct heapframe;
|
||||
|
||||
/* Structure for passing "static" information around between the functions
|
||||
doing the matching, so that they are thread-safe. */
|
||||
doing traditional NFA matching, so that they are thread-safe. */
|
||||
|
||||
typedef struct match_data {
|
||||
unsigned long int match_call_count; /* As it says */
|
||||
@@ -660,6 +804,8 @@ typedef struct match_data {
|
||||
BOOL utf8; /* UTF8 flag */
|
||||
BOOL endonly; /* Dollar not before final \n */
|
||||
BOOL notempty; /* Empty string match not wanted */
|
||||
BOOL partial; /* PARTIAL flag */
|
||||
BOOL hitend; /* Hit the end of the subject at some point */
|
||||
const uschar *start_code; /* For use when recursing */
|
||||
const uschar *start_subject; /* Start of the subject string */
|
||||
const uschar *end_subject; /* End of the subject string */
|
||||
@@ -673,6 +819,19 @@ typedef struct match_data {
|
||||
struct heapframe *thisframe; /* Used only when compiling for no recursion */
|
||||
} match_data;
|
||||
|
||||
/* A similar structure is used for the same purpose by the DFA matching
|
||||
functions. */
|
||||
|
||||
typedef struct dfa_match_data {
|
||||
const uschar *start_code; /* Start of the compiled pattern */
|
||||
const uschar *start_subject; /* Start of the subject string */
|
||||
const uschar *end_subject; /* End of subject string */
|
||||
const uschar *tables; /* Character tables */
|
||||
int moptions; /* Match options */
|
||||
int poptions; /* Pattern options */
|
||||
void *callout_data; /* To pass back to callouts */
|
||||
} dfa_match_data;
|
||||
|
||||
/* Bit definitions for entries in the pcre_ctypes table. */
|
||||
|
||||
#define ctype_space 0x01
|
||||
@@ -706,4 +865,45 @@ total length. */
|
||||
#define ctypes_offset (cbits_offset + cbit_length)
|
||||
#define tables_length (ctypes_offset + 256)
|
||||
|
||||
/* End of internal.h */
|
||||
/* Layout of the UCP type table that translates property names into codes for
|
||||
ucp_findchar(). */
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int value;
|
||||
} ucp_type_table;
|
||||
|
||||
|
||||
/* Internal shared data tables. These are tables that are used by more than one
|
||||
of the exported public functions. They have to be "external" in the C sense,
|
||||
but are not part of the PCRE public API. The data for these tables is in the
|
||||
pcre_tables.c module. */
|
||||
|
||||
extern const int _pcre_utf8_table1[];
|
||||
extern const int _pcre_utf8_table2[];
|
||||
extern const int _pcre_utf8_table3[];
|
||||
extern const uschar _pcre_utf8_table4[];
|
||||
|
||||
extern const int _pcre_utf8_table1_size;
|
||||
|
||||
extern const ucp_type_table _pcre_utt[];
|
||||
extern const int _pcre_utt_size;
|
||||
|
||||
extern const uschar _pcre_default_tables[];
|
||||
|
||||
extern const uschar _pcre_OP_lengths[];
|
||||
|
||||
|
||||
/* Internal shared functions. These are functions that are used by more than
|
||||
one of the exported public functions. They have to be "external" in the C
|
||||
sense, but are not part of the PCRE public API. */
|
||||
|
||||
extern int _pcre_ord2utf8(int, uschar *);
|
||||
extern void _pcre_printint(pcre *, FILE *);
|
||||
extern real_pcre * _pcre_try_flipped(const real_pcre *, real_pcre *,
|
||||
const pcre_study_data *, pcre_study_data *);
|
||||
extern int _pcre_ucp_findchar(const int, int *, int *);
|
||||
extern int _pcre_valid_utf8(const uschar *, int);
|
||||
extern BOOL _pcre_xclass(int, const uschar *);
|
||||
|
||||
/* End of pcre_internal.h */
|
||||
@@ -2,48 +2,53 @@
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/*
|
||||
PCRE is a library of functions to support regular expressions whose syntax
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by: Philip Hazel <ph10@cam.ac.uk>
|
||||
|
||||
Copyright (c) 1997-2003 University of Cambridge
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2005 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Permission is granted to anyone to use this software for any purpose on any
|
||||
computer system, and to redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. This software 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.
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. The origin of this software must not be misrepresented, either by
|
||||
explicit claim or by omission.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Altered versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
4. If PCRE is embedded in any software that is released under the GNU
|
||||
General Purpose Licence (GPL), then the terms of that licence shall
|
||||
supersede any condition above with which it is incompatible.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
See the file Tech.Notes for some information on the internals.
|
||||
*/
|
||||
|
||||
|
||||
/* This file is compiled on its own as part of the PCRE library. However,
|
||||
it is also included in the compilation of dftables.c, in which case the macro
|
||||
DFTABLES is defined. */
|
||||
/* This module contains the external function pcre_maketables(), which builds
|
||||
character tables for PCRE in the current locale. The file is compiled on its
|
||||
own as part of the PCRE library. However, it is also included in the
|
||||
compilation of dftables.c, in which case the macro DFTABLES is defined. */
|
||||
|
||||
|
||||
#ifndef DFTABLES
|
||||
#include "internal.h"
|
||||
#include "pcre_internal.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Create PCRE character tables *
|
||||
*************************************************/
|
||||
@@ -137,4 +142,4 @@ for (i = 0; i < 256; i++)
|
||||
return yield;
|
||||
}
|
||||
|
||||
/* End of maketables.c */
|
||||
/* End of pcre_maketables.c */
|
||||
@@ -0,0 +1,78 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2005 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This file contains a private PCRE function that converts an ordinal
|
||||
character value into a UTF8 string. */
|
||||
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Convert character value to UTF-8 *
|
||||
*************************************************/
|
||||
|
||||
/* This function takes an integer value in the range 0 - 0x7fffffff
|
||||
and encodes it as a UTF-8 character in 0 to 6 bytes.
|
||||
|
||||
Arguments:
|
||||
cvalue the character value
|
||||
buffer pointer to buffer for result - at least 6 bytes long
|
||||
|
||||
Returns: number of characters placed in the buffer
|
||||
*/
|
||||
|
||||
EXPORT int
|
||||
_pcre_ord2utf8(int cvalue, uschar *buffer)
|
||||
{
|
||||
register int i, j;
|
||||
for (i = 0; i < _pcre_utf8_table1_size; i++)
|
||||
if (cvalue <= _pcre_utf8_table1[i]) break;
|
||||
buffer += i;
|
||||
for (j = i; j > 0; j--)
|
||||
{
|
||||
*buffer-- = 0x80 | (cvalue & 0x3f);
|
||||
cvalue >>= 6;
|
||||
}
|
||||
*buffer = _pcre_utf8_table2[i] | cvalue;
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
/* End of pcre_ord2utf8.c */
|
||||
@@ -0,0 +1,451 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2005 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains an PCRE private debugging function for printing out the
|
||||
internal form of a compiled regular expression, along with some supporting
|
||||
local functions. */
|
||||
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
static const char *OP_names[] = { OP_NAME_LIST };
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Print single- or multi-byte character *
|
||||
*************************************************/
|
||||
|
||||
static int
|
||||
print_char(FILE *f, uschar *ptr, BOOL utf8)
|
||||
{
|
||||
int c = *ptr;
|
||||
|
||||
if (!utf8 || (c & 0xc0) != 0xc0)
|
||||
{
|
||||
if (isprint(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
int a = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */
|
||||
int s = 6*a;
|
||||
c = (c & _pcre_utf8_table3[a]) << s;
|
||||
for (i = 1; i <= a; i++)
|
||||
{
|
||||
/* This is a check for malformed UTF-8; it should only occur if the sanity
|
||||
check has been turned off. Rather than swallow random bytes, just stop if
|
||||
we hit a bad one. Print it with \X instead of \x as an indication. */
|
||||
|
||||
if ((ptr[i] & 0xc0) != 0x80)
|
||||
{
|
||||
fprintf(f, "\\X{%x}", c);
|
||||
return i - 1;
|
||||
}
|
||||
|
||||
/* The byte is OK */
|
||||
|
||||
s -= 6;
|
||||
c |= (ptr[i] & 0x3f) << s;
|
||||
}
|
||||
if (c < 128) fprintf(f, "\\x%02x", c); else fprintf(f, "\\x{%x}", c);
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Find Unicode property name *
|
||||
*************************************************/
|
||||
|
||||
static const char *
|
||||
get_ucpname(int property)
|
||||
{
|
||||
#ifdef SUPPORT_UCP
|
||||
int i;
|
||||
for (i = _pcre_utt_size; i >= 0; i--)
|
||||
{
|
||||
if (property == _pcre_utt[i].value) break;
|
||||
}
|
||||
return (i >= 0)? _pcre_utt[i].name : "??";
|
||||
#else
|
||||
return "??";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Print compiled regex *
|
||||
*************************************************/
|
||||
|
||||
/* Make this function work for a regex with integers either byte order.
|
||||
However, we assume that what we are passed is a compiled regex. */
|
||||
|
||||
EXPORT void
|
||||
_pcre_printint(pcre *external_re, FILE *f)
|
||||
{
|
||||
real_pcre *re = (real_pcre *)external_re;
|
||||
uschar *codestart, *code;
|
||||
BOOL utf8;
|
||||
|
||||
unsigned int options = re->options;
|
||||
int offset = re->name_table_offset;
|
||||
int count = re->name_count;
|
||||
int size = re->name_entry_size;
|
||||
|
||||
if (re->magic_number != MAGIC_NUMBER)
|
||||
{
|
||||
offset = ((offset << 8) & 0xff00) | ((offset >> 8) & 0xff);
|
||||
count = ((count << 8) & 0xff00) | ((count >> 8) & 0xff);
|
||||
size = ((size << 8) & 0xff00) | ((size >> 8) & 0xff);
|
||||
options = ((options << 24) & 0xff000000) |
|
||||
((options << 8) & 0x00ff0000) |
|
||||
((options >> 8) & 0x0000ff00) |
|
||||
((options >> 24) & 0x000000ff);
|
||||
}
|
||||
|
||||
code = codestart = (uschar *)re + offset + count * size;
|
||||
utf8 = (options & PCRE_UTF8) != 0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
uschar *ccode;
|
||||
int c;
|
||||
int extra = 0;
|
||||
|
||||
fprintf(f, "%3d ", (int)(code - codestart));
|
||||
|
||||
if (*code >= OP_BRA)
|
||||
{
|
||||
if (*code - OP_BRA > EXTRACT_BASIC_MAX)
|
||||
fprintf(f, "%3d Bra extra\n", GET(code, 1));
|
||||
else
|
||||
fprintf(f, "%3d Bra %d\n", GET(code, 1), *code - OP_BRA);
|
||||
code += _pcre_OP_lengths[OP_BRA];
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(*code)
|
||||
{
|
||||
case OP_END:
|
||||
fprintf(f, " %s\n", OP_names[*code]);
|
||||
fprintf(f, "------------------------------------------------------------------\n");
|
||||
return;
|
||||
|
||||
case OP_OPT:
|
||||
fprintf(f, " %.2x %s", code[1], OP_names[*code]);
|
||||
break;
|
||||
|
||||
case OP_CHAR:
|
||||
{
|
||||
fprintf(f, " ");
|
||||
do
|
||||
{
|
||||
code++;
|
||||
code += 1 + print_char(f, code, utf8);
|
||||
}
|
||||
while (*code == OP_CHAR);
|
||||
fprintf(f, "\n");
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_CHARNC:
|
||||
{
|
||||
fprintf(f, " NC ");
|
||||
do
|
||||
{
|
||||
code++;
|
||||
code += 1 + print_char(f, code, utf8);
|
||||
}
|
||||
while (*code == OP_CHARNC);
|
||||
fprintf(f, "\n");
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_KETRMAX:
|
||||
case OP_KETRMIN:
|
||||
case OP_ALT:
|
||||
case OP_KET:
|
||||
case OP_ASSERT:
|
||||
case OP_ASSERT_NOT:
|
||||
case OP_ASSERTBACK:
|
||||
case OP_ASSERTBACK_NOT:
|
||||
case OP_ONCE:
|
||||
case OP_COND:
|
||||
case OP_REVERSE:
|
||||
fprintf(f, "%3d %s", GET(code, 1), OP_names[*code]);
|
||||
break;
|
||||
|
||||
case OP_BRANUMBER:
|
||||
printf("%3d %s", GET2(code, 1), OP_names[*code]);
|
||||
break;
|
||||
|
||||
case OP_CREF:
|
||||
if (GET2(code, 1) == CREF_RECURSE)
|
||||
fprintf(f, " Cond recurse");
|
||||
else
|
||||
fprintf(f, "%3d %s", GET2(code,1), OP_names[*code]);
|
||||
break;
|
||||
|
||||
case OP_STAR:
|
||||
case OP_MINSTAR:
|
||||
case OP_PLUS:
|
||||
case OP_MINPLUS:
|
||||
case OP_QUERY:
|
||||
case OP_MINQUERY:
|
||||
case OP_TYPESTAR:
|
||||
case OP_TYPEMINSTAR:
|
||||
case OP_TYPEPLUS:
|
||||
case OP_TYPEMINPLUS:
|
||||
case OP_TYPEQUERY:
|
||||
case OP_TYPEMINQUERY:
|
||||
fprintf(f, " ");
|
||||
if (*code >= OP_TYPESTAR)
|
||||
{
|
||||
fprintf(f, "%s", OP_names[code[1]]);
|
||||
if (code[1] == OP_PROP || code[1] == OP_NOTPROP)
|
||||
{
|
||||
fprintf(f, " %s ", get_ucpname(code[2]));
|
||||
extra = 1;
|
||||
}
|
||||
}
|
||||
else extra = print_char(f, code+1, utf8);
|
||||
fprintf(f, "%s", OP_names[*code]);
|
||||
break;
|
||||
|
||||
case OP_EXACT:
|
||||
case OP_UPTO:
|
||||
case OP_MINUPTO:
|
||||
fprintf(f, " ");
|
||||
extra = print_char(f, code+3, utf8);
|
||||
fprintf(f, "{");
|
||||
if (*code != OP_EXACT) fprintf(f, ",");
|
||||
fprintf(f, "%d}", GET2(code,1));
|
||||
if (*code == OP_MINUPTO) fprintf(f, "?");
|
||||
break;
|
||||
|
||||
case OP_TYPEEXACT:
|
||||
case OP_TYPEUPTO:
|
||||
case OP_TYPEMINUPTO:
|
||||
fprintf(f, " %s", OP_names[code[3]]);
|
||||
if (code[3] == OP_PROP || code[3] == OP_NOTPROP)
|
||||
{
|
||||
fprintf(f, " %s ", get_ucpname(code[4]));
|
||||
extra = 1;
|
||||
}
|
||||
fprintf(f, "{");
|
||||
if (*code != OP_TYPEEXACT) fprintf(f, "0,");
|
||||
fprintf(f, "%d}", GET2(code,1));
|
||||
if (*code == OP_TYPEMINUPTO) fprintf(f, "?");
|
||||
break;
|
||||
|
||||
case OP_NOT:
|
||||
if (isprint(c = code[1])) fprintf(f, " [^%c]", c);
|
||||
else fprintf(f, " [^\\x%02x]", c);
|
||||
break;
|
||||
|
||||
case OP_NOTSTAR:
|
||||
case OP_NOTMINSTAR:
|
||||
case OP_NOTPLUS:
|
||||
case OP_NOTMINPLUS:
|
||||
case OP_NOTQUERY:
|
||||
case OP_NOTMINQUERY:
|
||||
if (isprint(c = code[1])) fprintf(f, " [^%c]", c);
|
||||
else fprintf(f, " [^\\x%02x]", c);
|
||||
fprintf(f, "%s", OP_names[*code]);
|
||||
break;
|
||||
|
||||
case OP_NOTEXACT:
|
||||
case OP_NOTUPTO:
|
||||
case OP_NOTMINUPTO:
|
||||
if (isprint(c = code[3])) fprintf(f, " [^%c]{", c);
|
||||
else fprintf(f, " [^\\x%02x]{", c);
|
||||
if (*code != OP_NOTEXACT) fprintf(f, "0,");
|
||||
fprintf(f, "%d}", GET2(code,1));
|
||||
if (*code == OP_NOTMINUPTO) fprintf(f, "?");
|
||||
break;
|
||||
|
||||
case OP_RECURSE:
|
||||
fprintf(f, "%3d %s", GET(code, 1), OP_names[*code]);
|
||||
break;
|
||||
|
||||
case OP_REF:
|
||||
fprintf(f, " \\%d", GET2(code,1));
|
||||
ccode = code + _pcre_OP_lengths[*code];
|
||||
goto CLASS_REF_REPEAT;
|
||||
|
||||
case OP_CALLOUT:
|
||||
fprintf(f, " %s %d %d %d", OP_names[*code], code[1], GET(code,2),
|
||||
GET(code, 2 + LINK_SIZE));
|
||||
break;
|
||||
|
||||
case OP_PROP:
|
||||
case OP_NOTPROP:
|
||||
fprintf(f, " %s %s", OP_names[*code], get_ucpname(code[1]));
|
||||
break;
|
||||
|
||||
/* OP_XCLASS can only occur in UTF-8 mode. However, there's no harm in
|
||||
having this code always here, and it makes it less messy without all those
|
||||
#ifdefs. */
|
||||
|
||||
case OP_CLASS:
|
||||
case OP_NCLASS:
|
||||
case OP_XCLASS:
|
||||
{
|
||||
int i, min, max;
|
||||
BOOL printmap;
|
||||
|
||||
fprintf(f, " [");
|
||||
|
||||
if (*code == OP_XCLASS)
|
||||
{
|
||||
extra = GET(code, 1);
|
||||
ccode = code + LINK_SIZE + 1;
|
||||
printmap = (*ccode & XCL_MAP) != 0;
|
||||
if ((*ccode++ & XCL_NOT) != 0) fprintf(f, "^");
|
||||
}
|
||||
else
|
||||
{
|
||||
printmap = TRUE;
|
||||
ccode = code + 1;
|
||||
}
|
||||
|
||||
/* Print a bit map */
|
||||
|
||||
if (printmap)
|
||||
{
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
if ((ccode[i/8] & (1 << (i&7))) != 0)
|
||||
{
|
||||
int j;
|
||||
for (j = i+1; j < 256; j++)
|
||||
if ((ccode[j/8] & (1 << (j&7))) == 0) break;
|
||||
if (i == '-' || i == ']') fprintf(f, "\\");
|
||||
if (isprint(i)) fprintf(f, "%c", i); else fprintf(f, "\\x%02x", i);
|
||||
if (--j > i)
|
||||
{
|
||||
if (j != i + 1) fprintf(f, "-");
|
||||
if (j == '-' || j == ']') fprintf(f, "\\");
|
||||
if (isprint(j)) fprintf(f, "%c", j); else fprintf(f, "\\x%02x", j);
|
||||
}
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
ccode += 32;
|
||||
}
|
||||
|
||||
/* For an XCLASS there is always some additional data */
|
||||
|
||||
if (*code == OP_XCLASS)
|
||||
{
|
||||
int ch;
|
||||
while ((ch = *ccode++) != XCL_END)
|
||||
{
|
||||
if (ch == XCL_PROP)
|
||||
{
|
||||
fprintf(f, "\\p{%s}", get_ucpname(*ccode++));
|
||||
}
|
||||
else if (ch == XCL_NOTPROP)
|
||||
{
|
||||
fprintf(f, "\\P{%s}", get_ucpname(*ccode++));
|
||||
}
|
||||
else
|
||||
{
|
||||
ccode += 1 + print_char(f, ccode, TRUE);
|
||||
if (ch == XCL_RANGE)
|
||||
{
|
||||
fprintf(f, "-");
|
||||
ccode += 1 + print_char(f, ccode, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Indicate a non-UTF8 class which was created by negation */
|
||||
|
||||
fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : "");
|
||||
|
||||
/* Handle repeats after a class or a back reference */
|
||||
|
||||
CLASS_REF_REPEAT:
|
||||
switch(*ccode)
|
||||
{
|
||||
case OP_CRSTAR:
|
||||
case OP_CRMINSTAR:
|
||||
case OP_CRPLUS:
|
||||
case OP_CRMINPLUS:
|
||||
case OP_CRQUERY:
|
||||
case OP_CRMINQUERY:
|
||||
fprintf(f, "%s", OP_names[*ccode]);
|
||||
extra += _pcre_OP_lengths[*ccode];
|
||||
break;
|
||||
|
||||
case OP_CRRANGE:
|
||||
case OP_CRMINRANGE:
|
||||
min = GET2(ccode,1);
|
||||
max = GET2(ccode,3);
|
||||
if (max == 0) fprintf(f, "{%d,}", min);
|
||||
else fprintf(f, "{%d,%d}", min, max);
|
||||
if (*ccode == OP_CRMINRANGE) fprintf(f, "?");
|
||||
extra += _pcre_OP_lengths[*ccode];
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* Anything else is just an item with no data*/
|
||||
|
||||
default:
|
||||
fprintf(f, " %s", OP_names[*code]);
|
||||
break;
|
||||
}
|
||||
|
||||
code += _pcre_OP_lengths[*code] + extra;
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* End of pcre_printint.c */
|
||||
@@ -0,0 +1,77 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2005 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains the external function pcre_refcount(), which is an
|
||||
auxiliary function that can be used to maintain a reference count in a compiled
|
||||
pattern data block. This might be helpful in applications where the block is
|
||||
shared by different users. */
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Maintain reference count *
|
||||
*************************************************/
|
||||
|
||||
/* The reference count is a 16-bit field, initialized to zero. It is not
|
||||
possible to transfer a non-zero count from one host to a different host that
|
||||
has a different byte order - though I can't see why anyone in their right mind
|
||||
would ever want to do that!
|
||||
|
||||
Arguments:
|
||||
argument_re points to compiled code
|
||||
adjust value to add to the count
|
||||
|
||||
Returns: the (possibly updated) count value (a non-negative number), or
|
||||
a negative error number
|
||||
*/
|
||||
|
||||
EXPORT int
|
||||
pcre_refcount(pcre *argument_re, int adjust)
|
||||
{
|
||||
real_pcre *re = (real_pcre *)argument_re;
|
||||
if (re == NULL) return PCRE_ERROR_NULL;
|
||||
re->ref_count = (-adjust > re->ref_count)? 0 :
|
||||
(adjust + re->ref_count > 65535)? 65535 :
|
||||
re->ref_count + adjust;
|
||||
return re->ref_count;
|
||||
}
|
||||
|
||||
/* End of pcre_refcount.c */
|
||||
@@ -0,0 +1,169 @@
|
||||
// Copyright (c) 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: Sanjay Ghemawat
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm> // for count()
|
||||
#include <assert.h>
|
||||
#include "config.h"
|
||||
#include "pcre_scanner.h"
|
||||
|
||||
using std::vector;
|
||||
|
||||
namespace pcrecpp {
|
||||
|
||||
Scanner::Scanner()
|
||||
: data_(),
|
||||
input_(data_),
|
||||
skip_(NULL),
|
||||
should_skip_(false),
|
||||
save_comments_(false),
|
||||
comments_(NULL),
|
||||
comments_offset_(0) {
|
||||
}
|
||||
|
||||
Scanner::Scanner(const string& in)
|
||||
: data_(in),
|
||||
input_(data_),
|
||||
skip_(NULL),
|
||||
should_skip_(false),
|
||||
save_comments_(false),
|
||||
comments_(NULL),
|
||||
comments_offset_(0) {
|
||||
}
|
||||
|
||||
Scanner::~Scanner() {
|
||||
delete skip_;
|
||||
delete comments_;
|
||||
}
|
||||
|
||||
void Scanner::Skip(const char* re) {
|
||||
delete skip_;
|
||||
if (re != NULL) {
|
||||
skip_ = new RE(re);
|
||||
should_skip_ = true;
|
||||
ConsumeSkip();
|
||||
} else {
|
||||
skip_ = NULL;
|
||||
should_skip_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Scanner::DisableSkip() {
|
||||
assert(skip_ != NULL);
|
||||
should_skip_ = false;
|
||||
}
|
||||
|
||||
void Scanner::EnableSkip() {
|
||||
assert(skip_ != NULL);
|
||||
should_skip_ = true;
|
||||
ConsumeSkip();
|
||||
}
|
||||
|
||||
int Scanner::LineNumber() const {
|
||||
// TODO: Make it more efficient by keeping track of the last point
|
||||
// where we computed line numbers and counting newlines since then.
|
||||
return 1 + std::count(data_.data(), input_.data(), '\n');
|
||||
}
|
||||
|
||||
int Scanner::Offset() const {
|
||||
return input_.data() - data_.c_str();
|
||||
}
|
||||
|
||||
bool Scanner::LookingAt(const RE& re) const {
|
||||
int consumed;
|
||||
return re.DoMatch(input_, RE::ANCHOR_START, &consumed, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
bool Scanner::Consume(const RE& re,
|
||||
const Arg& arg0,
|
||||
const Arg& arg1,
|
||||
const Arg& arg2) {
|
||||
const bool result = re.Consume(&input_, arg0, arg1, arg2);
|
||||
if (result && should_skip_) ConsumeSkip();
|
||||
return result;
|
||||
}
|
||||
|
||||
// helper function to consume *skip_ and honour save_comments_
|
||||
void Scanner::ConsumeSkip() {
|
||||
if (save_comments_) {
|
||||
if (NULL == comments_) {
|
||||
comments_ = new vector<StringPiece>;
|
||||
}
|
||||
const char *start_data = input_.data();
|
||||
skip_->Consume(&input_);
|
||||
// already pointing one past end, so no need to +1
|
||||
int length = input_.data() - start_data;
|
||||
if (length > 0) {
|
||||
comments_->push_back(StringPiece(start_data, length));
|
||||
}
|
||||
} else {
|
||||
skip_->Consume(&input_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Scanner::GetComments(int start, int end, vector<StringPiece> *ranges) {
|
||||
// short circuit out if we've not yet initialized comments_
|
||||
// (e.g., when save_comments is false)
|
||||
if (!comments_) {
|
||||
return;
|
||||
}
|
||||
// TODO: if we guarantee that comments_ will contain StringPieces
|
||||
// that are ordered by their start, then we can do a binary search
|
||||
// for the first StringPiece at or past start and then scan for the
|
||||
// ones contained in the range, quit early (use equal_range or
|
||||
// lower_bound)
|
||||
for (vector<StringPiece>::const_iterator it = comments_->begin();
|
||||
it != comments_->end(); ++it) {
|
||||
if ((it->data() >= data_.c_str() + start &&
|
||||
it->data() + it->size() <= data_.c_str() + end)) {
|
||||
ranges->push_back(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Scanner::GetNextComments(vector<StringPiece> *ranges) {
|
||||
// short circuit out if we've not yet initialized comments_
|
||||
// (e.g., when save_comments is false)
|
||||
if (!comments_) {
|
||||
return;
|
||||
}
|
||||
for (vector<StringPiece>::const_iterator it =
|
||||
comments_->begin() + comments_offset_;
|
||||
it != comments_->end(); ++it) {
|
||||
ranges->push_back(*it);
|
||||
++comments_offset_;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pcrecpp
|
||||
@@ -0,0 +1,163 @@
|
||||
// Copyright (c) 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: Sanjay Ghemawat
|
||||
//
|
||||
// Regular-expression based scanner for parsing an input stream.
|
||||
//
|
||||
// Example 1: parse a sequence of "var = number" entries from input:
|
||||
//
|
||||
// Scanner scanner(input);
|
||||
// string var;
|
||||
// int number;
|
||||
// scanner.Skip("\\s+"); // Skip any white space we encounter
|
||||
// while (scanner.Consume("(\\w+) = (\\d+)", &var, &number)) {
|
||||
// ...;
|
||||
// }
|
||||
|
||||
#ifndef _PCRE_SCANNER_H
|
||||
#define _PCRE_SCANNER_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <pcrecpp.h>
|
||||
#include <pcre_stringpiece.h>
|
||||
|
||||
namespace pcrecpp {
|
||||
|
||||
class Scanner {
|
||||
public:
|
||||
Scanner();
|
||||
explicit Scanner(const std::string& input);
|
||||
~Scanner();
|
||||
|
||||
// Return current line number. The returned line-number is
|
||||
// one-based. I.e. it returns 1 + the number of consumed newlines.
|
||||
//
|
||||
// Note: this method may be slow. It may take time proportional to
|
||||
// the size of the input.
|
||||
int LineNumber() const;
|
||||
|
||||
// Return the byte-offset that the scanner is looking in the
|
||||
// input data;
|
||||
int Offset() const;
|
||||
|
||||
// Return true iff the start of the remaining input matches "re"
|
||||
bool LookingAt(const RE& re) const;
|
||||
|
||||
// Return true iff all of the following are true
|
||||
// a. the start of the remaining input matches "re",
|
||||
// b. if any arguments are supplied, matched sub-patterns can be
|
||||
// parsed and stored into the arguments.
|
||||
// If it returns true, it skips over the matched input and any
|
||||
// following input that matches the "skip" regular expression.
|
||||
bool Consume(const RE& re,
|
||||
const Arg& arg0 = no_arg,
|
||||
const Arg& arg1 = no_arg,
|
||||
const Arg& arg2 = no_arg
|
||||
// TODO: Allow more arguments?
|
||||
);
|
||||
|
||||
// Set the "skip" regular expression. If after consuming some data,
|
||||
// a prefix of the input matches this RE, it is automatically
|
||||
// skipped. For example, a programming language scanner would use
|
||||
// a skip RE that matches white space and comments.
|
||||
//
|
||||
// scanner.Skip("(\\s|//.*|/[*](.|\n)*?[*]/)*");
|
||||
//
|
||||
// You can pass NULL for "re" if you do not want any data to be skipped.
|
||||
void Skip(const char* re);
|
||||
|
||||
// Temporarily pause "skip"ing. This
|
||||
// Skip("Foo"); code ; DisableSkip(); code; EnableSkip()
|
||||
// is similar to
|
||||
// Skip("Foo"); code ; Skip(NULL); code ; Skip("Foo");
|
||||
// but avoids creating/deleting new RE objects.
|
||||
void DisableSkip();
|
||||
|
||||
// Reenable previously paused skipping. Any prefix of the input
|
||||
// that matches the skip pattern is immediately dropped.
|
||||
void EnableSkip();
|
||||
|
||||
/***** Special wrappers around SetSkip() for some common idioms *****/
|
||||
|
||||
// Arranges to skip whitespace, C comments, C++ comments.
|
||||
// The overall RE is a repeated disjunction of the following REs:
|
||||
// \\s whitespace
|
||||
// //.*\n C++ comment
|
||||
// /[*](.|\n)*?[*]/ C comment (x*? means minimal repetitions of x)
|
||||
void SkipCXXComments() {
|
||||
Skip("((\\s|//.*\n|/[*](.|\n)*?[*]/)*)");
|
||||
}
|
||||
|
||||
void set_save_comments(bool comments) {
|
||||
save_comments_ = comments;
|
||||
}
|
||||
|
||||
bool save_comments() {
|
||||
return save_comments_;
|
||||
}
|
||||
|
||||
// Append to vector ranges the comments found in the
|
||||
// byte range [start,end] (inclusive) of the input data.
|
||||
// Only comments that were extracted entirely within that
|
||||
// range are returned: no range splitting of atomically-extracted
|
||||
// comments is performed.
|
||||
void GetComments(int start, int end, std::vector<StringPiece> *ranges);
|
||||
|
||||
// Append to vector ranges the comments added
|
||||
// since the last time this was called. This
|
||||
// functionality is provided for efficiency when
|
||||
// interleaving scanning with parsing.
|
||||
void GetNextComments(std::vector<StringPiece> *ranges);
|
||||
|
||||
private:
|
||||
std::string data_; // All the input data
|
||||
StringPiece input_; // Unprocessed input
|
||||
RE* skip_; // If non-NULL, RE for skipping input
|
||||
bool should_skip_; // If true, use skip_
|
||||
bool save_comments_; // If true, aggregate the skip expression
|
||||
|
||||
// the skipped comments
|
||||
// TODO: later consider requiring that the StringPieces be added
|
||||
// in order by their start position
|
||||
std::vector<StringPiece> *comments_;
|
||||
|
||||
// the offset into comments_ that has been returned by GetNextComments
|
||||
int comments_offset_;
|
||||
|
||||
// helper function to consume *skip_ and honour
|
||||
// save_comments_
|
||||
void ConsumeSkip();
|
||||
};
|
||||
|
||||
} // namespace pcrecpp
|
||||
|
||||
#endif /* _PCRE_SCANNER_H */
|
||||
@@ -0,0 +1,125 @@
|
||||
// Copyright (c) 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: Greg J. Badros
|
||||
//
|
||||
// Unittest for scanner, especially GetNextComments and GetComments()
|
||||
// functionality.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
#include <pcre_stringpiece.h>
|
||||
#include <pcre_scanner.h>
|
||||
|
||||
// Dies with a fatal error if the two values are not equal.
|
||||
#define CHECK_EQ(a, b) do { \
|
||||
if ( (a) != (b) ) { \
|
||||
fprintf(stderr, "%s:%d: Check failed because %s != %s\n", \
|
||||
__FILE__, __LINE__, #a, #b); \
|
||||
exit(1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
using std::vector;
|
||||
using pcrecpp::StringPiece;
|
||||
using pcrecpp::Scanner;
|
||||
|
||||
static void TestScanner() {
|
||||
const char input[] = "\n"
|
||||
"alpha = 1; // this sets alpha\n"
|
||||
"bravo = 2; // bravo is set here\n"
|
||||
"gamma = 33; /* and here is gamma */\n";
|
||||
|
||||
const char *re = "(\\w+) = (\\d+);";
|
||||
|
||||
Scanner s(input);
|
||||
string var;
|
||||
int number;
|
||||
s.SkipCXXComments();
|
||||
s.set_save_comments(true);
|
||||
vector<StringPiece> comments;
|
||||
|
||||
s.Consume(re, &var, &number);
|
||||
CHECK_EQ(var, "alpha");
|
||||
CHECK_EQ(number, 1);
|
||||
s.GetNextComments(&comments);
|
||||
CHECK_EQ(comments.size(), 1);
|
||||
CHECK_EQ(comments[0].as_string(), " // this sets alpha\n");
|
||||
comments.resize(0);
|
||||
|
||||
s.Consume(re, &var, &number);
|
||||
CHECK_EQ(var, "bravo");
|
||||
CHECK_EQ(number, 2);
|
||||
s.GetNextComments(&comments);
|
||||
CHECK_EQ(comments.size(), 1);
|
||||
CHECK_EQ(comments[0].as_string(), " // bravo is set here\n");
|
||||
comments.resize(0);
|
||||
|
||||
s.Consume(re, &var, &number);
|
||||
CHECK_EQ(var, "gamma");
|
||||
CHECK_EQ(number, 33);
|
||||
s.GetNextComments(&comments);
|
||||
CHECK_EQ(comments.size(), 1);
|
||||
CHECK_EQ(comments[0].as_string(), " /* and here is gamma */\n");
|
||||
comments.resize(0);
|
||||
|
||||
s.GetComments(0, sizeof(input), &comments);
|
||||
CHECK_EQ(comments.size(), 3);
|
||||
CHECK_EQ(comments[0].as_string(), " // this sets alpha\n");
|
||||
CHECK_EQ(comments[1].as_string(), " // bravo is set here\n");
|
||||
CHECK_EQ(comments[2].as_string(), " /* and here is gamma */\n");
|
||||
comments.resize(0);
|
||||
|
||||
s.GetComments(0, strchr(input, '/') - input, &comments);
|
||||
CHECK_EQ(comments.size(), 0);
|
||||
comments.resize(0);
|
||||
|
||||
s.GetComments(strchr(input, '/') - input - 1, sizeof(input),
|
||||
&comments);
|
||||
CHECK_EQ(comments.size(), 3);
|
||||
CHECK_EQ(comments[0].as_string(), " // this sets alpha\n");
|
||||
CHECK_EQ(comments[1].as_string(), " // bravo is set here\n");
|
||||
CHECK_EQ(comments[2].as_string(), " /* and here is gamma */\n");
|
||||
comments.resize(0);
|
||||
|
||||
s.GetComments(strchr(input, '/') - input - 1,
|
||||
strchr(input + 1, '\n') - input + 1, &comments);
|
||||
CHECK_EQ(comments.size(), 1);
|
||||
CHECK_EQ(comments[0].as_string(), " // this sets alpha\n");
|
||||
comments.resize(0);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
TestScanner();
|
||||
|
||||
// Done
|
||||
printf("OK\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wilsonh@google.com (Wilson Hsieh)
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
#include "config.h"
|
||||
#include "pcre_stringpiece.h"
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const pcrecpp::StringPiece& piece) {
|
||||
return (o << piece.as_string());
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
// Copyright (c) 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: Sanjay Ghemawat
|
||||
//
|
||||
// A string like object that points into another piece of memory.
|
||||
// Useful for providing an interface that allows clients to easily
|
||||
// pass in either a "const char*" or a "string".
|
||||
//
|
||||
// Arghh! I wish C++ literals were automatically of type "string".
|
||||
|
||||
#ifndef _PCRE_STRINGPIECE_H
|
||||
#define _PCRE_STRINGPIECE_H
|
||||
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <iosfwd> // for ostream forward-declaration
|
||||
|
||||
#if 1
|
||||
#define HAVE_TYPE_TRAITS
|
||||
#include <type_traits.h>
|
||||
#elif 0
|
||||
#define HAVE_TYPE_TRAITS
|
||||
#include <bits/type_traits.h>
|
||||
#endif
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace pcrecpp {
|
||||
|
||||
class StringPiece {
|
||||
private:
|
||||
const char* ptr_;
|
||||
int length_;
|
||||
|
||||
public:
|
||||
// We provide non-explicit singleton constructors so users can pass
|
||||
// in a "const char*" or a "string" wherever a "StringPiece" is
|
||||
// expected.
|
||||
StringPiece()
|
||||
: ptr_(NULL), length_(0) { }
|
||||
StringPiece(const char* str)
|
||||
: ptr_(str), length_(static_cast<int>(strlen(str))) { }
|
||||
StringPiece(const string& str)
|
||||
: ptr_(str.data()), length_(static_cast<int>(str.size())) { }
|
||||
StringPiece(const char* offset, int len)
|
||||
: ptr_(offset), length_(len) { }
|
||||
|
||||
// data() may return a pointer to a buffer with embedded NULs, and the
|
||||
// returned buffer may or may not be null terminated. Therefore it is
|
||||
// typically a mistake to pass data() to a routine that expects a NUL
|
||||
// terminated string. Use "as_string().c_str()" if you really need to do
|
||||
// this. Or better yet, change your routine so it does not rely on NUL
|
||||
// termination.
|
||||
const char* data() const { return ptr_; }
|
||||
int size() const { return length_; }
|
||||
bool empty() const { return length_ == 0; }
|
||||
|
||||
void clear() { ptr_ = NULL; length_ = 0; }
|
||||
void set(const char* buffer, int len) { ptr_ = buffer; length_ = len; }
|
||||
void set(const char* str) {
|
||||
ptr_ = str;
|
||||
length_ = static_cast<int>(strlen(str));
|
||||
}
|
||||
void set(const void* buffer, int len) {
|
||||
ptr_ = reinterpret_cast<const char*>(buffer);
|
||||
length_ = len;
|
||||
}
|
||||
|
||||
char operator[](int i) const { return ptr_[i]; }
|
||||
|
||||
void remove_prefix(int n) {
|
||||
ptr_ += n;
|
||||
length_ -= n;
|
||||
}
|
||||
|
||||
void remove_suffix(int n) {
|
||||
length_ -= n;
|
||||
}
|
||||
|
||||
bool operator==(const StringPiece& x) const {
|
||||
return ((length_ == x.length_) &&
|
||||
(memcmp(ptr_, x.ptr_, length_) == 0));
|
||||
}
|
||||
bool operator!=(const StringPiece& x) const {
|
||||
return !(*this == x);
|
||||
}
|
||||
|
||||
#define STRINGPIECE_BINARY_PREDICATE(cmp,auxcmp) \
|
||||
bool operator cmp (const StringPiece& x) const { \
|
||||
int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_); \
|
||||
return ((r auxcmp 0) || ((r == 0) && (length_ cmp x.length_))); \
|
||||
}
|
||||
STRINGPIECE_BINARY_PREDICATE(<, <);
|
||||
STRINGPIECE_BINARY_PREDICATE(<=, <);
|
||||
STRINGPIECE_BINARY_PREDICATE(>=, >);
|
||||
STRINGPIECE_BINARY_PREDICATE(>, >);
|
||||
#undef STRINGPIECE_BINARY_PREDICATE
|
||||
|
||||
int compare(const StringPiece& x) const {
|
||||
int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_);
|
||||
if (r == 0) {
|
||||
if (length_ < x.length_) r = -1;
|
||||
else if (length_ > x.length_) r = +1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
string as_string() const {
|
||||
return string(data(), size());
|
||||
}
|
||||
|
||||
void CopyToString(string* target) const {
|
||||
target->assign(ptr_, length_);
|
||||
}
|
||||
|
||||
// Does "this" start with "x"
|
||||
bool starts_with(const StringPiece& x) const {
|
||||
return ((length_ >= x.length_) && (memcmp(ptr_, x.ptr_, x.length_) == 0));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace pcrecpp
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Functions used to create STL containers that use StringPiece
|
||||
// Remember that a StringPiece's lifetime had better be less than
|
||||
// that of the underlying string or char*. If it is not, then you
|
||||
// cannot safely store a StringPiece into an STL container
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
#ifdef HAVE_TYPE_TRAITS
|
||||
// This makes vector<StringPiece> really fast for some STL implementations
|
||||
template<> struct __type_traits<pcrecpp::StringPiece> {
|
||||
typedef __true_type has_trivial_default_constructor;
|
||||
typedef __true_type has_trivial_copy_constructor;
|
||||
typedef __true_type has_trivial_assignment_operator;
|
||||
typedef __true_type has_trivial_destructor;
|
||||
typedef __true_type is_POD_type;
|
||||
};
|
||||
#endif
|
||||
|
||||
// allow StringPiece to be logged
|
||||
std::ostream& operator<<(std::ostream& o, const pcrecpp::StringPiece& piece);
|
||||
|
||||
#endif /* _PCRE_STRINGPIECE_H */
|
||||
@@ -0,0 +1,145 @@
|
||||
// Copyright 2003 and onwards Google Inc.
|
||||
// Author: Sanjay Ghemawat
|
||||
|
||||
#include <stdio.h>
|
||||
#include <map>
|
||||
#include <algorithm> // for make_pair
|
||||
#include <pcre_stringpiece.h>
|
||||
|
||||
// CHECK dies with a fatal error if condition is not true. It is *not*
|
||||
// controlled by NDEBUG, so the check will be executed regardless of
|
||||
// compilation mode. Therefore, it is safe to do things like:
|
||||
// CHECK(fp->Write(x) == 4)
|
||||
#define CHECK(condition) do { \
|
||||
if (!(condition)) { \
|
||||
fprintf(stderr, "%s:%d: Check failed: %s\n", \
|
||||
__FILE__, __LINE__, #condition); \
|
||||
exit(1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
using std::map;
|
||||
using std::make_pair;
|
||||
using pcrecpp::StringPiece;
|
||||
|
||||
static void CheckSTLComparator() {
|
||||
string s1("foo");
|
||||
string s2("bar");
|
||||
string s3("baz");
|
||||
|
||||
StringPiece p1(s1);
|
||||
StringPiece p2(s2);
|
||||
StringPiece p3(s3);
|
||||
|
||||
typedef map<StringPiece, int> TestMap;
|
||||
TestMap map;
|
||||
|
||||
map.insert(make_pair(p1, 0));
|
||||
map.insert(make_pair(p2, 1));
|
||||
map.insert(make_pair(p3, 2));
|
||||
CHECK(map.size() == 3);
|
||||
|
||||
TestMap::const_iterator iter = map.begin();
|
||||
CHECK(iter->second == 1);
|
||||
++iter;
|
||||
CHECK(iter->second == 2);
|
||||
++iter;
|
||||
CHECK(iter->second == 0);
|
||||
++iter;
|
||||
CHECK(iter == map.end());
|
||||
|
||||
TestMap::iterator new_iter = map.find("zot");
|
||||
CHECK(new_iter == map.end());
|
||||
|
||||
new_iter = map.find("bar");
|
||||
CHECK(new_iter != map.end());
|
||||
|
||||
map.erase(new_iter);
|
||||
CHECK(map.size() == 2);
|
||||
|
||||
iter = map.begin();
|
||||
CHECK(iter->second == 2);
|
||||
++iter;
|
||||
CHECK(iter->second == 0);
|
||||
++iter;
|
||||
CHECK(iter == map.end());
|
||||
}
|
||||
|
||||
static void CheckComparisonOperators() {
|
||||
#define CMP_Y(op, x, y) \
|
||||
CHECK( (StringPiece((x)) op StringPiece((y)))); \
|
||||
CHECK( (StringPiece((x)).compare(StringPiece((y))) op 0))
|
||||
|
||||
#define CMP_N(op, x, y) \
|
||||
CHECK(!(StringPiece((x)) op StringPiece((y)))); \
|
||||
CHECK(!(StringPiece((x)).compare(StringPiece((y))) op 0))
|
||||
|
||||
CMP_Y(==, "", "");
|
||||
CMP_Y(==, "a", "a");
|
||||
CMP_Y(==, "aa", "aa");
|
||||
CMP_N(==, "a", "");
|
||||
CMP_N(==, "", "a");
|
||||
CMP_N(==, "a", "b");
|
||||
CMP_N(==, "a", "aa");
|
||||
CMP_N(==, "aa", "a");
|
||||
|
||||
CMP_N(!=, "", "");
|
||||
CMP_N(!=, "a", "a");
|
||||
CMP_N(!=, "aa", "aa");
|
||||
CMP_Y(!=, "a", "");
|
||||
CMP_Y(!=, "", "a");
|
||||
CMP_Y(!=, "a", "b");
|
||||
CMP_Y(!=, "a", "aa");
|
||||
CMP_Y(!=, "aa", "a");
|
||||
|
||||
CMP_Y(<, "a", "b");
|
||||
CMP_Y(<, "a", "aa");
|
||||
CMP_Y(<, "aa", "b");
|
||||
CMP_Y(<, "aa", "bb");
|
||||
CMP_N(<, "a", "a");
|
||||
CMP_N(<, "b", "a");
|
||||
CMP_N(<, "aa", "a");
|
||||
CMP_N(<, "b", "aa");
|
||||
CMP_N(<, "bb", "aa");
|
||||
|
||||
CMP_Y(<=, "a", "a");
|
||||
CMP_Y(<=, "a", "b");
|
||||
CMP_Y(<=, "a", "aa");
|
||||
CMP_Y(<=, "aa", "b");
|
||||
CMP_Y(<=, "aa", "bb");
|
||||
CMP_N(<=, "b", "a");
|
||||
CMP_N(<=, "aa", "a");
|
||||
CMP_N(<=, "b", "aa");
|
||||
CMP_N(<=, "bb", "aa");
|
||||
|
||||
CMP_N(>=, "a", "b");
|
||||
CMP_N(>=, "a", "aa");
|
||||
CMP_N(>=, "aa", "b");
|
||||
CMP_N(>=, "aa", "bb");
|
||||
CMP_Y(>=, "a", "a");
|
||||
CMP_Y(>=, "b", "a");
|
||||
CMP_Y(>=, "aa", "a");
|
||||
CMP_Y(>=, "b", "aa");
|
||||
CMP_Y(>=, "bb", "aa");
|
||||
|
||||
CMP_N(>, "a", "a");
|
||||
CMP_N(>, "a", "b");
|
||||
CMP_N(>, "a", "aa");
|
||||
CMP_N(>, "aa", "b");
|
||||
CMP_N(>, "aa", "bb");
|
||||
CMP_Y(>, "b", "a");
|
||||
CMP_Y(>, "aa", "a");
|
||||
CMP_Y(>, "b", "aa");
|
||||
CMP_Y(>, "bb", "aa");
|
||||
|
||||
#undef CMP_Y
|
||||
#undef CMP_N
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
CheckComparisonOperators();
|
||||
CheckSTLComparator();
|
||||
|
||||
printf("OK\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -2,42 +2,47 @@
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/*
|
||||
This is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language. See
|
||||
the file Tech.Notes for some information on the internals.
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by: Philip Hazel <ph10@cam.ac.uk>
|
||||
|
||||
Copyright (c) 1997-2003 University of Cambridge
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2005 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Permission is granted to anyone to use this software for any purpose on any
|
||||
computer system, and to redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. This software 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.
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. The origin of this software must not be misrepresented, either by
|
||||
explicit claim or by omission.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Altered versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
4. If PCRE is embedded in any software that is released under the GNU
|
||||
General Purpose Licence (GPL), then the terms of that licence shall
|
||||
supersede any condition above with which it is incompatible.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* Include the internals header, which itself includes Standard C headers plus
|
||||
the external pcre header. */
|
||||
/* This module contains the external function pcre_study(), along with local
|
||||
supporting functions. */
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
/*************************************************
|
||||
@@ -57,7 +62,7 @@ Returns: nothing
|
||||
*/
|
||||
|
||||
static void
|
||||
set_bit(uschar *start_bits, int c, BOOL caseless, compile_data *cd)
|
||||
set_bit(uschar *start_bits, unsigned int c, BOOL caseless, compile_data *cd)
|
||||
{
|
||||
start_bits[c/8] |= (1 << (c&7));
|
||||
if (caseless && (cd->ctypes[c] & ctype_letter) != 0)
|
||||
@@ -123,7 +128,7 @@ do
|
||||
/* Skip over callout */
|
||||
|
||||
case OP_CALLOUT:
|
||||
tcode += 2;
|
||||
tcode += 2 + 2*LINK_SIZE;
|
||||
break;
|
||||
|
||||
/* Skip over extended extraction bracket number */
|
||||
@@ -186,11 +191,10 @@ do
|
||||
/* At least one single char sets the bit and stops */
|
||||
|
||||
case OP_EXACT: /* Fall through */
|
||||
tcode++;
|
||||
|
||||
case OP_CHARS: /* Fall through */
|
||||
tcode++;
|
||||
tcode += 2;
|
||||
|
||||
case OP_CHAR:
|
||||
case OP_CHARNC:
|
||||
case OP_PLUS:
|
||||
case OP_MINPLUS:
|
||||
set_bit(start_bits, tcode[1], caseless, cd);
|
||||
@@ -403,8 +407,9 @@ pcre_study(const pcre *external_re, int options, const char **errorptr)
|
||||
uschar start_bits[32];
|
||||
pcre_extra *extra;
|
||||
pcre_study_data *study;
|
||||
const uschar *tables;
|
||||
const real_pcre *re = (const real_pcre *)external_re;
|
||||
uschar *code = (uschar *)re + sizeof(real_pcre) +
|
||||
uschar *code = (uschar *)re + re->name_table_offset +
|
||||
(re->name_count * re->name_entry_size);
|
||||
compile_data compile_block;
|
||||
|
||||
@@ -429,12 +434,17 @@ at present. */
|
||||
if ((re->options & (PCRE_ANCHORED|PCRE_FIRSTSET|PCRE_STARTLINE)) != 0)
|
||||
return NULL;
|
||||
|
||||
/* Set the character tables in the block which is passed around */
|
||||
/* Set the character tables in the block that is passed around */
|
||||
|
||||
compile_block.lcc = re->tables + lcc_offset;
|
||||
compile_block.fcc = re->tables + fcc_offset;
|
||||
compile_block.cbits = re->tables + cbits_offset;
|
||||
compile_block.ctypes = re->tables + ctypes_offset;
|
||||
tables = re->tables;
|
||||
if (tables == NULL)
|
||||
(void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
|
||||
(void *)(&tables));
|
||||
|
||||
compile_block.lcc = tables + lcc_offset;
|
||||
compile_block.fcc = tables + fcc_offset;
|
||||
compile_block.cbits = tables + cbits_offset;
|
||||
compile_block.ctypes = tables + ctypes_offset;
|
||||
|
||||
/* See if we can find a fixed set of initial characters for the pattern. */
|
||||
|
||||
@@ -469,4 +479,4 @@ memcpy(study->start_bits, start_bits, sizeof(start_bits));
|
||||
return extra;
|
||||
}
|
||||
|
||||
/* End of study.c */
|
||||
/* End of pcre_study.c */
|
||||
Loaded 100 of 301 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user