@ -964,7 +964,6 @@ static const char *get_th(char *num, int type);
static char * str_numth ( char * dest , char * num , int type ) ;
static char * str_numth ( char * dest , char * num , int type ) ;
static int adjust_partial_year_to_2020 ( int year ) ;
static int adjust_partial_year_to_2020 ( int year ) ;
static int strspace_len ( char * str ) ;
static int strspace_len ( char * str ) ;
static int strdigits_len ( char * str ) ;
static void from_char_set_mode ( TmFromChar * tmfc , const FromCharDateMode mode ) ;
static void from_char_set_mode ( TmFromChar * tmfc , const FromCharDateMode mode ) ;
static void from_char_set_int ( int * dest , const int value , const FormatNode * node ) ;
static void from_char_set_int ( int * dest , const int value , const FormatNode * node ) ;
static int from_char_parse_int_len ( int * dest , char * * src , const int len , FormatNode * node ) ;
static int from_char_parse_int_len ( int * dest , char * * src , const int len , FormatNode * node ) ;
@ -1976,9 +1975,19 @@ asc_toupper_z(const char *buff)
/* ----------
/* ----------
* Skip TM / th in FROM_CHAR
* Skip TM / th in FROM_CHAR
*
* If S_THth is on , skip two chars , assuming there are two available
* - - - - - - - - - -
* - - - - - - - - - -
*/
*/
# define SKIP_THth(_suf) (S_THth(_suf) ? 2 : 0)
# define SKIP_THth(ptr, _suf) \
do { \
if ( S_THth ( _suf ) ) \
{ \
if ( * ( ptr ) ) ( ptr ) + + ; \
if ( * ( ptr ) ) ( ptr ) + + ; \
} \
} while ( 0 )
# ifdef DEBUG_TO_FROM_CHAR
# ifdef DEBUG_TO_FROM_CHAR
/* -----------
/* -----------
@ -2086,23 +2095,6 @@ strspace_len(char *str)
return len ;
return len ;
}
}
static int
strdigits_len ( char * str )
{
char * p = str ;
int len ;
len = strspace_len ( str ) ;
p + = len ;
while ( * p & & isdigit ( ( unsigned char ) * p ) & & len < = DCH_MAX_ITEM_SIZ )
{
len + + ;
p + + ;
}
return len ;
}
/*
/*
* Set the date mode of a from - char conversion .
* Set the date mode of a from - char conversion .
*
*
@ -3007,19 +2999,19 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
case DCH_HH12 :
case DCH_HH12 :
from_char_parse_int_len ( & out - > hh , & s , 2 , n ) ;
from_char_parse_int_len ( & out - > hh , & s , 2 , n ) ;
out - > clock = CLOCK_12_HOUR ;
out - > clock = CLOCK_12_HOUR ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_HH24 :
case DCH_HH24 :
from_char_parse_int_len ( & out - > hh , & s , 2 , n ) ;
from_char_parse_int_len ( & out - > hh , & s , 2 , n ) ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_MI :
case DCH_MI :
from_char_parse_int ( & out - > mi , & s , n ) ;
from_char_parse_int ( & out - > mi , & s , n ) ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_SS :
case DCH_SS :
from_char_parse_int ( & out - > ss , & s , n ) ;
from_char_parse_int ( & out - > ss , & s , n ) ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_MS : /* millisecond */
case DCH_MS : /* millisecond */
len = from_char_parse_int_len ( & out - > ms , & s , 3 , n ) ;
len = from_char_parse_int_len ( & out - > ms , & s , 3 , n ) ;
@ -3030,7 +3022,7 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
out - > ms * = len = = 1 ? 100 :
out - > ms * = len = = 1 ? 100 :
len = = 2 ? 10 : 1 ;
len = = 2 ? 10 : 1 ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_US : /* microsecond */
case DCH_US : /* microsecond */
len = from_char_parse_int_len ( & out - > us , & s , 6 , n ) ;
len = from_char_parse_int_len ( & out - > us , & s , 6 , n ) ;
@ -3041,11 +3033,11 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
len = = 4 ? 100 :
len = = 4 ? 100 :
len = = 5 ? 10 : 1 ;
len = = 5 ? 10 : 1 ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_SSSS :
case DCH_SSSS :
from_char_parse_int ( & out - > ssss , & s , n ) ;
from_char_parse_int ( & out - > ssss , & s , n ) ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_tz :
case DCH_tz :
case DCH_TZ :
case DCH_TZ :
@ -3085,7 +3077,7 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
break ;
break ;
case DCH_MM :
case DCH_MM :
from_char_parse_int ( & out - > mm , & s , n ) ;
from_char_parse_int ( & out - > mm , & s , n ) ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_DAY :
case DCH_DAY :
case DCH_Day :
case DCH_Day :
@ -3105,31 +3097,31 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
break ;
break ;
case DCH_DDD :
case DCH_DDD :
from_char_parse_int ( & out - > ddd , & s , n ) ;
from_char_parse_int ( & out - > ddd , & s , n ) ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_IDDD :
case DCH_IDDD :
from_char_parse_int_len ( & out - > ddd , & s , 3 , n ) ;
from_char_parse_int_len ( & out - > ddd , & s , 3 , n ) ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_DD :
case DCH_DD :
from_char_parse_int ( & out - > dd , & s , n ) ;
from_char_parse_int ( & out - > dd , & s , n ) ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_D :
case DCH_D :
from_char_parse_int ( & out - > d , & s , n ) ;
from_char_parse_int ( & out - > d , & s , n ) ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_ID :
case DCH_ID :
from_char_parse_int_len ( & out - > d , & s , 1 , n ) ;
from_char_parse_int_len ( & out - > d , & s , 1 , n ) ;
/* Shift numbering to match Gregorian where Sunday = 1 */
/* Shift numbering to match Gregorian where Sunday = 1 */
if ( + + out - > d > 7 )
if ( + + out - > d > 7 )
out - > d = 1 ;
out - > d = 1 ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_WW :
case DCH_WW :
case DCH_IW :
case DCH_IW :
from_char_parse_int ( & out - > ww , & s , n ) ;
from_char_parse_int ( & out - > ww , & s , n ) ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_Q :
case DCH_Q :
@ -3144,55 +3136,57 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
* isn ' t stored anywhere in ' out ' .
* isn ' t stored anywhere in ' out ' .
*/
*/
from_char_parse_int ( ( int * ) NULL , & s , n ) ;
from_char_parse_int ( ( int * ) NULL , & s , n ) ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_CC :
case DCH_CC :
from_char_parse_int ( & out - > cc , & s , n ) ;
from_char_parse_int ( & out - > cc , & s , n ) ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_Y_YYY :
case DCH_Y_YYY :
{
{
int matched ,
int matched ,
years ,
years ,
millenia ;
millenia ,
nch ;
matched = sscanf ( s , " %d,%03d " , & millenia , & years ) ;
matched = sscanf ( s , " %d,%03d%n " , & millenia , & years , & nch ) ;
if ( matched ! = 2 )
if ( matched < 2 )
ereport ( ERROR ,
ereport ( ERROR ,
( errcode ( ERRCODE_INVALID_DATETIME_FORMAT ) ,
( errcode ( ERRCODE_INVALID_DATETIME_FORMAT ) ,
errmsg ( " invalid input string for \" Y,YYY \" " ) ) ) ;
errmsg ( " invalid input string for \" Y,YYY \" " ) ) ) ;
years + = ( millenia * 1000 ) ;
years + = ( millenia * 1000 ) ;
from_char_set_int ( & out - > year , years , n ) ;
from_char_set_int ( & out - > year , years , n ) ;
out - > yysz = 4 ;
out - > yysz = 4 ;
s + = strdigits_len ( s ) + 4 + SKIP_THth ( n - > suffix ) ;
s + = nch ;
SKIP_THth ( s , n - > suffix ) ;
}
}
break ;
break ;
case DCH_YYYY :
case DCH_YYYY :
case DCH_IYYY :
case DCH_IYYY :
from_char_parse_int ( & out - > year , & s , n ) ;
from_char_parse_int ( & out - > year , & s , n ) ;
out - > yysz = 4 ;
out - > yysz = 4 ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_YYY :
case DCH_YYY :
case DCH_IYY :
case DCH_IYY :
if ( from_char_parse_int ( & out - > year , & s , n ) < 4 )
if ( from_char_parse_int ( & out - > year , & s , n ) < 4 )
out - > year = adjust_partial_year_to_2020 ( out - > year ) ;
out - > year = adjust_partial_year_to_2020 ( out - > year ) ;
out - > yysz = 3 ;
out - > yysz = 3 ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_YY :
case DCH_YY :
case DCH_IY :
case DCH_IY :
if ( from_char_parse_int ( & out - > year , & s , n ) < 4 )
if ( from_char_parse_int ( & out - > year , & s , n ) < 4 )
out - > year = adjust_partial_year_to_2020 ( out - > year ) ;
out - > year = adjust_partial_year_to_2020 ( out - > year ) ;
out - > yysz = 2 ;
out - > yysz = 2 ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_Y :
case DCH_Y :
case DCH_I :
case DCH_I :
if ( from_char_parse_int ( & out - > year , & s , n ) < 4 )
if ( from_char_parse_int ( & out - > year , & s , n ) < 4 )
out - > year = adjust_partial_year_to_2020 ( out - > year ) ;
out - > year = adjust_partial_year_to_2020 ( out - > year ) ;
out - > yysz = 1 ;
out - > yysz = 1 ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_RM :
case DCH_RM :
from_char_seq_search ( & value , & s , rm_months_upper ,
from_char_seq_search ( & value , & s , rm_months_upper ,
@ -3206,11 +3200,11 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
break ;
break ;
case DCH_W :
case DCH_W :
from_char_parse_int ( & out - > w , & s , n ) ;
from_char_parse_int ( & out - > w , & s , n ) ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
case DCH_J :
case DCH_J :
from_char_parse_int ( & out - > j , & s , n ) ;
from_char_parse_int ( & out - > j , & s , n ) ;
s + = SKIP_THth ( n - > suffix ) ;
SKIP_THth ( s , n - > suffix ) ;
break ;
break ;
}
}
}
}