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.
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
)
41 CStrBuf
working(value
, static_cast<int>(min(wcslen(ptr
), static_cast<size_t>(UINT16_MAX
))));
42 wchar_t* fixed
= working
;
49 else if (*ptr
!= L
'\\')
51 if (!quoted
&& (*ptr
== L
'#' || *ptr
== L
';'))
57 /* backslash, check the next char */
59 const wchar_t* esc
= wcschr(escapes
, *ptr
);
61 *fixed
++ = escaped
[esc
- escapes
];
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.";
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
;
99 version
+= m_version
.minor
;
101 version
+= m_version
.micro
;
103 version
+= m_version
.build
;
107 err
= L
"Invalid version check file.";
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
;
123 CVersioncheckParser::Version
CVersioncheckParser::GetTortoiseGitVersion()
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%";
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";
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
));
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()
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()));
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();
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
);
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
));
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
);