This repository has been archived on 2024-12-16. You can view files and clone it, but cannot push or open issues or pull requests.
CodeBlocksPortable/Borland/BCC55/Include/Rw/time.cc

706 lines
20 KiB
C++
Raw Normal View History

#ifndef __TIME_CC
#define __TIME_CC
#pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
/***************************************************************************
*
* time.cc - Definitions for the Standard Library time facets
*
*
***************************************************************************
*
* Copyright (c) 1994-1999 Rogue Wave Software, Inc. All Rights Reserved.
*
* This computer software is owned by Rogue Wave Software, Inc. and is
* protected by U.S. copyright laws and other laws and by international
* treaties. This computer software is furnished by Rogue Wave Software,
* Inc. pursuant to a written license agreement and may be used, copied,
* transmitted, and stored only in accordance with the terms of such
* license and with the inclusion of the above copyright notice. This
* computer software or any other copies thereof may not be provided or
* otherwise made available to any other person.
*
* U.S. Government Restricted Rights. This computer software is provided
* with Restricted Rights. Use, duplication, or disclosure by the
* Government is subject to restrictions as set forth in subparagraph (c)
* (1) (ii) of The Rights in Technical Data and Computer Software clause
* at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the
* Commercial Computer Software <EFBFBD> Restricted Rights at 48 CFR 52.227-19,
* as applicable. Manufacturer is Rogue Wave Software, Inc., 5500
* Flatiron Parkway, Boulder, Colorado 80301 USA.
*
**************************************************************************/
#include <time.h>
#ifndef _RWSTD_NO_NAMESPACE
namespace __rwstd {
#endif
// --------------------------------------
// Template time_reader member templates.
// --------------------------------------
template <class charT,class InputIterator>
time_reader<charT,InputIterator>::time_reader
(InputIterator& in,InputIterator& end,_RW_STD::ios_base& io,
const __RWSTD::timepunct<charT>& tpunct)
: digit_reader<charT,InputIterator>(in,end,io), __timp(tpunct)
{
// Don't recognize signs on any numeric input.
this->is_signed=false;
}
template <class charT,class InputIterator>
bool time_reader<charT,InputIterator>::
get_time_pattern (const string_type &patt,tm *time)
{
enum {
edit_year = 0x01,
edit_month = 0x02,
edit_century = 0x04,
edit_hour = 0x08
};
int post_edits=0;
const charT *p=patt.c_str(),*patt_end=p+patt.length();
for ( ; p<patt_end; p++) {
switch (this->ctyp.narrow(*p,' ')) {
case '%':
{
int *iresult;
int ampm_dummy; // scratch space for ampm value
const keyword_map<charT> *keywords=NULL;
switch (this->ctyp.narrow(*++p,' ')) {
case 'a':
case 'A':
// Day of week (abbreviated or not).
keywords=&get_day_map(__timp);
iresult=&time->tm_wday;
break;
case 'b':
case 'B':
// Month name (abbreviated or not).
keywords=&get_month_map(__timp);
iresult=&time->tm_mon;
break;
case 'm':
// Numeric month, comes in 1 higher than the number we want.
post_edits|=edit_month;
iresult=&time->tm_mon;
break;
case 'c':
// Full date, time and year in default format.
return get_time_pattern(get_patt_string(__timp,2),time);
case 'd':
// Day of month.
iresult=&time->tm_mday;
break;
case 'I': // 12-hour clock
case 'H': // 24-hour clock
// Hours (12/24 distinction is made in the 'p' section)
iresult=&time->tm_hour;
break;
case 'p':
// am/pm indicator
keywords=&get_ampm_map(__timp);
// Assumes charT[0] are equal means entire string will be
if (*(this->in) == get_ampm_string(__timp,true)[0])
post_edits|=edit_hour;
iresult=&ampm_dummy;
break;
case 'M':
// Minutes.
iresult=&time->tm_min;
break;
case 'S':
// Seconds.
iresult=&time->tm_sec;
break;
case 'Y':
// Year with Century.
post_edits|=edit_year;
iresult=&time->tm_year;
break;
case 'y':
// 2-digit Year without Century.
post_edits|=(edit_year|edit_century);
iresult=&time->tm_year;
break;
default:
// All other format characters are not supported on input.
return false;
}
if (keywords) {
if ((*iresult=get_keyword(*keywords))<0)
return false;
} else
*iresult=to_ulong(this->get_int_digits());
}
break;
default:
if (!this->at_end() && *this->in==*p)
this->in++;
else
return false;
}
if (this->error)
return false;
}
if (post_edits&edit_year)
if (post_edits&edit_century && time->tm_year<100)
; // 2-digit year is already relative to 1900
else
time->tm_year-=1900;
if (post_edits&edit_month)
time->tm_mon--;
if (post_edits&edit_hour)
if (time->tm_hour < 12)
time->tm_hour+=12;
return true;
}
#ifndef _RWSTD_NO_NAMESPACE
} namespace std {
#endif
// -----------------------------------------------------
// Facet time_get<charT,InputIterator> member templates.
// -----------------------------------------------------
template <class charT, class InputIterator>
locale::id time_get<charT,InputIterator>::id;
template <class charT, class InputIterator>
time_get<charT,InputIterator>::~time_get() { }
template <class charT, class InputIterator>
time_base::dateorder time_get<charT,InputIterator>::do_date_order () const
{
// We would prefer to return a value that matches the date format defined
// in the timepunct facet in the caller's locale, but we can't get there
// from here ...
#ifndef _RWSTD_NO_NAMESPACE
const _TYPENAME __RWSTD::timepunct<charT>::string_type& s =
__RWSTD::keyword_cracker<charT>::get_patt_string(*__timp,0);
#else
const _TYPENAME timepunct<charT>::string_type& s =
keyword_cracker<charT>::get_patt_string(*__timp,0);
#endif
bool haveYear = false;
for (size_t i = 0; i < s.length(); i++) {
if (s[i] == charT('y') || s[i] == charT('Y')) haveYear = true;
if (s[i] == charT('d') || s[i] == charT('a') || s[i] == charT('A'))
if (haveYear) return ydm;
else return dmy;
if (s[i] == charT('m') || s[i] == charT('b') || s[i] == charT('B'))
if (haveYear) return ymd;
else return mdy;
}
return no_order;
}
template <class charT, class InputIterator>
_TYPENAME time_get<charT,InputIterator>::iter_type
time_get<charT,InputIterator>::do_get_time (InputIterator in,
InputIterator end, ios_base& io, ios_base::iostate& err, tm* time) const
{
__RWSTD::time_reader<charT,InputIterator> reader(in,end,io,*__timp);
err=ios_base::goodbit;
// Parse according to pattern 1 (strftime '%X' -- default time pattern)
if (!reader.get_time_pattern(reader.get_patt_string(reader.__timp,1),time))
err=ios_base::failbit;
if (reader.reached_end)
err|=ios_base::eofbit;
return in;
}
template <class charT, class InputIterator >
_TYPENAME time_get<charT,InputIterator>::iter_type
time_get<charT,InputIterator>::do_get_date (InputIterator in,
InputIterator end, ios_base& io, ios_base::iostate& err, tm* time) const
{
__RWSTD::time_reader<charT,InputIterator> reader(in,end,io,*__timp);
err=ios_base::goodbit;
// Parse according to pattern 0 (strftime '%x' -- default date pattern)
if (!reader.get_time_pattern(reader.get_patt_string(reader.__timp,0),time))
err=ios_base::failbit;
if (reader.reached_end)
err|=ios_base::eofbit;
return in;
}
template <class charT, class InputIterator >
_TYPENAME time_get<charT,InputIterator>::iter_type
time_get<charT,InputIterator>::do_get_weekday (InputIterator in,
InputIterator end, ios_base& io, ios_base::iostate& err, tm* time) const
{
__RWSTD::time_reader<charT,InputIterator> reader(in,end,io,*__timp);
int wd=reader.get_keyword(reader.get_day_map(reader.__timp));
err=ios_base::goodbit;
if (wd<0)
err=ios_base::failbit;
else
time->tm_wday=wd;
if (reader.reached_end)
err|=ios_base::eofbit;
return in;
}
template <class charT, class InputIterator >
_TYPENAME time_get<charT,InputIterator>::iter_type
time_get<charT,InputIterator>::do_get_monthname (InputIterator in,
InputIterator end, ios_base& io, ios_base::iostate& err, tm* time) const
{
__RWSTD::time_reader<charT,InputIterator> reader(in,end,io,*__timp);
int mo=reader.get_keyword(reader.get_month_map(reader.__timp));
err=ios_base::goodbit;
if (mo<0)
err=ios_base::failbit;
else
time->tm_mon=mo;
if (reader.reached_end)
err|=ios_base::eofbit;
return in;
}
template <class charT, class InputIterator >
_TYPENAME time_get<charT,InputIterator>::iter_type
time_get<charT,InputIterator>::do_get_year (InputIterator in,
InputIterator end, ios_base& io, ios_base::iostate& err, tm* time) const
{
__RWSTD::time_reader<charT,InputIterator> reader(in,end,io,*__timp);
int yr=reader.to_ulong(reader.get_int_digits());
err=ios_base::goodbit;
// 2-digit year numbers are accepted, but are not treated specially, and so
// end up in the 1st century C.E.
if (reader.error)
err=ios_base::failbit;
else
time->tm_year=yr-1900;
if (reader.reached_end)
err|=ios_base::eofbit;
return in;
}
// -----------------------------------------------------
// Facet time_put<charT,InputIterator> member templates.
// -----------------------------------------------------
template <class charT, class OutputIterator>
locale::id time_put<charT,OutputIterator>::id;
template <class charT, class OutputIterator>
time_put<charT,OutputIterator>::~time_put() { }
template <class charT, class OutputIterator>
OutputIterator time_put<charT,OutputIterator>::put
(OutputIterator out, ios_base &io, charT fill, const tm *time,
const charT* pattern, const charT* patt_end) const
{
size_t patt_len=patt_end-pattern;
char scratch[40];
char *narrow_patt=(patt_len<=sizeof scratch)? scratch : new char[patt_len];
#ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
use_facet<ctype<charT> >(io.getloc()).narrow(pattern,patt_end,' ',narrow_patt);
#else
use_facet(io.getloc(),(ctype<charT>*)0).narrow(pattern,patt_end,' ',narrow_patt);
#endif
char *np=narrow_patt;
for (const charT* wp=pattern; wp<patt_end; wp++,np++)
if (*np!='%')
*out++=*wp;
else if (++wp<patt_end)
switch (*++np) {
case 'O':
// POSIX-style modifier
if (++wp<patt_end)
out=do_put(out,io,fill,time,*++np,'O');
break;
case '%':
// Literal percent sign
*out++=*wp;
break;
default:
// Treat everything else as a time format specifier.
out=do_put(out,io,fill,time,*np,' ');
}
if (narrow_patt!=scratch)
delete[] narrow_patt;
return out;
}
template <class charT, class OutputIterator>
OutputIterator time_put<charT,OutputIterator>::do_put
(OutputIterator out, ios_base &io, charT fill, const tm *time,
char format, char modifier) const
{
static const char do_as_pattern[]="xXcDrT";
const char *p=strchr(do_as_pattern,format);
if (p) {
// Catch formats implemented as calls to the pattern-based method before
// going to the expense of constructing a digit_writer.
unsigned i=p-do_as_pattern;
#ifndef _RWSTD_NO_NAMESPACE
const _TYPENAME __RWSTD::timepunct<charT>::string_type& s =
__RWSTD::keyword_cracker<charT>::get_patt_string(*__timp,i);
#else
const _TYPENAME timepunct<charT>::string_type& s =
keyword_cracker<charT>::get_patt_string(*__timp,i);
#endif
return put(out,io,fill,time,s.c_str(),s.c_str()+s.length());
}
__RWSTD::digit_writer<charT,OutputIterator> writer(out,io);
writer.width=0;
if (modifier=='O') {
// Uppercase letter O (not zero) -- requests ordinal string if defined.
int n,m;
switch (format) {
case 'C':
// Exclusive Rogue Wave extension: Lets you announce,
// "Welcome to the %OC century!" (See note on unmodified 'C' below.)
n=(time->tm_year+1999)/100;
break;
case 'd':
case 'e':
n=time->tm_mday;
break;
case 'H':
n=time->tm_hour+1;
break;
case 'I':
n=time->tm_hour+1;
if (n>12)
n-=12;
break;
case 'm':
n=time->tm_mon+1;
break;
case 'M':
n=time->tm_min+1;
break;
case 'S':
n=time->tm_sec+1;
break;
case 'u':
n=time->tm_wday;
if (n==0) n=7;
break;
case 'w':
n=time->tm_wday;
break;
case 'U':
// Week number of year (assuming weeks start on Sunday).
// set m to wday of first day of year
m = (time->tm_wday)-((time->tm_yday)%7);
// Correct m to account for "days before first Sunday"
// and "Sunday first day of year" conditions
if ( m <= 0 )
m += 7;
if ( m == 7 )
// Sunday is first day of year
n = ((time->tm_yday)/7)+1;
else
// if not, shift Sunday to first day of week 1
n = ((time->tm_yday)+m)/7;
break;
case 'W':
// Week number of year (assuming weeks start on Monday).
// set m to wday of first day of year
m = (time->tm_wday)-((time->tm_yday)%7);
// Correct m to account for "days before first Monday"
// and "Monday first day of year" conditions
if ( m <= 0 )
m += 7;
if ( m == 1 )
// Monday is first day of year
n = ((time->tm_yday)/7)+1;
else
// if not, shift Monday to first day of week 1
n = (((time->tm_yday)+(m-1))/7);
break;
case 'y':
n=((time->tm_year+1900)%100)+1;
break;
default:
n=999; // Cause error output.
}
writer.put_keyword(writer.get_ord_string(*__timp,n),fill);
} else {
bool abbrev=false;
#ifndef _RWSTD_NO_NAMESPACE
const _TYPENAME __RWSTD::timepunct<charT>::string_type *s=NULL;
_TYPENAME __RWSTD::timepunct<charT>::string_type tzs;
#else
const _TYPENAME timepunct<charT>::string_type *s=NULL;
_TYPENAME timepunct<charT>::string_type tzs;
#endif
int n,m;
writer.radix=10;
writer.separable=false;
switch (format) {
case 'a':
abbrev=true;
case 'A':
// Week day name or abbreviation.
s=&writer.get_day_string(*__timp,time->tm_wday,abbrev);
break;
case 'b':
case 'h':
abbrev=true;
case 'B':
// Month name or abbreviation.
s=&writer.get_month_string(*__timp,time->tm_mon,abbrev);
break;
case 'C':
// Century. Note that we begin the 20th century in 1901, not 1900.
// The draft standard does not seem to address this controversy.
n=(time->tm_year+1999)/100;
break;
case 'd':
// Day of month with leading zero.
writer.iprecision=2;
case 'e':
// Day of month with leading blank.
n=time->tm_mday;
writer.width=2;
break;
case 'H':
// Hour (24-hour clock).
n=time->tm_hour;
writer.iprecision=2;
break;
case 'I':
// Hour (12-hour clock, caller must append am/pm to resolve ambiguity).
n=time->tm_hour;
if (n==0)
n=12;
else if (n>12)
n-=12;
writer.iprecision=2;
break;
case 'j':
// 3-digit day of year.
n=time->tm_yday+1;
writer.iprecision=3;
break;
case 'm':
// Month number.
n=time->tm_mon+1;
writer.iprecision=2;
break;
case 'M':
// Minutes.
n=time->tm_min;
writer.iprecision=2;
break;
case 'n':
// Newline character.
*out++=writer.ctyp.widen('\n');
break;
case 'p':
// ante/post meridian string.
s=&writer.get_ampm_string(*__timp,time->tm_hour>=12);
break;
case 'S':
// Seconds.
n=time->tm_sec;
writer.iprecision=2;
break;
case 't':
// Tab character.
*out++=writer.ctyp.widen('\t');
break;
case 'u':
// Weekday (1-7, 1==Monday)
n=time->tm_wday;
if (n==0)
n=7;
break;
case 'U':
// Week number of year (assuming weeks start on Sunday).
// set m to wday of first day of year
m = (time->tm_wday)-((time->tm_yday)%7);
// Correct m to account for "days before first Sunday"
// and "Sunday first day of year" conditions
if ( m <= 0 )
m += 7;
if ( m == 7 )
// Sunday is first day of year
n = ((time->tm_yday)/7)+1;
else
// if not, shift Sunday to first day of week 1
n = ((time->tm_yday)+m)/7;
writer.iprecision=2;
break;
case 'w':
// Weekday (0-6, 0==Sunday).
n=time->tm_wday;
break;
case 'W':
// Week number of year (assuming weeks start on Monday).
// set m to wday of first day of year
m = (time->tm_wday)-((time->tm_yday)%7);
// Correct m to account for "days before first Monday"
// and "Monday first day of year" conditions
if ( m <= 0 )
m += 7;
if ( m == 1 )
// Monday is first day of year
n = ((time->tm_yday)/7)+1;
else
// if not, shift Monday to first day of week 1
n = (((time->tm_yday)+(m-1))/7);
writer.iprecision=2;
break;
case 'y':
// Year without century.
n=(time->tm_year+1900)%100;
writer.iprecision=2;
break;
case 'Y':
// Year with century.
n=time->tm_year+1900;
break;
case 'Z':
// Time zone name (This is really standard, isn't it?)
#ifdef _RWSTD_STRUCT_TM_TZ
tzs = __RWSTD::timepunct<charT>::string_type(
writer.ctyp.widen(time->tm_zone));
s = &tzs;
break;
#else
# ifndef _RWSTD_NO_GLOBAL_TZ
# ifndef _RWSTD_STRICT_ANSI
# ifdef _RWSTD_NO_LEADING_UNDERSCORE
tzs = __RWSTD::timepunct<charT>::string_type(
writer.ctyp.widen(tzname[time->tm_isdst ? 1 : 0]));
#else
tzs = __RWSTD::timepunct<charT>::string_type(
writer.ctyp.widen(_tzname[time->tm_isdst ? 1 : 0]));
# endif
# else
charT* __temp;
__temp = 0;
# ifdef _RWSTD_NO_LEADING_UNDERSCORE
writer.ctyp.widen(tzname[time->tm_isdst ? 1 : 0], tzname[time->tm_isdst ? 1 : 0] + strlen(tzname[time->tm_isdst ? 1 : 0]), __temp);
# else
writer.ctyp.widen(_tzname[time->tm_isdst ? 1 : 0], _tzname[time->tm_isdst ? 1 : 0] + strlen(_tzname[time->tm_isdst ? 1 : 0]), __temp);
# endif
tzs = __temp;
# endif
s = &tzs;
break;
# endif // _RWSTD_NO_GLOBAL_TZ
#endif // _RWSTD_STRUCT_TM_TZ
default:
// Everything else is an error.
s=&writer.get_day_string(*__timp,99,false);
}
if (s)
writer.put_keyword(*s,fill);
else {
writer.digitize((unsigned long) n);
writer.put_digits(fill);
}
}
return out;
}
// --------------------------------------------------------------------
// Time input by-name member templates: time_get<charT,InputIterator>
// --------------------------------------------------------------------
template <class charT, class InputIterator >
time_get_byname<charT, InputIterator>::time_get_byname
(const char* name, size_t refs): time_get<charT,InputIterator>(refs)
{
this->__name = name;
}
template <class charT, class InputIterator>
time_get_byname<charT, InputIterator>::~time_get_byname()
{ }
// --------------------------------------------------------------------
// Time output by-name member templates: time_put<charT,InputIterator>
// --------------------------------------------------------------------
template <class charT, class OutputIterator>
time_put_byname<charT,OutputIterator>::time_put_byname
(const char* name, size_t refs): time_put<charT,OutputIterator>(refs)
{
this->__name = name;
}
template <class charT, class OutputIterator>
time_put_byname<charT,OutputIterator>::~time_put_byname()
{ }
#ifndef _RWSTD_NO_NAMESPACE
}
#endif
#pragma option pop
#endif /* __TIME_CC */