500 lines
12 KiB
C++
500 lines
12 KiB
C++
// 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 );
|
|
}
|