Fixed issue #4126: Capitalize the first letter in the Push dialog
[TortoiseGit.git] / src / TortoiseProc / VersioncheckParser.cpp
blob98751af221db293f7783a9f3d54216cf55d1435e
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2013-2019, 2022-2024 - TortoiseGit
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include "stdafx.h"
20 #include "VersioncheckParser.h"
21 #include "UnicodeUtils.h"
23 CVersioncheckParser::CVersioncheckParser()
24 : m_versioncheckfile(true, true)
28 CVersioncheckParser::~CVersioncheckParser()
32 static const wchar_t *escapes = L"ntb\"\\";
33 static const wchar_t *escaped = L"\n\t\b\"\\";
34 static CString GetConfigValue(const wchar_t* ptr)
36 if (!ptr)
37 return L"";
39 CString value;
41 CStrBuf working(value, static_cast<int>(min(wcslen(ptr), static_cast<size_t>(UINT16_MAX))));
42 wchar_t* fixed = working;
43 bool quoted = false;
45 while (*ptr)
47 if (*ptr == L'"')
48 quoted = !quoted;
49 else if (*ptr != L'\\')
51 if (!quoted && (*ptr == L'#' || *ptr == L';'))
52 break;
53 *fixed++ = *ptr;
55 else
57 /* backslash, check the next char */
58 ++ptr;
59 const wchar_t* esc = wcschr(escapes, *ptr);
60 if (esc)
61 *fixed++ = escaped[esc - escapes];
62 else
63 return L"";
65 ++ptr;
67 *fixed = L'\0';
70 return value;
73 CString CVersioncheckParser::GetStringValue(const CString& section, const CString& entry)
75 return GetConfigValue(m_versioncheckfile.GetValue(section, entry));
78 bool CVersioncheckParser::Load(const CString& filename, CString& err)
80 m_versioncheckfile.LoadFile(filename);
82 m_version.version = GetStringValue(L"tortoisegit", L"version");
83 if (m_version.version.IsEmpty())
85 err = L"Invalid version check file.";
86 return false;
88 unsigned __int64 version = 0;
89 CString vertemp = m_version.version;
90 m_version.major = _ttoi(vertemp);
91 vertemp = vertemp.Mid(vertemp.Find(L'.') + 1);
92 m_version.minor = _ttoi(vertemp);
93 vertemp = vertemp.Mid(vertemp.Find(L'.') + 1);
94 m_version.micro = _ttoi(vertemp);
95 vertemp = vertemp.Mid(vertemp.Find(L'.') + 1);
96 m_version.build = _ttoi(vertemp);
97 version = m_version.major;
98 version <<= 16;
99 version += m_version.minor;
100 version <<= 16;
101 version += m_version.micro;
102 version <<= 16;
103 version += m_version.build;
105 if (version == 0)
107 err = L"Invalid version check file.";
108 return false;
111 // another versionstring for the filename can be provided
112 // this is needed for preview releases
113 m_version.version_for_filename = GetStringValue(L"tortoisegit", L"versionstring");
114 if (m_version.version_for_filename.IsEmpty())
115 m_version.version_for_filename = m_version.version;
116 m_version.version_languagepacks = GetStringValue(L"tortoisegit", L"versionstringlanguagepacks");
117 if (m_version.version_languagepacks.IsEmpty())
118 m_version.version_languagepacks = m_version.version;
120 return true;
123 CVersioncheckParser::Version CVersioncheckParser::GetTortoiseGitVersion()
125 return m_version;
128 CString CVersioncheckParser::GetTortoiseGitInfoText()
130 return GetStringValue(L"tortoisegit", L"infotext");;
133 CString CVersioncheckParser::GetTortoiseGitInfoTextURL()
135 return GetStringValue(L"tortoisegit", L"infotexturl");;
138 CString CVersioncheckParser::GetTortoiseGitIssuesURL()
140 CString issueurl = GetStringValue(L"tortoisegit", L"issuesurl");
141 auto section = m_versioncheckfile.GetSection(L"TortoiseGit");
142 if (issueurl.IsEmpty() && section && section->find(L"issuesurl") == section->cend())
143 issueurl = L"https://tortoisegit.org/issue/%BUGID%";
144 return issueurl;
147 CString CVersioncheckParser::GetTortoiseGitChangelogURL()
149 CString changelogurl = GetStringValue(L"tortoisegit", L"changelogurl");
150 if (changelogurl.IsEmpty())
151 changelogurl = L"https://versioncheck.tortoisegit.org/changelog.txt";
152 return changelogurl;
155 CString CVersioncheckParser::GetTortoiseGitBaseURL()
157 CString baseurl = GetStringValue(L"tortoisegit", L"baseurl");
158 if (baseurl.IsEmpty())
159 baseurl.Format(L"http://updater.download.tortoisegit.org/tgit/%s/", static_cast<LPCWSTR>(m_version.version_for_filename));
160 return baseurl;
163 bool CVersioncheckParser::GetTortoiseGitIsDirectDownloadable()
165 return m_versioncheckfile.GetBoolValue(L"tortoisegit", L"directdownload", true);
168 bool CVersioncheckParser::GetTortoiseGitHasChangelog()
170 return m_versioncheckfile.GetBoolValue(L"tortoisegit", L"changelog", true);
173 bool CVersioncheckParser::GetTortoiseGitIsHotfix()
175 return m_versioncheckfile.GetBoolValue(L"tortoisegit", L"hotfix", false);
178 static inline CString architecture()
180 #if _M_ARM64
181 return L"arm64";
182 #elif WIN64
183 return L"64bit";
184 #else
185 return L"32bit";
186 #endif
189 CString CVersioncheckParser::GetTortoiseGitMainfilename()
191 CString mainfilenametemplate = GetStringValue(L"tortoisegit", L"mainfilename");
192 if (mainfilenametemplate.IsEmpty())
193 mainfilenametemplate = L"TortoiseGit-%1!s!-%2!s!bit.msi";
194 mainfilenametemplate.Replace(L"%2!s!bit", L"%2!s!");
195 CString mainfilename;
196 mainfilename.FormatMessage(mainfilenametemplate, static_cast<LPCWSTR>(m_version.version_for_filename), static_cast<LPCWSTR>(architecture()));
197 return mainfilename;
200 CString CVersioncheckParser::GetTortoiseGitLanguagepackFilenameTemplate()
202 CString languagepackfilenametemplate = GetStringValue(L"tortoisegit", L"languagepackfilename");
203 if (languagepackfilenametemplate.IsEmpty())
204 languagepackfilenametemplate = L"TortoiseGit-LanguagePack-%1!s!-%2!s!bit-%3!s!.msi";
205 languagepackfilenametemplate.Replace(L"%2!s!bit", L"%2!s!");
206 return languagepackfilenametemplate;
209 CVersioncheckParser::LANGPACK_VECTOR CVersioncheckParser::GetTortoiseGitLanguagePacks()
211 CString languagepackfilenametemplate = GetTortoiseGitLanguagepackFilenameTemplate();
212 LANGPACK_VECTOR vec;
214 CSimpleIni::TNamesDepend values;
215 m_versioncheckfile.GetAllValues(L"tortoisegit", L"langs", values);
216 for (const auto& value : values)
218 CString langs = GetConfigValue(value.pItem);
219 LanguagePack pack;
221 int nextTokenPos = langs.Find(L";", 5); // be extensible for the future
222 if (nextTokenPos > 0)
223 langs = langs.Left(nextTokenPos);
224 pack.m_LangCode = langs.Mid(5);
225 pack.m_PackName = L"TortoiseGit Language Pack " + pack.m_LangCode;
227 pack.m_LocaleID = _tstoi(langs.Left(4));
228 wchar_t buf[MAX_PATH] = { 0 };
229 GetLocaleInfo(pack.m_LocaleID, LOCALE_SNATIVELANGNAME, buf, _countof(buf));
230 pack.m_LangName = buf;
231 GetLocaleInfo(pack.m_LocaleID, LOCALE_SNATIVECTRYNAME, buf, _countof(buf));
232 if (buf[0])
234 pack.m_LangName += L" (";
235 pack.m_LangName += buf;
236 pack.m_LangName += L')';
239 pack.m_filename.FormatMessage(languagepackfilenametemplate, static_cast<LPCWSTR>(m_version.version_languagepacks), static_cast<LPCWSTR>(architecture()), static_cast<LPCWSTR>(pack.m_LangCode), pack.m_LocaleID);
241 vec.push_back(pack);
243 return vec;