Skip to content

Commit a06b404

Browse files
committed
Add Notepad++ compatible versions in plugin list
Implement: notepad-plus-plus/nppPluginList#416 While PluginAdmin loading nppPluginList.dll, it will check an attribute "npp-compatible-versions" (optional), in order to determinate if plugin is compatible to the current version of Notepad++. If plugin is not compatible, then this plugin will be ignored, therefore it won't be shown on the PluginAdmin's plugin list. Note that it's only about pluginsAdmin's plugin list: it prevent from Notepad++ install/update a plugin non-compatible to current version of Notepad++, but it still allows Notepad++ load this plugin in question, if it's already installed. Here is the attribite "npp-compatible-versions" looks like in plugin list json file: ``` { "name": "npp-pluginList", "version": "1.4.7", "arch": "32", "npp-plugins": [ { "folder-name": "demoPluginA", "display-name": "Demo Plugin A", "version": "1.8.7", "npp-compatible-versions": "[4.2,6.6.6]", "id": "9c566a9083ef66a0ce93a3ce5f55977faea559b5b0993e37a1461b87f4aeb6f0", ... }, { "folder-name": "demoPluginB", "display-name": "Demo Plugin B", "version": "1.1.8.7", "id": "8a6b9dadbf2ec37d5c60a12a5445f0eec2ef00e6eaa80452925789fd73950193", ... }, ... } } ``` It's optional. In the case of its absence, it's considered compatible to all versions of Notepad++. The format of value for "npp-compatible-versions" is following (no white space is allowed): "6.9" : exact version 6.9 "[4.2,6.6.6]" : from version 4.2 to 6.6.6 inclusive "[8.3,]" : any version from 8.3 to the latest one "[,8.2.1]" : 8.2.1 and any previous version Fix #11338, close #11334
1 parent 0affe35 commit a06b404

File tree

6 files changed

+187
-5
lines changed

6 files changed

+187
-5
lines changed

PowerEditor/src/Notepad_plus.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7214,6 +7214,10 @@ static const QuoteParams quotes[] =
72147214
{TEXT("Anonymous #181"), QuoteParams::rapid, false, SC_CP_UTF8, L_TEXT, TEXT("I met a magical Genie. He gave me one wish.\nI said: \"I wish I could be you.\"\nThe Genue saud: \"Weurd wush but U wull grant ut.\"\n") },
72157215
{TEXT("Anonymous #182"), QuoteParams::slow, false, SC_CP_UTF8, L_CPP, TEXT("printf(\"%s%s\", \"\\\\o/\\n| |\\n| |8=\", \"=D\\n/ \\\\\\n\");\n") },
72167216
{TEXT("Anonymous #183"), QuoteParams::rapid, false, SC_CP_UTF8, L_TEXT, TEXT("Dear Optimist, Pessimist and Realist,\n\nWhile you guys were busy arguing about\nthe glass of water, I drank it!\n\n\n Sincerely,\n The Opportunist\n") },
7217+
{TEXT("Anonymous #184"), QuoteParams::slow, false, SC_CP_UTF8, L_TEXT, TEXT("Dance like nobody's watching.\nEncrypt like everyone is.\n") },
7218+
{TEXT("Anonymous #185"), QuoteParams::rapid, false, SC_CP_UTF8, L_TEXT, TEXT("Me: \"I'm 45 years old but I've got a 19 year-old young man's body\"\nHer: \"Show me\"\nI opened the freezer to show her the body.\nShe screamed.\nMe too.\n") },
7219+
{TEXT("Anonymous #186"), QuoteParams::slow, false, SC_CP_UTF8, L_TEXT, TEXT("Everyone complains about the weather,\nbut no one wants to sacrifice a virgin to change it.\n") },
7220+
{TEXT("Anonymous #187"), QuoteParams::rapid, false, SC_CP_UTF8, L_TEXT, TEXT("If you are alone at home and feel lonely:\nTurn off the lights, turn on the TV and watch a horror movie.\nThen you will have feeling that there are someone hidden in the kitchen, in the toilet\nand even under your bed.\n") },
72177221
{TEXT("xkcd"), QuoteParams::rapid, false, SC_CP_UTF8, L_TEXT, TEXT("Never have I felt so close to another soul\nAnd yet so helplessly alone\nAs when I Google an error\nAnd there's one result\nA thread by someone with the same problem\nAnd no answer\nLast posted to in 2003\n\n\"Who were you, DenverCoder9?\"\n\"What did you see?!\"\n\n(ref: https://xkcd.com/979/)") },
72187222
{TEXT("A developer"), QuoteParams::slow, false, SC_CP_UTF8, L_TEXT, TEXT("No hugs & kisses.\nOnly bugs & fixes.") },
72197223
{TEXT("Elon Musk"), QuoteParams::rapid, false, SC_CP_UTF8, L_TEXT, TEXT("Don't set your password as your child's name.\nName your child after your password.") },

PowerEditor/src/Parameters.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,31 @@ void cutString(const TCHAR* str2cut, vector<generic_string>& patternVect)
705705
patternVect.emplace_back(pBegin, pEnd);
706706
}
707707

708+
void cutStringBy(const TCHAR* str2cut, vector<generic_string>& patternVect, char byChar, bool allowEmptyStr)
709+
{
710+
if (str2cut == nullptr) return;
711+
712+
const TCHAR* pBegin = str2cut;
713+
const TCHAR* pEnd = pBegin;
714+
715+
while (*pEnd != '\0')
716+
{
717+
if (*pEnd == byChar)
718+
{
719+
if (allowEmptyStr)
720+
patternVect.emplace_back(pBegin, pEnd);
721+
else if (pBegin != pEnd)
722+
patternVect.emplace_back(pBegin, pEnd);
723+
pBegin = pEnd + 1;
724+
}
725+
++pEnd;
726+
}
727+
if (allowEmptyStr)
728+
patternVect.emplace_back(pBegin, pEnd);
729+
else if (pBegin != pEnd)
730+
patternVect.emplace_back(pBegin, pEnd);
731+
}
732+
708733

709734
std::wstring LocalizationSwitcher::getLangFromXmlFileName(const wchar_t *fn) const
710735
{

PowerEditor/src/Parameters.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ const TCHAR nppLogNetworkDriveIssue[] = TEXT("nppLogNetworkDriveIssue");
139139
const TCHAR nppLogNulContentCorruptionIssue[] = TEXT("nppLogNulContentCorruptionIssue");
140140

141141
void cutString(const TCHAR *str2cut, std::vector<generic_string> & patternVect);
142+
void cutStringBy(const TCHAR *str2cut, std::vector<generic_string> & patternVect, char byChar, bool allowEmptyStr);
142143

143144

144145
struct Position

PowerEditor/src/ScintillaComponent/Buffer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1553,7 +1553,7 @@ bool FileManager::loadFileData(Document doc, int64_t fileSize, const TCHAR * fil
15531553
switch (sciStatus)
15541554
{
15551555
case SC_STATUS_OK:
1556-
// either the Scintilla not catched this exception or the error is in the N++ code, report the exception anyway
1556+
// either the Scintilla doesn't catch this exception or the error is in the Notepad++ code, report the exception anyway
15571557
#if defined(__GNUC__)
15581558
// there is the std::current_exception() possibility, but getting the real exception code from there requires an ugly hack,
15591559
// because of the std::exception_ptr has its members _Data1 (GetExceptionCode) and _Data2 (GetExceptionInformation) private

PowerEditor/src/WinControls/PluginsAdmin/pluginsAdmin.cpp

Lines changed: 142 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,27 +41,41 @@ Version::Version(const generic_string& versionStr)
4141
auto ss = tokenizeString(versionStr, '.');
4242

4343
if (ss.size() > 4)
44-
throw generic_string(TEXT("The string to parse is not a valid version format. Let's make it default value in catch block."));
44+
throw wstring(TEXT("Version parts are more than 4. The string to parse is not a valid version format. Let's make it default value in catch block."));
4545

4646
int i = 0;
4747
vector<unsigned long*> v = {&_major, &_minor, &_patch, &_build};
4848
for (const auto& s : ss)
4949
{
5050
if (!isNumber(s))
5151
{
52-
throw generic_string(TEXT("The string to parse is not a valid version format. Let's make it default value in catch block."));
52+
throw wstring(TEXT("One of version character is not number. The string to parse is not a valid version format. Let's make it default value in catch block."));
5353
}
5454
*(v[i]) = std::stoi(s);
5555

5656
++i;
5757
}
5858
}
59+
#ifdef DEBUG
60+
catch (const wstring& s)
61+
{
62+
_major = 0;
63+
_minor = 0;
64+
_patch = 0;
65+
_build = 0;
66+
67+
throw s;
68+
}
69+
#endif
5970
catch (...)
6071
{
6172
_major = 0;
6273
_minor = 0;
6374
_patch = 0;
6475
_build = 0;
76+
#ifdef DEBUG
77+
throw wstring(TEXT("Unknown exception from \"Version::Version(const generic_string& versionStr)\""));
78+
#endif
6579
}
6680
}
6781

@@ -636,6 +650,56 @@ void PluginViewList::pushBack(PluginUpdateInfo* pi)
636650
_ui.addLine(values2Add, reinterpret_cast<LPARAM>(pi), static_cast<int>(i));
637651
}
638652

653+
// intervalVerStr format:
654+
//
655+
// "6.9" : exact version 6.9
656+
// "[4.2,6.6.6]" : from version 4.2 to 6.6.6 inclusive
657+
// "[8.3,]" : any version from 8.3 to the latest one
658+
// "[,8.2.1]" : 8.2.1 and any previous version
659+
//
660+
std::pair<Version, Version> getIntervalVersions(generic_string intervalVerStr)
661+
{
662+
std::pair<Version, Version> result;
663+
664+
if (intervalVerStr.empty())
665+
return result;
666+
667+
const size_t indexEnd = intervalVerStr.length() - 1;
668+
if (intervalVerStr[0] == '[' && intervalVerStr[indexEnd] == ']') // interval versions format
669+
{
670+
generic_string cleanIntervalVerStr = intervalVerStr.substr(1, indexEnd - 1);
671+
vector<generic_string> versionVect;
672+
cutStringBy(cleanIntervalVerStr.c_str(), versionVect, ',', true);
673+
if (versionVect.size() == 2)
674+
{
675+
if (!versionVect[0].empty() && !versionVect[1].empty()) // "[4.2,6.6.6]" : from version 4.2 to 6.6.6 inclusive
676+
{
677+
result.first = Version(versionVect[0]);
678+
result.second = Version(versionVect[1]);
679+
}
680+
else if (!versionVect[0].empty() && versionVect[1].empty()) // "[8.3,]" : any version from 8.3 to the latest one
681+
{
682+
result.first = Version(versionVect[0]);
683+
}
684+
else if (versionVect[0].empty() && !versionVect[1].empty()) // "[,8.2.1]" : 8.2.1 and any previous version
685+
{
686+
result.second = Version(versionVect[1]);
687+
}
688+
}
689+
}
690+
else if (intervalVerStr[0] != '[' && intervalVerStr[indexEnd] != ']') // one version format -> "6.9" : exact version 6.9
691+
{
692+
result.first = Version(intervalVerStr);
693+
result.second = Version(intervalVerStr);
694+
}
695+
else // invalid format
696+
{
697+
// do nothing
698+
}
699+
700+
return result;
701+
}
702+
639703
bool loadFromJson(PluginViewList & pl, const json& j)
640704
{
641705
if (j.empty())
@@ -650,7 +714,65 @@ bool loadFromJson(PluginViewList & pl, const json& j)
650714
for (const auto& i : jArray)
651715
{
652716
try {
653-
//std::unique_ptr<PluginUpdateInfo*> pi = make_unique<PluginUpdateInfo*>();
717+
718+
// Optional
719+
std::pair<Version, Version> _nppCompatibleVersions; // compatible to Notepad++ interval versions: <from, to> example:
720+
// <0.0.0.0, 0.0.0.0>: plugin is compatible to all Notepad++ versions (due to invalid format set)
721+
// <6.9, 6.9>: plugin is compatible to only v6.9
722+
// <4.2, 6.6.6>: from v4.2 (included) to v6.6.6 (included)
723+
// <0.0.0.0, 8.2.1> all until v8.2.1 (included)
724+
// <8.3, 0.0.0.0> from v8.3 (included) to all
725+
if (i.contains("npp-compatible-versions"))
726+
{
727+
json jNppCompatibleVer = i["npp-compatible-versions"];
728+
729+
string versionsStr = jNppCompatibleVer.get<std::string>();
730+
generic_string nppCompatibleVersionStr(versionsStr.begin(), versionsStr.end());
731+
std::pair<Version, Version> nppCompatibleVersions = getIntervalVersions(nppCompatibleVersionStr);
732+
733+
// nppCompatibleVersions contains compatibilty to Notepad++ versions <from, to> example:
734+
// <0.0.0.0, 0.0.0.0>: plugin is compatible to all Notepad++ versions
735+
// <6.9, 6.9>: plugin is compatible to only v6.9
736+
// <4.2, 6.6.6>: from v4.2 (included) to v6.6.6 (included)
737+
// <0.0.0.0, 8.2.1>: all version until v8.2.1 (included)
738+
// <8.3, 0.0.0.0>: from v8.3 (included) to the latest verrsion
739+
740+
if (nppCompatibleVersions.first == nppCompatibleVersions.second && nppCompatibleVersions.first.empty()) // compatible versions not set
741+
// 1 case is processed:
742+
// <0.0.0.0, 0.0.0.0>: plugin is compatible to all Notepad++ versions
743+
{
744+
// OK - do nothing
745+
}
746+
else
747+
{
748+
TCHAR nppFullPathName[MAX_PATH];
749+
GetModuleFileName(NULL, nppFullPathName, MAX_PATH);
750+
751+
Version nppVer;
752+
nppVer.setVersionFrom(nppFullPathName);
753+
754+
if (nppCompatibleVersions.first <= nppVer && nppCompatibleVersions.second >= nppVer) // from <= npp <= to
755+
// 3 cases are processed:
756+
// <6.9, 6.9>: plugin is compatible to only v6.9
757+
// <4.2, 6.6.6>: from v4.2 (included) to v6.6.6 (included)
758+
// <0.0.0.0, 8.2.1>: all versions until v8.2.1 (included)
759+
{
760+
// OK - do nothing
761+
}
762+
else if (nppCompatibleVersions.first <= nppVer && nppCompatibleVersions.second.empty()) // from <= npp <= to
763+
// 1 case is processed:
764+
// <8.3, 0.0.0.0>: from v8.3 (included) to the latest version
765+
{
766+
// OK - do nothing
767+
}
768+
else // Not compatible to Notepad++ current version
769+
{
770+
// Not OK - skip this plugin
771+
continue;
772+
}
773+
}
774+
}
775+
654776
PluginUpdateInfo* pi = new PluginUpdateInfo();
655777

656778
string valStr = i.at("folder-name").get<std::string>();
@@ -681,8 +803,24 @@ bool loadFromJson(PluginViewList & pl, const json& j)
681803

682804
pl.pushBack(pi);
683805
}
684-
catch (...) // Every field is mandatory. If one of property is missing, an exception is thrown then this plugin will be ignored
806+
#ifdef DEBUG
807+
catch (const wstring& s)
685808
{
809+
::MessageBox(NULL, s.c_str(), TEXT("Exception caught in: PluginsAdmin loadFromJson()"), MB_ICONERROR);
810+
continue;
811+
}
812+
813+
catch (std::exception& e)
814+
{
815+
::MessageBoxA(NULL, e.what(), "Exception caught in: PluginsAdmin loadFromJson()", MB_ICONERROR);
816+
continue;
817+
}
818+
#endif
819+
catch (...) // If one of mandatory properties is missing or with the incorrect format, an exception is thrown then this plugin will be ignored
820+
{
821+
#ifdef DEBUG
822+
::MessageBoxA(NULL, "An unknown exception is just caught", "Unknown Exception", MB_OK);
823+
#endif
686824
continue;
687825
}
688826
}

PowerEditor/src/WinControls/PluginsAdmin/pluginsAdmin.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,31 @@ struct Version
4949
return compareTo(v2c) == -1;
5050
};
5151

52+
bool operator <= (const Version& v2c) const {
53+
int r = compareTo(v2c);
54+
return r == -1 || r == 0;
55+
};
56+
5257
bool operator > (const Version& v2c) const {
5358
return compareTo(v2c) == 1;
5459
};
5560

61+
bool operator >= (const Version& v2c) const {
62+
int r = compareTo(v2c);
63+
return r == 1 || r == 0;
64+
};
65+
5666
bool operator == (const Version& v2c) const {
5767
return compareTo(v2c) == 0;
5868
};
5969

6070
bool operator != (const Version& v2c) const {
6171
return compareTo(v2c) != 0;
6272
};
73+
74+
bool empty() const {
75+
return _major == 0 && _minor == 0 && _patch == 0 && _build == 0;
76+
}
6377
};
6478

6579
struct PluginUpdateInfo

0 commit comments

Comments
 (0)