diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/gd/config.h.stub | 3 | ||||
-rw-r--r-- | ext/gd/config.m4 | 54 | ||||
-rw-r--r-- | ext/gd/gd.c | 91 | ||||
-rw-r--r-- | ext/gd/gdcache.c | 6 | ||||
-rw-r--r-- | ext/gd/gdttf.c | 20 | ||||
-rw-r--r-- | ext/gd/php3_gd.h | 7 | ||||
-rw-r--r-- | ext/informix/ifx.ec | 39 | ||||
-rw-r--r-- | ext/standard/Makefile.am | 3 | ||||
-rw-r--r-- | ext/standard/basic_functions.c | 3 | ||||
-rw-r--r-- | ext/standard/datetime.c | 31 | ||||
-rw-r--r-- | ext/standard/datetime.h | 1 | ||||
-rw-r--r-- | ext/standard/fsock.c | 2 | ||||
-rw-r--r-- | ext/standard/parsedate.y | 919 | ||||
-rw-r--r-- | ext/standard/php3_string.h | 1 | ||||
-rw-r--r-- | ext/standard/rand.c | 50 | ||||
-rw-r--r-- | ext/wddx/wddx.c | 2 | ||||
-rw-r--r-- | ext/xml/Makefile.am | 2 | ||||
-rw-r--r-- | ext/xml/config.m4 | 17 |
18 files changed, 1175 insertions, 76 deletions
diff --git a/ext/gd/config.h.stub b/ext/gd/config.h.stub index 4e619595f7..db06b056cd 100644 --- a/ext/gd/config.h.stub +++ b/ext/gd/config.h.stub @@ -4,3 +4,6 @@ /* Define if you have the gd version 1.3 library (-lgd). */ #define HAVE_LIBGD13 0 +#undef FREETYPE_4BIT_ANTIALIAS_HACK +#undef HAVE_LIBFREETYPE +#undef HAVE_LIBTTF diff --git a/ext/gd/config.m4 b/ext/gd/config.m4 index 6378535f0a..452c151fd3 100644 --- a/ext/gd/config.m4 +++ b/ext/gd/config.m4 @@ -44,10 +44,62 @@ dnl A whole whack of possible places where this might be AC_CHECK_LIB(gd, gdImageString16, [ AC_DEFINE(HAVE_LIBGD13) ]) ]) if test "$ac_cv_lib_gd_gdImageLine" = "yes"; then + CHECK_TTF="yes" + AC_ARG_WITH(ttf, + [ --with-ttf[=DIR] Include Freetype support],[ + if test $withval = "no" ; then + CHECK_TTF="" + else + CHECK_TTF="$withval" + fi + ]) + + AC_MSG_CHECKING(whether to include ttf support) + if test -n "$CHECK_TTF" ; then + for i in /usr /usr/local "$CHECK_TTF" ; do + if test -f "$i/include/truetype.h" ; then + FREETYPE_DIR="$i" + fi + if test -f "$i/include/freetype.h" ; then + TTF_DIR="$i" + fi + done + if test -n "$FREETYPE_DIR" ; then + AC_DEFINE(HAVE_LIBFREETYPE) + AC_ADD_LIBRARY_WITH_PATH(freetype, $FREETYPE_DIR/lib) + AC_ADD_INCLUDE($FREETYPE_DIR/include) + AC_MSG_RESULT(yes) + else + if test -n "$TTF_DIR" ; then + AC_DEFINE(HAVE_LIBTTF) + AC_ADD_LIBRARY_WITH_PATH(ttf, $TTF_DIR/lib) + AC_ADD_INCLUDE($TTF_DIR/include) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + fi + else + AC_MSG_RESULT(no) + fi + if test -f /usr/pkg/include/gd/gd.h -a -z "$GD_INCLUDE" ; then GD_INCLUDE="-I/usr/pkg/include/gd" fi - AC_CHECK_LIB(ttf, TT_Open_Face) + + AC_MSG_CHECKING(whether to enable 4bit antialias hack with FreeType2) + AC_ARG_ENABLE(freetype-4bit-antialias-hack, + [ --enable-freetype-4bit-antialias-hack For the crazy with FreeType2.],[ + if test "$enableval" = "yes" ; then + AC_DEFINE(FREETYPE_4BIT_ANTIALIAS_HACK, 1) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + ],[ + AC_MSG_RESULT(no) + ]) + PHP_EXTENSION(gd) EXTRA_LIBS="$EXTRA_LIBS $GD_LIBS" INCLUDES="$INCLUDES $GD_INCLUDE" diff --git a/ext/gd/gd.c b/ext/gd/gd.c index 511e349586..bd82f1ce70 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -49,7 +49,7 @@ #include <gdfontmb.h> /* 3 Medium bold font */ #include <gdfontl.h> /* 4 Large font */ #include <gdfontg.h> /* 5 Giant font */ -#if HAVE_LIBTTF +#ifdef ENABLE_GD_TTF # include "gdttf.h" #endif @@ -57,7 +57,7 @@ #define M_PI 3.14159265358979323846 #endif -#if HAVE_LIBTTF +#ifdef ENABLE_GD_TTF static void php3_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int); #endif @@ -118,7 +118,7 @@ function_entry gd_functions[] = { {"imagesx", php3_imagesxfn, NULL}, {"imagesy", php3_imagesyfn, NULL}, {"imagedashedline", php3_imagedashedline, NULL}, -#if HAVE_LIBTTF +#ifdef ENABLE_GD_TTF {"imagettfbbox", php3_imagettfbbox, NULL}, {"imagettftext", php3_imagettftext, NULL}, #endif @@ -175,7 +175,7 @@ void php3_info_gd(ZEND_MODULE_INFO_FUNC_ARGS) #else php3_printf("Version 1.2"); #endif -#if HAVE_LIBTTF +#ifdef ENABLE_GD_TTF php3_printf(" with FreeType support"); #endif } @@ -340,7 +340,8 @@ PHP_FUNCTION(imageloadfont) { /* {{{ proto int imagecreate(int x_size, int y_size) Create a new image */ -PHP_FUNCTION(imagecreate) { +PHP_FUNCTION(imagecreate) +{ pval *x_size, *y_size; int ind; gdImagePtr im; @@ -362,7 +363,8 @@ PHP_FUNCTION(imagecreate) { /* {{{ proto int imagecreatefromgif(string filename) Create a new image from file or URL */ -PHP_FUNCTION(imagecreatefromgif ) { +PHP_FUNCTION(imagecreatefromgif ) +{ pval *file; int ind; gdImagePtr im; @@ -404,7 +406,8 @@ PHP_FUNCTION(imagecreatefromgif ) { /* {{{ proto int imagedestroy(int im) Destroy an image */ -PHP_FUNCTION(imagedestroy) { +PHP_FUNCTION(imagedestroy) +{ pval *imgind; if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &imgind) == FAILURE) { @@ -421,7 +424,8 @@ PHP_FUNCTION(imagedestroy) { /* {{{ proto int imagecolorallocate(int im, int red, int green, int blue) Allocate a color for an image */ -PHP_FUNCTION(imagecolorallocate) { +PHP_FUNCTION(imagecolorallocate) +{ pval *imgind, *red, *green, *blue; int ind, ind_type; int col; @@ -457,7 +461,8 @@ PHP_FUNCTION(imagecolorallocate) { /* im, x, y */ /* {{{ proto int imagecolorat(int im, int x, int y) Get the index of the color of a pixel */ -PHP_FUNCTION(imagecolorat) { +PHP_FUNCTION(imagecolorat) +{ pval *imgind, *x, *y; int ind, ind_type; gdImagePtr im; @@ -493,7 +498,8 @@ PHP_FUNCTION(imagecolorat) { /* {{{ proto int imagecolorclosest(int im, int red, int green, int blue) Get the index of the closest color to the specified color */ -PHP_FUNCTION(imagecolorclosest) { +PHP_FUNCTION(imagecolorclosest) +{ pval *imgind, *red, *green, *blue; int ind, ind_type; int col; @@ -528,7 +534,8 @@ PHP_FUNCTION(imagecolorclosest) { /* {{{ proto int imagecolordeallocate(int im, int index) De-allocate a color for an image */ -PHP_FUNCTION(imagecolordeallocate) { +PHP_FUNCTION(imagecolordeallocate) +{ pval *imgind, *index; int ind, ind_type, col; gdImagePtr im; @@ -562,7 +569,8 @@ PHP_FUNCTION(imagecolordeallocate) { /* {{{ proto int imagecolorresolve(int im, int red, int green, int blue) Get the index of the specified color or its closest possible alternative */ -PHP_FUNCTION(imagecolorresolve) { +PHP_FUNCTION(imagecolorresolve) +{ pval *imgind, *red, *green, *blue; int ind, ind_type; int col; @@ -597,7 +605,8 @@ PHP_FUNCTION(imagecolorresolve) { /* {{{ proto int imagecolorexact(int im, int red, int green, int blue) Get the index of the specified color */ -PHP_FUNCTION(imagecolorexact) { +PHP_FUNCTION(imagecolorexact) +{ pval *imgind, *red, *green, *blue; int ind, ind_type; int col; @@ -632,7 +641,8 @@ PHP_FUNCTION(imagecolorexact) { /* {{{ proto int imagecolorset(int im, int col, int red, int green, int blue) Set the color for the specified palette index */ -PHP_FUNCTION(imagecolorset) { +PHP_FUNCTION(imagecolorset) +{ pval *imgind, *color, *red, *green, *blue; int ind, ind_type; int col; @@ -674,7 +684,8 @@ PHP_FUNCTION(imagecolorset) { /* {{{ proto array imagecolorsforindex(int im, int col) Get the colors for an index */ -PHP_FUNCTION(imagecolorsforindex) { +PHP_FUNCTION(imagecolorsforindex) +{ pval *imgind, *index; int col, ind, ind_type; gdImagePtr im; @@ -712,7 +723,8 @@ PHP_FUNCTION(imagecolorsforindex) { /* {{{ proto int imagegif(int im, string filename) Output image to browser or file */ -PHP_FUNCTION(imagegif ) { +PHP_FUNCTION(imagegif ) +{ pval *imgind, *file; gdImagePtr im; char *fn=NULL; @@ -791,7 +803,8 @@ PHP_FUNCTION(imagegif ) { /* {{{ proto int imagesetpixel(int im, int x, int y, int col) Set a single pixel */ -PHP_FUNCTION(imagesetpixel) { +PHP_FUNCTION(imagesetpixel) +{ pval *imarg, *xarg, *yarg, *colarg; gdImagePtr im; int col, y, x; @@ -828,7 +841,8 @@ PHP_FUNCTION(imagesetpixel) { /* im, x1, y1, x2, y2, col */ /* {{{ proto int imageline(int im, int x1, int y1, int x2, int y2, int col) Draw a line */ -PHP_FUNCTION(imageline) { +PHP_FUNCTION(imageline) +{ pval *IM, *COL, *X1, *Y1, *X2, *Y2; gdImagePtr im; int col, y2, x2, y1, x1; @@ -867,7 +881,8 @@ PHP_FUNCTION(imageline) { /* {{{ proto int imagedashedline(int im, int x1, int y1, int x2, int y2, int col) Draw a dashed line */ -PHP_FUNCTION(imagedashedline) { +PHP_FUNCTION(imagedashedline) +{ pval *IM, *COL, *X1, *Y1, *X2, *Y2; gdImagePtr im; int col, y2, x2, y1, x1; @@ -906,7 +921,8 @@ PHP_FUNCTION(imagedashedline) { /* im, x1, y1, x2, y2, col */ /* {{{ proto int imagerectangle(int im, int x1, int y1, int x2, int y2, int col) Draw a rectangle */ -PHP_FUNCTION(imagerectangle) { +PHP_FUNCTION(imagerectangle) +{ pval *IM, *COL, *X1, *Y1, *X2, *Y2; gdImagePtr im; int col, y2, x2, y1, x1; @@ -946,7 +962,8 @@ PHP_FUNCTION(imagerectangle) { /* im, x1, y1, x2, y2, col */ /* {{{ proto int imagefilledrectangle(int im, int x1, int y1, int x2, int y2, int col) Draw a filled rectangle */ -PHP_FUNCTION(imagefilledrectangle) { +PHP_FUNCTION(imagefilledrectangle) +{ pval *IM, *COL, *X1, *Y1, *X2, *Y2; gdImagePtr im; int col, y2, x2, y1, x1; @@ -985,7 +1002,8 @@ PHP_FUNCTION(imagefilledrectangle) { /* {{{ proto int imagearc(int im, int cx, int cy, int w, int h, int s, int e, int col) Draw a partial ellipse */ -PHP_FUNCTION(imagearc) { +PHP_FUNCTION(imagearc) +{ pval *COL, *E, *ST, *H, *W, *CY, *CX, *IM; gdImagePtr im; int col, e, st, h, w, cy, cx; @@ -1036,7 +1054,8 @@ PHP_FUNCTION(imagearc) { /* im, x, y, border, col */ /* {{{ proto int imagefilltoborder(int im, int x, int y, int border, int col) Flood fill to specific color */ -PHP_FUNCTION(imagefilltoborder) { +PHP_FUNCTION(imagefilltoborder) +{ pval *IM, *X, *Y, *BORDER, *COL; gdImagePtr im; int col, border, y, x; @@ -1074,7 +1093,8 @@ PHP_FUNCTION(imagefilltoborder) { /* im, x, y, col */ /* {{{ proto int imagefill(int im, int x, int y, int col) Flood fill */ -PHP_FUNCTION(imagefill) { +PHP_FUNCTION(imagefill) +{ pval *IM, *X, *Y, *COL; gdImagePtr im; int col, y, x; @@ -1109,7 +1129,8 @@ PHP_FUNCTION(imagefill) { /* {{{ proto int imagecolorstotal(int im) Find out the number of colors in an image's palette */ -PHP_FUNCTION(imagecolorstotal) { +PHP_FUNCTION(imagecolorstotal) +{ pval *IM; gdImagePtr im; int ind_type; @@ -1133,7 +1154,8 @@ PHP_FUNCTION(imagecolorstotal) { /* im, col */ /* {{{ proto int imagecolortransparent(int im [, int col]) Define a color as transparent */ -PHP_FUNCTION(imagecolortransparent) { +PHP_FUNCTION(imagecolortransparent) +{ pval *IM, *COL = NULL; gdImagePtr im; int col; @@ -1175,7 +1197,8 @@ PHP_FUNCTION(imagecolortransparent) { /* im, interlace */ /* {{{ proto int imageinterlace(int im [, int interlace]) Enable or disable interlace */ -PHP_FUNCTION(imageinterlace) { +PHP_FUNCTION(imageinterlace) +{ pval *IM, *INT = NULL; gdImagePtr im; int interlace; @@ -1218,7 +1241,7 @@ PHP_FUNCTION(imageinterlace) { arg = 1 filled polygon */ /* im, points, num_points, col */ static void _php3_imagepolygon(INTERNAL_FUNCTION_PARAMETERS, int filled) { - pval *IM, *POINTS, *NPOINTS, *COL, *var; + pval *IM, *POINTS, *NPOINTS, *COL, **var; gdImagePtr im; gdPoint points[PolyMaxPoints]; int npoints, col, nelem, i; @@ -1279,12 +1302,14 @@ static void _php3_imagepolygon(INTERNAL_FUNCTION_PARAMETERS, int filled) { for (i = 0; i < npoints; i++) { if (_php3_hash_index_find(POINTS->value.ht, (i * 2), (void **)&var) == SUCCESS) { - convert_to_long(var); - points[i].x = var->value.lval; + SEPARATE_ZVAL(var); + convert_to_long(*var); + points[i].x = (*var)->value.lval; } if (_php3_hash_index_find(POINTS->value.ht, (i * 2) + 1, (void **)&var) == SUCCESS) { - convert_to_long(var); - points[i].y = var->value.lval; + SEPARATE_ZVAL(var); + convert_to_long(*var); + points[i].y = (*var)->value.lval; } } @@ -1671,7 +1696,7 @@ PHP_FUNCTION(imagesyfn) } /* }}} */ -#if HAVE_LIBTTF +#ifdef ENABLE_GD_TTF #define TTFTEXT_DRAW 0 #define TTFTEXT_BBOX 1 diff --git a/ext/gd/gdcache.c b/ext/gd/gdcache.c index 1662ebb184..e9c628607b 100644 --- a/ext/gd/gdcache.c +++ b/ext/gd/gdcache.c @@ -38,11 +38,11 @@ /* This just seems unessacary */ #if (WIN32|WINNT) -#define HAVE_LIBTTF 1 +#define ENABLE_GD_TTF #else #include "php_config.h" #endif -#if HAVE_LIBTTF +#ifdef ENABLE_GD_TTF #include "gdcache.h" @@ -198,4 +198,4 @@ main(char *argv[], int argc) #endif -#endif /* HAVE_LIBTTF */ +#endif /* ENABLE_GD_TTF */ diff --git a/ext/gd/gdttf.c b/ext/gd/gdttf.c index 93bb3528d1..f2c1a03a9a 100644 --- a/ext/gd/gdttf.c +++ b/ext/gd/gdttf.c @@ -9,7 +9,7 @@ #else #include "php_config.h" #endif -#if HAVE_LIBTTF +#if HAVE_LIBTTF|HAVE_LIBFREETYPE #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -17,7 +17,11 @@ #include <gd.h> #include "gdttf.h" #include "gdcache.h" +#if HAVE_LIBFREETYPE +#include <truetype.h> +#else #include <freetype.h> +#endif /* number of fonts cached before least recently used is replaced */ #define FONTCACHESIZE 6 @@ -31,7 +35,11 @@ #define BITMAPCACHESIZE 8 /* number of antialias color lookups cached */ +#if FREETYPE_4BIT_ANTIALIAS_HACK +#define TWEENCOLORCACHESIZE 128 +#else #define TWEENCOLORCACHESIZE 32 +#endif /* ptsize below which anti-aliasing is ineffective */ #define MINANTIALIASPTSIZE 0 @@ -40,7 +48,11 @@ #define RESOLUTION 72 /* Number of colors used for anti-aliasing */ +#if FREETYPE_4BIT_ANTIALIAS_HACK +#define NUMCOLORS 16 +#else #define NUMCOLORS 4 +#endif /* Line separation as a factor of font height. No space between if LINESPACE = 1.00 @@ -379,7 +391,11 @@ fontFetch ( char **error, void *key ) a->cos_a = cos(a->angle); a->engine = b->engine; if ((err = TT_Open_Face(*b->engine, a->fontname, &a->face))) { +#if HAVE_LIBFREETYPE + if (err == 0x008) { /* The FT2 oldapi is missing this code */ +#else if (err == TT_Err_Could_Not_Open_File) { +#endif *error = "Could not find/open font"; } else { @@ -852,7 +868,7 @@ gdttf(gdImage *im, int *brect, int fg, char *fontname, return (char *)NULL; } -#endif /* HAVE_LIBTTF */ +#endif /* HAVE_LIBTTF|HAVE_LIBFREETYPE */ /* * Local variables: diff --git a/ext/gd/php3_gd.h b/ext/gd/php3_gd.h index d3f4dfced3..d6ef1d53b1 100644 --- a/ext/gd/php3_gd.h +++ b/ext/gd/php3_gd.h @@ -34,6 +34,11 @@ #ifndef _PHP3_GD_H #define _PHP3_GD_H + +#if defined(HAVE_LIBTTF) && defined(HAVE_FREETYPE_H) +#define ENABLE_GD_TTF +#endif + #if COMPILE_DL #undef HAVE_LIBGD #define HAVE_LIBGD 1 @@ -89,7 +94,7 @@ PHP_FUNCTION(imagesyfn); void php3_free_gd_font(gdFontPtr); void _php3_gdimagecharup(gdImagePtr, gdFontPtr, int, int, int, int); PHP_FUNCTION(imagedashedline); -#ifdef HAVE_LIBTTF +#ifdef ENABLE_GD_TTF PHP_FUNCTION(imagettfbbox); PHP_FUNCTION(imagettftext); #endif diff --git a/ext/informix/ifx.ec b/ext/informix/ifx.ec index df60a38921..f97c4d4a28 100644 --- a/ext/informix/ifx.ec +++ b/ext/informix/ifx.ec @@ -1159,7 +1159,7 @@ $ifdef HAVE_IFX_IUS; $endif; ) { - int bid; + int bid = 0; if(fieldtype==SQLTEXT) { bid=php3_intifx_create_blob(TYPE_BLTEXT,BLMODE_INMEM,"",-1,list); locator=php3_intifx_get_blobloc(bid,list); @@ -1243,9 +1243,6 @@ EXEC SQL BEGIN DECLARE SECTION; long sqlerrd[6]; int e; -$ifdef HAVE_IFX_IUS; - fixed binary 'blob' ifx_lo_t *slocator; -$endif; EXEC SQL END DECLARE SECTION; @@ -1643,7 +1640,7 @@ $ifdef HAVE_IFX_IUS; $endif; ) { - int bid; + int bid = 0; if(fieldtype==SQLTEXT) { bid=php3_intifx_create_blob(TYPE_BLTEXT,BLMODE_INMEM,"",-1,list); locator=php3_intifx_get_blobloc(bid,list); @@ -3143,7 +3140,7 @@ EXEC SQL END DECLARE SECTION; int type; - int i, locind; + int i; IFXLS_FETCH(); @@ -3777,7 +3774,7 @@ static char* php3_intifx_create_tmpfile(long bid) { if ((blobdir = getenv("php3_blobdir")) == NULL) blobdir="."; - sprintf(filename,"blb%d",bid); + sprintf(filename,"blb%d",(int)bid); blobfile=tempnam(blobdir,filename); free(blobdir); retval=emalloc(strlen(blobfile)+1); @@ -4257,17 +4254,17 @@ PHP_FUNCTION(ifxus_create_slob) { mode=pmode->value.lval; create_mode=0; - if(mode&1!=0) + if((mode&1) !=0) create_mode|=LO_RDONLY; - if(mode&2!=0) + if((mode&2) !=0) create_mode|=LO_WRONLY; - if(mode&4!=0) + if((mode&4) !=0) create_mode|=LO_APPEND; - if(mode&8!=0) + if((mode&8) !=0) create_mode|=LO_RDWR; - if(mode&16!=0) + if((mode&16) !=0) create_mode|=LO_BUFFER; - if(mode&32!=0) + if((mode&32) !=0) create_mode|=LO_NOBUFFER; @@ -4467,7 +4464,6 @@ static long php3_intifxus_close_slob(long bid, HashTable *list) { opens an slob-object */ PHP_FUNCTION(ifxus_open_slob) { pval *pbid,*pmode; - long id; long mode,create_mode; if (ARG_COUNT(ht)!=2 || getParameters(ht, 1, &pbid,&pmode)==FAILURE) { @@ -4478,17 +4474,17 @@ PHP_FUNCTION(ifxus_open_slob) { mode=pmode->value.lval; create_mode=0; - if(mode&1!=0) + if((mode&1) !=0) create_mode|=LO_RDONLY; - if(mode&2!=0) + if((mode&2) !=0) create_mode|=LO_WRONLY; - if(mode&4!=0) + if((mode&4) !=0) create_mode|=LO_APPEND; - if(mode&8!=0) + if((mode&8) !=0) create_mode|=LO_RDWR; - if(mode&16!=0) + if((mode&16) !=0) create_mode|=LO_BUFFER; - if(mode&32!=0) + if((mode&32) !=0) create_mode|=LO_NOBUFFER; RETURN_LONG(php3_intifxus_open_slob(pbid->value.lval,create_mode,list)); @@ -4550,7 +4546,6 @@ static long php3_intifxus_open_slob(long bid, long create_mode, HashTable *list) */ static long php3_intifxus_new_slob(HashTable *list) { IFX_IDRES *Ifx_slob; - int errcode; Ifx_slob=emalloc(sizeof(IFX_IDRES)); @@ -4578,7 +4573,7 @@ static long php3_intifxus_new_slob(HashTable *list) { */ static ifx_lo_t *php3_intifxus_get_slobloc(long bid, HashTable *list) { IFX_IDRES *Ifx_slob; - int errcode, type; + int type; Ifx_slob = (IFX_IDRES *) php3_list_find(bid,&type); if (type!=IFXG(le_idresult) || Ifx_slob->type!=TYPE_SLOB) { diff --git a/ext/standard/Makefile.am b/ext/standard/Makefile.am index ae0d698617..0f4f063c8a 100644 --- a/ext/standard/Makefile.am +++ b/ext/standard/Makefile.am @@ -7,7 +7,8 @@ libphpext_standard_a_SOURCES=\ html.c image.c info.c link.c mail.c math.c md5.c microtime.c \ pack.c pageinfo.c rand.c reg.c soundex.c string.c \ syslog.c type.c uniqid.c url.c iptc.c var.c quot_print.c \ - cyr_convert.c flock_compat.c crypt.c dl.c head.c post.c + cyr_convert.c flock_compat.c crypt.c dl.c head.c post.c \ + parsedate.y #number.o: number.c # $(CC) $(CFLAGS) -w@WARNING_LEVEL@ -c $< -o $@ diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 3f445804a0..bd9854179b 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -84,6 +84,7 @@ function_entry basic_functions[] = { #if HAVE_STRFTIME {"strftime", php3_strftime, NULL}, #endif + PHP_FE(strtotime, NULL) {"date", php3_date, NULL}, {"gmdate", php3_gmdate, NULL}, {"getdate", php3_getdate, NULL}, @@ -110,6 +111,8 @@ function_entry basic_functions[] = { {"trim", php3_trim, NULL}, {"ltrim", php3_ltrim, NULL}, {"rtrim", php3_chop, NULL}, + PHP_FE(strip_tags, NULL) + PHP_FE(similar_text, NULL) {"pos", array_current, first_arg_force_ref}, {"getimagesize", php3_getimagesize, NULL}, diff --git a/ext/standard/datetime.c b/ext/standard/datetime.c index 99038e0bd5..11cd604e9b 100644 --- a/ext/standard/datetime.c +++ b/ext/standard/datetime.c @@ -29,6 +29,9 @@ #include "php_globals.h" #include <time.h> +#ifdef HAVE_SYS_TIME_H +# include <sys/time.h> +#endif #include <stdio.h> char *mon_full_names[] = @@ -62,6 +65,8 @@ static int phpday_tab[2][12] = #define isleap(year) (((year%4) == 0 && (year%100)!=0) || (year%400)==0) +extern PHPAPI time_t parsedate(char *p, struct timeval *now); + PHP_FUNCTION(time) { return_value->value.lval = (long) time(NULL); @@ -550,6 +555,32 @@ PHP_FUNCTION(strftime) RETURN_FALSE; } #endif + +/* {{{ proto int strtotime(string time, int now) */ +PHP_FUNCTION(strtotime) +{ + pval *timep, *nowp; + int ac; + struct timeval tv; + + ac = ARG_COUNT(ht); + + if (ac < 1 || ac > 2 || getParameters(ht, ac, &timep, &nowp)==FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_string(timep); + if (ac == 2) { + convert_to_long(nowp); + tv.tv_sec = nowp->value.lval; + tv.tv_usec = 0; + RETURN_LONG(parsedate(timep->value.str.val, &tv)); + } else { + RETURN_LONG(parsedate(timep->value.str.val, NULL)); + } +} +/* }}} */ + /* * Local variables: * tab-width: 4 diff --git a/ext/standard/datetime.h b/ext/standard/datetime.h index 0a27f5efa2..bf518fcd7f 100644 --- a/ext/standard/datetime.h +++ b/ext/standard/datetime.h @@ -44,6 +44,7 @@ PHP_FUNCTION(checkdate); #if HAVE_STRFTIME PHP_FUNCTION(strftime); #endif +PHP_FUNCTION(strtotime); extern char *php3_std_date(time_t t); void _php3_mktime(INTERNAL_FUNCTION_PARAMETERS, int gm); diff --git a/ext/standard/fsock.c b/ext/standard/fsock.c index cc000f42b4..227e606c5d 100644 --- a/ext/standard/fsock.c +++ b/ext/standard/fsock.c @@ -248,7 +248,7 @@ static void _php3_fsockopen(INTERNAL_FUNCTION_PARAMETERS, int persistent) { switch(arg_count) { case 5: convert_to_double(args[4]); - conv = args[4]->value.dval * 1000000.0; + conv = (unsigned long) (args[4]->value.dval * 1000000.0); timeout.tv_sec = conv / 1000000; timeout.tv_usec = conv % 1000000; /* fall-through */ diff --git a/ext/standard/parsedate.y b/ext/standard/parsedate.y new file mode 100644 index 0000000000..6552c517a2 --- /dev/null +++ b/ext/standard/parsedate.y @@ -0,0 +1,919 @@ +%{ +/* $Revision$ +** +** Originally written by Steven M. Bellovin <smb@research.att.com> while +** at the University of North Carolina at Chapel Hill. Later tweaked by +** a couple of people on Usenet. Completely overhauled by Rich $alz +** <rsalz@osf.org> and Jim Berets <jberets@bbn.com> in August, 1990. +** Further revised (removed obsolete constructs and cleaned up timezone +** names) in August, 1991, by Rich. Paul Eggert <eggert@twinsun.com> +** helped in September, 1992. +** +** This grammar has six shift/reduce conflicts. +** +** This code is in the public domain and has no copyright. +*/ +/* SUPPRESS 530 *//* Empty body for statement */ +/* SUPPRESS 593 on yyerrlab *//* Label was not used */ +/* SUPPRESS 593 on yynewstate *//* Label was not used */ +/* SUPPRESS 595 on yypvt *//* Automatic variable may be used before set */ + +#ifdef WIN32 +# include "config.w32.h" +#else +# include "php_config.h" +#endif + +#if WIN32||WINNT +#include <malloc.h> +#endif + +#include <stdio.h> +#include <sys/types.h> +#include <time.h> + +#ifdef HAVE_SYS_TIME_H +# include <sys/time.h> +#endif +#ifdef WIN32 +# include "win32/time.h" +#endif + +#include <ctype.h> + +#if defined(_HPUX_SOURCE) +#include <alloca.h> +#endif + +#if WIN32||WINNT +#include <time.h> +#else +# if !defined(HAVE_TM_ZONE) && !defined(_TIMEZONE) +extern time_t timezone; +# endif +#endif + +#define yylhs date_yylhs +#define yylen date_yylen +#define yydefred date_yydefred +#define yydgoto date_yydgoto +#define yysindex date_yysindex +#define yyrindex date_yyrindex +#define yygindex date_yygindex +#define yytable date_yytable +#define yycheck date_yycheck +#define yyparse date_parse +#define yylex date_lex +#define yyerror date_error + +static int date_lex(void); + + /* See the LeapYears table in Convert. */ +#define EPOCH 1970 +#define END_OF_TIME 2038 + /* Constants for general time calculations. */ +#define DST_OFFSET 1 +#define SECSPERDAY (24L * 60L * 60L) + /* Readability for TABLE stuff. */ +#define HOUR(x) (x * 60) + +#define LPAREN '(' +#define RPAREN ')' +#define IS7BIT(x) ((unsigned int)(x) < 0200) + +/* +** Get the number of elements in a fixed-size array, or a pointer just +** past the end of it. +*/ +#define SIZEOF(array) ((int)(sizeof array / sizeof array[0])) +#define ENDOF(array) (&array[SIZEOF(array)]) +#define CTYPE(isXXXXX, c) ((isascii((c)) && isXXXXX((c)))) + +typedef struct _TIMEINFO { + time_t time; + long usec; + long tzone; +} TIMEINFO; + +typedef char const *STRING; +typedef char * const CSTRING; + +/* +** An entry in the lexical lookup table. +*/ +typedef struct _TABLE { + STRING name; + int type; + time_t value; +} TABLE; + +/* +** Daylight-savings mode: on, off, or not yet known. +*/ +typedef enum _DSTMODE { + DSTon, DSToff, DSTmaybe +} DSTMODE; + +/* +** Meridian: am, pm, or 24-hour style. +*/ +typedef enum _MERIDIAN { + MERam, MERpm, MER24 +} MERIDIAN; + + +/* +** Global variables. We could get rid of most of them by using a yacc +** union, but this is more efficient. (This routine predates the +** yacc %union construct.) +*/ +static char *yyInput; +static DSTMODE yyDSTmode; +static int yyHaveDate; +static int yyHaveRel; +static int yyHaveTime; +static time_t yyTimezone; +static time_t yyDay; +static time_t yyHour; +static time_t yyMinutes; +static time_t yyMonth; +static time_t yySeconds; +static time_t yyYear; +static MERIDIAN yyMeridian; +static time_t yyRelMonth; +static time_t yyRelSeconds; + + +extern struct tm *localtime(); + +static void date_error(); +%} + +%expect 6 + +%union { + time_t Number; + enum _MERIDIAN Meridian; +} + +%token tDAY tDAYZONE tMERIDIAN tMONTH tMONTH_UNIT tSEC_UNIT tSNUMBER +%token tUNUMBER tZONE + +%type <Number> tDAYZONE tMONTH tMONTH_UNIT tSEC_UNIT +%type <Number> tSNUMBER tUNUMBER tZONE numzone zone +%type <Meridian> tMERIDIAN o_merid + +%% + +spec : /* NULL */ + | spec item + ; + +item : time { + yyHaveTime++; +#if defined(lint) + /* I am compulsive about lint natterings... */ + if (yyHaveTime == -1) { + YYERROR; + } +#endif /* defined(lint) */ + } + | time zone { + yyHaveTime++; + yyTimezone = $2; + } + | date { + yyHaveDate++; + } + | rel { + yyHaveRel = 1; + } + ; + +time : tUNUMBER o_merid { + if ($1 < 100) { + yyHour = $1; + yyMinutes = 0; + } + else { + yyHour = $1 / 100; + yyMinutes = $1 % 100; + } + yySeconds = 0; + yyMeridian = $2; + } + | tUNUMBER ':' tUNUMBER o_merid { + yyHour = $1; + yyMinutes = $3; + yySeconds = 0; + yyMeridian = $4; + } + | tUNUMBER ':' tUNUMBER numzone { + yyHour = $1; + yyMinutes = $3; + yyTimezone = $4; + yyMeridian = MER24; + yyDSTmode = DSToff; + } + | tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid { + yyHour = $1; + yyMinutes = $3; + yySeconds = $5; + yyMeridian = $6; + } + | tUNUMBER ':' tUNUMBER ':' tUNUMBER numzone { + yyHour = $1; + yyMinutes = $3; + yySeconds = $5; + yyTimezone = $6; + yyMeridian = MER24; + yyDSTmode = DSToff; + } + ; + +zone : tZONE { + $$ = $1; + yyDSTmode = DSToff; + } + | tDAYZONE { + $$ = $1; + yyDSTmode = DSTon; + } + | tZONE numzone { + /* Only allow "GMT+300" and "GMT-0800" */ + if ($1 != 0) { + YYABORT; + } + $$ = $2; + yyDSTmode = DSToff; + } + | numzone { + $$ = $1; + yyDSTmode = DSToff; + } + ; + +numzone : tSNUMBER { + int i; + + /* Unix and GMT and numeric timezones -- a little confusing. */ + if ($1 < 0) { + /* Don't work with negative modulus. */ + $1 = -$1; + if ($1 > 9999 || (i = $1 % 100) >= 60) { + YYABORT; + } + $$ = ($1 / 100) * 60 + i; + } + else { + if ($1 > 9999 || (i = $1 % 100) >= 60) { + YYABORT; + } + $$ = -(($1 / 100) * 60 + i); + } + } + ; + +date : tUNUMBER '/' tUNUMBER { + yyMonth = $1; + yyDay = $3; + } + | tUNUMBER '/' tUNUMBER '/' tUNUMBER { + if ($1 > 100) { + /* assume YYYY/MM/DD format, so need not to add 1900 */ + yyYear = $1; + yyMonth = $3; + yyDay = $5; + } + else { + /* assume MM/DD/YY* format */ + yyMonth = $1; + yyDay = $3; + if ($5 > 100) { + /* assume year is YYYY format, so need not to add 1900 */ + yyYear = $5; + } else { + /* assume year is YY format, so need to add 1900 */ + yyYear = $5 + 1900; + } + } + } + | tMONTH tUNUMBER { + yyMonth = $1; + yyDay = $2; + } + | tMONTH tUNUMBER ',' tUNUMBER { + yyMonth = $1; + yyDay = $2; + if ($4 > 100) { + /* assume year is YYYY format, so need not to add 1900 */ + yyYear = $4; + } else { + /* assume year is YY format, so need to add 1900 */ + yyYear = $4 + 1900; + } + } + | tUNUMBER tMONTH { + yyDay = $1; + yyMonth = $2; + } + | tUNUMBER tMONTH tUNUMBER { + yyDay = $1; + yyMonth = $2; + if ($3 > 100) { + /* assume year is YYYY format, so need not to add 1900 */ + yyYear = $3; + } else { + /* assume year is YY format, so need to add 1900 */ + yyYear = $3 + 1900; + } + } + | tDAY ',' tUNUMBER tMONTH tUNUMBER { + yyDay = $3; + yyMonth = $4; + if ($5 > 100) { + /* assume year is YYYY format, so need not to add 1900 */ + yyYear = $5; + } else { + /* assume year is YY format, so need to add 1900 */ + yyYear = $5 + 1900; + } + } + ; + +rel : tSNUMBER tSEC_UNIT { + yyRelSeconds += $1 * $2; + } + | tUNUMBER tSEC_UNIT { + yyRelSeconds += $1 * $2; + } + | tSNUMBER tMONTH_UNIT { + yyRelMonth += $1 * $2; + } + | tUNUMBER tMONTH_UNIT { + yyRelMonth += $1 * $2; + } + ; + +o_merid : /* NULL */ { + $$ = MER24; + } + | tMERIDIAN { + $$ = $1; + } + ; + +%% + +/* Month and day table. */ +static TABLE MonthDayTable[] = { + { "january", tMONTH, 1 }, + { "february", tMONTH, 2 }, + { "march", tMONTH, 3 }, + { "april", tMONTH, 4 }, + { "may", tMONTH, 5 }, + { "june", tMONTH, 6 }, + { "july", tMONTH, 7 }, + { "august", tMONTH, 8 }, + { "september", tMONTH, 9 }, + { "october", tMONTH, 10 }, + { "november", tMONTH, 11 }, + { "december", tMONTH, 12 }, + /* The value of the day isn't used... */ + { "sunday", tDAY, 0 }, + { "monday", tDAY, 0 }, + { "tuesday", tDAY, 0 }, + { "wednesday", tDAY, 0 }, + { "thursday", tDAY, 0 }, + { "friday", tDAY, 0 }, + { "saturday", tDAY, 0 }, +}; + +/* Time units table. */ +static TABLE UnitsTable[] = { + { "year", tMONTH_UNIT, 12 }, + { "month", tMONTH_UNIT, 1 }, + { "week", tSEC_UNIT, 7 * 24 * 60 * 60 }, + { "day", tSEC_UNIT, 1 * 24 * 60 * 60 }, + { "hour", tSEC_UNIT, 60 * 60 }, + { "minute", tSEC_UNIT, 60 }, + { "min", tSEC_UNIT, 60 }, + { "second", tSEC_UNIT, 1 }, + { "sec", tSEC_UNIT, 1 }, +}; + +/* Timezone table. */ +static TABLE TimezoneTable[] = { + { "gmt", tZONE, HOUR( 0) }, /* Greenwich Mean */ + { "ut", tZONE, HOUR( 0) }, /* Universal */ + { "utc", tZONE, HOUR( 0) }, /* Universal Coordinated */ + { "cut", tZONE, HOUR( 0) }, /* Coordinated Universal */ + { "z", tZONE, HOUR( 0) }, /* Greenwich Mean */ + { "wet", tZONE, HOUR( 0) }, /* Western European */ + { "bst", tDAYZONE, HOUR( 0) }, /* British Summer */ + { "nst", tZONE, HOUR(3)+30 }, /* Newfoundland Standard */ + { "ndt", tDAYZONE, HOUR(3)+30 }, /* Newfoundland Daylight */ + { "ast", tZONE, HOUR( 4) }, /* Atlantic Standard */ + { "adt", tDAYZONE, HOUR( 4) }, /* Atlantic Daylight */ + { "est", tZONE, HOUR( 5) }, /* Eastern Standard */ + { "edt", tDAYZONE, HOUR( 5) }, /* Eastern Daylight */ + { "cst", tZONE, HOUR( 6) }, /* Central Standard */ + { "cdt", tDAYZONE, HOUR( 6) }, /* Central Daylight */ + { "mst", tZONE, HOUR( 7) }, /* Mountain Standard */ + { "mdt", tDAYZONE, HOUR( 7) }, /* Mountain Daylight */ + { "pst", tZONE, HOUR( 8) }, /* Pacific Standard */ + { "pdt", tDAYZONE, HOUR( 8) }, /* Pacific Daylight */ + { "yst", tZONE, HOUR( 9) }, /* Yukon Standard */ + { "ydt", tDAYZONE, HOUR( 9) }, /* Yukon Daylight */ + { "akst", tZONE, HOUR( 9) }, /* Alaska Standard */ + { "akdt", tDAYZONE, HOUR( 9) }, /* Alaska Daylight */ + { "hst", tZONE, HOUR(10) }, /* Hawaii Standard */ + { "hast", tZONE, HOUR(10) }, /* Hawaii-Aleutian Standard */ + { "hadt", tDAYZONE, HOUR(10) }, /* Hawaii-Aleutian Daylight */ + { "ces", tDAYZONE, -HOUR(1) }, /* Central European Summer */ + { "cest", tDAYZONE, -HOUR(1) }, /* Central European Summer */ + { "mez", tZONE, -HOUR(1) }, /* Middle European */ + { "mezt", tDAYZONE, -HOUR(1) }, /* Middle European Summer */ + { "cet", tZONE, -HOUR(1) }, /* Central European */ + { "met", tZONE, -HOUR(1) }, /* Middle European */ + { "eet", tZONE, -HOUR(2) }, /* Eastern Europe */ + { "msk", tZONE, -HOUR(3) }, /* Moscow Winter */ + { "msd", tDAYZONE, -HOUR(3) }, /* Moscow Summer */ + { "wast", tZONE, -HOUR(8) }, /* West Australian Standard */ + { "wadt", tDAYZONE, -HOUR(8) }, /* West Australian Daylight */ + { "hkt", tZONE, -HOUR(8) }, /* Hong Kong */ + { "cct", tZONE, -HOUR(8) }, /* China Coast */ + { "jst", tZONE, -HOUR(9) }, /* Japan Standard */ + { "kst", tZONE, -HOUR(9) }, /* Korean Standard */ + { "kdt", tZONE, -HOUR(9) }, /* Korean Daylight */ + { "cast", tZONE, -(HOUR(9)+30) }, /* Central Australian Standard */ + { "cadt", tDAYZONE, -(HOUR(9)+30) }, /* Central Australian Daylight */ + { "east", tZONE, -HOUR(10) }, /* Eastern Australian Standard */ + { "eadt", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylight */ + { "nzst", tZONE, -HOUR(12) }, /* New Zealand Standard */ + { "nzdt", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */ + + /* For completeness we include the following entries. */ +#if 0 + + /* Duplicate names. Either they conflict with a zone listed above + * (which is either more likely to be seen or just been in circulation + * longer), or they conflict with another zone in this section and + * we could not reasonably choose one over the other. */ + { "fst", tZONE, HOUR( 2) }, /* Fernando De Noronha Standard */ + { "fdt", tDAYZONE, HOUR( 2) }, /* Fernando De Noronha Daylight */ + { "bst", tZONE, HOUR( 3) }, /* Brazil Standard */ + { "est", tZONE, HOUR( 3) }, /* Eastern Standard (Brazil) */ + { "edt", tDAYZONE, HOUR( 3) }, /* Eastern Daylight (Brazil) */ + { "wst", tZONE, HOUR( 4) }, /* Western Standard (Brazil) */ + { "wdt", tDAYZONE, HOUR( 4) }, /* Western Daylight (Brazil) */ + { "cst", tZONE, HOUR( 5) }, /* Chile Standard */ + { "cdt", tDAYZONE, HOUR( 5) }, /* Chile Daylight */ + { "ast", tZONE, HOUR( 5) }, /* Acre Standard */ + { "adt", tDAYZONE, HOUR( 5) }, /* Acre Daylight */ + { "cst", tZONE, HOUR( 5) }, /* Cuba Standard */ + { "cdt", tDAYZONE, HOUR( 5) }, /* Cuba Daylight */ + { "est", tZONE, HOUR( 6) }, /* Easter Island Standard */ + { "edt", tDAYZONE, HOUR( 6) }, /* Easter Island Daylight */ + { "sst", tZONE, HOUR(11) }, /* Samoa Standard */ + { "ist", tZONE, -HOUR(2) }, /* Israel Standard */ + { "idt", tDAYZONE, -HOUR(2) }, /* Israel Daylight */ + { "idt", tDAYZONE, -(HOUR(3)+30) }, /* Iran Daylight */ + { "ist", tZONE, -(HOUR(3)+30) }, /* Iran Standard */ + { "cst", tZONE, -HOUR(8) }, /* China Standard */ + { "cdt", tDAYZONE, -HOUR(8) }, /* China Daylight */ + { "sst", tZONE, -HOUR(8) }, /* Singapore Standard */ + + /* Dubious (e.g., not in Olson's TIMEZONE package) or obsolete. */ + { "gst", tZONE, HOUR( 3) }, /* Greenland Standard */ + { "wat", tZONE, -HOUR(1) }, /* West Africa */ + { "at", tZONE, HOUR( 2) }, /* Azores */ + { "gst", tZONE, -HOUR(10) }, /* Guam Standard */ + { "nft", tZONE, HOUR(3)+30 }, /* Newfoundland */ + { "idlw", tZONE, HOUR(12) }, /* International Date Line West */ + { "mewt", tZONE, -HOUR(1) }, /* Middle European Winter */ + { "mest", tDAYZONE, -HOUR(1) }, /* Middle European Summer */ + { "swt", tZONE, -HOUR(1) }, /* Swedish Winter */ + { "sst", tDAYZONE, -HOUR(1) }, /* Swedish Summer */ + { "fwt", tZONE, -HOUR(1) }, /* French Winter */ + { "fst", tDAYZONE, -HOUR(1) }, /* French Summer */ + { "bt", tZONE, -HOUR(3) }, /* Baghdad */ + { "it", tZONE, -(HOUR(3)+30) }, /* Iran */ + { "zp4", tZONE, -HOUR(4) }, /* USSR Zone 3 */ + { "zp5", tZONE, -HOUR(5) }, /* USSR Zone 4 */ + { "ist", tZONE, -(HOUR(5)+30) }, /* Indian Standard */ + { "zp6", tZONE, -HOUR(6) }, /* USSR Zone 5 */ + { "nst", tZONE, -HOUR(7) }, /* North Sumatra */ + { "sst", tZONE, -HOUR(7) }, /* South Sumatra */ + { "jt", tZONE, -(HOUR(7)+30) }, /* Java (3pm in Cronusland!) */ + { "nzt", tZONE, -HOUR(12) }, /* New Zealand */ + { "idle", tZONE, -HOUR(12) }, /* International Date Line East */ + { "cat", tZONE, HOUR(10) }, /* -- expired 1967 */ + { "nt", tZONE, HOUR(11) }, /* -- expired 1967 */ + { "ahst", tZONE, HOUR(10) }, /* -- expired 1983 */ + { "hdt", tDAYZONE, HOUR(10) }, /* -- expired 1986 */ +#endif /* 0 */ +}; + + + +/* ARGSUSED */ +static void +date_error(s) + char *s; +{ + /* NOTREACHED */ +} + +int GetTimeInfo(TIMEINFO *Now) +{ + static time_t NextHour; + static long LastTzone; + struct tm *tm; + int secondsUntilNextHour; +#if defined(HAVE_GETTIMEOFDAY) + struct timeval tv; +#endif /* defined(HAVE_GETTIMEOFDAY) */ +#if !defined(HAVE_TM_GMTOFF) + struct tm local; + struct tm gmt; +#endif /* !defined(HAVE_TM_GMTOFF) */ + + /* Get the basic time. */ +#if defined(HAVE_GETTIMEOFDAY) + if (gettimeofday(&tv, (struct timezone *)NULL) == -1) + return -1; + Now->time = tv.tv_sec; + Now->usec = tv.tv_usec; +#else + /* Can't check for -1 since that might be a time, I guess. */ + (void)time(&Now->time); + Now->usec = 0; +#endif /* defined(HAVE_GETTIMEOFDAY) */ + + /* Now get the timezone if the last time < HH:00:00 <= now for some HH. */ + if (NextHour <= Now->time) { + if ((tm = localtime(&Now->time)) == NULL) + return -1; + secondsUntilNextHour = 60 * (60 - tm->tm_min) - tm->tm_sec; +#if !defined(HAVE_TM_GMTOFF) + /* To get the timezone, compare localtime with GMT. */ + local = *tm; + if ((tm = gmtime(&Now->time)) == NULL) + return -1; + gmt = *tm; + + /* Assume we are never more than 24 hours away. */ + LastTzone = gmt.tm_yday - local.tm_yday; + if (LastTzone > 1) + LastTzone = -24; + else if (LastTzone < -1) + LastTzone = 24; + else + LastTzone *= 24; + + /* Scale in the hours and minutes; ignore seconds. */ + LastTzone += gmt.tm_hour - local.tm_hour; + LastTzone *= 60; + LastTzone += gmt.tm_min - local.tm_min; +#else + LastTzone = (0 - tm->tm_gmtoff) / 60; +#endif /* defined(HAVE_TM_GMTOFF) */ + NextHour = Now->time + secondsUntilNextHour; + } + Now->tzone = LastTzone; + return 0; +} + + +static time_t +ToSeconds(Hours, Minutes, Seconds, Meridian) + time_t Hours; + time_t Minutes; + time_t Seconds; + MERIDIAN Meridian; +{ + if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 61) + return -1; + if (Meridian == MER24) { + if (Hours < 0 || Hours > 23) + return -1; + } + else { + if (Hours < 1 || Hours > 12) + return -1; + if (Hours == 12) + Hours = 0; + if (Meridian == MERpm) + Hours += 12; + } + return (Hours * 60L + Minutes) * 60L + Seconds; +} + + +static time_t +Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, dst) + time_t Month; + time_t Day; + time_t Year; + time_t Hours; + time_t Minutes; + time_t Seconds; + MERIDIAN Meridian; + DSTMODE dst; +{ + static int DaysNormal[13] = { + 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 + }; + static int DaysLeap[13] = { + 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 + }; + static int LeapYears[] = { + 1972, 1976, 1980, 1984, 1988, 1992, 1996, + 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036 + }; + int *yp; + int *mp; + time_t Julian; + int i; + time_t tod; + + /* Year should not be passed as a relative value, but absolute one. + so this should not happen, but just ensure it */ + if (Year < 0) + Year = -Year; + if (Year < 100) + Year += 1900; + if (Year < EPOCH) + Year += 100; + for (mp = DaysNormal, yp = LeapYears; yp < ENDOF(LeapYears); yp++) + if (Year == *yp) { + mp = DaysLeap; + break; + } + if (Year < EPOCH || Year > END_OF_TIME + || Month < 1 || Month > 12 + /* NOSTRICT *//* conversion from long may lose accuracy */ + || Day < 1 || Day > mp[(int)Month]) + return -1; + + Julian = Day - 1 + (Year - EPOCH) * 365; + for (yp = LeapYears; yp < ENDOF(LeapYears); yp++, Julian++) + if (Year <= *yp) + break; + for (i = 1; i < Month; i++) + Julian += *++mp; + Julian *= SECSPERDAY; + Julian += yyTimezone * 60L; + if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0) + return -1; + Julian += tod; + tod = Julian; + if (dst == DSTon || (dst == DSTmaybe && localtime(&tod)->tm_isdst)) + Julian -= DST_OFFSET * 60 * 60; + return Julian; +} + + +static time_t +DSTcorrect(Start, Future) + time_t Start; + time_t Future; +{ + time_t StartDay; + time_t FutureDay; + + StartDay = (localtime(&Start)->tm_hour + 1) % 24; + FutureDay = (localtime(&Future)->tm_hour + 1) % 24; + return (Future - Start) + (StartDay - FutureDay) * DST_OFFSET * 60 * 60; +} + + +static time_t +RelativeMonth(Start, RelMonth) + time_t Start; + time_t RelMonth; +{ + struct tm *tm; + time_t Month; + time_t Year; + + tm = localtime(&Start); + Month = 12 * tm->tm_year + tm->tm_mon + RelMonth; + Year = Month / 12; + Year += 1900; + Month = Month % 12 + 1; + return DSTcorrect(Start, + Convert(Month, (time_t)tm->tm_mday, Year, + (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec, + MER24, DSTmaybe)); +} + + +static int LookupWord(char *buff, int length) +{ + char *p; + STRING q; + TABLE *tp; + int c; + + p = buff; + c = p[0]; + + /* See if we have an abbreviation for a month. */ + if (length == 3 || (length == 4 && p[3] == '.')) + for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++) { + q = tp->name; + if (c == q[0] && p[1] == q[1] && p[2] == q[2]) { + yylval.Number = tp->value; + return tp->type; + } + } + else + for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++) + if (c == tp->name[0] && strcmp(p, tp->name) == 0) { + yylval.Number = tp->value; + return tp->type; + } + + /* Try for a timezone. */ + for (tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++) + if (c == tp->name[0] && p[1] == tp->name[1] + && strcmp(p, tp->name) == 0) { + yylval.Number = tp->value; + return tp->type; + } + + /* Try the units table. */ + for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++) + if (c == tp->name[0] && strcmp(p, tp->name) == 0) { + yylval.Number = tp->value; + return tp->type; + } + + /* Strip off any plural and try the units table again. */ + if (--length > 0 && p[length] == 's') { + p[length] = '\0'; + for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++) + if (c == tp->name[0] && strcmp(p, tp->name) == 0) { + p[length] = 's'; + yylval.Number = tp->value; + return tp->type; + } + p[length] = 's'; + } + length++; + + /* Drop out any periods. */ + for (p = buff, q = (STRING)buff; *q; q++) + if (*q != '.') + *p++ = *q; + *p = '\0'; + + /* Try the meridians. */ + if (buff[1] == 'm' && buff[2] == '\0') { + if (buff[0] == 'a') { + yylval.Meridian = MERam; + return tMERIDIAN; + } + if (buff[0] == 'p') { + yylval.Meridian = MERpm; + return tMERIDIAN; + } + } + + /* If we saw any periods, try the timezones again. */ + if (p - buff != length) { + c = buff[0]; + for (p = buff, tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++) + if (c == tp->name[0] && p[1] == tp->name[1] + && strcmp(p, tp->name) == 0) { + yylval.Number = tp->value; + return tp->type; + } + } + + /* Unknown word -- assume GMT timezone. */ + yylval.Number = 0; + return tZONE; +} + + +static int date_lex(void) +{ + char c; + char *p; + char buff[20]; + int sign; + int i; + int nesting; + + for ( ; ; ) { + /* Get first character after the whitespace. */ + for ( ; ; ) { + while (CTYPE(isspace, (int)*yyInput)) + yyInput++; + c = *yyInput; + + /* Ignore RFC 822 comments, typically time zone names. */ + if (c != LPAREN) + break; + for (nesting = 1; (c = *++yyInput) != RPAREN || --nesting; ) + if (c == LPAREN) + nesting++; + else if (!IS7BIT(c) || c == '\0' || c == '\r' + || (c == '\\' && ((c = *++yyInput) == '\0' || !IS7BIT(c)))) + /* Lexical error: bad comment. */ + return '?'; + yyInput++; + } + + /* A number? */ + if (CTYPE(isdigit, (int)c) || c == '-' || c == '+') { + if (c == '-' || c == '+') { + sign = c == '-' ? -1 : 1; + yyInput++; + if (!CTYPE(isdigit, (int)*yyInput)) + /* Skip the plus or minus sign. */ + continue; + } + else + sign = 0; + for (i = 0; (c = *yyInput++) != '\0' && CTYPE(isdigit, (int)c); ) + i = 10 * i + c - '0'; + yyInput--; + yylval.Number = sign < 0 ? -i : i; + return sign ? tSNUMBER : tUNUMBER; + } + + /* A word? */ + if (CTYPE(isalpha, (int)c)) { + for (p = buff; (c = *yyInput++) == '.' || CTYPE(isalpha, (int)c); ) + if (p < &buff[sizeof buff - 1]) + *p++ = CTYPE(isupper, (int)c) ? tolower(c) : c; + *p = '\0'; + yyInput--; + return LookupWord(buff, p - buff); + } + + return *yyInput++; + } +} + + +time_t parsedate(char *p, TIMEINFO *now) +{ + extern int date_parse(); + struct tm *tm; + TIMEINFO ti; + time_t Start; + + yyInput = p; + if (now == NULL) { + now = &ti; + (void)GetTimeInfo(&ti); + } + + tm = localtime(&now->time); + yyYear = tm->tm_year + 1900; + yyMonth = tm->tm_mon + 1; + yyDay = tm->tm_mday; +#ifdef HAVE_TM_GMTOFF + yyTimezone = tm->tm_gmtoff/60; +#else + yyTimezone = timezone/60; +#endif + yyDSTmode = DSTmaybe; + yyHour = 0; + yyMinutes = 0; + yySeconds = 0; + yyMeridian = MER24; + yyRelSeconds = 0; + yyRelMonth = 0; + yyHaveDate = 0; + yyHaveRel = 0; + yyHaveTime = 0; + + if (date_parse() || yyHaveTime > 1 || yyHaveDate > 1) + return -1; + + if (yyHaveDate || yyHaveTime) { + Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds, + yyMeridian, yyDSTmode); + if (Start < 0) + return -1; + } + else { + Start = now->time; + if (!yyHaveRel) + Start -= (tm->tm_hour * 60L + tm->tm_min) * 60L + tm->tm_sec; + } + + Start += yyRelSeconds; + if (yyRelMonth) + Start += RelativeMonth(Start, yyRelMonth); + + /* Have to do *something* with a legitimate -1 so it's distinguishable + * from the error return value. (Alternately could set errno on error.) */ + return Start == -1 ? 0 : Start; +} diff --git a/ext/standard/php3_string.h b/ext/standard/php3_string.h index 0619a58d76..111138ab36 100644 --- a/ext/standard/php3_string.h +++ b/ext/standard/php3_string.h @@ -83,6 +83,7 @@ PHP_FUNCTION(chunk_split); PHP_FUNCTION(parsestr); PHP_FUNCTION(bin2hex); PHP_FUNCTION(similar_text); +PHP_FUNCTION(strip_tags); extern PHPAPI char *_php3_strtoupper(char *s); extern PHPAPI char *_php3_strtolower(char *s); diff --git a/ext/standard/rand.c b/ext/standard/rand.c index 09d28b6d65..051eab8ce6 100644 --- a/ext/standard/rand.c +++ b/ext/standard/rand.c @@ -201,6 +201,8 @@ static inline uint32 randomMT(void) #define PHP_RAND_MAX RAND_MAX #endif +/* {{{ proto void srand(int seed) + Seeds random number generator */ PHP_FUNCTION(srand) { pval *arg; @@ -219,7 +221,10 @@ PHP_FUNCTION(srand) #endif #endif } +/* }}} */ +/* {{{ proto void mt_srand(int seed) + Seeds Mersenne Twister random number generator */ PHP_FUNCTION(mt_srand) { pval *arg; @@ -229,7 +234,10 @@ PHP_FUNCTION(mt_srand) convert_to_long(arg); seedMT(arg->value.lval); } +/* }}} */ +/* {{{ proto int rand([int min, int max]) + Returns a random number */ PHP_FUNCTION(rand) { pval *p_min=NULL, *p_max=NULL; @@ -262,13 +270,40 @@ PHP_FUNCTION(rand) return_value->value.lval = rand(); #endif #endif - + /* + * A bit of tricky math here. We want to avoid using a modulus because + * that simply tosses the high-order bits and might skew the distribution + * of random values over the range. Instead we map the range directly. + * + * We need to map the range from 0...M evenly to the range a...b + * Let n = the random number and n' = the mapped random number + * + * Then we have: n' = a + n(b-a)/M + * + * We have a problem here in that only n==M will get mapped to b which + # means the chances of getting b is much much less than getting any of + # the other values in the range. We can fix this by increasing our range + # artifically and using: + # + # n' = a + n(b-a+1)/M + * + # Now we only have a problem if n==M which would cause us to produce a + # number of b+1 which would be bad. So we bump M up by one to make sure + # this will never happen, and the final algorithm looks like this: + # + # n' = a + n(b-a+1)/(M+1) + * + * -RL + */ if (p_min && p_max) { /* implement range */ return_value->value.lval = p_min->value.lval + - (int)((double)p_max->value.lval * return_value->value.lval/(PHP_RAND_MAX+(double)p_min->value.lval)); + (int)((double)(p_max->value.lval - p_min->value.lval + 1) * return_value->value.lval/(PHP_RAND_MAX+1.0)); } } +/* }}} */ +/* {{{ proto int mt_rand([int min, int max]) + Returns a random number from Mersenne Twister */ PHP_FUNCTION(mt_rand) { pval *p_min=NULL, *p_max=NULL; @@ -304,16 +339,23 @@ PHP_FUNCTION(mt_rand) if (p_min && p_max) { /* implement range */ return_value->value.lval = p_min->value.lval + - (int)((double)p_max->value.lval * return_value->value.lval/(PHP_RAND_MAX+(double)p_min->value.lval)); + (int)((double)(p_max->value.lval - p_min->value.lval + 1) * return_value->value.lval/(PHP_RAND_MAX+1.0)); } } +/* }}} */ +/* {{{ proto int getrandmax(void) + Returns the maximum value a random number can have */ PHP_FUNCTION(getrandmax) { return_value->type = IS_LONG; return_value->value.lval = PHP_RAND_MAX; } +/* }}} */ + +/* {{{ proto int mt_getrandmax(void) + Returns the maximum value a random number from Mersenne Twister can have */ PHP_FUNCTION(mt_getrandmax) { return_value->type = IS_LONG; @@ -323,7 +365,7 @@ PHP_FUNCTION(mt_getrandmax) */ return_value->value.lval = 2147483647; /* 2^^31 */ } - +/* }}} */ /* * Local variables: * tab-width: 4 diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c index 3fbc211bbb..a14f4e3f06 100644 --- a/ext/wddx/wddx.c +++ b/ext/wddx/wddx.c @@ -696,6 +696,7 @@ PHP_FUNCTION(wddx_serialize_vars) _php_wddx_add_chunk(packet, WDDX_STRUCT_S); for (i=0; i<argc; i++) { + convert_to_string(args[i]); _php_wddx_add_var(packet, args[i]); } @@ -815,6 +816,7 @@ PHP_FUNCTION(wddx_add_vars) } for (i=1; i<argc; i++) { + convert_to_string(args[i]); _php_wddx_add_var(packet, args[i]); } diff --git a/ext/xml/Makefile.am b/ext/xml/Makefile.am index 9b6e9cdec4..9f2ca1b1be 100644 --- a/ext/xml/Makefile.am +++ b/ext/xml/Makefile.am @@ -3,7 +3,7 @@ phplibdir=$(libdir)/php SRC=xml.c -INCLUDES=@INCLUDES@ @XML_INCLUDE@ -I@top_srcdir@ -I@top_srcdir@/libzend +INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend noinst_LIBRARIES=libphpext_xml.a phplib_LTLIBRARIES=libphpext_xml.la libphpext_xml_a_SOURCES=$(SRC) diff --git a/ext/xml/config.m4 b/ext/xml/config.m4 index 787ee3465d..df323399dc 100644 --- a/ext/xml/config.m4 +++ b/ext/xml/config.m4 @@ -3,7 +3,10 @@ AC_MSG_CHECKING(for XML support) AC_ARG_WITH(xml, -[ --with-xml Include XML support],[ +[ --with-xml[=DIR] Include XML support. Will look for expat + in DIR if specified. Set DIR to "shared" to + build as a dl, or "shared,DIR" to build as a dl + and still specify DIR.],[ case $withval in shared) shared=yes @@ -24,19 +27,20 @@ AC_ARG_WITH(xml, AC_MSG_RESULT([yes (static)]) fi if test "$withval" = "yes"; then - test -d /usr/include/xmltok && XML_INCLUDE="-I/usr/include/xmltok" - test -d /usr/include/xml && XML_INCLUDE="-I/usr/include/xml" - test -d /usr/local/include/xml && XML_INCLUDE="-I/usr/local/include/xml" + test -d /usr/include/xmltok && XML_INCLUDE="/usr/include/xmltok" + test -d /usr/include/xml && XML_INCLUDE="/usr/include/xml" + test -d /usr/local/include/xml && XML_INCLUDE="/usr/local/include/xml" AC_CHECK_LIB(expat, main, XML_LIBS="-lexpat", XML_LIBS="-lxmlparse -lxmltok") else XML_LIBS="-L$withval/lib -lexpat" if test -d $withval/include/xml; then - XML_INCLUDE="-I$withval/include/xml" + XML_INCLUDE="$withval/include/xml" else - XML_INCLUDE="-I$withval/include" + XML_INCLUDE="$withval/include" fi fi AC_DEFINE(HAVE_LIBEXPAT, 1) + AC_ADD_INCLUDE($XML_INCLUDE) PHP_EXTENSION(xml, $shared) if test "$shared" != "yes"; then EXTRA_LIBS="$EXTRA_LIBS $XML_LIBS" @@ -48,4 +52,3 @@ AC_ARG_WITH(xml, AC_MSG_RESULT(no) ]) AC_SUBST(XML_LIBS) -AC_SUBST(XML_INCLUDE) |