@@ -796,69 +796,147 @@ void IGFD::FilterManager::ParseFilters(const char* vFilters) {
796796 puDLGFilters.clear (); // directory mode
797797
798798 if (!puDLGFilters.empty ()) {
799- // ".*,.cpp,.h,.hpp" => simple filters
800- // "Source files{.cpp,.h,.hpp},Image files{.png,.gif,.jpg,.jpeg},.md" => collection filters
801- // "([.][0-9]{3}),.cpp,.h,.hpp" => simple filters with regex
802- // "frames files{([.][0-9]{3}),.frames}" => collection filters with regex
803-
804- bool currentFilterFound = false ;
805-
806- size_t nan = std::string::npos;
807- size_t p = 0 , lp = 0 ;
808- while ((p = puDLGFilters.find_first_of (" {," , p)) != nan) {
809- FilterInfos infos;
810-
811- if (puDLGFilters[p] == ' {' ) // {
812- {
813- infos.filter = puDLGFilters.substr (lp, p - lp);
814- infos.filter_optimized = Utils::LowerCaseString (infos.filter );
815- p++;
816- lp = puDLGFilters.find (' }' , p);
817- if (lp != nan) {
818- std::string fs = puDLGFilters.substr (p, lp - p);
819- auto arr = IGFD::Utils::SplitStringToVector (fs, ' ,' , false );
820- for (auto a : arr) {
821- infos.collectionfilters .emplace (a);
822- infos.collectionfilters_optimized .emplace (Utils::LowerCaseString (a));
823-
824- // a regex
825- if (a.find (' (' ) != std::string::npos) {
826- if (a.find (' )' ) != std::string::npos) { infos.collectionfilters_regex .push_back (std::regex (a)); }
799+ /* Rules
800+ 0) a filter must have 2 chars mini and the first must be a .
801+ 1) a regex must be in (( and ))
802+ 2) a , will separate filters except if between a ( and )
803+ 3) name{filter1, filter2} is a spetial form for collection filters
804+ 3.1) the name can be composed of what you want except { and }
805+ 3.2) the filter can be a regex
806+ 4) the filters cannot integrate these chars '(' ')' '{' '}' ' ' except for a regex with respect to rule 1)
807+ 5) the filters cannot integrate a ','
808+ */
809+
810+ bool collection_started = false ;
811+ bool regex_started = false ;
812+ bool parenthesis_started = false ;
813+
814+ std::string word;
815+ std::string filter_name;
816+
817+ char last_split_char = 0 ;
818+ for (char c : puDLGFilters) {
819+ if (c == ' {' ) {
820+ if (regex_started) {
821+ word += c;
822+ } else {
823+ collection_started = true ;
824+ prParsedFilters.emplace_back ();
825+ prParsedFilters.back ().filter = filter_name;
826+ filter_name.clear ();
827+ word.clear ();
828+ }
829+ last_split_char = c;
830+ } else if (c == ' }' ) {
831+ if (regex_started) {
832+ word += c;
833+ } else {
834+ if (collection_started) {
835+ if (word.size () > 1U && word[0 ] == ' .' ) {
836+ if (prParsedFilters.empty ()) { prParsedFilters.emplace_back (); }
837+ prParsedFilters.back ().collectionfilters .emplace (word);
827838 }
839+ word.clear ();
840+ filter_name.clear ();
841+ collection_started = false ;
828842 }
829843 }
830- p = lp + 1 ;
831- } else // ,
832- {
833- infos.filter = puDLGFilters.substr (lp, p - lp);
834- infos.filter_optimized = Utils::LowerCaseString (infos.filter );
835-
836- // a regex
837- if (infos.filter .find (' (' ) != std::string::npos) {
838- if (infos.filter .find (' )' ) != std::string::npos) { infos.filter_regex = std::regex (infos.filter ); }
844+ last_split_char = c;
845+ } else if (c == ' (' ) {
846+ word += c;
847+ if (last_split_char == ' (' ) { regex_started = true ; }
848+ parenthesis_started = true ;
849+ if (!collection_started) { filter_name += c; }
850+ last_split_char = c;
851+ } else if (c == ' )' ) {
852+ word += c;
853+ if (last_split_char == ' )' ) {
854+ if (regex_started) {
855+ try {
856+ auto rx = std::regex (word); // cant thrwo an exception so if first, prevent emplace if failed
857+ if (collection_started) {
858+ prParsedFilters.back ().collectionfilters .emplace (word);
859+ prParsedFilters.back ().collectionfilters_regex .emplace_back (rx);
860+ } else {
861+ prParsedFilters.emplace_back ();
862+ prParsedFilters.back ().filter = word;
863+ prParsedFilters.back ().filter_regex = rx;
864+ }
865+ } catch (std::exception&) {}
866+ word.clear ();
867+ filter_name.clear ();
868+ regex_started = false ;
869+ } else {
870+ if (!collection_started) {
871+ if (!prParsedFilters.empty ()) {
872+ prParsedFilters.erase (prParsedFilters.begin () + prParsedFilters.size () - 1U );
873+ } else {
874+ prParsedFilters.clear ();
875+ }
876+ }
877+ word.clear ();
878+ filter_name.clear ();
879+ }
839880 }
840-
841- p++;
881+ parenthesis_started = false ;
882+ if (!collection_started) { filter_name += c; }
883+ last_split_char = c;
884+ } else if (c == ' .' ) {
885+ word += c;
886+ if (!collection_started) { filter_name += c; }
887+ last_split_char = c;
888+ } else if (c == ' ,' ) {
889+ if (regex_started) {
890+ regex_started = false ;
891+ word.clear ();
892+ filter_name.clear ();
893+ } else {
894+ if (collection_started) {
895+ if (word.size () > 1U && word[0 ] == ' .' ) {
896+ prParsedFilters.back ().collectionfilters .emplace (word);
897+ word.clear ();
898+ filter_name.clear ();
899+ }
900+ } else {
901+ if (word.size () > 1U && word[0 ] == ' .' ) {
902+ prParsedFilters.emplace_back ();
903+ prParsedFilters.back ().filter = word;
904+ word.clear ();
905+ filter_name.clear ();
906+ }
907+ if (parenthesis_started) { filter_name += c; }
908+ }
909+ }
910+ } else {
911+ if (c != ' ' ) { word += c; }
912+ if (!collection_started) { filter_name += c; }
842913 }
914+ }
843915
844- if (!currentFilterFound && prSelectedFilter.filter == infos.filter ) {
845- currentFilterFound = true ;
846- prSelectedFilter = infos;
916+ if (collection_started) {
917+ if (!prParsedFilters.empty ()) {
918+ prParsedFilters.erase (prParsedFilters.begin () + prParsedFilters.size () - 1U );
919+ } else {
920+ prParsedFilters.clear ();
847921 }
848-
849- lp = p;
850- if (!infos.empty ()) prParsedFilters.emplace_back (infos);
922+ } else if (word.size () > 1U && word[0 ] == ' .' ) {
923+ prParsedFilters.emplace_back ();
924+ prParsedFilters.back ().filter = word;
925+ word.clear ();
851926 }
852927
853- std::string token = puDLGFilters.substr (lp);
854- if (!token.empty ()) {
855- FilterInfos infos;
856- infos.filter = std::move (token);
857- prParsedFilters.emplace_back (infos);
928+ bool currentFilterFound = false ;
929+
930+ for (const auto & it : prParsedFilters) {
931+ if (it.filter == prSelectedFilter.filter ) {
932+ currentFilterFound = true ;
933+ prSelectedFilter = it;
934+ }
858935 }
859936
860- if (!currentFilterFound)
937+ if (!currentFilterFound) {
861938 if (!prParsedFilters.empty ()) prSelectedFilter = *prParsedFilters.begin ();
939+ }
862940 }
863941}
864942
0 commit comments