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

LCOV - code coverage report
Current view: top level - lcov_data/ext/date/lib - parse_iso_intervals.re (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 0 228 0.0 %
Date: 2014-04-16 Functions: 0 10 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 5                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2014 The PHP Group                                |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 3.01 of the PHP license,      |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.php.net/license/3_01.txt                                  |
      11             :    | If you did not receive a copy of the PHP license and are unable to   |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@php.net so we can mail you a copy immediately.               |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Derick Rethans <derick@derickrethans.nl>                    |
      16             :    +----------------------------------------------------------------------+
      17             :  */
      18             : 
      19             : /* $Id$ */
      20             : 
      21             : #include "timelib.h"
      22             : 
      23             : #include <stdio.h>
      24             : #include <ctype.h>
      25             : 
      26             : #ifdef HAVE_STDLIB_H
      27             : #include <stdlib.h>
      28             : #endif
      29             : #ifdef HAVE_STRING_H
      30             : #include <string.h>
      31             : #else
      32             : #include <strings.h>
      33             : #endif
      34             : 
      35             : #if defined(_MSC_VER)
      36             : # define strtoll(s, f, b) _atoi64(s)
      37             : #elif !defined(HAVE_STRTOLL)
      38             : # if defined(HAVE_ATOLL)
      39             : #  define strtoll(s, f, b) atoll(s)
      40             : # else
      41             : #  define strtoll(s, f, b) strtol(s, f, b)
      42             : # endif
      43             : #endif
      44             : 
      45             : #define TIMELIB_UNSET   -99999
      46             : 
      47             : #define TIMELIB_SECOND  1
      48             : #define TIMELIB_MINUTE  2
      49             : #define TIMELIB_HOUR    3
      50             : #define TIMELIB_DAY     4
      51             : #define TIMELIB_MONTH   5
      52             : #define TIMELIB_YEAR    6
      53             : 
      54             : #define EOI      257
      55             : 
      56             : #define TIMELIB_PERIOD  260
      57             : #define TIMELIB_ISO_DATE 261
      58             : #define TIMELIB_ERROR   999
      59             : 
      60             : typedef unsigned char uchar;
      61             : 
      62             : #define   BSIZE    8192
      63             : 
      64             : #define   YYCTYPE      uchar
      65             : #define   YYCURSOR     cursor
      66             : #define   YYLIMIT      s->lim
      67             : #define   YYMARKER     s->ptr
      68             : #define   YYFILL(n)    return EOI;
      69             : 
      70             : #define   RET(i)       {s->cur = cursor; return i;}
      71             : 
      72             : #define timelib_string_free free
      73             : 
      74             : #define TIMELIB_INIT  s->cur = cursor; str = timelib_string(s); ptr = str
      75             : #define TIMELIB_DEINIT timelib_string_free(str)
      76             : 
      77             : #ifdef DEBUG_PARSER
      78             : #define DEBUG_OUTPUT(s) printf("%s\n", s);
      79             : #define YYDEBUG(s,c) { if (s != -1) { printf("state: %d ", s); printf("[%c]\n", c); } }
      80             : #else
      81             : #define DEBUG_OUTPUT(s)
      82             : #define YYDEBUG(s,c)
      83             : #endif
      84             : 
      85             : #include "timelib_structs.h"
      86             : 
      87             : typedef struct Scanner {
      88             :         int           fd;
      89             :         uchar        *lim, *str, *ptr, *cur, *tok, *pos;
      90             :         unsigned int  line, len;
      91             :         struct timelib_error_container *errors;
      92             : 
      93             :         struct timelib_time     *begin;
      94             :         struct timelib_time     *end;
      95             :         struct timelib_rel_time *period;
      96             :         int                      recurrences;
      97             : 
      98             :         int have_period;
      99             :         int have_recurrences;
     100             :         int have_date;
     101             :         int have_begin_date;
     102             :         int have_end_date;
     103             : } Scanner;
     104             : 
     105           0 : static void add_warning(Scanner *s, char *error)
     106             : {
     107           0 :         s->errors->warning_count++;
     108           0 :         s->errors->warning_messages = realloc(s->errors->warning_messages, s->errors->warning_count * sizeof(timelib_error_message));
     109           0 :         s->errors->warning_messages[s->errors->warning_count - 1].position = s->tok ? s->tok - s->str : 0;
     110           0 :         s->errors->warning_messages[s->errors->warning_count - 1].character = s->tok ? *s->tok : 0;
     111           0 :         s->errors->warning_messages[s->errors->warning_count - 1].message = strdup(error);
     112           0 : }
     113             : 
     114           0 : static void add_error(Scanner *s, char *error)
     115             : {
     116           0 :         s->errors->error_count++;
     117           0 :         s->errors->error_messages = realloc(s->errors->error_messages, s->errors->error_count * sizeof(timelib_error_message));
     118           0 :         s->errors->error_messages[s->errors->error_count - 1].position = s->tok ? s->tok - s->str : 0;
     119           0 :         s->errors->error_messages[s->errors->error_count - 1].character = s->tok ? *s->tok : 0;
     120           0 :         s->errors->error_messages[s->errors->error_count - 1].message = strdup(error);
     121           0 : }
     122             : 
     123           0 : static char *timelib_string(Scanner *s)
     124             : {
     125           0 :         char *tmp = calloc(1, s->cur - s->tok + 1);
     126           0 :         memcpy(tmp, s->tok, s->cur - s->tok);
     127             : 
     128           0 :         return tmp;
     129             : }
     130             : 
     131           0 : static timelib_sll timelib_get_nr(char **ptr, int max_length)
     132             : {
     133             :         char *begin, *end, *str;
     134           0 :         timelib_sll tmp_nr = TIMELIB_UNSET;
     135           0 :         int len = 0;
     136             : 
     137           0 :         while ((**ptr < '0') || (**ptr > '9')) {
     138           0 :                 if (**ptr == '\0') {
     139           0 :                         return TIMELIB_UNSET;
     140             :                 }
     141           0 :                 ++*ptr;
     142             :         }
     143           0 :         begin = *ptr;
     144           0 :         while ((**ptr >= '0') && (**ptr <= '9') && len < max_length) {
     145           0 :                 ++*ptr;
     146           0 :                 ++len;
     147             :         }
     148           0 :         end = *ptr;
     149           0 :         str = calloc(1, end - begin + 1);
     150           0 :         memcpy(str, begin, end - begin);
     151           0 :         tmp_nr = strtoll(str, NULL, 10);
     152           0 :         free(str);
     153           0 :         return tmp_nr;
     154             : }
     155             : 
     156           0 : static timelib_ull timelib_get_unsigned_nr(char **ptr, int max_length)
     157             : {
     158           0 :         timelib_ull dir = 1;
     159             : 
     160           0 :         while (((**ptr < '0') || (**ptr > '9')) && (**ptr != '+') && (**ptr != '-')) {
     161           0 :                 if (**ptr == '\0') {
     162           0 :                         return TIMELIB_UNSET;
     163             :                 }
     164           0 :                 ++*ptr;
     165             :         }
     166             : 
     167           0 :         while (**ptr == '+' || **ptr == '-')
     168             :         {
     169           0 :                 if (**ptr == '-') {
     170           0 :                         dir *= -1;
     171             :                 }
     172           0 :                 ++*ptr;
     173             :         }
     174           0 :         return dir * timelib_get_nr(ptr, max_length);
     175             : }
     176             : 
     177           0 : static void timelib_eat_spaces(char **ptr)
     178             : {
     179           0 :         while (**ptr == ' ' || **ptr == '\t') {
     180           0 :                 ++*ptr;
     181             :         }
     182           0 : }
     183             : 
     184           0 : static void timelib_eat_until_separator(char **ptr)
     185             : {
     186           0 :         while (strchr(" \t.,:;/-0123456789", **ptr) == NULL) {
     187           0 :                 ++*ptr;
     188             :         }
     189           0 : }
     190             : 
     191           0 : static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_found, const timelib_tzdb *tzdb)
     192             : {
     193           0 :         long retval = 0;
     194             : 
     195           0 :         *tz_not_found = 0;
     196             : 
     197           0 :         while (**ptr == ' ' || **ptr == '\t' || **ptr == '(') {
     198           0 :                 ++*ptr;
     199             :         }
     200           0 :         if ((*ptr)[0] == 'G' && (*ptr)[1] == 'M' && (*ptr)[2] == 'T' && ((*ptr)[3] == '+' || (*ptr)[3] == '-')) {
     201           0 :                 *ptr += 3;
     202             :         }
     203           0 :         if (**ptr == '+') {
     204           0 :                 ++*ptr;
     205           0 :                 t->is_localtime = 1;
     206           0 :                 t->zone_type = TIMELIB_ZONETYPE_OFFSET;
     207           0 :                 *tz_not_found = 0;
     208           0 :                 t->dst = 0;
     209             : 
     210           0 :                 retval = -1 * timelib_parse_tz_cor(ptr);
     211           0 :         } else if (**ptr == '-') {
     212           0 :                 ++*ptr;
     213           0 :                 t->is_localtime = 1;
     214           0 :                 t->zone_type = TIMELIB_ZONETYPE_OFFSET;
     215           0 :                 *tz_not_found = 0;
     216           0 :                 t->dst = 0;
     217             : 
     218           0 :                 retval = timelib_parse_tz_cor(ptr);
     219             :         }
     220           0 :         while (**ptr == ')') {
     221           0 :                 ++*ptr;
     222             :         }
     223           0 :         return retval;
     224             : }
     225             : 
     226             : #define timelib_split_free(arg) {       \
     227             :         int i;                         \
     228             :         for (i = 0; i < arg.c; i++) {  \
     229             :                 free(arg.v[i]);            \
     230             :         }                              \
     231             :         if (arg.v) {                   \
     232             :                 free(arg.v);               \
     233             :         }                              \
     234             : }
     235             : 
     236             : /* date parser's scan function too large for VC6 - VC7.x
     237             :    drop the optimization solves the problem */
     238             : #ifdef PHP_WIN32
     239             : #pragma optimize( "", off )
     240             : #endif
     241           0 : static int scan(Scanner *s)
     242             : {
     243           0 :         uchar *cursor = s->cur;
     244           0 :         char *str, *ptr = NULL;
     245             :                 
     246             : std:
     247           0 :         s->tok = cursor;
     248           0 :         s->len = 0;
     249             : /*!re2c
     250             : 
     251             : /* */
     252             : any = [\000-\377];
     253             : number = [0-9]+;
     254             : 
     255             : hour24lz = [01][0-9] | "2"[0-4];
     256             : minutelz = [0-5][0-9];
     257             : monthlz = "0" [1-9] | "1" [0-2];
     258             : monthlzz = "0" [0-9] | "1" [0-2];
     259             : daylz   = "0" [1-9] | [1-2][0-9] | "3" [01];
     260             : daylzz  = "0" [0-9] | [1-2][0-9] | "3" [01];
     261             : secondlz = minutelz;
     262             : year4 = [0-9]{4};
     263             : weekofyear = "0"[1-9] | [1-4][0-9] | "5"[0-3];
     264             : 
     265             : space = [ \t]+;
     266             : datetimebasic  = year4 monthlz daylz "T" hour24lz minutelz secondlz "Z";
     267             : datetimeextended  = year4 "-" monthlz "-" daylz "T" hour24lz ':' minutelz ':' secondlz "Z";
     268             : period   = "P" (number "Y")? (number "M")? (number "W")? (number "D")? ("T" (number "H")? (number "M")? (number "S")?)?;
     269             : combinedrep = "P" year4 "-" monthlzz "-" daylzz "T" hour24lz ':' minutelz ':' secondlz;
     270             : 
     271             : recurrences = "R" number;
     272             : 
     273             : isoweekday       = year4 "-"? "W" weekofyear "-"? [0-7];
     274             : isoweek          = year4 "-"? "W" weekofyear;
     275             : 
     276             : */
     277             : 
     278             : /*!re2c
     279             :         /* so that vim highlights correctly */
     280             :         recurrences
     281             :         {
     282             :                 DEBUG_OUTPUT("recurrences");
     283           0 :                 TIMELIB_INIT;
     284           0 :                 ptr++;
     285           0 :                 s->recurrences = timelib_get_unsigned_nr((char **) &ptr, 9);
     286           0 :                 TIMELIB_DEINIT;
     287           0 :                 s->have_recurrences = 1;
     288           0 :                 return TIMELIB_PERIOD;
     289             :         }
     290             : 
     291             :         datetimebasic| datetimeextended
     292             :         {
     293             :                 timelib_time *current;
     294             : 
     295           0 :                 if (s->have_date || s->have_period) {
     296           0 :                         current = s->end;
     297           0 :                         s->have_end_date = 1;
     298             :                 } else {
     299           0 :                         current = s->begin;
     300           0 :                         s->have_begin_date = 1;
     301             :                 }
     302             :                 DEBUG_OUTPUT("datetimebasic | datetimeextended");
     303           0 :                 TIMELIB_INIT;
     304           0 :                 current->y = timelib_get_nr((char **) &ptr, 4);
     305           0 :                 current->m = timelib_get_nr((char **) &ptr, 2);
     306           0 :                 current->d = timelib_get_nr((char **) &ptr, 2);
     307           0 :                 current->h = timelib_get_nr((char **) &ptr, 2);
     308           0 :                 current->i = timelib_get_nr((char **) &ptr, 2);
     309           0 :                 current->s = timelib_get_nr((char **) &ptr, 2);
     310           0 :                 s->have_date = 1;
     311           0 :                 TIMELIB_DEINIT;
     312           0 :                 return TIMELIB_ISO_DATE;
     313             :         }
     314             : 
     315             :         period
     316             :         {
     317             :                 timelib_sll nr;
     318           0 :                 int         in_time = 0;
     319             :                 DEBUG_OUTPUT("period");
     320           0 :                 TIMELIB_INIT;
     321           0 :                 ptr++;
     322             :                 do {
     323           0 :                         if ( *ptr == 'T' ) {
     324           0 :                                 in_time = 1;
     325           0 :                                 ptr++;
     326             :                         }
     327           0 :                         if ( *ptr == '\0' ) {
     328           0 :                                 add_error(s, "Missing expected time part");
     329           0 :                                 break;
     330             :                         }
     331             : 
     332           0 :                         nr = timelib_get_unsigned_nr((char **) &ptr, 12);
     333           0 :                         switch (*ptr) {
     334           0 :                                 case 'Y': s->period->y = nr; break;
     335           0 :                                 case 'W': s->period->d = nr * 7; break;
     336           0 :                                 case 'D': s->period->d = nr; break;
     337           0 :                                 case 'H': s->period->h = nr; break;
     338           0 :                                 case 'S': s->period->s = nr; break;
     339             :                                 case 'M': 
     340           0 :                                         if (in_time) {
     341           0 :                                                 s->period->i = nr;
     342             :                                         } else {
     343           0 :                                                 s->period->m = nr; 
     344             :                                         }
     345           0 :                                         break;
     346             :                                 default:
     347           0 :                                         add_error(s, "Undefined period specifier");
     348             :                                         break;
     349             :                         }
     350           0 :                         ptr++;
     351           0 :                 } while (!s->errors->error_count && *ptr);
     352           0 :                 s->have_period = 1;
     353           0 :                 TIMELIB_DEINIT;
     354           0 :                 return TIMELIB_PERIOD;
     355             :         }
     356             : 
     357             :         combinedrep
     358             :         {
     359             :                 DEBUG_OUTPUT("combinedrep");
     360           0 :                 TIMELIB_INIT;
     361           0 :                 s->period->y = timelib_get_unsigned_nr((char **) &ptr, 4);
     362           0 :                 ptr++;
     363           0 :                 s->period->m = timelib_get_unsigned_nr((char **) &ptr, 2);
     364           0 :                 ptr++;
     365           0 :                 s->period->d = timelib_get_unsigned_nr((char **) &ptr, 2);
     366           0 :                 ptr++;
     367           0 :                 s->period->h = timelib_get_unsigned_nr((char **) &ptr, 2);
     368           0 :                 ptr++;
     369           0 :                 s->period->i = timelib_get_unsigned_nr((char **) &ptr, 2);
     370           0 :                 ptr++;
     371           0 :                 s->period->s = timelib_get_unsigned_nr((char **) &ptr, 2);
     372           0 :                 s->have_period = 1;
     373           0 :                 TIMELIB_DEINIT;
     374           0 :                 return TIMELIB_PERIOD;
     375             :         }
     376             : 
     377             :         [ .,\t/]
     378             :         {
     379           0 :                 goto std;
     380             :         }
     381             : 
     382             :         "\000"|"\n"
     383             :         {
     384           0 :                 s->pos = cursor; s->line++;
     385           0 :                 goto std;
     386             :         }
     387             : 
     388             :         any
     389             :         {
     390           0 :                 add_error(s, "Unexpected character");
     391           0 :                 goto std;
     392             :         }
     393             : */
     394             : }
     395             : #ifdef PHP_WIN32
     396             : #pragma optimize( "", on )
     397             : #endif
     398             : 
     399             : /*!max:re2c */
     400             : 
     401           0 : void timelib_strtointerval(char *s, int len, 
     402             :                            timelib_time **begin, timelib_time **end, 
     403             :                                                    timelib_rel_time **period, int *recurrences, 
     404             :                                                    struct timelib_error_container **errors)
     405             : {
     406             :         Scanner in;
     407             :         int t;
     408           0 :         char *e = s + len - 1;
     409             : 
     410           0 :         memset(&in, 0, sizeof(in));
     411           0 :         in.errors = malloc(sizeof(struct timelib_error_container));
     412           0 :         in.errors->warning_count = 0;
     413           0 :         in.errors->warning_messages = NULL;
     414           0 :         in.errors->error_count = 0;
     415           0 :         in.errors->error_messages = NULL;
     416             : 
     417           0 :         if (len > 0) {
     418           0 :                 while (isspace(*s) && s < e) {
     419           0 :                         s++;
     420             :                 }
     421           0 :                 while (isspace(*e) && e > s) {
     422           0 :                         e--;
     423             :                 }
     424             :         }
     425           0 :         if (e - s < 0) {
     426           0 :                 add_error(&in, "Empty string");
     427           0 :                 if (errors) {
     428           0 :                         *errors = in.errors;
     429             :                 } else {
     430           0 :                         timelib_error_container_dtor(in.errors);
     431             :                 }
     432           0 :                 return;
     433             :         }
     434           0 :         e++;
     435             : 
     436             :         /* init cursor */
     437           0 :         in.str = malloc((e - s) + YYMAXFILL);
     438           0 :         memset(in.str, 0, (e - s) + YYMAXFILL);
     439           0 :         memcpy(in.str, s, (e - s));
     440           0 :         in.lim = in.str + (e - s) + YYMAXFILL;
     441           0 :         in.cur = in.str;
     442             : 
     443             :         /* init value containers */
     444           0 :         in.begin = timelib_time_ctor();
     445           0 :         in.begin->y = TIMELIB_UNSET;
     446           0 :         in.begin->d = TIMELIB_UNSET;
     447           0 :         in.begin->m = TIMELIB_UNSET;
     448           0 :         in.begin->h = TIMELIB_UNSET;
     449           0 :         in.begin->i = TIMELIB_UNSET;
     450           0 :         in.begin->s = TIMELIB_UNSET;
     451           0 :         in.begin->f = 0;
     452           0 :         in.begin->z = 0;
     453           0 :         in.begin->dst = 0;
     454           0 :         in.begin->is_localtime = 0;
     455           0 :         in.begin->zone_type = TIMELIB_ZONETYPE_OFFSET;
     456             : 
     457           0 :         in.end = timelib_time_ctor();
     458           0 :         in.end->y = TIMELIB_UNSET;
     459           0 :         in.end->d = TIMELIB_UNSET;
     460           0 :         in.end->m = TIMELIB_UNSET;
     461           0 :         in.end->h = TIMELIB_UNSET;
     462           0 :         in.end->i = TIMELIB_UNSET;
     463           0 :         in.end->s = TIMELIB_UNSET;
     464           0 :         in.end->f = 0;
     465           0 :         in.end->z = 0;
     466           0 :         in.end->dst = 0;
     467           0 :         in.end->is_localtime = 0;
     468           0 :         in.end->zone_type = TIMELIB_ZONETYPE_OFFSET;
     469             : 
     470           0 :         in.period = timelib_rel_time_ctor();
     471           0 :         in.period->y = 0;
     472           0 :         in.period->d = 0;
     473           0 :         in.period->m = 0;
     474           0 :         in.period->h = 0;
     475           0 :         in.period->i = 0;
     476           0 :         in.period->s = 0;
     477           0 :         in.period->weekday = 0;
     478           0 :         in.period->weekday_behavior = 0;
     479           0 :         in.period->first_last_day_of = 0;
     480           0 :         in.period->days = TIMELIB_UNSET;
     481             : 
     482           0 :         in.recurrences = 1;
     483             : 
     484             :         do {
     485           0 :                 t = scan(&in);
     486             : #ifdef DEBUG_PARSER
     487             :                 printf("%d\n", t);
     488             : #endif
     489           0 :         } while(t != EOI);
     490             : 
     491           0 :         free(in.str);
     492           0 :         if (errors) {
     493           0 :                 *errors = in.errors;
     494             :         } else {
     495           0 :                 timelib_error_container_dtor(in.errors);
     496             :         }
     497           0 :         if (in.have_begin_date) {
     498           0 :                 *begin = in.begin;
     499             :         } else {
     500           0 :                 timelib_time_dtor(in.begin);
     501             :         }
     502           0 :         if (in.have_end_date) {
     503           0 :                 *end   = in.end;
     504             :         } else {
     505           0 :                 timelib_time_dtor(in.end);
     506             :         }
     507           0 :         if (in.have_period) {
     508           0 :                 *period = in.period;
     509             :         } else {
     510           0 :                 timelib_rel_time_dtor(in.period);
     511             :         }
     512           0 :         if (in.have_recurrences) {
     513           0 :                 *recurrences = in.recurrences;
     514             :         }
     515             : }
     516             : 
     517             : 
     518             : /*
     519             :  * vim: syntax=c
     520             :  */

Generated by: LCOV version 1.10

Generated at Wed, 16 Apr 2014 12:48:02 +0000 (6 hours ago)

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