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