1 /*
2 * Part of WCM Commander
3 * https://github.com/corporateshark/WCMCommander
4 * wcm@linderdaum.com
5 */
6
7 #include "strconfig.h"
8 #include "swl.h"
9 #include <algorithm>
10
11 using namespace wal;
12
13
StrConfig()14 StrConfig::StrConfig() {}
15
Clear()16 void StrConfig::Clear() { varHash.clear(); }
17
SS(const char * s)18 inline const char* SS( const char* s ) { while ( IsSpace( *s ) ) { s++; } return s; }
SNotS(const char * s)19 inline const char* SNotS( const char* s ) { while ( *s && !IsSpace( *s ) ) { s++; } return s; }
SNotC(const char * s,int c)20 inline const char* SNotC( const char* s, int c ) { while ( *s && *s != c ) { s++; } return s; }
21
Upper(int c)22 inline int Upper( int c )
23 {
24 if ( c >= 'a' && c <= 'z' ) { return c - 'a' + 'A'; }
25
26 return c;
27 }
28
UpStr(std::string & s)29 inline void UpStr(std::string& s)
30 {
31 std::transform( s.begin(), s.end(), s.begin(), ::toupper );
32 }
33
UpStr(char * s)34 inline void UpStr( char* s )
35 {
36 for ( ; *s; s++ ) { *s = Upper( *s ); }
37 }
38
39
40 //синтаксис var = [val]; ..
41 //var - [_0-9a-zA-Z]+
42 //val - "..." или '..' или слово без пробелов и ; , \ -экран
43
Load(const char * s)44 bool StrConfig::Load( const char* s )
45 {
46 varHash.clear();
47
48 while ( *s )
49 {
50 s = SS( s );
51
52 if ( !*s ) { break; }
53
54 if ( *s == ';' )
55 {
56 s++;
57 continue;
58 }
59
60 ccollect<char, 0x100> var;
61
62 while ( *s == '_' || IsAlpha( *s ) || IsDigit( *s ) )
63 {
64 var.append( Upper( *s ) );
65 s++;
66 }
67
68 if ( !var.count() ) { return false; }
69
70 var.append( 0 );
71 s = SS( s );
72
73 if ( *s != '=' ) { return false; }
74
75 s++;
76 s = SS( s );
77
78 int c1 = 0;
79
80 if ( *s == '\'' || *s == '"' ) { c1 = *s; s++; }
81
82 std::string value;
83
84 while ( *s )
85 {
86 if ( c1 && *s == c1 ) { s++; break; }
87
88 if ( *s == '\\' )
89 {
90 s++;
91
92 if ( !*s ) { break; }
93
94 value.push_back( *s );
95 s++;
96 continue;
97 }
98
99 if ( !c1 && ( IsSpace( *s ) || *s == ';' ) ) { break; }
100
101 value.push_back( *s );
102 s++;
103 }
104
105 //if (c1 && *s !=c1) return false;
106 value.push_back( 0 );
107 varHash[ var.ptr() ] = value;
108 }
109
110 return true;
111 }
112
GetConfig()113 std::vector<char> StrConfig::GetConfig()
114 {
115 std::vector<char> res;
116 std::vector<const char*> k = varHash.keys();
117 int count = varHash.count();
118
119 for ( int i = 0; i < count; i++ )
120 {
121 const char* s = k[i];
122
123 for ( ; *s; s++ ) { res.push_back( *s ); }
124
125 res.push_back( '=' );
126 s = varHash[k[i]].data();
127
128 if ( s )
129 {
130 bool simple = true;
131
132 for ( const char* t = s; *t; t++ )
133 if ( *t == ';' || *t == '\\' || *t == '\'' || *t == '"' || IsSpace( *t ) )
134 {
135 simple = false;
136 break;
137 };
138
139 if ( simple )
140 {
141 for ( ; *s; s++ ) { res.push_back( *s ); }
142 }
143 else
144 {
145 res.push_back( '"' );
146
147 for ( ; *s; s++ )
148 {
149 if ( *s == '\'' || *s == '"' || *s == '\\' )
150 {
151 res.push_back( '\\' );
152 }
153
154 res.push_back( *s );
155 }
156
157 res.push_back( '"' );
158 }
159 }
160
161 res.push_back( ';' );
162 }
163
164 res.push_back( 0 );
165 return res;
166 }
167
Set(const char * name,const char * value)168 void StrConfig::Set( const char* name, const char* value )
169 {
170 std::string s( name );
171 UpStr( s );
172 varHash[s.data()] = std::string( value );
173 }
174
Set(const char * name,int value)175 void StrConfig::Set( const char* name, int value )
176 {
177 char buf[64];
178 Lsnprintf( buf, sizeof( buf ) - 1, "%i", value );
179 Set( name, buf );
180 }
181
182
GetStrVal(const char * name)183 const char* StrConfig::GetStrVal( const char* name )
184 {
185 std::string s( name );
186 UpStr( s );
187 std::string* p = varHash.exist( s.data() );
188
189 if ( p && p[0].data() )
190 {
191 return p[0].data();
192 }
193
194 return 0;
195 }
196
GetIntVal(const char * name)197 int StrConfig::GetIntVal( const char* name )
198 {
199 std::string s( name );
200 UpStr( s );
201 std::string* p = varHash.exist( s.data() );
202
203 if ( p && p[0].data() )
204 {
205 return atoi( p[0].data() );
206 }
207
208 return -1;
209 }
210
~StrConfig()211 StrConfig::~StrConfig() {}
212