From aa856fda743569678f111b6acb6f425aaf17bafc Mon Sep 17 00:00:00 2001 From: raspopov Date: Thu, 23 Mar 2017 22:27:02 +0300 Subject: [PATCH] Added PVS-Studio comments. Bumped version 1.0.0.8. Added lang-file structure preservation. --- BrowseCtrl.cpp | 98 ++++++++++++++++++------------------ Polang.cpp | 130 ++++++++++++++++++++++++------------------------ Polang.h | 100 ++++++++++++++++++------------------- Polang.rc | Bin 19466 -> 19492 bytes PolangDlg.cpp | 67 +++++++++++++++---------- Translation.cpp | 96 ++++++++++++++++++++++++++--------- Translation.h | 8 ++- stdafx.cpp | 44 ++++++++-------- 8 files changed, 308 insertions(+), 235 deletions(-) diff --git a/BrowseCtrl.cpp b/BrowseCtrl.cpp index 2db5596..9185b8c 100644 --- a/BrowseCtrl.cpp +++ b/BrowseCtrl.cpp @@ -1,48 +1,50 @@ -/* - -Polang -Copyright (C) 2017 Nikolay Raspopov - -This program 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. - -This program 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 this program. If not, see . - -*/ - -#include "stdafx.h" -#include "Polang.h" -#include "BrowseCtrl.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#endif - -// CBrowseCtrl - -IMPLEMENT_DYNAMIC(CBrowseCtrl, CMFCEditBrowseCtrl) - -BEGIN_MESSAGE_MAP(CBrowseCtrl, CMFCEditBrowseCtrl) - ON_WM_DROPFILES() -END_MESSAGE_MAP() - -// CBrowseCtrl message handlers - -void CBrowseCtrl::OnDropFiles( HDROP hDropInfo ) -{ - TCHAR szItem[ 1024 ] = {}; - if ( DragQueryFile( hDropInfo, 0, szItem, _countof( szItem ) ) && ( GetFileAttributes( szItem ) & FILE_ATTRIBUTE_DIRECTORY ) == 0 ) - { - SetWindowText( szItem ); - } - - DragFinish( hDropInfo ); -} +// This is an open source non-commercial project. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +/* + +Polang +Copyright (C) 2017 Nikolay Raspopov + +This program 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. + +This program 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 this program. If not, see . + +*/ + +#include "stdafx.h" +#include "Polang.h" +#include "BrowseCtrl.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + +// CBrowseCtrl + +IMPLEMENT_DYNAMIC(CBrowseCtrl, CMFCEditBrowseCtrl) + +BEGIN_MESSAGE_MAP(CBrowseCtrl, CMFCEditBrowseCtrl) + ON_WM_DROPFILES() +END_MESSAGE_MAP() + +// CBrowseCtrl message handlers + +void CBrowseCtrl::OnDropFiles( HDROP hDropInfo ) +{ + TCHAR szItem[ 1024 ] = {}; + if ( DragQueryFile( hDropInfo, 0, szItem, _countof( szItem ) ) && ( GetFileAttributes( szItem ) & FILE_ATTRIBUTE_DIRECTORY ) == 0 ) + { + SetWindowText( szItem ); + } + + DragFinish( hDropInfo ); +} diff --git a/Polang.cpp b/Polang.cpp index a4748c3..43b59e7 100644 --- a/Polang.cpp +++ b/Polang.cpp @@ -1,64 +1,66 @@ -/* - -Polang -Copyright (C) 2017 Nikolay Raspopov - -This program 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. - -This program 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 this program. If not, see . - -*/ - -#include "stdafx.h" -#include "Polang.h" -#include "PolangDlg.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#endif - -// CPolangApp - -BEGIN_MESSAGE_MAP(CPolangApp, CWinAppEx) -END_MESSAGE_MAP() - -// CPolangApp construction - -CPolangApp::CPolangApp() -{ - m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART; -} - -// The one and only CPolangApp object - -CPolangApp theApp; - -// CPolangApp initialization - -BOOL CPolangApp::InitInstance() -{ - INITCOMMONCONTROLSEX InitCtrls = { sizeof( InitCtrls ), ICC_WIN95_CLASSES }; - InitCommonControlsEx( &InitCtrls ); - - CWinApp::InitInstance(); - - // Activate "Windows Native" visual manager for enabling themes in MFC controls - CMFCVisualManager::SetDefaultManager( RUNTIME_CLASS( CMFCVisualManagerWindows ) ); - - SetRegistryKey( AFX_IDS_COMPANY_NAME ); - - CPolangDlg dlg; - m_pMainWnd = &dlg; - dlg.DoModal(); - - return FALSE; -} +// This is an open source non-commercial project. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +/* + +Polang +Copyright (C) 2017 Nikolay Raspopov + +This program 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. + +This program 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 this program. If not, see . + +*/ + +#include "stdafx.h" +#include "Polang.h" +#include "PolangDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + +// CPolangApp + +BEGIN_MESSAGE_MAP(CPolangApp, CWinAppEx) +END_MESSAGE_MAP() + +// CPolangApp construction + +CPolangApp::CPolangApp() +{ + m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART; +} + +// The one and only CPolangApp object + +CPolangApp theApp; + +// CPolangApp initialization + +BOOL CPolangApp::InitInstance() +{ + INITCOMMONCONTROLSEX InitCtrls = { sizeof( InitCtrls ), ICC_WIN95_CLASSES }; + InitCommonControlsEx( &InitCtrls ); + + CWinApp::InitInstance(); + + // Activate "Windows Native" visual manager for enabling themes in MFC controls + CMFCVisualManager::SetDefaultManager( RUNTIME_CLASS( CMFCVisualManagerWindows ) ); + + SetRegistryKey( AFX_IDS_COMPANY_NAME ); + + CPolangDlg dlg; + m_pMainWnd = &dlg; + dlg.DoModal(); + + return FALSE; +} diff --git a/Polang.h b/Polang.h index ccb53ea..369e4e6 100644 --- a/Polang.h +++ b/Polang.h @@ -1,50 +1,50 @@ -/* - -Polang -Copyright (C) 2017 Nikolay Raspopov - -This program 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. - -This program 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 this program. If not, see . - -*/ - -#pragma once - -#ifndef __AFXWIN_H__ - #error "include 'stdafx.h' before including this file for PCH" -#endif - -#include "resource.h" // main symbols - - -// CPolangApp - -class CPolangApp : public CWinAppEx -{ -public: - CPolangApp(); - -protected: - virtual BOOL InitInstance(); - - DECLARE_MESSAGE_MAP() -}; - -extern CPolangApp theApp; - -inline CString LoadString(UINT nId) -{ - CString str; - str.LoadString( nId ); - return str; -} +/* + +Polang +Copyright (C) 2017 Nikolay Raspopov + +This program 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. + +This program 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 this program. If not, see . + +*/ + +#pragma once + +#ifndef __AFXWIN_H__ + #error "include 'stdafx.h' before including this file for PCH" +#endif + +#include "resource.h" // main symbols + + +// CPolangApp + +class CPolangApp : public CWinAppEx +{ +public: + CPolangApp(); + +protected: + virtual BOOL InitInstance(); + + DECLARE_MESSAGE_MAP() +}; + +extern CPolangApp theApp; + +inline CString LoadString(UINT nId) +{ + CString str; + VERIFY( str.LoadString( nId ) ); + return str; +} diff --git a/Polang.rc b/Polang.rc index 7d58e862111fdf7500afb6812965abfff4050785..d71412b1d1ff378279f4940c7fe370bc0b0549f5 100644 GIT binary patch delta 59 zcmeC0!MJ1w Local.lang - if ( s1Filename.IsEmpty() || s2Filename.IsEmpty() || GetFileAttributes( s1Filename ) == INVALID_FILE_ATTRIBUTES ) + if ( s2Filename.IsEmpty() || s3Filename.IsEmpty() || GetFileAttributes( s2Filename ) == INVALID_FILE_ATTRIBUTES ) { AfxMessageBox( IDS_MSG_NO_FILE, MB_OK | MB_ICONEXCLAMATION ); return; } - if ( ! translations.LoadPo( s1Filename ) ) + if ( ! translations.LoadPo( s2Filename ) ) { AfxMessageBox( IDS_MSG_PO_LOAD_ERROR, MB_OK | MB_ICONEXCLAMATION ); return; } - if ( ! translations.SaveLang( s2Filename ) ) + if ( s1Filename.IsEmpty() || GetFileAttributes( s1Filename ) == INVALID_FILE_ATTRIBUTES ) { - AfxMessageBox( IDS_MSG_LANG_SAVE_ERROR, MB_OK | MB_ICONEXCLAMATION ); - return; + if ( ! translations.SaveLang( s3Filename ) ) + { + AfxMessageBox( IDS_MSG_LANG_SAVE_ERROR, MB_OK | MB_ICONEXCLAMATION ); + return; + } + } + else + { + if ( !translations.LoadLang( s1Filename, false, s3Filename ) ) + { + AfxMessageBox( IDS_MSG_LANG_SAVE_ERROR, MB_OK | MB_ICONEXCLAMATION ); + return; + } } if ( AfxMessageBox( IDS_MSG_LANG_SAVE_OK, MB_YESNO | MB_ICONQUESTION ) == IDYES ) { - ShellExecute( GetSafeHwnd(), nullptr, s2Filename, nullptr, nullptr, SW_NORMAL ); + ShellExecute( GetSafeHwnd(), nullptr, s3Filename, nullptr, nullptr, SW_NORMAL ); } break; } diff --git a/Translation.cpp b/Translation.cpp index 784ac9e..3c63efa 100644 --- a/Translation.cpp +++ b/Translation.cpp @@ -1,3 +1,5 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com /* Polang @@ -91,7 +93,7 @@ CStringA CTranslation::UTF8Encode(__in const CStringW& strInput) return UTF8Encode( strInput, strInput.GetLength() ); } -CString CTranslation::Escape(__in CString str) +CString CTranslation::EscapePo(__in CString str) { str.Replace( _T("\""), _T("\\\"") ); str.Replace( _T("\t"), _T("\\t") ); @@ -100,6 +102,12 @@ CString CTranslation::Escape(__in CString str) return str; } +CString CTranslation::EscapeLang(__in CString str) +{ + str.Replace( _T( "\n" ), _T( "\\n" ) ); + return str; +} + CString CTranslation::Decode(__in CString str) { CString tmp; @@ -322,16 +330,45 @@ bool CTranslation::LoadPo(const CString& sFilename) return bResult; } -bool CTranslation::LoadLang(const CString& sFilename, bool bMsgstr) +CString CTranslation::Get(const CString& sId) const +{ + CString sMsgid; + if ( m_IdToMsgid.Lookup( sId, sMsgid ) ) + { + CTrans trans; + if ( m_MsgidToTrans.Lookup( sMsgid, trans ) ) + { + return trans.m_sMsgstr; + } + } + return CString(); +} + +bool CTranslation::LoadLang(const CString& sFilename, bool bMsgstr, const CString& sAndSaveToFilename) { bool bResult = false; + FILE* fileAndSaveTo = nullptr; + if ( ! sAndSaveToFilename.IsEmpty() ) + { + // Backup old output file + CopyFile( _T( "\\\\?\\" ) + sAndSaveToFilename, _T( "\\\\?\\" ) + sAndSaveToFilename + _T( ".bak" ), FALSE ); + + // Create output file + if ( _tfopen_s( &fileAndSaveTo, _T( "\\\\?\\" ) + sAndSaveToFilename, _T( "wb" ) ) != 0 || ! fileAndSaveTo ) + { + return false; + } + } + // Open input file FILE* fileIn = nullptr; if ( _tfopen_s( &fileIn, _T("\\\\?\\") + sFilename, _T("rt,ccs=UTF-8") ) == 0 && fileIn ) { while( ! feof( fileIn ) ) { + bool bSaved = false; + CString sLine; if ( ! _fgetts( sLine.GetBuffer( 1024 ), 1024, fileIn ) ) { @@ -340,36 +377,49 @@ bool CTranslation::LoadLang(const CString& sFilename, bool bMsgstr) } sLine.ReleaseBuffer(); - sLine.TrimLeft(); - sLine.TrimRight( _T("\r\n") ); - - if ( sLine.IsEmpty() ) - // Skip empty line - continue; - - if ( sLine.GetAt( 0 ) == _T('#') ) - // Skip comments - continue; - // "key=value" const int nSplit = sLine.Find( _T('=') ); if ( nSplit > 0 ) { const CString sId = sLine.Left( nSplit ).Trim(); - const CString sMsgid = sLine.Mid( nSplit + 1 ); + const CString sMsgid = sLine.Mid( nSplit + 1 ).TrimRight( _T("\r\n") ); - if ( bMsgstr ) - Add( sId, sMsgid ); - else - SetAt( sId, sMsgid ); + if ( ! sId.IsEmpty() && // Skip empty key line + sId.GetAt( 0 ) != _T( '#' ) ) // Skip comments + { + if ( fileAndSaveTo ) + { + const CString sMsgstr = Get( sId ); + if ( ! sMsgstr.IsEmpty() ) + { + fputs( UTF8Encode( sId ) + "=" + UTF8Encode( EscapeLang( sMsgstr ) ) + "\n", fileAndSaveTo ); + bSaved = true; + } + } + else + { + if ( bMsgstr ) + Add( sId, sMsgid ); + else + SetAt( sId, sMsgid ); + } + + bResult = true; + } + } - bResult = true; + if ( fileAndSaveTo && ! bSaved ) + { + fputs( UTF8Encode( sLine ), fileAndSaveTo ); } } fclose( fileIn ); } + if ( fileAndSaveTo ) + fclose( fileAndSaveTo ); + return bResult; } @@ -405,8 +455,8 @@ bool CTranslation::SavePo(const CString& sFilename) const GetNext( pos, trans, sMsgid ); fputs( "\n#:" + UTF8Encode( trans.GetId() ) + "\n", fileOut ); - fputs( "msgid \"" + UTF8Encode( Escape( sMsgid ) ) + "\"\n", fileOut ); - fputs( "msgstr \"" + UTF8Encode( Escape( trans.m_sMsgstr ) ) + "\"\n", fileOut ); + fputs( "msgid \"" + UTF8Encode( EscapePo( sMsgid ) ) + "\"\n", fileOut ); + fputs( "msgstr \"" + UTF8Encode( EscapePo( trans.m_sMsgstr ) ) + "\"\n", fileOut ); } bResult = true; @@ -434,9 +484,7 @@ bool CTranslation::SaveLang(const CString& sFilename) const const CString sId = trans.m_sId.GetNext( posI ); if ( ! trans.m_sMsgstr.IsEmpty() ) { - CString str = trans.m_sMsgstr; - str.Replace( _T("\n"), _T("\\n") ); - out.SetAt( sId + _T("=") + str, 0 ); + out.SetAt( sId + _T("=") + EscapeLang( trans.m_sMsgstr ), 0 ); } } } diff --git a/Translation.h b/Translation.h index b6e887f..3c86c8a 100644 --- a/Translation.h +++ b/Translation.h @@ -81,6 +81,9 @@ class CTranslation m_MsgidToTrans.GetNextAssoc( pos, sMsgid, trans ); } + // Get localized string + CString Get(const CString& sId) const; + // Add English void SetAt(const CString& sId, const CString& sMsgid); void SetAt(const CStringList& lIds, const CString& sMsgid); @@ -90,7 +93,7 @@ class CTranslation void Add(const CStringList& lIds, const CString& sMsgstr); bool LoadPo(const CString& sFilename); - bool LoadLang(const CString& sFilename, bool bMsgstr = false); + bool LoadLang(const CString& sFilename, bool bMsgstr = false, const CString& sAndSaveToFilename = CString()); bool SavePo(const CString& sFilename) const; bool SaveLang(const CString& sFilename) const; @@ -103,5 +106,6 @@ class CTranslation static CStringA UTF8Encode(__in_bcount(nInput) LPCWSTR psInput, __in int nInput); static CStringA UTF8Encode(__in const CStringW& strInput); static CString Decode(__in CString str); - static CString Escape(__in CString str); + static CString EscapePo(__in CString str); + static CString EscapeLang(__in CString str); }; diff --git a/stdafx.cpp b/stdafx.cpp index 5a4e577..d2eaaa9 100644 --- a/stdafx.cpp +++ b/stdafx.cpp @@ -1,21 +1,23 @@ -/* - -Polang -Copyright (C) 2017 Nikolay Raspopov - -This program 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. - -This program 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 this program. If not, see . - -*/ - -#include "stdafx.h" +// This is an open source non-commercial project. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +/* + +Polang +Copyright (C) 2017 Nikolay Raspopov + +This program 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. + +This program 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 this program. If not, see . + +*/ + +#include "stdafx.h"