77
88#include " Util/StringUtil.h"
99
10- std::shared_ptr<LuaEditorConfig> LuaEditorConfig::LoadFromFile (const std::string &path) {
11- std::fstream fin (path, std::ios::in);
10+ #ifdef WIN32
11+ #include < Windows.h>
12+ std::wstring utf8ToWideChar (const std::string &utf8Str) {
13+ int wideCharSize = MultiByteToWideChar (CP_UTF8, 0 , utf8Str.c_str (), -1 , NULL , 0 );
14+ std::wstring wideStr (wideCharSize, L' \0 ' );
15+ MultiByteToWideChar (CP_UTF8, 0 , utf8Str.c_str (), -1 , &wideStr[0 ], wideCharSize);
16+ return wideStr;
17+ }
18+ #endif
19+
20+ std::shared_ptr<LuaEditorConfig> LuaEditorConfig::OpenFile (const std::string &path) {
21+ // FIX windows下读取中文路径
22+ #ifdef WIN32
23+ std::fstream fin (utf8ToWideChar (path), std::ios::in | std::ios::binary);
24+ #else
25+ std::fstream fin (path, std::ios::in | std::ios::binary);
26+ #endif
1227 if (fin.is_open ()) {
13- std::stringstream s;
14- s << fin.rdbuf ();
15- auto editorConfig = std::make_shared<LuaEditorConfig>(s.str ());
16- return editorConfig;
28+ fin.seekg (0 , std::ios::end);
29+ auto size = fin.tellg ();
30+ std::string s (size, ' ' );
31+ fin.seekg (0 );
32+ fin.read (s.data (), size);
33+ auto config = std::make_shared<LuaEditorConfig>();
34+ config->Parse (s);
35+ return config;
1736 }
1837
1938 return nullptr ;
2039}
2140
22- LuaEditorConfig::LuaEditorConfig (std::string &&source)
23- : _source(source) {
41+ static bool IsWhiteSpaces ( int c) {
42+ return c > 0 && std::isspace (c);
2443}
2544
26- void LuaEditorConfig::Parse () {
27- auto lines = string_util::Split (_source, " \n " );
28-
29- std::regex comment = std::regex (R"( ^\s*(;|#))" );
30- std::regex luaSection = std::regex (R"( ^\s*\[\s*([^\]]+)\s*\]\s*$)" );
31- std::regex valueRegex = std::regex (R"( ^\s*([\w\d_\\.]+)\s*=\s*(.+)$)" );
32- bool sectionFounded = false ;
33-
34- for (auto &lineView: lines) {
35- std::string line (lineView);
36- if (std::regex_search (line, comment)) {
37- continue ;
38- }
39-
40- std::smatch m;
41-
42- if (std::regex_search (line, m, luaSection)) {
43- auto pattern = m.str (1 );
44- sectionFounded = (pattern.find (" lua" ) != std::string::npos) || pattern == " *" ;
45- _sections.emplace_back (pattern);
46- continue ;
47- }
45+ static bool IsEndOfLine (int c){
46+ return c == ' \r ' || c == ' \n ' ;
47+ }
4848
49- if (sectionFounded) {
50- if (std::regex_search (line, m, valueRegex)) {
51- _sections.back ().ConfigMap .insert ({m.str (1 ), std::string (string_util::TrimSpace (m.str (2 )))});
49+ void LuaEditorConfig::Parse (std::string_view text) {
50+ auto reader = TextReader (text);
51+ _sections.emplace_back (" " );
52+ while (!reader.IsEof ()) {
53+ reader.ResetBuffer ();
54+ switch (reader.GetCurrentChar ()) {
55+ // comment
56+ case ' ;' :
57+ case ' #' :
58+ // skip empty line
59+ case ' \r ' :
60+ case ' \n ' : {
61+ reader.NextLine ();
62+ break ;
63+ }
64+ case ' \t ' :
65+ case ' ' : {
66+ reader.EatWhile (IsWhiteSpaces);
67+ break ;
68+ }
69+ case ' [' : {
70+ reader.NextChar ();
71+ reader.EatWhile ([](char ch) { return ch != ' ]' && !IsEndOfLine (ch); });
72+ auto pattern = string_util::TrimSpace (reader.GetSaveText ());
73+ if (pattern.empty () || reader.GetCurrentChar () != ' ]' ) {
74+ reader.NextLine ();
75+ break ;
76+ }
77+ reader.NextLine ();
78+ _sections.emplace_back (pattern);
79+ break ;
80+ }
81+ default : {
82+ reader.EatWhile ([](char ch) { return ch != ' =' && !IsEndOfLine (ch); });
83+ auto key = string_util::TrimSpace (reader.GetSaveText ());
84+ if (key.empty () || reader.GetCurrentChar () != ' =' ) {
85+ reader.NextLine ();
86+ break ;
87+ }
88+
89+ reader.NextChar ();
90+ reader.ResetBuffer ();
91+ reader.EatWhile ([](char ch) { return !IsEndOfLine (ch); });
92+ auto value = string_util::TrimSpace (reader.GetSaveText ());
93+ if (value.empty ()) {
94+ reader.NextLine ();
95+ break ;
96+ }
97+ _sections.back ().ConfigMap .insert ({std::string (key), std::string (value)});
98+ break ;
5299 }
53100 }
54101 }
@@ -60,8 +107,8 @@ LuaStyle &LuaEditorConfig::Generate(std::string_view filePath) {
60107 for (std::size_t i = 0 ; i != _sections.size (); i++) {
61108 auto &pattern = _sections[i].Pattern ;
62109
63- // [*] [*.lua]
64- if (pattern.GetPattern () == " *" || pattern.GetPattern () == " *.lua" ) {
110+ // "" [*] [*.lua]
111+ if (pattern.GetPattern (). empty () || pattern. GetPattern () == " *" || pattern.GetPattern () == " *.lua" ) {
65112 patternSection.push_back (i);
66113 }
67114 // [{test.lua,lib.lua}]
@@ -85,7 +132,9 @@ LuaStyle &LuaEditorConfig::Generate(std::string_view filePath) {
85132 auto &luaStyle = _styleMap.at (patternKey);
86133 for (auto i: patternSection) {
87134 auto &configMap = _sections[i].ConfigMap ;
88- luaStyle.Parse (configMap);
135+ if (!configMap.empty ()) {
136+ luaStyle.Parse (configMap);
137+ }
89138 }
90139
91140 return luaStyle;
0 commit comments