ec7a7821bf3d493ca26fcd92458c46d30c3acee6
[libs/core.git] / source / strings / fmt.cpp
1 #include "fmt.h"
2
3 using namespace std;
4
5 namespace Msp {
6
7 void Fmt::parse(const char *s)
8 {
9         const char *f = s;
10         if(*f=='%') ++f;
11
12         for(; *f; ++f)
13         {
14                 if(*f=='#')
15                 {
16                         sbase = true;
17                         spoint = true;
18                 }
19                 else if(*f=='0')
20                         fillc = '0';
21                 else if(*f=='-')
22                         align = LEFT;
23                 else if(*f=='+')
24                         spos = true;
25                 else
26                         break;
27         }
28
29         wd = 0;
30         for(; *f; ++f)
31         {
32                 if(*f>='0' && *f<='9')
33                         wd = wd*10+(*f-'0');
34                 else
35                         break;
36         }
37
38         if(*f=='.')
39         {
40                 ++f;
41                 prec = 0;
42                 for(; *f; ++f)
43                 {
44                         if(*f>='0' && *f<='9')
45                                 prec = prec*10+(*f-'0');
46                         else
47                                 break;
48                 }
49         }
50
51         type = NUM;
52         if(*f=='d' || *f=='u')
53                 base = DEC;
54         else if(*f=='x' || *f=='X')
55                 base = HEX;
56         else if(*f=='o')
57                 base = OCT;
58         else if(*f=='b')
59                 base = BIN;
60         else if(*f=='e' || *f=='E')
61                 fmode = SCI;
62         else if(*f=='f' || *f=='F')
63                 fmode = FIXED;
64         else if(*f=='g' || *f=='G')
65                 fmode = AUTOFLT;
66         else if(*f=='p' || *f=='P')
67         {
68                 base = HEX;
69                 sbase = true;
70         }
71         else if(*f=='c')
72                 type = CHAR;
73         else if(*f=='s')
74                 type = STR;
75         else if(*f=='i')
76                 base = AUTOBASE;
77         else
78                 throw format_error(s);
79
80         if(*f=='E' || *f=='F' || *f=='G' || *f=='X' || *f=='P')
81                 ucase = true;
82
83         ++f;
84
85         if(*f)
86                 throw format_error(s);
87 }
88
89 Fmt &Fmt::reset()
90 {
91         wd = 0;
92         prec = 6;
93         spos = false;
94         fillc = ' ';
95         base = DEC;
96         sbase = false;
97         fmode = AUTOFLT;
98         spoint = false;
99         align = RIGHT;
100         ucase = false;
101         type = STR;
102
103         return *this;
104 }
105
106 void Fmt::apply(ostream &out) const
107 {
108         out.flags(((base==HEX) ? ios_base::hex : (base==OCT) ? ios_base::oct : ios_base::dec)
109                 | ((fmode==SCI) ? ios_base::scientific : (fmode==FIXED) ? ios_base::fixed : ios_base::fmtflags(0))
110                 | (fillc=='0' ? ios_base::internal : (align==LEFT) ? ios_base::left : ios_base::right)
111                 | (sbase ? ios_base::showbase : ios_base::fmtflags(0))
112                 | (spoint ? ios_base::showpoint : ios_base::fmtflags(0))
113                 | (spos ? ios_base::showpos : ios_base::fmtflags(0))
114                 | (ucase ? ios_base::uppercase : ios_base::fmtflags(0)));
115         out.fill(fillc);
116         out.width(wd);
117         out.precision(prec);
118 }
119
120 } // namespace Msp