diff --git a/MSIBuild/Makefile b/MSIBuild/Makefile index 3a9af25..e427515 100644 --- a/MSIBuild/Makefile +++ b/MSIBuild/Makefile @@ -41,17 +41,17 @@ s$(MSIBUILD_LENGTH_ID) S38 s$(MSIBUILD_LENGTH_ID) i2 S255 S$(MSIBUILD_LENGTH_ID) Component Component !IFNDEF WXEXTEND_STATIC !IF "$(PLAT)" == "Win32" -compwxExtend.dll.Win32 {7645D753-4A8C-40C6-BD6F-6DDE54F2B8F8} $(WXEXTEND_BIN_DIR) 0 filewxExtend.dll.Win32 +compwxExtend.dll.Win32 {37C6943E-B5D0-4C22-B039-29FEE015D0E8} $(WXEXTEND_BIN_DIR) 0 filewxExtend.dll.Win32 !ENDIF !IF "$(PLAT)" == "x64" -compwxExtend.dll.x64 {919135CB-B106-467E-A3DA-CBC463FBB7FF} $(WXEXTEND_BIN_DIR) 256 filewxExtend.dll.x64 +compwxExtend.dll.x64 {F323428B-B329-4492-943C-0F2387C80DC9} $(WXEXTEND_BIN_DIR) 256 filewxExtend.dll.x64 !ENDIF !ENDIF !IF "$(LANG)" == "ru_RU" -compwxExtend.mo.ru_RU {53ED87E7-83E9-44B2-8969-A6B7059466F5} WXEXTENDLOCRURUDIR $(MSIBUILD_COMPONENT_ATTRIB_FILE) filewxExtend.mo.ru_RU +compwxExtend.mo.ru_RU {3B4C86C3-ABFF-4272-B8E4-2E9B59DC7867} WXEXTENDLOCRURUDIR $(MSIBUILD_COMPONENT_ATTRIB_FILE) filewxExtend.mo.ru_RU !ENDIF !IF "$(LANG)" == "sl_SI" -compwxExtend.mo.sl_SI {08656BB6-0887-4605-B6D3-20B0444624BA} WXEXTENDLOCSLSIDIR $(MSIBUILD_COMPONENT_ATTRIB_FILE) filewxExtend.mo.sl_SI +compwxExtend.mo.sl_SI {E970685D-7997-40C9-A95C-95F1204BD534} WXEXTENDLOCSLSIDIR $(MSIBUILD_COMPONENT_ATTRIB_FILE) filewxExtend.mo.sl_SI !ENDIF < - 13 + 14 ..\..\..\output\$(Platform).$(Configuration)\ diff --git a/build/wxExtendDll.vcxproj b/build/wxExtendDll.vcxproj index 10d4952..ed36282 100644 --- a/build/wxExtendDll.vcxproj +++ b/build/wxExtendDll.vcxproj @@ -31,6 +31,7 @@ + @@ -43,6 +44,7 @@ + diff --git a/build/wxExtendDll.vcxproj.filters b/build/wxExtendDll.vcxproj.filters index 3c471d8..f3e9484 100644 --- a/build/wxExtendDll.vcxproj.filters +++ b/build/wxExtendDll.vcxproj.filters @@ -46,6 +46,9 @@ Source Files + + Source Files + @@ -81,6 +84,9 @@ Header Files + + Header Files + diff --git a/build/wxExtendLib.vcxproj b/build/wxExtendLib.vcxproj index a3045ec..1959c45 100644 --- a/build/wxExtendLib.vcxproj +++ b/build/wxExtendLib.vcxproj @@ -31,6 +31,7 @@ + @@ -44,6 +45,7 @@ + diff --git a/build/wxExtendLib.vcxproj.filters b/build/wxExtendLib.vcxproj.filters index 7e7b484..b9f9a04 100644 --- a/build/wxExtendLib.vcxproj.filters +++ b/build/wxExtendLib.vcxproj.filters @@ -46,6 +46,9 @@ Source Files + + Source Files + @@ -84,6 +87,9 @@ Header Files + + Header Files + diff --git a/include/wxex/common.h b/include/wxex/common.h index af7458c..d646654 100644 --- a/include/wxex/common.h +++ b/include/wxex/common.h @@ -33,7 +33,7 @@ #define wxEXTEND_VERSION_STR "1.3" #define wxEXTEND_BUILD_YEAR_STR "2016" -#define wxExtendVersion "13" +#define wxExtendVersion "14" #if !defined(RC_INVOKED) && !defined(MIDL_PASS) diff --git a/include/wxex/valnet.h b/include/wxex/valnet.h new file mode 100644 index 0000000..0377be1 --- /dev/null +++ b/include/wxex/valnet.h @@ -0,0 +1,171 @@ +/* + Copyright 2015-2016 Amebis + + This file is part of wxExtend. + + wxExtend is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + wxExtend is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with wxExtend. If not, see . +*/ + +#pragma once + +#include "common.h" + +#include +#include +#include + + +#ifdef __VISUALC__ +// non dll-interface class 'xxx' used as base for dll-interface class 'yyy' +#pragma warning (push) +#pragma warning (disable:4275) +#endif + +/// +/// Validator for host name +/// +class WXEXTEND_API wxHostNameValidator : public wxValidator +{ +public: + /// + /// Construct the validator with a value to store data + /// + wxHostNameValidator(wxString *val = NULL); + + /// + /// Copies this validator + /// + virtual wxObject* Clone() const; + + /// + /// Validates the value + /// + virtual bool Validate(wxWindow *parent); + + /// + /// Transfers the value to the window + /// + virtual bool TransferToWindow(); + + /// + /// Transfers the value from the window + /// + virtual bool TransferFromWindow(); + + /// + /// Parses FQDN value + /// + static bool Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, wxString *val_out = NULL); + +protected: + wxString *m_val; ///< Pointer to variable to receive control's parsed value + +private: + wxDECLARE_DYNAMIC_CLASS(wxHostNameValidator); + wxDECLARE_NO_ASSIGN_CLASS(wxHostNameValidator); +}; + + +/// +/// Validator for FQDN +/// +class WXEXTEND_API wxFQDNValidator : public wxValidator +{ +public: + /// + /// Construct the validator with a value to store data + /// + wxFQDNValidator(wxString *val = NULL); + + /// + /// Copies this validator + /// + virtual wxObject* Clone() const; + + /// + /// Validates the value + /// + virtual bool Validate(wxWindow *parent); + + /// + /// Transfers the value to the window + /// + virtual bool TransferToWindow(); + + /// + /// Transfers the value from the window + /// + virtual bool TransferFromWindow(); + + /// + /// Parses FQDN value + /// + static bool Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, wxString *val_out = NULL); + +protected: + wxString *m_val; ///< Pointer to variable to receive control's parsed value + +private: + wxDECLARE_DYNAMIC_CLASS(wxFQDNValidator); + wxDECLARE_NO_ASSIGN_CLASS(wxFQDNValidator); +}; + + +/// +/// Validator for FQDN lists +/// +class WXEXTEND_API wxFQDNListValidator : public wxValidator +{ +public: + /// + /// Construct the validator with a value to store data + /// + wxFQDNListValidator(wxArrayString *val = NULL); + + /// + /// Copies this validator + /// + virtual wxObject* Clone() const; + + /// + /// Validates the value + /// + virtual bool Validate(wxWindow *parent); + + /// + /// Transfers the value to the window + /// + virtual bool TransferToWindow(); + + /// + /// Transfers the value from the window + /// + virtual bool TransferFromWindow(); + + /// + /// Parses FQDN list value + /// + static bool Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, wxArrayString *val_out = NULL); + +protected: + wxArrayString *m_val; ///< Pointer to variable to receive control's parsed value + +private: + wxDECLARE_DYNAMIC_CLASS(wxFQDNListValidator); + wxDECLARE_NO_ASSIGN_CLASS(wxFQDNListValidator); +}; + +#ifdef __VISUALC__ +#pragma warning(pop) +#endif diff --git a/locale/de_DE.po b/locale/de_DE.po index be69a84..8170427 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -1,19 +1,32 @@ +# +#, fuzzy msgid "" msgstr "" "Project-Id-Version: wxExtend\n" -"POT-Creation-Date: 2016-10-05 08:39+0200\n" -"PO-Revision-Date: 2016-10-05 08:39+0200\n" -"Last-Translator: Simon Rozman \n" -"Language-Team: Amebis, d. o. o., Kamnik \n" -"Language: de_DE\n" +"POT-Creation-Date: 2016-10-07 12:59+0200\n" +"PO-Revision-Date: 2016-02-06 09:04+0100\n" +"Last-Translator: Simon Rozman , 2016\n" +"Language-Team: German (https://www.transifex.com/eduroam_devel/teams/11799/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.8.9\n" -"X-Poedit-Basepath: .\n" +"Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Poedit-SourceCharset: UTF-8\n" +"X-Generator: Poedit 1.8.9\n" +"X-Poedit-Basepath: ..\n" "X-Poedit-KeywordsList: _\n" +"X-Poedit-SearchPath-0: src\n" +"X-Poedit-SearchPath-1: include\n" +"X-Poedit-SourceCharset: UTF-8\n" + +#: src/valnet.cpp:99 +#, c-format +msgid "Invalid character in host name found: %c" +msgstr "Ungültiger Buchstabe im Servernamen gefunden: %c" + +#: src/valnet.cpp:99 +msgid "Validation conflict" +msgstr "Fehler bei der Validierung" #: include/wxex/appbar.h:981 msgid "" diff --git a/locale/ru_RU.po b/locale/ru_RU.po index 9305bf5..79e7c8d 100644 --- a/locale/ru_RU.po +++ b/locale/ru_RU.po @@ -1,20 +1,32 @@ +# +#, fuzzy msgid "" msgstr "" "Project-Id-Version: wxExtend\n" -"POT-Creation-Date: 2016-10-05 08:38+0200\n" -"PO-Revision-Date: 2016-10-05 08:38+0200\n" -"Last-Translator: Simon Rozman \n" -"Language-Team: Amebis, d. o. o., Kamnik \n" -"Language: ru_RU\n" +"POT-Creation-Date: 2016-10-07 12:59+0200\n" +"PO-Revision-Date: 2016-02-06 09:04+0100\n" +"Last-Translator: Simon Rozman , 2016\n" +"Language-Team: Russian (Russia) (https://www.transifex.com/eduroam_devel/teams/11799/ru_RU/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: ru_RU\n" +"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n" "X-Generator: Poedit 1.8.9\n" -"X-Poedit-Basepath: .\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" -"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -"X-Poedit-SourceCharset: UTF-8\n" +"X-Poedit-Basepath: ..\n" "X-Poedit-KeywordsList: _\n" +"X-Poedit-SearchPath-0: src\n" +"X-Poedit-SearchPath-1: include\n" +"X-Poedit-SourceCharset: UTF-8\n" + +#: src/valnet.cpp:99 +#, c-format +msgid "Invalid character in host name found: %c" +msgstr "" + +#: src/valnet.cpp:99 +msgid "Validation conflict" +msgstr "" #: include/wxex/appbar.h:981 msgid "" @@ -23,8 +35,7 @@ msgid "" "Auto-hide feature is now off." msgstr "" "На этом месте уже автоматически скрыта панель.\n" -"На каждом месте может находится только одна автоматически скрыта " -"панель.\n" +"На каждом месте может находится только одна автоматически скрыта панель.\n" "Автоматическое скрытие теперь выключен." #: include/wxex/appbar.h:981 diff --git a/locale/sl_SI.po b/locale/sl_SI.po index 50a4b44..6c8e490 100644 --- a/locale/sl_SI.po +++ b/locale/sl_SI.po @@ -1,20 +1,32 @@ +# +#, fuzzy msgid "" msgstr "" "Project-Id-Version: wxExtend\n" -"POT-Creation-Date: 2016-10-05 08:38+0200\n" -"PO-Revision-Date: 2016-10-05 08:38+0200\n" -"Last-Translator: Simon Rozman \n" -"Language-Team: Amebis, d. o. o., Kamnik \n" -"Language: sl_SI\n" +"POT-Creation-Date: 2016-10-07 12:59+0200\n" +"PO-Revision-Date: 2016-02-06 09:04+0100\n" +"Last-Translator: Simon Rozman , 2016\n" +"Language-Team: Slovenian (Slovenia) (https://www.transifex.com/eduroam_devel/teams/11799/sl_SI/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: sl_SI\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n" "X-Generator: Poedit 1.8.9\n" -"X-Poedit-Basepath: .\n" -"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n" -"%100==4 ? 2 : 3);\n" -"X-Poedit-SourceCharset: UTF-8\n" +"X-Poedit-Basepath: ..\n" "X-Poedit-KeywordsList: _\n" +"X-Poedit-SearchPath-0: src\n" +"X-Poedit-SearchPath-1: include\n" +"X-Poedit-SourceCharset: UTF-8\n" + +#: src/valnet.cpp:99 +#, c-format +msgid "Invalid character in host name found: %c" +msgstr "Napačen znak v imenu gostitelja: %c" + +#: src/valnet.cpp:99 +msgid "Validation conflict" +msgstr "Nesoglasje pri preverjanju" #: include/wxex/appbar.h:981 msgid "" diff --git a/locale/wxExtend.pot b/locale/wxExtend.pot index cfd5364..91ef5e2 100644 --- a/locale/wxExtend.pot +++ b/locale/wxExtend.pot @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: wxExtend\n" -"POT-Creation-Date: 2016-09-19 11:19+0200\n" +"POT-Creation-Date: 2016-10-07 12:59+0200\n" "PO-Revision-Date: 2016-02-06 09:04+0100\n" "Last-Translator: Simon Rozman \n" "Language-Team: Amebis, d. o. o., Kamnik \n" @@ -18,6 +18,15 @@ msgstr "" "X-Poedit-SearchPath-0: src\n" "X-Poedit-SearchPath-1: include\n" +#: src/valnet.cpp:99 +#, c-format +msgid "Invalid character in host name found: %c" +msgstr "" + +#: src/valnet.cpp:99 +msgid "Validation conflict" +msgstr "" + #: include/wxex/appbar.h:981 msgid "" "There is already an auto hidden bar on this edge.\n" diff --git a/src/stdafx.h b/src/stdafx.h index 97e48fd..8e264b3 100644 --- a/src/stdafx.h +++ b/src/stdafx.h @@ -30,6 +30,7 @@ #include "../include/wxex/object.h" #include "../include/wxex/url.h" #include "../include/wxex/valhex.h" +#include "../include/wxex/valnet.h" #include "../include/wxex/xml.h" #include "../include/wxex/common.h" diff --git a/src/valnet.cpp b/src/valnet.cpp new file mode 100644 index 0000000..9ee80ec --- /dev/null +++ b/src/valnet.cpp @@ -0,0 +1,267 @@ +/* + Copyright 2015-2016 Amebis + + This file is part of wxExtend. + + wxExtend is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + wxExtend is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with wxExtend. If not, see . +*/ + +#include "stdafx.h" + + +////////////////////////////////////////////////////////////////////// +// wxHostNameValidator +////////////////////////////////////////////////////////////////////// + +wxIMPLEMENT_DYNAMIC_CLASS(wxHostNameValidator, wxValidator); + + +wxHostNameValidator::wxHostNameValidator(wxString *val) : + m_val(val), + wxValidator() +{ +} + + +wxObject* wxHostNameValidator::Clone() const +{ + return new wxHostNameValidator(*this); +} + + +bool wxHostNameValidator::Validate(wxWindow *parent) +{ + wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); + wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow(); + if (!ctrl->IsEnabled()) return true; + + wxString val(ctrl->GetValue()); + return Parse(val, 0, val.Length(), ctrl, parent); +} + + +bool wxHostNameValidator::TransferToWindow() +{ + wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); + + if (m_val) + ((wxTextCtrl*)GetWindow())->SetValue(*m_val); + + return true; +} + + +bool wxHostNameValidator::TransferFromWindow() +{ + wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); + wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow(); + + wxString val(ctrl->GetValue()); + return Parse(val, 0, val.Length(), ctrl, NULL, m_val); +} + + +bool wxHostNameValidator::Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, wxString *val_out) +{ + const wxStringCharType *buf = val_in; + + size_t i = i_start; + for (;;) { + if (i >= i_end) { + // End of host name found. + if (val_out) val_out->assign(val_in.c_str() + i_start, i - i_start); + return true; + } else if (buf[i] == _T('-') || buf[i] == _T('_') || buf[i] == _T('*') || _istalnum(buf[i])) { + // Valid character found. + i++; + } else { + // Invalid character found. + ctrl->SetFocus(); + ctrl->SetSelection(i, i + 1); + wxMessageBox(wxString::Format(_("Invalid character in host name found: %c"), buf[i]), _("Validation conflict"), wxOK | wxICON_EXCLAMATION, parent); + return false; + } + } +} + + +////////////////////////////////////////////////////////////////////// +// wxFQDNValidator +////////////////////////////////////////////////////////////////////// + +wxIMPLEMENT_DYNAMIC_CLASS(wxFQDNValidator, wxValidator); + + +wxFQDNValidator::wxFQDNValidator(wxString *val) : + m_val(val), + wxValidator() +{ +} + + +wxObject* wxFQDNValidator::Clone() const +{ + return new wxFQDNValidator(*this); +} + + +bool wxFQDNValidator::Validate(wxWindow *parent) +{ + wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); + wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow(); + if (!ctrl->IsEnabled()) return true; + + wxString val(ctrl->GetValue()); + return Parse(val, 0, val.Length(), ctrl, parent); +} + + +bool wxFQDNValidator::TransferToWindow() +{ + wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); + + if (m_val) + ((wxTextCtrl*)GetWindow())->SetValue(*m_val); + + return true; +} + + +bool wxFQDNValidator::TransferFromWindow() +{ + wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); + wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow(); + + wxString val(ctrl->GetValue()); + return Parse(val, 0, val.Length(), ctrl, NULL, m_val); +} + + +bool wxFQDNValidator::Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, wxString *val_out) +{ + const wxStringCharType *buf = val_in; + + size_t i = i_start; + for (;;) { + const wxStringCharType *buf_next; + if ((buf_next = wmemchr(buf + i, L'.', i_end - i)) != NULL) { + // FQDN separator found. + if (!wxHostNameValidator::Parse(val_in, i, buf_next - buf, ctrl, parent)) + return false; + i = buf_next - buf + 1; + } else if (wxHostNameValidator::Parse(val_in, i, i_end, ctrl, parent)) { + // The rest of the FQDN parsed succesfully. + if (val_out) val_out->assign(val_in.c_str() + i_start, i_end - i_start); + return true; + } else + return false; + } +} + + +////////////////////////////////////////////////////////////////////// +// wxFQDNListValidator +////////////////////////////////////////////////////////////////////// + +wxIMPLEMENT_DYNAMIC_CLASS(wxFQDNListValidator, wxValidator); + + +wxFQDNListValidator::wxFQDNListValidator(wxArrayString *val) : + m_val(val), + wxValidator() +{ +} + + +wxObject* wxFQDNListValidator::Clone() const +{ + return new wxFQDNListValidator(*this); +} + + +bool wxFQDNListValidator::Validate(wxWindow *parent) +{ + wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow(); + if (!ctrl->IsEnabled()) return true; + + wxString val(ctrl->GetValue()); + return Parse(val, 0, val.Length(), ctrl, parent); +} + + +bool wxFQDNListValidator::TransferToWindow() +{ + wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); + + if (m_val) { + wxString str; + for (wxArrayString::const_iterator name = m_val->begin(), name_end = m_val->end(); name != name_end; ++name) { + if (!str.IsEmpty()) str += wxT("; "); + str += *name; + } + ((wxTextCtrl*)GetWindow())->SetValue(str); + } + + return true; +} + + +bool wxFQDNListValidator::TransferFromWindow() +{ + wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); + wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow(); + + wxString val(ctrl->GetValue()); + return Parse(val, 0, val.Length(), ctrl, NULL, m_val); +} + + +bool wxFQDNListValidator::Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, wxArrayString *val_out) +{ + const wxStringCharType *buf = val_in; + wxString _fqdn, *fqdn = val_out ? &_fqdn : NULL; + wxArrayString _val_out; + + size_t i = i_start; + for (;;) { + // Skip initial white-space. + for (; i < i_end && _istspace(buf[i]); i++); + + const wxStringCharType *buf_next; + if ((buf_next = wmemchr(buf + i, L';', i_end - i)) != NULL) { + // FQDN list separator found. + + // Skip trailing white-space. + size_t i_next = buf_next - buf; + for (; i < i_next && _istspace(buf[i_next - 1]); i_next--); + + if (!wxFQDNValidator::Parse(val_in, i, i_next, ctrl, parent, fqdn)) + return false; + if (fqdn && !fqdn->empty()) _val_out.push_back(std::move(*fqdn)); + + i = buf_next - buf + 1; + } else { + // Skip trailing white-space. + for (; i < i_end && _istspace(buf[i_end - 1]); i_end--); + + if (wxFQDNValidator::Parse(val_in, i, i_end, ctrl, parent, fqdn)) { + // The rest of the FQDN list parsed succesfully. + if (fqdn && !fqdn->empty()) _val_out.push_back(std::move(*fqdn)); + if (val_out) *val_out = std::move(_val_out); + return true; + } else + return false; + } + } +}