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/numbrw.cc

725 lines
19 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef __NUMBRW_CC
#define __NUMBRW_CC
#pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
/****************************************************************************
*
* rw/numbrw.cc - Internal classes for numeric formatting and parsing.
*
***************************************************************************
*
* 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 Restricted Rights at 48 CFR 52.227-19,
* as applicable. Manufacturer is Rogue Wave Software, Inc., 5500
* Flatiron Parkway, Boulder, Colorado 80301 USA.
*
***************************************************************************/
#ifndef __STD_RW_NUMBRW_CC__
#define __STD_RW_NUMBRW_CC__
#ifndef _RWSTD_NO_NEW_HEADER
#include <clocale>
#else
#include <locale.h>
#endif
#ifndef _RWSTD_NO_NAMESPACE
namespace __rwstd {
#endif
#if !defined (_RWSTD_NO_NEW_HEADER) && !defined (_RWSTD_NO_NAMESPACE)
using std::tm;
using std::setlocale;
using std::strftime;
using std::mktime;
using std::strlen;
#endif
// ------------------------------------------------
// Template timepunct_data<charT> member templates.
// ------------------------------------------------
template <class charT>
timepunct_data<charT>::timepunct_data
(const timepunct_loc<charT> &init)
{
int i;
for (i=0; i<7; i++) {
dn_[i][0]=init.get_day(i,false);
dn_[i][1]=init.get_day(i,true);
}
for (i=0; i<12; i++) {
mn_[i][0]=init.get_month(i,false);
mn_[i][1]=init.get_month(i,true);
}
ampm_[0]=init.get_ampm(false);
ampm_[1]=init.get_ampm(true);
bad_=init.get_bad();
for (i=0; i<100; i++)
ord_[i]=init.get_ord(i);
for (i=0; i<sizeof pat_/sizeof pat_[0]; i++)
pat_[i]=init.get_pattern(i);
}
// struct for storing formatting information in map
struct __fmt {
__fmt () {}
__fmt (int p, int l, char f) : position(p), length(l), fmtChar(f) {}
int position;
int length;
char fmtChar;
bool operator < (const __fmt& f) {
return position < f.position;
}
};
// initialize data member pat_ which holds formatting strings
template <class charT>
void timepunct_data<charT>::__initpat (const locale* loc)
{
const _RW_STD::string timeFmtChars("YyjSMIHmBbAapdZUWw");
tm tmb;
char buf[256];
__fmt fmtArray[20];
// set up tmp
tmb.tm_sec = 56;
tmb.tm_min = 54;
tmb.tm_hour = 22;
tmb.tm_mday = 30;
tmb.tm_mon = 10;
tmb.tm_year = 90;
tmb.tm_wday = 5;
tmb.tm_yday = -1;
tmb.tm_isdst = -1;
(void) mktime(&tmb);
const _RW_STD::ctype<charT>& ct =
#ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
_RW_STD::use_facet<_RW_STD::ctype<charT> >(*loc);
#else
_RW_STD::use_facet(*loc, (_RW_STD::ctype<charT>*)0);
#endif
// Set up passed in locale
_RW_STD::string oldlocale = setlocale(LC_ALL, 0);
#ifdef __BORLANDC__
_RW_STD::string::size_type posd = loc->name().find('=')+1;
setlocale(LC_ALL, _RW_STD::string(loc->name(),posd,loc->name().find('\n')-posd).c_str());
#else
setlocale(LC_ALL, loc->name().c_str());
#endif // __BORLANDC__
// for each composite format character create format string
const char do_as_pattern[] = "xXcDrT";
for (unsigned int j = 0; j < strlen(do_as_pattern); j++) {
// create format string to parse
_RW_STD::string timeFmtStr("% ");
timeFmtStr[1] = do_as_pattern[j];
strftime(buf, sizeof(buf), timeFmtStr.c_str(), &tmb);
_RW_STD::string timeFmt(buf);
// starting at the beginning of the formatted string find each component
// and save in an ordered structure
int pos;
int fmtArrayIndex = 0;
for (unsigned int i=0; i < timeFmtChars.length(); i++) {
_RW_STD::string fmtChar("% ");
fmtChar[1] = timeFmtChars[i];
strftime(buf, sizeof(buf), fmtChar.data(), &tmb);
if ((pos = timeFmt.find(buf)) != -1) {
if (strlen(buf) > 0) {
fmtArray[fmtArrayIndex++] = __fmt(pos, strlen(buf), timeFmtChars[i]);
timeFmt.replace(pos, strlen(buf), strlen(buf), ' ');
}
}
}
// sort format items
for (int top = fmtArrayIndex; top > 0; --top) {
int large = 0;
for (int i = 0; i < top; ++i) {
if (fmtArray[i] < fmtArray[large])
large = i;
}
__fmt temp = fmtArray[large];
fmtArray[large] = fmtArray[top-1];
fmtArray[top-1] = temp;
}
// put format characters into formatting string
for (__fmt *p = fmtArray; p < fmtArray + fmtArrayIndex; ++p) {
timeFmt.replace((*p).position, (*p).length,
(_RW_STD::string("%").append(1,(*p).fmtChar)));
}
// convert to string_type and insert in array pat_
string_type cnvt;
for (unsigned int k = 0; k < timeFmt.length(); k++)
cnvt = _RW_STD::operator + (cnvt, ct.widen(timeFmt[k]));
pat_[j] = cnvt;
}
setlocale(LC_ALL, oldlocale.c_str());
}
template <class charT>
void timepunct_data<charT>::__initfacet (const locale* loc) {
int i;
for (i=0; i<7; i++) {
dn_defs_[i][0].s=dn_[i][0].c_str();
dn_defs_[i][0].v=i;
dn_defs_[i][1].s=dn_[i][1].c_str();
dn_defs_[i][1].v=i;
}
for (i=0; i<12; i++) {
mn_defs_[i][0].s=mn_[i][0].c_str();
mn_defs_[i][0].v=i;
mn_defs_[i][1].s=mn_[i][1].c_str();
mn_defs_[i][1].v=i;
}
ampm_defs_[0].s=ampm_[0].c_str();
ampm_defs_[0].v= 0;
ampm_defs_[1].s=ampm_[1].c_str();
ampm_defs_[1].v= 1;
dn_map_.num_defs_=7*2;
dn_map_.defs_=&(dn_defs_[0][0]);
mn_map_.num_defs_=12*2;
mn_map_.defs_=&(mn_defs_[0][0]);
ampm_map_.num_defs_=2;
ampm_map_.defs_=&(ampm_defs_[0]);
__initpat(loc);
}
// -----------------------------------------------
// Facet rwstd::timepunct<charT> member templates.
// -----------------------------------------------
#ifndef _RWSTD_NO_NAMESPACE
} namespace __rwstd { // Leave std, enter __rwstd
#endif
template <class charT>
_RW_STD::locale::id timepunct<charT>::id;
template <class charT>
void timepunct<charT>::__initfacet (const locale* loc) {
int n;
for (n=0; n<7; n++) {
this->dn_[n][false]=do_dayname(n,false);
this->dn_[n][true]=do_dayname(n,true);
}
for (n=0; n<12; n++) {
this->mn_[n][false]=do_monthname(n,false);
this->mn_[n][true]=do_monthname(n,true);
}
for (n=0; n<100; n++)
this->ord_[n]=do_ordinal(n);
timepunct_impl<charT>::__initfacet(loc);
}
template <class charT>
_TYPENAME timepunct<charT>::string_type
timepunct<charT>::do_dayname (int day, bool abbr) const {
return this->dn_[day][abbr];
}
template <class charT>
_TYPENAME timepunct<charT>::string_type
timepunct<charT>::do_monthname (int mon, bool abbr) const {
return this->mn_[mon][abbr];
}
template <class charT>
_TYPENAME timepunct<charT>::string_type
timepunct<charT>::do_ordinal (int number) const {
return (number<0 || number>99) ? this->bad_ : this->ord_[number];
}
// -----------------------------------------------
// Template digit_handler_base_1 member templates.
// -----------------------------------------------
template <class charT>
digit_handler_base_1<charT>::
digit_handler_base_1 (const _RW_STD::locale &loc):
#ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
ctyp(_RW_STD::use_facet<_RW_STD::ctype<charT> >(loc)),
dmap(digit_map<charT>::get_digit_map(ctyp)),
punct(_RW_STD::use_facet<_RW_STD::numpunct<charT> >(loc))
#else
ctyp(_RW_STD::use_facet(loc,(_RW_STD::ctype<charT>*)0)),
dmap(digit_map<charT>::get_digit_map(ctyp)),
punct(_RW_STD::use_facet(loc,(_RW_STD::numpunct<charT>*)0))
#endif
{ }
template <class charT>
digit_handler_base_1<charT>::
digit_handler_base_1
(const _RW_STD::locale &loc, const punct_data<charT> &pun):
#ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
ctyp(_RW_STD::use_facet<_RW_STD::ctype<charT> >(loc)),
dmap(digit_map<charT>::get_digit_map(ctyp)),
#else
ctyp(_RW_STD::use_facet(loc,(_RW_STD::ctype<charT>*)0)),
dmap(digit_map<charT>::get_digit_map(ctyp)),
#endif
punct(pun)
{ }
// ----------------------------------------------
// Template digit_reader_base_1 member templates.
// ----------------------------------------------
template <class charT>
digit_reader_base_1<charT>::
digit_reader_base_1 (const _RW_STD::locale &loc):
digit_handler_base_1<charT>(loc)
{ }
template <class charT>
digit_reader_base_1<charT>::
digit_reader_base_1 (const _RW_STD::locale &loc,
const punct_data<charT> &mp):
digit_handler_base_1<charT>(loc,mp)
{ }
// ---------------------------------------
// Template digit_reader member templates.
// ---------------------------------------
template <class charT,class InputIterator>
digit_reader<charT,InputIterator>::
digit_reader(InputIterator& i,InputIterator& e,_RW_STD::ios_base &b):
digit_reader_base_1<charT>(b.getloc()),
io(b), in(i), end(e)
{ }
template <class charT,class InputIterator>
digit_reader<charT,InputIterator>::
digit_reader(InputIterator& i,InputIterator& e,_RW_STD::ios_base &b,
const punct_data<charT> &mp):
digit_reader_base_1<charT>(b.getloc(),mp),
io(b), in(i), end(e)
{ }
template <class charT,class InputIterator>
char* digit_reader<charT,InputIterator>::
get_digit_string (char *dpos)
{
char *eod=dpos;
int i;
while (!at_end() && (i=this->dmap.eval(*in))>=0 && i<this->radix) {
if (eod==this->digits+sizeof this->digits)
this->error|=this->too_many_digits;
else
*eod++=(char) i;
++in;
}
return eod;
}
template <class charT,class InputIterator>
char* digit_reader<charT,InputIterator>::
get_int_digits (void)
{
charT c;
char *eod=this->digits;
const charT* ctype_punct=this->dmap.get_punct();
if (!at_end() && this->is_signed)
// If a sign is present, set negative if it's a minus sign.
do {
if ((c=*in)==ctype_punct[this->minus])
this->negative=true;
else if (c!=ctype_punct[this->plus])
break;
// Eat white space after the sign. Standard seems to mandate this
// regardless of whether ios_base::skipws is set.
do
++in;
while (!at_end() && this->ctyp.is(_RW_STD::ctype_base::space,*in));
this->advanced=true;
} while (0);
if (!this->radix) {
bool noradix = false;
switch (io.flags() & _RW_STD::ios_base::basefield) {
case _RW_STD::ios_base::dec:
this->radix=10;
break;
case _RW_STD::ios_base::hex:
this->radix=16;
break;
case _RW_STD::ios_base::oct:
this->radix=8;
break;
default:
noradix = true;
}
if (noradix || (io.flags() & _RW_STD::ios_base::showbase))
{
// No radix was forced by the ios_base flags, so poke around for a radix
// specifier on the front of the input value.
if (noradix)
this->radix=10;
if (!at_end() && *in==ctype_punct[this->zero]) {
this->radix=8;
++in;
*eod++=0;
this->advanced=true;
if (!at_end() &&
((c=*in)==ctype_punct[this->x] || c==ctype_punct[this->X]))
{
this->radix=16;
++in;
eod--; // Leading 0 was not a digit after all.
}
}
}
}
grouping=this->get_grouping();
if (!*grouping)
eod=get_digit_string(eod);
else {
gpos=groups;
thousands_sep=this->get_thousands_sep();
eod=get_digit_groups(eod);
if (!this->error && --gpos>groups) {
// Digit grouping is optional, but if present it must be right.
const char *gdef=grouping;
do {
if (*gdef!=*gpos && *gdef!=CHAR_MAX)
break;
else
if (gdef[1])
gdef++;
} while (--gpos>groups);
if (gpos>groups || *gpos>*gdef)
this->error|=this->bad_grouping;
}
}
if (eod>this->digits)
this->advanced=true;
return eod;
}
template <class charT,class InputIterator>
char* digit_reader<charT,InputIterator>::
get_float_digits (void)
{
charT c;
this->radix=10;
char *eod=get_int_digits();
const charT *ctyp_punct=this->dmap.get_punct();
this->frac_beg=eod;
if (!this->error && !at_end() && *in==this->get_decimal_point()) {
in++;
eod=get_digit_string(eod);
}
if (eod==this->digits)
this->error|=this->no_digits;
this->exp_beg=eod;
this->exp_negative=false;
if (!this->error && !at_end() &&
((c=*in)==ctyp_punct[this->e] || c==ctyp_punct[this->E]))
{
in++;
if (at_end())
this->error|=this->bad_exponent;
else {
if ((c=*in)==ctyp_punct[this->plus])
in++;
else if (c==ctyp_punct[this->minus]) {
this->exp_negative=true;
in++;
}
int save_radix=this->radix;
this->radix=10;
eod=get_digit_string(eod);
this->radix=save_radix;
if (eod==this->exp_beg)
this->error|=this->bad_exponent;
}
}
return eod;
}
template <class charT,class InputIterator>
char *digit_reader<charT,InputIterator>::
get_pointer_digits (void)
{
this->radix=16;
char *eod=get_int_digits();
return eod;
}
template <class charT,class InputIterator>
char* digit_reader<charT,InputIterator>::
get_digit_groups (char *dpos)
{
char *eod=get_digit_string(dpos);
if (gpos==groups+sizeof groups)
this->error|=this->too_many_groups;
else {
int i=eod-dpos;
if (i >= CHAR_MAX)
this->error|=this->group_too_long;
else {
*gpos++=i;
if (i!=0 && !at_end() && *in==thousands_sep) {
++in;
eod=get_digit_groups(eod);
}
}
}
return eod;
}
template <class charT,class InputIterator>
int digit_reader<charT,InputIterator>::
get_keyword (const keyword_map<charT> &mapit)
{
const keyword_def<charT> *canp=mapit.defs_;
const keyword_def<charT> *endp=mapit.defs_+mapit.num_defs_;
keyword_def<charT> cans[40],*ansp=cans;
charT c;
const charT *p;
int result;
while (1) {
if (at_end()) {
for ( ; canp<endp; canp++)
if (!*canp->s)
return canp->v;
return -1;
}
c=*in;
result=-1;
for ( ; canp<endp; canp++) {
p=canp->s;
if (c==*p) {
ansp->s=++p;
ansp->v=canp->v;
ansp++;
} else if (*p==0)
result=ansp->v; // abbreviation
}
if (ansp==cans)
return result;
in++;
if (ansp==cans+1) {
for (p=cans[0].s; *p; p++) {
if (at_end() || *in!=*p)
return -1;
in++;
}
return cans[0].v;
}
endp=ansp;
ansp=cans;
canp=cans;
}
}
// ----------------------------------------------
// Template digit_writer_base_1 member templates.
// ----------------------------------------------
template <class charT>
digit_writer_base_1<charT>::
digit_writer_base_1(_RW_STD::ios_base &b,const _RW_STD::locale &loc)
: digit_writer_base(b), digit_handler_base_1<charT>(loc)
{ }
template <class charT>
digit_writer_base_1<charT>::
digit_writer_base_1(_RW_STD::ios_base &b,const punct_data<charT> &mp)
: digit_writer_base(b),digit_handler_base_1<charT>(b.getloc(),mp)
{
flags&=~(_RW_STD::ios_base::floatfield | _RW_STD::ios_base::showpos);
flags|=_RW_STD::ios_base::fixed;
radix=10;
precision=0;
}
// ---------------------------------------
// Template digit_writer member templates.
// ---------------------------------------
template <class charT,class OutputIterator>
digit_writer<charT,OutputIterator>::
digit_writer (OutputIterator &o, _RW_STD::ios_base &b)
: digit_writer_base_1<charT>(b,b.getloc()), out(o)
{ }
template <class charT,class OutputIterator>
digit_writer<charT,OutputIterator>::
digit_writer (OutputIterator &o, _RW_STD::ios_base &b,
const punct_data<charT> &mp)
: digit_writer_base_1<charT>(b,mp), out(o)
{ }
template <class charT, class OutputIterator>
void digit_writer<charT,OutputIterator>::put_digits (charT fill)
{
char *p=this->start;
bool has_sign=false,has_point=false;
if (p<this->end && (*p==' ' || *p=='-' || *p=='+'))
has_sign=true;
// Locate the end of the integral digits.
char *dec;
if (!this->fractional)
dec=this->end;
else {
dec=this->start;
if (has_sign) dec++;
for ( ; dec<this->end; dec++)
if (*dec<'0' || *dec>'9') {
if (*dec!='e' && *dec!='E')
has_point=true;
break;
}
}
// Calculate the number and pattern of separators needed if any.
charT separator;
int unGrouped=dec-this->start;
if (has_sign)
unGrouped--;
if (this->radix==10 && this->separable) {
unGrouped=calc_groups(unGrouped,this->get_grouping());
if (this->num_groups)
separator=this->get_thousands_sep();
}
// Compute the number of fill charT-s needed, and where they should be put.
int leftFill=0,internalFill=0,rightFill=0;
if (this->width>0) {
int w=this->width - (this->end - this->start) - this->num_groups;
this->width=0;
if (w>0) {
switch (this->adjust) {
case digit_writer_base::left:
rightFill=w;
break;
case digit_writer_base::internal:
internalFill=w;
break;
default:
leftFill=w;
}
}
}
// Widen the sign + digits + exponent string.
//charT wide_digits[sizeof digit_writer_base::buffer];
charT wide_digits[400];
this->ctyp.widen(this->start,this->end,wide_digits);
// Write the widened string with fill and decorations to output.
charT *digit_pos=wide_digits;
while (leftFill--)
*out++=fill;
if (has_sign)
*out++=*digit_pos++; // the widened sign
while (internalFill--)
*out++=fill;
while (unGrouped--)
*out++=*digit_pos++;
while (this->num_groups--) {
*out++=separator;
while (this->group[0]--)
*out++=*digit_pos++;
this->group++;
}
if (has_point) {
*out++=this->get_decimal_point();
digit_pos++;
}
unGrouped=this->end-dec;
if (has_point)
unGrouped--;
while (unGrouped-->0)
*out++=*digit_pos++;
while (rightFill--)
*out++=fill;
}
template <class charT, class OutputIterator>
void digit_writer<charT,OutputIterator>::
put_keyword (const string_type &k, charT fill)
{
int leftFill=0,rightFill=0;
int n=this->width-k.length();
if (n>0) {
switch (this->adjust) {
case digit_writer_base::left:
rightFill=n;
break;
case digit_writer_base::internal:
default:
leftFill=n;
}
if (leftFill)
do *out++=fill;
while (--leftFill);
}
const charT *p=k.c_str(),*end=p+k.length();
while (p<end)
*out++=*p++;
if (rightFill)
do *out++=fill;
while (--rightFill);
}
#ifndef _RWSTD_NO_NAMESPACE
} // namespace __rwstd
#endif
#endif // __STD_RW_NUMBRW_CC__
#pragma option pop
#endif /* __NUMBRW_CC */