Index: src/rc2lng/rc.cpp =================================================================== diff -u --- src/rc2lng/rc.cpp (revision 0) +++ src/rc2lng/rc.cpp (revision 2f3512c2df187a16a62c131d69bcddc06d671ed7) @@ -0,0 +1,579 @@ +#include "stdafx.h" +#include +#include +#include +#include +#include "rc.h" +#include "../libicpf/exception.h" +#include "../libicpf/crc32.h" + +#define MAX_LINE 65536 + +CRCFile::CRCFile() : + m_pszBuffer(new TCHAR[MAX_LINE]) +{ + AddInitialValues(); +} + +CRCFile::~CRCFile() +{ + delete [] m_pszBuffer; +} + +void CRCFile::ReadRC(PCTSTR pszFilename) +{ + // read file + CRCFile::ReadFile(pszFilename, m_vInRCFile, false); + + // and process it + ProcessRCFile(); +} + +void CRCFile::ReadResourceIDs(PCTSTR pszFile) +{ + std::vector vLines; + CRCFile::ReadFile(pszFile, vLines, false); + + long lLineNo = 0; + CString str, str2; + for(std::vector::iterator itLine = vLines.begin(); itLine != vLines.end(); ++itLine) + { + str = (*itLine); + str.TrimLeft(_T(" \t")); + if (str.Left(7) == _T("#define")) + { + str=str.Mid(8); + int iPos=str.FindOneOf(_T(" \t")); + str2=str.Left(iPos); + str=str.Mid(iPos); + str.TrimLeft(_T(" \t")); + str.TrimRight(_T(" \t\r\n")); + + int iID; + if(str.Find(_T("x")) != -1) + { + // hex2dec + if(_stscanf(str, _T("%lx"), &iID) != 1) + THROW(icpf::exception::format(TSTRFMT _T("(%ld) : Error: Cannot parse hex number in line:\n") TSTRFMT, pszFile, lLineNo, m_pszBuffer), 0, 0, 0); + } + else + iID=_ttoi(str); + + m_mapNameToID.insert(std::map::value_type(str2, iID)); + } + + ++lLineNo; + } +} + +void CRCFile::WriteRC(PCTSTR pszFilename) +{ + CRCFile::WriteFile(pszFilename, m_vOutRCFile, false); +} + +void CRCFile::WriteLang(PCTSTR pszFilename, PCTSTR pszHeaderFile) +{ + // write header file to the output file + std::vector vData; + CRCFile::ReadFile(pszHeaderFile, vData, true); + + // append the translation + CString str; + for(group_map::iterator itGroup = m_mapOutputLanguage.begin(); itGroup != m_mapOutputLanguage.end(); ++itGroup) + { + // write section header + AddTranslationLine(eLine_Group, (*itGroup).first, NULL, vData); + + // and key=value assignment + element_map& rElementMap = (*itGroup).second; + for(element_map::iterator itElement = rElementMap.begin(); itElement != rElementMap.end(); ++itElement) + { + AddTranslationLine(eLine_Translation, (*itElement).first, (*itElement).second, vData); + } + } + + CRCFile::WriteFile(pszFilename, vData, true); +} + +void CRCFile::Clear() +{ + m_vInRCFile.clear(); + m_vOutRCFile.clear(); + m_mapNameToID.clear(); + m_mapOutputLanguage.clear(); + + AddInitialValues(); +} + +void CRCFile::AddInitialValues() +{ + m_mapNameToID.insert(std::map::value_type(CString(_T("IDOK")), 1)); + m_mapNameToID.insert(std::map::value_type(CString(_T("IDCANCEL")), 2)); + m_mapNameToID.insert(std::map::value_type(CString(_T("IDABORT")), 3)); + m_mapNameToID.insert(std::map::value_type(CString(_T("IDRETRY")), 4)); + m_mapNameToID.insert(std::map::value_type(CString(_T("IDIGNORE")), 5)); + m_mapNameToID.insert(std::map::value_type(CString(_T("IDYES")), 6)); + m_mapNameToID.insert(std::map::value_type(CString(_T("IDNO")), 7)); + m_mapNameToID.insert(std::map::value_type(CString(_T("IDCLOSE")), 8)); + m_mapNameToID.insert(std::map::value_type(CString(_T("IDHELP")), 9)); + m_mapNameToID.insert(std::map::value_type(CString(_T("IDTRYAGAIN")), 10)); + m_mapNameToID.insert(std::map::value_type(CString(_T("IDCONTINUE")), 11)); +} + +int CRCFile::GetCommasCount(const CString& str) +{ + int cnt=0; + bool bInside=false; + for (int i=0;i& vLines) +{ + switch(eLineType) + { + case eLine_Group: + { + CString str; + str.Format(_T("[") UIFMT _T("]"), uiID); + vLines.push_back(_T("")); + vLines.push_back(str); + break; + } + case eLine_Translation: + { + if(!pszText) + THROW(_T("Error: Invalid string."), 0, 0, 0); + if(pszText[0] != _T('\0')) + { + CString str; + str.Format(UIFMT _T("[") UIXFMT _T("]=") TSTRFMT, uiID, icpf::crc32((const byte_t*)pszText, _tcslen(pszText)*sizeof(TCHAR)), pszText); + vLines.push_back(str); + } + break; + } + default: + { + _ASSERTE(FALSE); + THROW(_T("Error: Unknown line type."), 0, 0, 0); + } + } +} + +void CRCFile::ReadFile(PCTSTR pszFile, std::vector& rLines, bool bUnicode) +{ + // load file + FILE* pFile = _tfopen(pszFile, bUnicode ? _T("rb") : _T("rt")); + if(!pFile) + THROW(icpf::exception::format(_T("Error: Cannot open file: ") TSTRFMT, pszFile), 0, errno, 0); + + CString str; + while(_fgetts(str.GetBufferSetLength(MAX_LINE), MAX_LINE, pFile)) + { + str.ReleaseBuffer(); + str.TrimRight(_T("\r\n")); + rLines.push_back(str); + } + str.ReleaseBuffer(); + + fclose(pFile); +} + +void CRCFile::WriteFile(PCTSTR pszFile, const std::vector& rLines, bool bUnicode) +{ + FILE* pFile = _tfopen(pszFile, bUnicode ? _T("wb") : _T("wt")); + if(!pFile) + THROW(icpf::exception::format(_T("Error: Cannot open file: ") TSTRFMT _T(" for writing."), pszFile), 0, errno, 0); + + for (std::vector::const_iterator it=rLines.begin();it != rLines.end();it++) + { + CString str = (*it); + str += _T("\r\n"); + if(_fputts((PCTSTR)str, pFile) < 0) + THROW(icpf::exception::format(_T("Cannot write data to file ") TSTRFMT, pszFile), 0, errno, 0); + } + + fclose(pFile); +} + +void CRCFile::ProcessMenu(UINT uiMenuID, std::vector::iterator *init) +{ + element_map* pElementMap = GetElementMap(uiMenuID); + if(!pElementMap) + return; + + CString str; + for (;(*init) != m_vInRCFile.end();(*init)++) + { + str=**init; + str.TrimLeft(_T(" ")); + str.TrimRight(_T(" ")); + + // check for exit + if ( str == _T("END") ) + { + // add the line to the outrc wo changes + m_vOutRCFile.push_back(**init); + return; + } + else if (str.Left(5) == _T("POPUP")) // if that is the popup string - call the function once more + { + // add the line to the outrc with changes - replace string inside "" with P + str=**init; + + // processing menuitem - find the text + int iPos=str.Find(_T("\""), 0); + CString strText; + if (iPos != -1) + { + strText=str.Mid(iPos+1); + int iPos2=strText.Find(_T("\"")); + if (iPos2 != -1) + strText=strText.Left(iPos2); + } + + // now find the | that separates the text from the pseudo-ID + int iBar=strText.ReverseFind(_T('|')); + if (iBar != -1) + { + // there is a text with an ID + CString strID=strText.Mid(iBar+1); + strText=strText.Left(iBar); + + // put the id and text in the translation file + // find the equiv for the id + UINT uiID = GetResourceID(strID); + pElementMap->insert(std::make_pair(uiID, strText)); + + // put the found ID as output text + CString out; + out.Format(_T("\"%lu\""), uiID); + str=str.Left(iPos)+out; + } + else + { + // no pseudoID in menu name + str=str.Left(iPos)+_T("\"P\""); + } + + m_vOutRCFile.push_back(str); + + (*init)++; + ProcessMenu(uiMenuID, init); + } + else + { + // if the line has MENUITEM + if (str.Left(8) == _T("MENUITEM") && str.Right(9) != _T("SEPARATOR")) + { + // restore original + str=**init; + + // check if there is any text after the comma + int iPos=str.Find(_T(","), 0); + CString strTest=str.Mid(iPos); + strTest.TrimLeft(_T(" ,\t\r\n")); + if (strTest.IsEmpty()) + { + (*init)++; + + CString tmp=**init; + tmp.Trim(_T(" ,\t\r\n")); + str+=tmp; + } + + // processing menuitem - find the text + iPos=str.Find(_T("\""), 0); + CString strText; + if (iPos != -1) + { + strText=str.Mid(iPos+1); + int iPos2=strText.Find(_T("\"")); + if (iPos2 != -1) + strText=strText.Left(iPos2); + } + + // find the ID + iPos=str.Find(_T(","), 0); + CString strID; + if (iPos != -1) + { + strID=str.Mid(iPos+1); + int iPos2=strID.Find(_T(","), 0); + if (iPos2 != -1) + strID=strID.Left(iPos2); + } + strID.TrimLeft(_T(" \t")); + strID.TrimRight(_T(" \t")); + + // find the equiv for the id + UINT uiID = GetResourceID(strID); + pElementMap->insert(std::make_pair(uiID, strText)); + CString out = str; + // out=**init; + out.Replace(_T("\"")+strText+_T("\""), _T("\"i\"")); + m_vOutRCFile.push_back(out); + } + else + m_vOutRCFile.push_back(**init); + } + } +} + +void CRCFile::ProcessDialog(UINT uiDialogID, std::vector::iterator *init) +{ + element_map* pElementMap = GetElementMap(uiDialogID); + if(!pElementMap) + return; + + CString str; + for (;(*init) != m_vInRCFile.end();(*init)++) + { + str=**init; + str.TrimLeft(_T(" ")); + str.TrimRight(_T(" ")); + + // check for exit + if ( str == _T("END") ) + { + // add the line to the outrc wo changes + m_vOutRCFile.push_back(**init); + return; + } + else if ( str.Left(7) == _T("CAPTION") ) + { + // read the caption + CString strText=str.Mid(7); + strText.TrimLeft(_T(" \t\"")); + strText.TrimRight(_T(" \t\"")); + + pElementMap->insert(std::make_pair(0, strText)); + + // save to rc wo title + str=**init; + str.Replace(_T("\"")+strText+_T("\""), _T("\"\"")); + m_vOutRCFile.push_back(str); + } + else if ( str.Left(5) == _T("LTEXT") || str.Left(5) == _T("CTEXT") || str.Left(5) == _T("RTEXT") || str.Left(13) == _T("DEFPUSHBUTTON") || str.Left(10) == _T("PUSHBUTTON") || str.Left(7) == _T("CONTROL") || str.Left(8) == _T("GROUPBOX") ) + { + // needed only 2 commas (outside the '\"') + if ( GetCommasCount(str) < 3 ) + str+=*((*init)+1); + + // the first thing after LTEXT(and other) is the caption + CString strText; + bool bControl = false; + + if (str.Left(5) == _T("LTEXT") || str.Left(5) == _T("CTEXT") || str.Left(5) == _T("RTEXT")) + str=str.Mid(5); + else if (str.Left(13) == _T("DEFPUSHBUTTON")) + str=str.Mid(13); + else if (str.Left(10) == _T("PUSHBUTTON")) + str=str.Mid(10); + else if (str.Left(7) == _T("CONTROL")) + { + bControl = true; + str=str.Mid(7); + } + else if (str.Left(8) == _T("GROUPBOX")) + str=str.Mid(8); + + str=str.Mid(str.Find(_T("\""))+1); + int iPos=str.Find(_T("\""), 0); + if (iPos != -1) + strText=str.Left(iPos); + else + THROW(_T("Error: cannot find a comma in processed text"), 0, 0, 0); + + str = str.Mid(iPos+1); + + // after the first comma there is an ID + iPos=str.Find(_T(","), 0); + CString strID; + if (iPos != -1) + { + str=str.Mid(iPos+1); + iPos=str.Find(_T(","), 0); + if (iPos != -1) + strID=str.Left(iPos); + else + THROW(_T("Error: cannot find a comma in processed text"), 0, 0, 0); + + strID.TrimLeft(_T(" \t")); + strID.TrimRight(_T(" \t")); + } + else + THROW(_T("Error: cannot find a comma in processed text"), 0, 0, 0); + + bool bSkip = false; + if(bControl) + { + str = str.Mid(iPos+1); + iPos = str.Find(_T(","), 0); + if(iPos == -1) + THROW(_T("Error: cannot find a comma in processed text"), 0, 0, 0); + + CString strType = str.Left(iPos); + strType.Trim(_T("\"")); + if(strType == _T("SysListView32") || strType == _T("msctls_progress32") || + strType == _T("ComboBoxEx32") || strType == _T("msctls_updown32") || + strType == _T("SysDateTimePick32")) + { + bSkip = true; + } + } + + if(!bSkip) + { + // find id + UINT uiID = GetResourceID(strID); + CString out; + pElementMap->insert(std::make_pair(uiID, strText)); + } + + // now add the data to output rc + str=**init; + str.Replace(_T("\"")+strText+_T("\""), _T("\"\"")); + + m_vOutRCFile.push_back(str); + } + else + m_vOutRCFile.push_back(**init); + } +} + +void CRCFile::ProcessStringTable(UINT uiStringGroupID, std::vector::iterator *init) +{ + element_map* pElementMap = GetElementMap(uiStringGroupID); + if(!pElementMap) + return; + + CString str; + for (;(*init) != m_vInRCFile.end();(*init)++) + { + str=**init; + str.TrimLeft(_T(" ")); + str.TrimRight(_T(" ")); + + if ( str == _T("END") ) + return; + else if ( str != _T("BEGIN") ) + { + // the first stuff is ID, the second is text + int iPos=str.Find(_T("\""), 0); + if (iPos == -1) + { + (*init)++; + str+=**init; + iPos=str.Find(_T("\""), 0); + } + + if (iPos != -1) + { + CString strID=str.Left(iPos); + strID.TrimRight(_T(" \"\t\n\r")); + + CString strText=str.Mid(iPos+1); + strText.Replace(_T("\"\""), _T("\"")); + strText=strText.Left(strText.ReverseFind(_T('\"'))); + + UINT uiID = GetResourceID(strID); + pElementMap->insert(std::make_pair(uiID, strText)); + + str=**init; + str.Replace(_T("\"")+strText+_T("\""), _T("\"\"")); + } + } + } +} + +bool CRCFile::ProcessRCFile() +{ + int iPos; + CString strData; + std::vector vStrTable; + for (std::vector::iterator it=m_vInRCFile.begin();it != m_vInRCFile.end();it++) + { + if ( (iPos=it->Find(_T(" MENU "))) != -1 ) + { + // add the line to the output rc with no change + m_vOutRCFile.push_back(*it); + + UINT uiID = GetResourceID(it->Left(iPos)); + + // begin enumerating items + it++; + + // process the menu + ProcessMenu(uiID, &it); + } + else if ( (iPos=it->Find(_T(" DIALOGEX "))) != -1) + { + // add the line to the output rc with no change + m_vOutRCFile.push_back(*it); + + UINT uiID = GetResourceID(it->Left(iPos)); + // begin processing dialog template + it++; + ProcessDialog(uiID, &it); + } + else if ( (iPos=it->Find(_T("STRINGTABLE "))) != -1) + { + // begin of the string table + it++; + ProcessStringTable(0, &it); + } + else + m_vOutRCFile.push_back(*it); + } + + return true; +} + +CRCFile::element_map* CRCFile::GetElementMap(UINT uiGroup) +{ + // insert menu if does not exist + element_map* pElementMap = NULL; + group_map::iterator itGroup = m_mapOutputLanguage.find(uiGroup); + if(itGroup == m_mapOutputLanguage.end()) + { + std::pair pairGroup = m_mapOutputLanguage.insert(std::make_pair(uiGroup, element_map())); + if(!pairGroup.second) + { + _ASSERTE(false); + return NULL; + } + + pElementMap = &(*(pairGroup.first)).second; + } + else + pElementMap = &((*itGroup).second); + + if(!pElementMap) + { + _ASSERTE(false); + return NULL; + } + + return pElementMap; +} + +UINT CRCFile::GetResourceID(PCTSTR pszID) +{ + std::map::iterator mit = m_mapNameToID.find(pszID); + if (mit != m_mapNameToID.end()) + return (*mit).second; + else + { + _ASSERTE(false); + THROW(icpf::exception::format(_T("Error: Cannot find resource identifier ") TSTRFMT, pszID), 0, 0, 0); + } +} Index: src/rc2lng/rc.h =================================================================== diff -u --- src/rc2lng/rc.h (revision 0) +++ src/rc2lng/rc.h (revision 2f3512c2df187a16a62c131d69bcddc06d671ed7) @@ -0,0 +1,56 @@ +#ifndef __RC_H__ +#define __RC_H__ + +class CRCFile +{ +private: + typedef std::map element_map; + typedef std::map group_map; + + enum ELineType + { + eLine_Group, + eLine_Translation + }; +public: + CRCFile(); + ~CRCFile(); + + void ReadRC(PCTSTR pszFilename); + void ReadResourceIDs(PCTSTR pszFilename); + + void WriteRC(PCTSTR pszFilename); + void WriteLang(PCTSTR pszFilename, PCTSTR pszHeaderFile); + + void Clear(); + +protected: + // Adds initial values to the maps + void AddInitialValues(); + + static int GetCommasCount(const CString& str); + + static void WriteFile(PCTSTR pszFile, const std::vector& rLines, bool bUnicode); + static void ReadFile(PCTSTR pszFile, std::vector& rLines, bool bUnicode); + + void AddTranslationLine(ELineType eLineType, UINT uiID, PCTSTR pszText, std::vector& vLines); + + bool ProcessRCFile(); + void ProcessMenu(UINT uiMenuID, std::vector::iterator *init); + void ProcessDialog(UINT uiDialogID, std::vector::iterator *init); + void ProcessStringTable(UINT uiStringGroupID, std::vector::iterator *init); + + element_map* GetElementMap(UINT uiGroup); + UINT GetResourceID(PCTSTR pszID); + +protected: + std::map m_mapNameToID; // resource name to resource id + std::vector m_vInRCFile; // lines from rc file + std::vector m_vOutRCFile; // lines to write to rc file + + group_map m_mapOutputLanguage; // section_id->element_id->string +// std::vector m_vOutputLanguage; // lines of the language file to be written + TCHAR* m_pszBuffer; +}; + +#endif Index: src/rc2lng/rc2lng.cpp =================================================================== diff -u -rbee51aca3d5d9b67ecac4f528a3203738cc63455 -r2f3512c2df187a16a62c131d69bcddc06d671ed7 --- src/rc2lng/rc2lng.cpp (.../rc2lng.cpp) (revision bee51aca3d5d9b67ecac4f528a3203738cc63455) +++ src/rc2lng/rc2lng.cpp (.../rc2lng.cpp) (revision 2f3512c2df187a16a62c131d69bcddc06d671ed7) @@ -1,9 +1,11 @@ -// CHExe2Lng.cpp : Defines the entry point for the console application. +// rc2lng.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "rc2lng.h" #include "conio.h" +#include "rc.h" +#include "../libicpf/exception.h" #pragma warning(disable : 4786) @@ -13,650 +15,44 @@ static char THIS_FILE[] = __FILE__; #endif -CWinApp theApp; - -int GetCommasCount(const CString& str) +int _tmain(int argc, TCHAR* argv[], TCHAR* /*envp*/[]) { - int cnt=0; - bool bInside=false; - for (int i=0;i* pIDs) -{ - try - { - CFile file(pszFile, CFile::modeRead); - CArchive ar(&file, CArchive::load); - CString str, str2; - while(ar.ReadString(str)) - { - if (str.Left(7) == _T("#define")) - { - str=str.Mid(8); - int iPos=str.FindOneOf(" \t"); - str2=str.Left(iPos); - str=str.Mid(iPos); - str.TrimLeft(_T(" \t")); - str.TrimRight(_T(" \t\r\n")); - - int iID; - if (str.Find("x") != -1) - { - // hex2dec - _stscanf(str, "%lx", &iID); - } - else - iID=_ttoi(str); - - pIDs->insert(map::value_type(str2, iID)); - } - } - - ar.Close(); - file.Close(); - - pIDs->insert(map::value_type(CString("IDOK"), 1)); - pIDs->insert(map::value_type(CString("IDCANCEL"), 2)); - } - catch(...) - { - return false; - } - -/* map::iterator it=pIDs->begin(); - while (it != pIDs->end()) - { - cout<<(PCTSTR)(CString)(it->first)<<" = "<<(UINT)(it->second)<* pvData) -{ - try - { - CFile file(pszFile, CFile::modeRead); - CArchive ar(&file, CArchive::load); - - CString str; - while (ar.ReadString(str)) - pvData->push_back(str); - - ar.Close(); - file.Close(); - } - catch(...) - { - return false; - } - return true; -} - -bool ReadRCFile(PCTSTR pszFile, vector *pv) -{ - try - { - CFile file(pszFile, CFile::modeRead); - CArchive ar(&file, CArchive::load); - - CString str; - while (ar.ReadString(str)) - pv->push_back(str); - - ar.Close(); - file.Close(); - } - catch(...) - { - return false; - } - return true; -} - -void ProcessMenu(vector* pinrc, vector::iterator *init, map* pids, vector* poutrc, vector* pol) -{ - CString str; - map::iterator mit; - for (;(*init) != pinrc->end();(*init)++) - { - str=**init; - str.TrimLeft(" "); - str.TrimRight(" "); - - // check for exit - if ( str == "END" ) - { - // add the line to the outrc wo changes - poutrc->push_back(**init); - return; - } - else if (str.Left(5) == "POPUP") // if that is the popup string - call the function once more - { - // add the line to the outrc with changes - replace string inside "" with P - str=**init; - - // processing menuitem - find the text - int iPos=str.Find("\"", 0); - CString strText; - if (iPos != -1) - { - strText=str.Mid(iPos+1); - int iPos2=strText.Find("\""); - if (iPos2 != -1) - strText=strText.Left(iPos2); - } - - // now find the | that separates the text from the pseudo-ID - int iBar=strText.ReverseFind(_T('|')); - if (iBar != -1) - { - // there is a text with an ID - CString strID=strText.Mid(iBar+1); - strText=strText.Left(iBar); - - // put the id and text in the translation file - // find the equiv for the id - mit=pids->find(strID); - CString out; - if (mit != pids->end()) - { - out.Format("%lu=%s", mit->second, strText); - pol->push_back(out); - - // put the found ID as output text - out.Format("\"%lu\"", mit->second); - str=str.Left(iPos)+out; - } - else - { - out.Format("%s=%s", strID, strText); - pol->push_back(out); - - // put the ID as output text - str=str.Left(iPos)+"\""+strID+"\""; - } - } - else - { - // no ID - str=str.Left(iPos)+"\"P\""; - } - - poutrc->push_back(str); - - (*init)++; - ProcessMenu(pinrc, init, pids, poutrc, pol); - } - else - { - // if the line has MENUITEM - if (str.Left(8) == "MENUITEM" && str.Right(9) != "SEPARATOR") - { - // restore original - str=**init; - - // check if there is any text after the comma - int iPos=str.Find(",", 0); - CString strTest=str.Mid(iPos); - strTest.TrimLeft(" ,\t\r\n"); - if (strTest.IsEmpty()) - { - (*init)++; - - CString tmp=**init; - tmp.Trim(" ,\t\r\n"); - str+=tmp; - } - - // processing menuitem - find the text - iPos=str.Find("\"", 0); - CString strText; - if (iPos != -1) - { - strText=str.Mid(iPos+1); - int iPos2=strText.Find("\""); - if (iPos2 != -1) - strText=strText.Left(iPos2); - } - - // find the ID - iPos=str.Find(",", 0); - CString strID; - if (iPos != -1) - { - strID=str.Mid(iPos+1); - int iPos2=strID.Find(",", 0); - if (iPos2 != -1) - strID=strID.Left(iPos2); - } - strID.TrimLeft(" \t"); - strID.TrimRight(" \t"); - - // find the equiv for the id - mit=pids->find(strID); - CString out; - if (mit != pids->end()) - { - out.Format("%lu=%s", mit->second, strText); - pol->push_back(out); - } - else - { - out.Format("%s=%s", strID, strText); - pol->push_back(out); - } -// AfxMessageBox(str); - out=str; -// out=**init; - out.Replace("\""+strText+"\"", "\"i\""); - poutrc->push_back(out); - } - else - poutrc->push_back(**init); - } - } -} - -void ProcessDialog(vector* pinrc, vector::iterator *init, map* pids, vector* poutrc, vector* pol) -{ - CString str; - map::iterator mit; - for (;(*init) != pinrc->end();(*init)++) - { - str=**init; - str.TrimLeft(" "); - str.TrimRight(" "); - - // check for exit - if ( str == "END" ) - { - // add the line to the outrc wo changes - poutrc->push_back(**init); - return; - } - else if ( str.Left(7) == "CAPTION" ) - { - // read the caption - CString strText=str.Mid(7); - strText.TrimLeft(" \t\""); - strText.TrimRight(" \t\""); - - pol->push_back("0="+strText); - - // save to rc wo title - str=**init; - str.Replace("\""+strText+"\"", "\"\""); - poutrc->push_back(str); - } - else if ( str.Left(5) == "LTEXT" || str.Left(5) == "CTEXT" || str.Left(5) == "RTEXT" || str.Left(13) == "DEFPUSHBUTTON" || str.Left(10) == "PUSHBUTTON" || str.Left(7) == "CONTROL" || str.Left(8) == "GROUPBOX" ) - { - // needed only 2 commas (outside the '\"') - if ( GetCommasCount(str) < 2 ) - str+=*((*init)+1); - - // the first thing after LTEXT(and other) is the caption - CString strText; - - if (str.Left(5) == "LTEXT" || str.Left(5) == "CTEXT" || str.Left(5) == "RTEXT") - strText=str.Mid(5); - else if (str.Left(13) == "DEFPUSHBUTTON") - strText=str.Mid(13); - else if (str.Left(10) == "PUSHBUTTON") - strText=str.Mid(10); - else if (str.Left(7) == "CONTROL") - strText=str.Mid(7); - else if (str.Left(8) == "GROUPBOX") - strText=str.Mid(8); - - strText=strText.Mid(strText.Find("\"")+1); - int iPos=strText.Find("\"", 0); - if (iPos != -1) - strText=strText.Left(iPos); - - // after the first comma there is an ID - iPos=str.Find(",", 0); - CString strID; - if (iPos != -1) - { - strID=str.Mid(iPos+1); - iPos=strID.Find(",", 0); - if (iPos != -1) - strID=strID.Left(iPos); - strID.TrimLeft(" \t"); - strID.TrimRight(" \t"); - } - - // find id - mit=pids->find( strID ); - CString out; - if (mit != pids->end()) - { - // id found - if (mit->second != 0) - { - out.Format("%lu=%s", mit->second, strText); - pol->push_back(out); - } - } - else - { - out.Format("%s=%s", strID, strText); - pol->push_back(out); - } - - // now add the data to rc - str=**init; - str.Replace("\""+strText+"\"", "\"\""); - - poutrc->push_back(str); - } - else - { - poutrc->push_back(**init); - } - } -} - -void ProcessStringTable(vector* pinrc, vector::iterator *init, map* pids, vector* poutrc, vector* ptab) -{ - map::iterator mit; - CString str; - for (;(*init) != pinrc->end();(*init)++) - { - str=**init; - str.TrimLeft(" "); - str.TrimRight(" "); - - if ( str == "END" ) - return; - else if ( str != "BEGIN" ) - { - // the first stuff is ID, the second is text - int iPos=str.Find("\"", 0); - if (iPos == -1) - { - (*init)++; - str+=**init; - iPos=str.Find("\"", 0); - } - - if (iPos != -1) - { - CString strID=str.Left(iPos); - strID.TrimRight(" \"\t\n\r"); - - CString strText=str.Mid(iPos+1); - strText.Replace("\"\"", "\""); - - strText=strText.Left(strText.ReverseFind('\"')); - - mit=pids->find(strID); - CString out; - if (mit!= pids->end()) - out.Format("%lu=%s", mit->second, strText); - else - out.Format("%lu=%s", strID, strText); - ptab->push_back(out); - str=**init; - str.Replace("\""+strText+"\"", "\"\""); - } - } - } -} -CString ProcessLine(PCTSTR psz) -{ - CString str=psz; - str.Replace("\r", "\\r"); - str.Replace("\n", "\\n"); - str.Replace("\t", "\\t"); - - return str; -} - -bool ProcessRCFile(PCTSTR pszRCPath, vector* pinrc, map* pids, vector* poutrc, vector* pol) -{ - int iPos; - map::iterator mit; - CString strData; - vector vStrTable; - for (vector::iterator it=pinrc->begin();it != pinrc->end();it++) - { - if ( (iPos=it->Find(" MENU ")) != -1 ) - { - // retrieve the identifier and add it to the outlng - mit=pids->find( it->Left(iPos) ); - if (mit != pids->end()) - strData.Format("\r\n# Menu - %s\r\n[%lu]", it->Left(iPos), mit->second); - else - strData.Format("\r\n# Menu - %s\r\n[%s]", it->Left(iPos), it->Left(iPos)); - - pol->push_back(strData); - - // add the line to the output rc with no change - poutrc->push_back(*it); - - // begin enumerating items - it++; - ProcessMenu(pinrc, &it, pids, poutrc, pol); - } - else if ( (iPos=it->Find(" DIALOGEX ")) != -1) - { - // find the ID of a dialog box - mit=pids->find( it->Left(iPos) ); - if (mit != pids->end()) - strData.Format("\r\n# Dialog box - %s\r\n[%lu]", it->Left(iPos), mit->second); - else - strData.Format("\r\n# Dialog box - %s\r\n[%s]", it->Left(iPos), it->Left(iPos)); - - pol->push_back(strData); - - // add the line to the output rc with no change - poutrc->push_back(*it); - - // begin processing dialog template - it++; - ProcessDialog(pinrc, &it, pids, poutrc, pol); - } - else if ( (iPos=it->Find("STRINGTABLE ")) != -1) - { - // begin of the string table - it++; - ProcessStringTable(pinrc, &it, pids, poutrc, &vStrTable); - } - else if ( (iPos=it->Find(" 25 ")) != -1) - { //pszRCPath - CString strID=it->Left(iPos); - strID.TrimLeft(" \t\n\r\""); - strID.TrimRight(" \t\n\r\""); - - // file name - iPos=it->Find("\""); - CString strName=it->Mid(iPos+1); - strName.TrimRight(" \t\n\r\""); - strName.Replace("\\\\", "\\"); - - // concat the path - CString strPath=pszRCPath; - strPath=strPath.Left(strPath.ReverseFind('\\')+1); - - // read the file - TCHAR szData[16384]; - CFile file(strPath+strName, CFile::modeRead); - file.Read(szData, 16384); - file.Close(); - CString out=ProcessLine(szData); - - // add to lang - mit=pids->find(strID); - CString strLng; - if (mit!=pids->end()) - strLng.Format("%lu=%s", mit->second, out); - else - strLng.Format("%s=%s", strID, out); - vStrTable.push_back(strLng); - } - else - { - poutrc->push_back(*it); - } - } - - if (vStrTable.size() > 0) - { - // write header - pol->push_back(CString("\r\n# String table\r\n[0]")); - - // copy data to the out lng - for (vector::iterator it=vStrTable.begin();it!=vStrTable.end();it++) - pol->push_back(*it); - } - - return true; -} - -bool WriteFiles(vector* prc, PCTSTR pszRCFile, vector* plng, PCTSTR pszLngFile) -{ - vector::iterator it; - try - { - CFile file1(pszRCFile, CFile::modeWrite | CFile::modeCreate); - CArchive ar1(&file1, CArchive::store); - - for (it=prc->begin();it != prc->end();it++) - ar1.WriteString((*it)+_T("\r\n")); - - ar1.Close(); - file1.Close(); - - CFile file2(pszLngFile, CFile::modeWrite | CFile::modeCreate); - CArchive ar2(&file2, CArchive::store); - - for (it=plng->begin();it != plng->end();it++) - ar2.WriteString((*it)+_T("\r\n")); - - ar2.Close(); - file2.Close(); - } - catch(...) - { - return false; - } - return true; -} - -struct CmpStr : public binary_function -{ - bool operator() (const CString& _Left, const CString& _Right) const - { - CString l=_Left.Left(_Left.Find("=")); - CString r=_Right.Left(_Right.Find("=")); - - return (_ttoi(l) <= _ttoi(r)); - } -}; - -void SortItems(vector* pv, int iHdrCnt) -{ - // find the begin and the end of section - vector::iterator st=pv->begin()+iHdrCnt, en; - while (st != pv->end()) - { - for (;st != pv->end();st++) - { - // find section beginning - if (st->Left(3) == "\r\n#" && st->Find("\r\n[") != -1) - { - st++; - break; - } - } - if (st != pv->end()) - { - en=st+1; - for (;en != pv->end();en++) - { - if (en->Left(3) == "\r\n#" && en->Find("\r\n[") != -1) - break; - } - - sort(st, en, CmpStr()); - st=en; - } - } -} - -int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) -{ // initialize MFC and print and error on failure - if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) + HMODULE hModule = ::GetModuleHandle(NULL); + if(!hModule) + return -1; + if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0)) { cerr << _T("Fatal Error: MFC initialization failed") << endl; return 1; } - // usage - chexe2lng infile.rc resource.h inheader.lng outfile.rc outfile.lng + // usage - rc2lng infile.rc resource.h inheader.lng outfile.rc outfile.lng if (argc < 6) { - cerr<<_T("Fatal Error: Incorrect numer of params") << endl; - cerr << _T("Usage: infile.rc inheader.lng outfile.rc outfile.lng resource.h resource2.h") << endl; - return 2; + wcerr << _T("Fatal Error: Incorrect numer of params") << endl; + wcerr << _T("Usage: infile.rc inheader.lng outfile.rc outfile.lng resource.h resource2.h") << endl; + return -1; } - // open the resource.h file and interprete it - map mID; - for (int i=5;i vOutLang; - if (!UpdateLngHeader(argv[2], &vOutLang)) - { - cerr<<"Fatal Error: Cannot read lang header file"< vRCIn, vRCOut; - if (!ReadRCFile(argv[1], &vRCIn)) + catch(icpf::exception& e) { - cerr<<"Fatal Error: Cannot read source RC file"< + + + +