1 // 2 // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See 5 // accompanying file LICENSE_1_0.txt or copy at 6 // http://www.boost.org/LICENSE_1_0.txt) 7 // 8 #define BOOST_LOCALE_SOURCE 9 #include <boost/locale/format.hpp> 10 #include <boost/locale/generator.hpp> 11 #include <boost/locale/info.hpp> 12 #include <limits> 13 #include <stdlib.h> 14 15 #include <iostream> 16 17 namespace boost { 18 namespace locale { 19 namespace details { 20 struct format_parser::data { 21 unsigned position; 22 std::streamsize precision; 23 std::ios_base::fmtflags flags; 24 ios_info info; 25 std::locale saved_locale; 26 bool restore_locale; 27 void *cookie; 28 void (*imbuer)(void *,std::locale const &); 29 }; 30 format_parser(std::ios_base & ios,void * cookie,void (* imbuer)(void *,std::locale const &))31 format_parser::format_parser(std::ios_base &ios,void *cookie,void (*imbuer)(void *,std::locale const &)) : 32 ios_(ios), 33 d(new data) 34 { 35 d->position=std::numeric_limits<unsigned>::max(); 36 d->precision=ios.precision(); 37 d->flags = ios.flags(); 38 d->info=ios_info::get(ios); 39 d->saved_locale = ios.getloc(); 40 d->restore_locale=false; 41 d->cookie = cookie; 42 d->imbuer = imbuer; 43 } 44 imbue(std::locale const & l)45 void format_parser::imbue(std::locale const &l) 46 { 47 d->imbuer(d->cookie,l); 48 } 49 ~format_parser()50 format_parser::~format_parser() 51 { 52 } 53 restore()54 void format_parser::restore() 55 { 56 ios_info::get(ios_) = d->info; 57 ios_.width(0); 58 ios_.flags(d->flags); 59 if(d->restore_locale) 60 imbue(d->saved_locale); 61 } 62 get_position()63 unsigned format_parser::get_position() 64 { 65 return d->position; 66 } 67 set_one_flag(std::string const & key,std::string const & value)68 void format_parser::set_one_flag(std::string const &key,std::string const &value) 69 { 70 if(key.empty()) 71 return; 72 unsigned i; 73 for(i=0;i<key.size();i++) { 74 if(key[i] < '0' || '9'< key[i]) 75 break; 76 } 77 if(i==key.size()) { 78 d->position=atoi(key.c_str()) - 1; 79 return; 80 } 81 82 if(key=="num" || key=="number") { 83 as::number(ios_); 84 85 if(value=="hex") 86 ios_.setf(std::ios_base::hex,std::ios_base::basefield); 87 else if(value=="oct") 88 ios_.setf(std::ios_base::oct,std::ios_base::basefield); 89 else if(value=="sci" || value=="scientific") 90 ios_.setf(std::ios_base::scientific,std::ios_base::floatfield); 91 else if(value=="fix" || value=="fixed") 92 ios_.setf(std::ios_base::fixed,std::ios_base::floatfield); 93 } 94 else if(key=="cur" || key=="currency") { 95 as::currency(ios_); 96 if(value=="iso") 97 as::currency_iso(ios_); 98 else if(value=="nat" || value=="national") 99 as::currency_national(ios_); 100 } 101 else if(key=="per" || key=="percent") { 102 as::percent(ios_); 103 } 104 else if(key=="date") { 105 as::date(ios_); 106 if(value=="s" || value=="short") 107 as::date_short(ios_); 108 else if(value=="m" || value=="medium") 109 as::date_medium(ios_); 110 else if(value=="l" || value=="long") 111 as::date_long(ios_); 112 else if(value=="f" || value=="full") 113 as::date_full(ios_); 114 } 115 else if(key=="time") { 116 as::time(ios_); 117 if(value=="s" || value=="short") 118 as::time_short(ios_); 119 else if(value=="m" || value=="medium") 120 as::time_medium(ios_); 121 else if(value=="l" || value=="long") 122 as::time_long(ios_); 123 else if(value=="f" || value=="full") 124 as::time_full(ios_); 125 } 126 else if(key=="dt" || key=="datetime") { 127 as::datetime(ios_); 128 if(value=="s" || value=="short") { 129 as::date_short(ios_); 130 as::time_short(ios_); 131 } 132 else if(value=="m" || value=="medium") { 133 as::date_medium(ios_); 134 as::time_medium(ios_); 135 } 136 else if(value=="l" || value=="long") { 137 as::date_long(ios_); 138 as::time_long(ios_); 139 } 140 else if(value=="f" || value=="full") { 141 as::date_full(ios_); 142 as::time_full(ios_); 143 } 144 } 145 else if(key=="spell" || key=="spellout") { 146 as::spellout(ios_); 147 } 148 else if(key=="ord" || key=="ordinal") { 149 as::ordinal(ios_); 150 } 151 else if(key=="left" || key=="<") 152 ios_.setf(std::ios_base::left,std::ios_base::adjustfield); 153 else if(key=="right" || key==">") 154 ios_.setf(std::ios_base::right,std::ios_base::adjustfield); 155 else if(key=="gmt") 156 as::gmt(ios_); 157 else if(key=="local") 158 as::local_time(ios_); 159 else if(key=="timezone" || key=="tz") 160 ios_info::get(ios_).time_zone(value); 161 else if(key=="w" || key=="width") 162 ios_.width(atoi(value.c_str())); 163 else if(key=="p" || key=="precision") 164 ios_.precision(atoi(value.c_str())); 165 else if(key=="locale") { 166 if(!d->restore_locale) { 167 d->saved_locale=ios_.getloc(); 168 d->restore_locale=true; 169 } 170 171 std::string encoding=std::use_facet<info>(d->saved_locale).encoding(); 172 generator gen; 173 gen.categories(formatting_facet); 174 175 std::locale new_loc; 176 if(value.find('.')==std::string::npos) 177 new_loc = gen(value + "." + encoding); 178 else 179 new_loc = gen(value); 180 181 imbue(new_loc); 182 } 183 184 } 185 } 186 } 187 } 188 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 189