PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - gd/libgd - gdkanji.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 204
Code covered: 0.0 % Executed lines: 0
Legend: not executed executed

       1                 : 
       2                 : /* gdkanji.c (Kanji code converter)                            */
       3                 : /*                 written by Masahito Yamaga (ma@yama-ga.com) */
       4                 : 
       5                 : #include <stdio.h>
       6                 : #include <stdlib.h>
       7                 : #include <string.h>
       8                 : #include "gd.h"
       9                 : #include "gdhelpers.h"
      10                 : 
      11                 : #include <stdarg.h>
      12                 : #if defined(HAVE_ICONV_H) || defined(HAVE_ICONV)
      13                 : #include <iconv.h>
      14                 : #ifdef HAVE_ERRNO_H
      15                 : #include <errno.h>
      16                 : #endif
      17                 : #endif
      18                 : 
      19                 : #if defined(HAVE_ICONV_H) && !defined(HAVE_ICONV)
      20                 : #define HAVE_ICONV 1
      21                 : #endif
      22                 : 
      23                 : #define LIBNAME "any2eucjp()"
      24                 : 
      25                 : #if defined(__MSC__) || defined(__BORLANDC__) || defined(__TURBOC__) || defined(_Windows) || defined(MSDOS)
      26                 : #ifndef SJISPRE
      27                 : #define SJISPRE 1
      28                 : #endif
      29                 : #endif
      30                 : 
      31                 : #ifdef TRUE
      32                 : #undef TRUE
      33                 : #endif
      34                 : #ifdef FALSE
      35                 : #undef FALSE
      36                 : #endif
      37                 : 
      38                 : #define TRUE  1
      39                 : #define FALSE 0
      40                 : 
      41                 : #define NEW 1
      42                 : #define OLD 2
      43                 : #define ESCI 3
      44                 : #define NEC 4
      45                 : #define EUC 5
      46                 : #define SJIS 6
      47                 : #define EUCORSJIS 7
      48                 : #define ASCII 8
      49                 : 
      50                 : #define NEWJISSTR "JIS7"
      51                 : #define OLDJISSTR "jis"
      52                 : #define EUCSTR    "eucJP"
      53                 : #define SJISSTR   "SJIS"
      54                 : 
      55                 : #define ESC 27
      56                 : #define SS2 142
      57                 : 
      58                 : static void
      59                 : debug (const char *format,...)
      60               0 : {
      61                 : #ifdef DEBUG
      62                 :   va_list args;
      63                 : 
      64                 :   va_start (args, format);
      65                 :   fprintf (stdout, "%s: ", LIBNAME);
      66                 :   vfprintf (stdout, format, args);
      67                 :   fprintf (stdout, "\n");
      68                 :   va_end (args);
      69                 : #endif
      70               0 : }
      71                 : 
      72                 : static void
      73                 : error (const char *format,...)
      74               0 : {
      75                 :         va_list args;
      76                 :         char *tmp;
      77                 :         TSRMLS_FETCH();
      78                 : 
      79               0 :         va_start(args, format);
      80               0 :         vspprintf(&tmp, 0, format, args);
      81               0 :         va_end(args);
      82               0 :         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s: %s", LIBNAME, tmp);
      83               0 :         efree(tmp);
      84               0 : }
      85                 : 
      86                 : /* DetectKanjiCode() derived from DetectCodeType() by Ken Lunde. */
      87                 : 
      88                 : static int
      89                 : DetectKanjiCode (unsigned char *str)
      90               0 : {
      91                 :   static int whatcode = ASCII;
      92               0 :   int oldcode = ASCII;
      93                 :   int c, i;
      94               0 :   char *lang = NULL;
      95                 : 
      96               0 :   c = '\1';
      97               0 :   i = 0;
      98                 : 
      99               0 :   if (whatcode != EUCORSJIS && whatcode != ASCII)
     100                 :     {
     101               0 :       oldcode = whatcode;
     102               0 :       whatcode = ASCII;
     103                 :     }
     104                 : 
     105               0 :   while ((whatcode == EUCORSJIS || whatcode == ASCII) && c != '\0')
     106                 :     {
     107               0 :       if ((c = str[i++]) != '\0')
     108                 :         {
     109               0 :           if (c == ESC)
     110                 :             {
     111               0 :               c = str[i++];
     112               0 :               if (c == '$')
     113                 :                 {
     114               0 :                   c = str[i++];
     115               0 :                   if (c == 'B')
     116               0 :                     whatcode = NEW;
     117               0 :                   else if (c == '@')
     118               0 :                     whatcode = OLD;
     119                 :                 }
     120               0 :               else if (c == '(')
     121                 :                 {
     122               0 :                   c = str[i++];
     123               0 :                   if (c == 'I')
     124               0 :                     whatcode = ESCI;
     125                 :                 }
     126               0 :               else if (c == 'K')
     127               0 :                 whatcode = NEC;
     128                 :             }
     129               0 :           else if ((c >= 129 && c <= 141) || (c >= 143 && c <= 159))
     130               0 :             whatcode = SJIS;
     131               0 :           else if (c == SS2)
     132                 :             {
     133               0 :               c = str[i++];
     134               0 :               if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160) || (c >= 224 && c <= 252))
     135               0 :                 whatcode = SJIS;
     136               0 :               else if (c >= 161 && c <= 223)
     137               0 :                 whatcode = EUCORSJIS;
     138                 :             }
     139               0 :           else if (c >= 161 && c <= 223)
     140                 :             {
     141               0 :               c = str[i++];
     142               0 :               if (c >= 240 && c <= 254)
     143               0 :                 whatcode = EUC;
     144               0 :               else if (c >= 161 && c <= 223)
     145               0 :                 whatcode = EUCORSJIS;
     146               0 :               else if (c >= 224 && c <= 239)
     147                 :                 {
     148               0 :                   whatcode = EUCORSJIS;
     149               0 :                   while (c >= 64 && c != '\0' && whatcode == EUCORSJIS)
     150                 :                     {
     151               0 :                       if (c >= 129)
     152                 :                         {
     153               0 :                           if (c <= 141 || (c >= 143 && c <= 159))
     154               0 :                             whatcode = SJIS;
     155               0 :                           else if (c >= 253 && c <= 254)
     156               0 :                             whatcode = EUC;
     157                 :                         }
     158               0 :                       c = str[i++];
     159                 :                     }
     160                 :                 }
     161               0 :               else if (c <= 159)
     162               0 :                 whatcode = SJIS;
     163                 :             }
     164               0 :           else if (c >= 240 && c <= 254)
     165               0 :             whatcode = EUC;
     166               0 :           else if (c >= 224 && c <= 239)
     167                 :             {
     168               0 :               c = str[i++];
     169               0 :               if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160))
     170               0 :                 whatcode = SJIS;
     171               0 :               else if (c >= 253 && c <= 254)
     172               0 :                 whatcode = EUC;
     173               0 :               else if (c >= 161 && c <= 252)
     174               0 :                 whatcode = EUCORSJIS;
     175                 :             }
     176                 :         }
     177                 :     }
     178                 : 
     179                 : #ifdef DEBUG
     180                 :   if (whatcode == ASCII)
     181                 :     debug ("Kanji code not included.");
     182                 :   else if (whatcode == EUCORSJIS)
     183                 :     debug ("Kanji code not detected.");
     184                 :   else
     185                 :     debug ("Kanji code detected at %d byte.", i);
     186                 : #endif
     187                 : 
     188               0 :   if (whatcode == EUCORSJIS && oldcode != ASCII)
     189               0 :     whatcode = oldcode;
     190                 : 
     191               0 :   if (whatcode == EUCORSJIS)
     192                 :     {
     193               0 :       if (getenv ("LC_ALL"))
     194               0 :         lang = getenv ("LC_ALL");
     195               0 :       else if (getenv ("LC_CTYPE"))
     196               0 :         lang = getenv ("LC_CTYPE");
     197               0 :       else if (getenv ("LANG"))
     198               0 :         lang = getenv ("LANG");
     199                 : 
     200               0 :       if (lang)
     201                 :         {
     202               0 :           if (strcmp (lang, "ja_JP.SJIS") == 0 ||
     203                 : #ifdef hpux
     204                 :               strcmp (lang, "japanese") == 0 ||
     205                 : #endif
     206                 :               strcmp (lang, "ja_JP.mscode") == 0 ||
     207                 :               strcmp (lang, "ja_JP.PCK") == 0)
     208               0 :             whatcode = SJIS;
     209               0 :           else if (strncmp (lang, "ja", 2) == 0)
     210                 : #ifdef SJISPRE
     211                 :             whatcode = SJIS;
     212                 : #else
     213               0 :             whatcode = EUC;
     214                 : #endif
     215                 :         }
     216                 :     }
     217                 : 
     218               0 :   if (whatcode == EUCORSJIS)
     219                 : #ifdef SJISPRE
     220                 :     whatcode = SJIS;
     221                 : #else
     222               0 :     whatcode = EUC;
     223                 : #endif
     224                 : 
     225               0 :   return whatcode;
     226                 : }
     227                 : 
     228                 : /* SJIStoJIS() is sjis2jis() by Ken Lunde. */
     229                 : 
     230                 : static void
     231                 : SJIStoJIS (int *p1, int *p2)
     232               0 : {
     233               0 :   register unsigned char c1 = *p1;
     234               0 :   register unsigned char c2 = *p2;
     235               0 :   register int adjust = c2 < 159;
     236               0 :   register int rowOffset = c1 < 160 ? 112 : 176;
     237               0 :   register int cellOffset = adjust ? (31 + (c2 > 127)) : 126;
     238                 : 
     239               0 :   *p1 = ((c1 - rowOffset) << 1) - adjust;
     240               0 :   *p2 -= cellOffset;
     241               0 : }
     242                 : 
     243                 : /* han2zen() was derived from han2zen() written by Ken Lunde. */
     244                 : 
     245                 : #define IS_DAKU(c) ((c >= 182 && c <= 196) || (c >= 202 && c <= 206) || (c == 179))
     246                 : #define IS_HANDAKU(c) (c >= 202 && c <= 206)
     247                 : 
     248                 : static void
     249                 : han2zen (int *p1, int *p2)
     250               0 : {
     251               0 :   int c = *p1;
     252               0 :   int daku = FALSE;
     253               0 :   int handaku = FALSE;
     254                 :   int mtable[][2] =
     255                 :   {
     256                 :     {129, 66},
     257                 :     {129, 117},
     258                 :     {129, 118},
     259                 :     {129, 65},
     260                 :     {129, 69},
     261                 :     {131, 146},
     262                 :     {131, 64},
     263                 :     {131, 66},
     264                 :     {131, 68},
     265                 :     {131, 70},
     266                 :     {131, 72},
     267                 :     {131, 131},
     268                 :     {131, 133},
     269                 :     {131, 135},
     270                 :     {131, 98},
     271                 :     {129, 91},
     272                 :     {131, 65},
     273                 :     {131, 67},
     274                 :     {131, 69},
     275                 :     {131, 71},
     276                 :     {131, 73},
     277                 :     {131, 74},
     278                 :     {131, 76},
     279                 :     {131, 78},
     280                 :     {131, 80},
     281                 :     {131, 82},
     282                 :     {131, 84},
     283                 :     {131, 86},
     284                 :     {131, 88},
     285                 :     {131, 90},
     286                 :     {131, 92},
     287                 :     {131, 94},
     288                 :     {131, 96},
     289                 :     {131, 99},
     290                 :     {131, 101},
     291                 :     {131, 103},
     292                 :     {131, 105},
     293                 :     {131, 106},
     294                 :     {131, 107},
     295                 :     {131, 108},
     296                 :     {131, 109},
     297                 :     {131, 110},
     298                 :     {131, 113},
     299                 :     {131, 116},
     300                 :     {131, 119},
     301                 :     {131, 122},
     302                 :     {131, 125},
     303                 :     {131, 126},
     304                 :     {131, 128},
     305                 :     {131, 129},
     306                 :     {131, 130},
     307                 :     {131, 132},
     308                 :     {131, 134},
     309                 :     {131, 136},
     310                 :     {131, 137},
     311                 :     {131, 138},
     312                 :     {131, 139},
     313                 :     {131, 140},
     314                 :     {131, 141},
     315                 :     {131, 143},
     316                 :     {131, 147},
     317                 :     {129, 74},
     318                 :     {129, 75}
     319               0 :   };
     320                 : 
     321               0 :   if (*p2 == 222 && IS_DAKU (*p1))
     322               0 :     daku = TRUE;                /* Daku-ten */
     323               0 :   else if (*p2 == 223 && IS_HANDAKU (*p1))
     324               0 :     handaku = TRUE;             /* Han-daku-ten */
     325                 : 
     326               0 :   *p1 = mtable[c - 161][0];
     327               0 :   *p2 = mtable[c - 161][1];
     328                 : 
     329               0 :   if (daku)
     330                 :     {
     331               0 :       if ((*p2 >= 74 && *p2 <= 103) || (*p2 >= 110 && *p2 <= 122))
     332               0 :         (*p2)++;
     333               0 :       else if (*p2 == 131 && *p2 == 69)
     334               0 :         *p2 = 148;
     335                 :     }
     336               0 :   else if (handaku && *p2 >= 110 && *p2 <= 122)
     337               0 :     (*p2) += 2;
     338               0 : }
     339                 : 
     340                 : /* Recast strcpy to handle unsigned chars used below. */
     341                 : #define ustrcpy(A,B) (strcpy((char*)(A),(const char*)(B)))
     342                 : 
     343                 : static void
     344                 : do_convert (unsigned char *to, unsigned char *from, const char *code)
     345               0 : {
     346                 : #ifdef HAVE_ICONV
     347                 :   iconv_t cd;
     348                 :   size_t from_len, to_len;
     349                 : 
     350               0 :   if ((cd = iconv_open (EUCSTR, code)) == (iconv_t) - 1)
     351                 :     {
     352               0 :       error ("iconv_open() error");
     353                 : #ifdef HAVE_ERRNO_H
     354               0 :       if (errno == EINVAL)
     355               0 :         error ("invalid code specification: \"%s\" or \"%s\"",
     356                 :                EUCSTR, code);
     357                 : #endif
     358               0 :       strcpy ((char *) to, (const char *) from);
     359               0 :       return;
     360                 :     }
     361                 : 
     362               0 :   from_len = strlen ((const char *) from) + 1;
     363               0 :   to_len = BUFSIZ;
     364                 : 
     365               0 :   if ((int) iconv(cd, (char **) &from, &from_len, (char **) &to, &to_len) == -1)
     366                 :     {
     367                 : #ifdef HAVE_ERRNO_H
     368               0 :       if (errno == EINVAL)
     369               0 :         error ("invalid end of input string");
     370               0 :       else if (errno == EILSEQ)
     371               0 :         error ("invalid code in input string");
     372               0 :       else if (errno == E2BIG)
     373               0 :         error ("output buffer overflow at do_convert()");
     374                 :       else
     375                 : #endif
     376               0 :         error ("something happen");
     377               0 :       strcpy ((char *) to, (const char *) from);
     378               0 :       return;
     379                 :     }
     380                 : 
     381               0 :   if (iconv_close (cd) != 0)
     382                 :     {
     383               0 :       error ("iconv_close() error");
     384                 :     }
     385                 : #else
     386                 :   int p1, p2, i, j;
     387                 :   int jisx0208 = FALSE;
     388                 :   int hankaku = FALSE;
     389                 : 
     390                 :   j = 0;
     391                 :   if (strcmp (code, NEWJISSTR) == 0 || strcmp (code, OLDJISSTR) == 0)
     392                 :     {
     393                 :       for (i = 0; from[i] != '\0' && j < BUFSIZ; i++)
     394                 :         {
     395                 :           if (from[i] == ESC)
     396                 :             {
     397                 :               i++;
     398                 :               if (from[i] == '$')
     399                 :                 {
     400                 :                   jisx0208 = TRUE;
     401                 :                   hankaku = FALSE;
     402                 :                   i++;
     403                 :                 }
     404                 :               else if (from[i] == '(')
     405                 :                 {
     406                 :                   jisx0208 = FALSE;
     407                 :                   i++;
     408                 :                   if (from[i] == 'I')   /* Hankaku Kana */
     409                 :                     hankaku = TRUE;
     410                 :                   else
     411                 :                     hankaku = FALSE;
     412                 :                 }
     413                 :             }
     414                 :           else
     415                 :             {
     416                 :               if (jisx0208)
     417                 :                 to[j++] = from[i] + 128;
     418                 :               else if (hankaku)
     419                 :                 {
     420                 :                   to[j++] = SS2;
     421                 :                   to[j++] = from[i] + 128;
     422                 :                 }
     423                 :               else
     424                 :                 to[j++] = from[i];
     425                 :             }
     426                 :         }
     427                 :     }
     428                 :   else if (strcmp (code, SJISSTR) == 0)
     429                 :     {
     430                 :       for (i = 0; from[i] != '\0' && j < BUFSIZ; i++)
     431                 :         {
     432                 :           p1 = from[i];
     433                 :           if (p1 < 127)
     434                 :             to[j++] = p1;
     435                 :           else if ((p1 >= 161) && (p1 <= 223))
     436                 :             {                   /* Hankaku Kana */
     437                 :               to[j++] = SS2;
     438                 :               to[j++] = p1;
     439                 :             }
     440                 :           else
     441                 :             {
     442                 :               p2 = from[++i];
     443                 :               SJIStoJIS (&p1, &p2);
     444                 :               to[j++] = p1 + 128;
     445                 :               to[j++] = p2 + 128;
     446                 :             }
     447                 :         }
     448                 :     }
     449                 :   else
     450                 :     {
     451                 :       error ("invalid code specification: \"%s\"", code);
     452                 :       return;
     453                 :     }
     454                 : 
     455                 :   if (j >= BUFSIZ)
     456                 :     {
     457                 :       error ("output buffer overflow at do_convert()");
     458                 :       ustrcpy (to, from);
     459                 :     }
     460                 :   else
     461                 :     to[j] = '\0';
     462                 : #endif /* HAVE_ICONV */
     463                 : }
     464                 : 
     465                 : static int
     466                 : do_check_and_conv (unsigned char *to, unsigned char *from)
     467               0 : {
     468                 :   static unsigned char tmp[BUFSIZ];
     469                 :   int p1, p2, i, j;
     470               0 :   int kanji = TRUE;
     471                 : 
     472               0 :   switch (DetectKanjiCode (from))
     473                 :     {
     474                 :     case NEW:
     475               0 :       debug ("Kanji code is New JIS.");
     476               0 :       do_convert (tmp, from, NEWJISSTR);
     477               0 :       break;
     478                 :     case OLD:
     479               0 :       debug ("Kanji code is Old JIS.");
     480               0 :       do_convert (tmp, from, OLDJISSTR);
     481               0 :       break;
     482                 :     case ESCI:
     483               0 :       debug ("This string includes Hankaku-Kana (jisx0201) escape sequence [ESC] + ( + I.");
     484               0 :       do_convert (tmp, from, NEWJISSTR);
     485               0 :       break;
     486                 :     case NEC:
     487               0 :       debug ("Kanji code is NEC Kanji.");
     488               0 :       error ("cannot convert NEC Kanji.");
     489               0 :       ustrcpy (tmp, from);
     490               0 :       kanji = FALSE;
     491               0 :       break;
     492                 :     case EUC:
     493               0 :       debug ("Kanji code is EUC.");
     494               0 :       ustrcpy (tmp, from);
     495               0 :       break;
     496                 :     case SJIS:
     497               0 :       debug ("Kanji code is SJIS.");
     498               0 :       do_convert (tmp, from, SJISSTR);
     499               0 :       break;
     500                 :     case EUCORSJIS:
     501               0 :       debug ("Kanji code is EUC or SJIS.");
     502               0 :       ustrcpy (tmp, from);
     503               0 :       kanji = FALSE;
     504               0 :       break;
     505                 :     case ASCII:
     506               0 :       debug ("This is ASCII string.");
     507               0 :       ustrcpy (tmp, from);
     508               0 :       kanji = FALSE;
     509               0 :       break;
     510                 :     default:
     511               0 :       debug ("This string includes unknown code.");
     512               0 :       ustrcpy (tmp, from);
     513               0 :       kanji = FALSE;
     514                 :       break;
     515                 :     }
     516                 : 
     517                 :   /* Hankaku Kana ---> Zenkaku Kana */
     518               0 :   if (kanji)
     519                 :     {
     520               0 :       j = 0;
     521               0 :       for (i = 0; tmp[i] != '\0' && j < BUFSIZ; i++)
     522                 :         {
     523               0 :           if (tmp[i] == SS2)
     524                 :             {
     525               0 :               p1 = tmp[++i];
     526               0 :               if (tmp[i + 1] == SS2)
     527                 :                 {
     528               0 :                   p2 = tmp[i + 2];
     529               0 :                   if (p2 == 222 || p2 == 223)
     530               0 :                     i += 2;
     531                 :                   else
     532               0 :                     p2 = 0;
     533                 :                 }
     534                 :               else
     535               0 :                 p2 = 0;
     536               0 :               han2zen (&p1, &p2);
     537               0 :               SJIStoJIS (&p1, &p2);
     538               0 :               to[j++] = p1 + 128;
     539               0 :               to[j++] = p2 + 128;
     540                 :             }
     541                 :           else
     542               0 :             to[j++] = tmp[i];
     543                 :         }
     544                 : 
     545               0 :       if (j >= BUFSIZ)
     546                 :         {
     547               0 :           error ("output buffer overflow at Hankaku --> Zenkaku");
     548               0 :           ustrcpy (to, tmp);
     549                 :         }
     550                 :       else
     551               0 :         to[j] = '\0';
     552                 :     }
     553                 :   else
     554               0 :     ustrcpy (to, tmp);
     555                 : 
     556               0 :   return kanji;
     557                 : }
     558                 : 
     559                 : int
     560                 : any2eucjp (unsigned char *dest, unsigned char *src, unsigned int dest_max)
     561               0 : {
     562                 :   static unsigned char tmp_dest[BUFSIZ];
     563                 :   int ret;
     564                 : 
     565               0 :   if (strlen ((const char *) src) >= BUFSIZ)
     566                 :     {
     567               0 :       error ("input string too large");
     568               0 :       return -1;
     569                 :     }
     570               0 :   if (dest_max > BUFSIZ)
     571                 :     {
     572               0 :       error ("invalid maximum size of destination\nit should be less than %d.", BUFSIZ);
     573               0 :       return -1;
     574                 :     }
     575               0 :   ret = do_check_and_conv (tmp_dest, src);
     576               0 :   if (strlen ((const char *) tmp_dest) >= dest_max)
     577                 :     {
     578               0 :       error ("output buffer overflow");
     579               0 :       ustrcpy (dest, src);
     580               0 :       return -1;
     581                 :     }
     582               0 :   ustrcpy (dest, tmp_dest);
     583               0 :   return ret;
     584                 : }
     585                 : 
     586                 : #if 0
     587                 : unsigned int
     588                 : strwidth (unsigned char *s)
     589                 : {
     590                 :   unsigned char *t;
     591                 :   unsigned int i;
     592                 : 
     593                 :   t = (unsigned char *) gdMalloc (BUFSIZ);
     594                 :   any2eucjp (t, s, BUFSIZ);
     595                 :   i = strlen (t);
     596                 :   gdFree (t);
     597                 :   return i;
     598                 : }
     599                 : 
     600                 : #ifdef DEBUG
     601                 : int
     602                 : main ()
     603                 : {
     604                 :   unsigned char input[BUFSIZ];
     605                 :   unsigned char *output;
     606                 :   unsigned char *str;
     607                 :   int c, i = 0;
     608                 : 
     609                 :   while ((c = fgetc (stdin)) != '\n' && i < BUFSIZ)
     610                 :     input[i++] = c;
     611                 :   input[i] = '\0';
     612                 : 
     613                 :   printf ("input : %d bytes\n", strlen ((const char *) input));
     614                 :   printf ("output: %d bytes\n", strwidth (input));
     615                 : 
     616                 :   output = (unsigned char *) gdMalloc (BUFSIZ);
     617                 :   any2eucjp (output, input, BUFSIZ);
     618                 :   str = output;
     619                 :   while (*str != '\0')
     620                 :     putchar (*(str++));
     621                 :   putchar ('\n');
     622                 :   gdFree (output);
     623                 : 
     624                 :   return 0;
     625                 : }
     626                 : #endif
     627                 : #endif

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:08 +0000 (5 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.