// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/> // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero 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 Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // VariableParserDlg.cpp : implementation file // #include "stdafx.h" #include "variable_parser.h" #include "variable_parserDlg.h" /*#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif*/ using namespace NLMISC; using namespace std; ///////////////////////////////////////////////////////////////////////////// // CVariableParserDlg dialog CVariableParserDlg::CVariableParserDlg(CWnd* pParent /*=NULL*/) : CDialog(CVariableParserDlg::IDD, pParent) { //{{AFX_DATA_INIT(CVariableParserDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } CVariableParserDlg::~CVariableParserDlg() { m_nomVariables.clear(); for ( uint i=0; i<m_variables.size(); i++ ) { m_variables[i].clear(); } m_variables.clear(); } void CVariableParserDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CVariableParserDlg) DDX_Control(pDX, IDC_VARDEF, m_varDefList); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CVariableParserDlg, CDialog) //{{AFX_MSG_MAP(CVariableParserDlg) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_HDR_BROWSE, OnHdrBrowse) ON_BN_CLICKED(IDC_TMPL_BROWSE, OnTmplBrowse) ON_BN_CLICKED(IDC_FOOT_BROWSE, OnFootBrowse) ON_BN_CLICKED(IDC_OUTPUT_BROWSE, OnOutputBrowse) ON_BN_CLICKED(IDC_GENERATE, OnGenerate) ON_BN_CLICKED(IDC_GEN_BROWSE, OnGenBrowse) ON_BN_CLICKED(IDC_LUA_BROWSE, OnLUABrowse) ON_BN_CLICKED(IDC_ADDVARDEF, OnAddvardef) ON_BN_CLICKED(IDC_REMVARDEF, OnRemvardef) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CVariableParserDlg message handlers BOOL CVariableParserDlg::OnInitDialog() { CDialog::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here return TRUE; // return TRUE unless you set the focus to a control } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CVariableParserDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CVariableParserDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CVariableParserDlg::OnHdrBrowse() { CFileDialog fileDlg( TRUE, NULL, NULL, OFN_OVERWRITEPROMPT, "Primitive file (*.primitive)|*.primitive||"); if ( fileDlg.DoModal() == IDOK ) { GetDlgItem( IDC_HDR_FILE )->SetWindowText( fileDlg.GetPathName() ); } } void CVariableParserDlg::OnTmplBrowse() { CFileDialog fileDlg( TRUE, NULL, NULL, OFN_OVERWRITEPROMPT, "Primitive file (*.primitive)|*.primitive||"); if ( fileDlg.DoModal() == IDOK ) { GetDlgItem( IDC_TMPL_FILE )->SetWindowText( fileDlg.GetPathName() ); } } void CVariableParserDlg::OnFootBrowse() { CFileDialog fileDlg( TRUE, NULL, NULL, OFN_OVERWRITEPROMPT, "Primitive file (*.primitive)|*.primitive||"); if ( fileDlg.DoModal() == IDOK ) { GetDlgItem( IDC_FOOT_FILE )->SetWindowText( fileDlg.GetPathName() ); } } void CVariableParserDlg::OnOutputBrowse() { CFileDialog fileDlg( FALSE, NULL, NULL, OFN_OVERWRITEPROMPT, "Primitive file (*.primitive)|*.primitive||"); if ( fileDlg.DoModal() == IDOK ) { GetDlgItem( IDC_OUTPUT_FILE )->SetWindowText( fileDlg.GetPathName() ); } } void CVariableParserDlg::OnGenBrowse() { CFileDialog fileDlg( TRUE, NULL, NULL, OFN_OVERWRITEPROMPT, "Comma Separated Values (*.csv)|*.csv||"); if ( fileDlg.DoModal() == IDOK ) { GetDlgItem( IDC_GEN_FILE )->SetWindowText( fileDlg.GetPathName() ); } } void CVariableParserDlg::OnLUABrowse() { CFileDialog fileDlg( TRUE, NULL, NULL, OFN_OVERWRITEPROMPT, "Lua files (*.lua)|*.lua||"); if ( fileDlg.DoModal() == IDOK ) { GetDlgItem( IDC_LUA_FILE )->SetWindowText( fileDlg.GetPathName() ); } } void CleanString( CSString &str ) { int i = (int)str.size(); bool ok = false; while ( !ok && ( i > 0 ) ) { char c = str.c_str()[i-1]; if ( !isalpha(c) && !isdigit(c) && ( c != '_' ) && ( c != ')' ) ) { i--; } else ok = true; } str = str.left( i ); } void CVariableParserDlg::ProcessGeneratorFile( const string& generatorFile ) { CSString genData, ligne; int colonneVar = 0; genData.readFromFile( generatorFile ); ligne = genData.splitTo( "\n", true ); while ( ligne != "" ) { CSString var = ligne.splitTo( ";", true ); CleanString( var ); if ( var != "" ) { m_nomVariables.push_back( var ) ; vector<string> vec; m_variables.push_back( vec ); } } while ( genData != "" ) { ligne = genData.splitTo( "\n", true ); if ( ligne != "" ) { for ( uint i=0;i<m_variables.size(); i++) { CSString var = ligne.splitTo( ";", true ); CleanString( var ); if ( var != "" ) { m_variables[i].push_back( var ); } } } } ParseParameters params; BuildParseParameters( params, 0, 0 ); } void CVariableParserDlg::BuildParseParameters( ParseParameters& params, uint ligne, uint colonne ) { CSString left = CSString( m_nomVariables[ colonne ] ).left(2); if ( left == "@@" ) { //if ( colonne+1 >= params.capacity() ) params.push_back( "" ); CString str = m_variables[colonne][ligne].c_str(); params[colonne] = str; if ( colonne+1 == m_variables.size() ) { ParseTemplate( params ); } else { BuildParseParameters( params, ligne, colonne+1 ); } } else if ( left == "##" ) { params.push_back( "" ); CString str = m_variables[colonne][0].c_str(); for ( uint j=(uint)m_nomVariables.size(); j>0; j-- ) { str.Replace( toString( "C%d", j-1 ).c_str(), params[j-1].c_str() ); } try { m_luaState.executeScript( str.GetBuffer( str.GetLength() ) ); } catch (ELuaError &e) { MessageBox( toString( "%s", e.luaWhat().c_str() ).c_str() ); return; } m_luaState.push("VAL"); m_luaState.getTable(LUA_GLOBALSINDEX); bool ok= false; sint type= m_luaState.type(); if ( type == LUA_TBOOLEAN ) { // get and pop bool val= m_luaState.toBoolean(); m_luaState.pop(); // set result if ( val ) str = "TRUE"; else str = "FALSE"; ok = true; } else if ( type == LUA_TNUMBER ) { // get and pop double val= m_luaState.toNumber(); m_luaState.pop(); // set double or integer? if ( val == floor( val ) ) str.Format( "%d", sint64( floor( val ) ) ); else str.Format( "%.3f", val ); ok = true; } else if ( type == LUA_TSTRING ) { // get and pop std::string val; m_luaState.toString(-1, val); m_luaState.pop(); // set result str = val.c_str(); ok = true; } if ( !ok ) { MessageBox( toString( "VAL is not defined on column %d", colonne ).c_str() ); } else { params[colonne] = str; if ( colonne+1 == m_variables.size() ) { ParseTemplate( params ); } else { BuildParseParameters( params, ligne, colonne+1 ); } } } else { for ( uint i=0; i<m_variables[colonne].size(); i++ ) { //if ( colonne+1 >= params.capacity() ) params.push_back( "" ); CString str; str = m_variables[colonne][i].c_str(); params[colonne] = str; if ( colonne+1 == m_variables.size() ) { ParseTemplate( params ); } else { BuildParseParameters( params, i, colonne+1 ); } } } } void CVariableParserDlg::ParseTemplate( const ParseParameters& params ) { CString tmp = m_templateText.c_str(); for ( uint i=0; i< m_nomVariables.size(); i++ ) { CSString toFind; if ( CSString( m_nomVariables[ i ] ).left(2) == "@@" ) { toFind = toString( "%s", m_nomVariables[i].c_str() ); } else if ( CSString( m_nomVariables[ i ] ).left(2) == "##" ) { toFind = toString( "%s", m_nomVariables[i].c_str() ); } else toFind = toString( "$$%s", m_nomVariables[i].c_str() ); tmp.Replace( toFind.c_str(), params[i].c_str() ); } m_outputText += tmp; } void CVariableParserDlg::OnGenerate() { CString error = ""; CSString hdr, foot; CString hdrFilename, templFileName, footFileName, outputFileName, luaFileName; GetDlgItem( IDC_HDR_FILE )->GetWindowText( hdrFilename ); if ( hdrFilename == "" ) error += "Header file name not set.\n"; GetDlgItem( IDC_FOOT_FILE )->GetWindowText( footFileName ); if ( footFileName == "" ) error += "Foot file name not set.\n"; GetDlgItem( IDC_TMPL_FILE )->GetWindowText( templFileName ); if ( templFileName == "" ) error += "Template file name not set.\n"; if ( m_varDefList.GetCount() == 0 ) error += "Generator file name not set.\n"; GetDlgItem( IDC_OUTPUT_FILE )->GetWindowText( outputFileName ); if ( outputFileName == "" ) error += "Output file name not set."; if ( error != "" ) { MessageBox( error, NULL, MB_OK ); } else { GetDlgItem( IDC_LUA_FILE )->GetWindowText( luaFileName ); if ( luaFileName != "" ) { m_luaState.executeFile( std::string( luaFileName ) ); } hdr.readFromFile( std::string( hdrFilename ) ); foot.readFromFile( std::string( footFileName ) ); m_templateText.readFromFile( std::string( templFileName ) ); m_outputText = hdr; for ( int i=0; i<m_varDefList.GetCount(); i++ ) { CString str; m_varDefList.GetText( i, str ); ProcessGeneratorFile( std::string( str ) ); m_variables.clear(); } m_outputText += foot; m_outputText.writeToFile( std::string( outputFileName ) ); MessageBox( "Done !" ); } } void CVariableParserDlg::OnAddvardef() { CFileDialog fileDlg( TRUE, NULL, NULL, OFN_OVERWRITEPROMPT|OFN_ALLOWMULTISELECT, "Comma Separated Values (*.csv)|*.csv||"); if ( fileDlg.DoModal() == IDOK ) { for ( POSITION pos = fileDlg.GetStartPosition(); pos != NULL; ) { CString str = fileDlg.GetNextPathName(pos); int index = m_varDefList.FindStringExact( 0, str ); if ( index == LB_ERR ) { m_varDefList.SetCurSel( m_varDefList.AddString( str ) ); } else m_varDefList.SetCurSel( index ); } } } void CVariableParserDlg::OnRemvardef() { int index = m_varDefList.GetCurSel(); if ( index != LB_ERR ) m_varDefList.DeleteString( index ); }