Big updates...

* alias calls work, and internal aliases can be registered through the
   script manager
 * Updated the build system to use cmake. Makes things so much nicer.


git-svn-id: file:///srv/svn/ircclient/trunk@5 a9804ffe-773b-11dd-bd7c-89c3ef1d2733
This commit is contained in:
Correl Roush 2009-04-17 02:45:22 +00:00
parent 0f7651d928
commit 1cf438da9b
17 changed files with 148 additions and 82 deletions

20
CMakeLists.txt Normal file
View file

@ -0,0 +1,20 @@
cmake_minimum_required (VERSION 2.6)
project (ircclient)
option (WITH_GUI "Build the GUI test app" ON)
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
find_package (Qt4 REQUIRED)
set (QT_DONT_USE_QTGUI TRUE)
set (QT_USE_QTNETWORK TRUE)
include (${QT_USE_FILE})
set (LIBS ${QT_LIBRARIES})
add_subdirectory(src)
add_subdirectory(mirc)
add_subdirectory(testapp)
if (WITH_GUI)
set (QT_DONT_USE_QTGUI FALSE)
include (${QT_USE_FILE})
set (LIBS ${QT_LIBRARIES})
add_subdirectory(guiapp)
endif()

16
guiapp/CMakeLists.txt Normal file
View file

@ -0,0 +1,16 @@
set (guiapp_SOURCES
main.cpp
messagehandler.cpp
)
set (guiapp_MOC_HEADERS
chatwindow.h
messagehandler.h
)
QT4_WRAP_CPP (guiapp_MOC_SOURCES ${guiapp_MOC_HEADERS})
QT4_WRAP_UI (guiapp_ui chatwindow.ui)
include_directories(${ircclient_SOURCE_DIR}/src)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
link_directories(${ircclient_BINARY_DIR}/src)
add_executable(guiapp ${guiapp_SOURCES} ${guiapp_MOC_SOURCES} ${guiapp_ui})
target_link_libraries (guiapp ircclient ${LIBS})

View file

@ -1,16 +0,0 @@
######################################################################
# Automatically generated by qmake (2.01a) Tue Aug 14 00:00:17 2007
######################################################################
TEMPLATE = app
TARGET = guiapp
DESTDIR = bin
DEPENDPATH += .
INCLUDEPATH += .
QT += network
# Input
HEADERS += chatwindow.h messagehandler.h ../src/ircclient.h ../src/dccserver.h
FORMS += chatwindow.ui
SOURCES += main.cpp messagehandler.cpp ../src/ircclient.cpp ../src/dccserver.cpp
TRANSLATIONS += guiapp_en.ts

View file

@ -1,13 +0,0 @@
######################################################################
# Automatically generated by qmake (2.01a) Mon Aug 13 14:31:09 2007
######################################################################
TEMPLATE = lib
TARGET = ircclient
DESTDIR = bin
DEPENDPATH += . src
INCLUDEPATH += . src
QT += network
# Input
HEADERS += src/ircclient.h
SOURCES += src/ircclient.cpp

17
mirc/CMakeLists.txt Normal file
View file

@ -0,0 +1,17 @@
set (mirc_SOURCES
src/mirc.cpp
src/parser.cpp
src/script.cpp
)
set (mirc_MOC_HEADERS
includes/mirc.h
includes/parser.h
includes/script.h
)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/includes)
QT4_WRAP_CPP (mirc_MOC_SOURCES ${mirc_MOC_HEADERS})
add_library (mirc STATIC ${mirc_SOURCES} ${mirc_MOC_SOURCES})
link_directories(${CMAKE_CURRENT_BINARY_DIR})
add_executable(mirctest src/main.cpp)
target_link_libraries (mirctest mirc ${LIBS})

View file

@ -3,9 +3,12 @@
#include <QObject> #include <QObject>
#include <QString> #include <QString>
#include <QStringList>
#include <QMap> #include <QMap>
#include <QVector> #include <QVector>
#include <QTextStream>
#include "script.h" #include "script.h"
#include "parser.h"
class MIRCScript; class MIRCScript;
@ -15,14 +18,18 @@ private:
QObject *parent; QObject *parent;
QVector<MIRCScript> scripts; QVector<MIRCScript> scripts;
QMap<QString, QString> _variables; QMap<QString, QString> _variables;
QMap<QString,void (*)(QStringList)> internal_aliases;
QMap<QString, mirc_alias> aliases;
QTextStream *output;
public: public:
MIRCScriptManager(QObject *parent = 0); MIRCScriptManager(QObject *parent = 0);
/* /*
bool load(QString filename); bool load(QString filename);
bool unload(QString filename); bool unload(QString filename);
QString call_alias(QString alias, QStringList arguments);
*/ */
void call_alias(QString alias, QStringList arguments);
bool register_alias(QString alias, void (*fn)(QStringList));
bool hasVariable(QString variable); bool hasVariable(QString variable);
QString variable(QString variable); QString variable(QString variable);
void variable(QString variable, QString value); void variable(QString variable, QString value);

View file

@ -51,6 +51,7 @@ private:
mirc_aliases::iterator current_alias; mirc_aliases::iterator current_alias;
mirc_variables::iterator current_variable; mirc_variables::iterator current_variable;
QStack<QStringList> stack; QStack<QStringList> stack;
public: public:
mirc_engine_stage stage; mirc_engine_stage stage;
mirc_alias script; mirc_alias script;
@ -69,6 +70,7 @@ public:
void assign_variable(char const* str, char const* end); void assign_variable(char const* str, char const* end);
void fetch_variable(char const*, char const*); void fetch_variable(char const*, char const*);
void append_expression(char const* str, char const *end); void append_expression(char const* str, char const *end);
void clear_stack(char const*, char const*);
}; };
struct mirc_script : public grammar<mirc_script> { struct mirc_script : public grammar<mirc_script> {
@ -109,6 +111,7 @@ struct mirc_script : public grammar<mirc_script> {
s_action v_fetch ( bind( &mirc_script_engine::fetch_variable, self.actions, _1, _2 ) ); s_action v_fetch ( bind( &mirc_script_engine::fetch_variable, self.actions, _1, _2 ) );
s_action e_append ( bind( &mirc_script_engine::append_expression, self.actions, _1, _2 ) ); s_action e_append ( bind( &mirc_script_engine::append_expression, self.actions, _1, _2 ) );
s_action s_code ( bind( &mirc_script_engine::store_code, self.actions, _1, _2 ) ); s_action s_code ( bind( &mirc_script_engine::store_code, self.actions, _1, _2 ) );
s_action c_stack ( bind( &mirc_script_engine::clear_stack, self.actions, _1, _2 ) );
script script
= *( = *(
@ -150,7 +153,7 @@ struct mirc_script : public grammar<mirc_script> {
; ;
alias_action alias_action
= !ch_p('/') >> !ch_p('/') = !ch_p('/') >> !ch_p('/')
>> identifier >> *space >> parameters >> (identifier >> *(*space >> parameters))[a_call]
; ;
alias_function alias_function
= ch_p('$') >> identifier = ch_p('$') >> identifier
@ -173,7 +176,7 @@ struct mirc_script : public grammar<mirc_script> {
assignment /* Must come first to avoid "var" being caught as an action */ assignment /* Must come first to avoid "var" being caught as an action */
| alias_action | alias_action
)[s_code] )[s_code]
) )[c_stack]
>> !eol_p >> !eol_p
; ;
code_block code_block

View file

@ -14,6 +14,8 @@ private:
QString script; QString script;
QMap<QString, mirc_alias> _aliases; QMap<QString, mirc_alias> _aliases;
QMap<QString, QString> _variables; QMap<QString, QString> _variables;
mirc_script_engine *interpreter;
mirc_script *parser;
bool loaded; bool loaded;
public: public:
MIRCScript(MIRCScriptManager *m); MIRCScript(MIRCScriptManager *m);

View file

@ -1,17 +0,0 @@
######################################################################
# Automatically generated by qmake (2.01a) Sat Aug 30 23:01:47 2008
######################################################################
TEMPLATE = app
# CONFIG += plugin
TARGET = mirc
DESTDIR = bin
DEPENDPATH += . includes src
INCLUDEPATH += . includes
# Input
HEADERS += includes/mirc.h includes/parser.h includes/script.h
SOURCES += src/mirc.cpp \
src/parser.cpp \
src/script.cpp \
src/main.cpp

View file

@ -1,36 +1,50 @@
#include <QTextStream> #include <QTextStream>
#include "script.h" #include "script.h"
void alias_echo(QStringList arguments) {
QTextStream output(stdout);
output << "[ECHO] " << arguments.join(" ") << "\n";
}
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
QTextStream output(stdout); QTextStream output(stdout);
output << "Creating manager\n"; output << "* Creating manager\n";
MIRCScriptManager *mirc = new MIRCScriptManager; MIRCScriptManager *mirc = new MIRCScriptManager;
output << "Creating script object\n"; mirc->register_alias("echo", &alias_echo);
output << "* Creating script object\n";
MIRCScript *ms = new MIRCScript(mirc); MIRCScript *ms = new MIRCScript(mirc);
if (argc < 2) { if (argc < 2) {
output << "No mIRC script file was specified!\n"; output << "! No mIRC script file was specified!\n";
return(1); return(1);
} }
output << "Attempting to load " << argv[1] << "\n"; output << "* Attempting to load " << argv[1] << "\n";
if (ms->load(argv[1])) { if (ms->load(argv[1])) {
output << "MRC LOADED\n"; output << "* MRC LOADED\n";
output << "Code:\n" << ms->code(); output << "Code:\n" << ms->code();
output << "Aliases:\n"; output << "Aliases:\n";
QMapIterator<QString, mirc_alias> alias(ms->aliases()); QMapIterator<QString, mirc_alias> alias(ms->aliases());
while(alias.hasNext()) { while(alias.hasNext()) {
alias.next(); alias.next();
output << (alias.value().global ? "global" : "local"); output << (alias.value().global ? "global" : "local");
output << " " << alias.key() << "\n"; output << " " << alias.key() << "()\n";
} }
output << "---\n";
if (ms->run()) { if (ms->run()) {
output << "MRC RAN SUCCESSFULLY\n"; output << "\n---\nMRC RAN SUCCESSFULLY\n";
QMapIterator<QString, QString> i(mirc->variables()); QMapIterator<QString, QString> i(mirc->variables());
output << "Variables:\n"; output << "Variables:\n";
while(i.hasNext()) { while(i.hasNext()) {
i.next(); i.next();
output << i.key() << " = " << i.value() << "\n"; output << i.key() << " = " << i.value() << "\n";
} }
output << "Aliases:\n";
QMapIterator<QString, mirc_alias> alias(ms->aliases());
while(alias.hasNext()) {
alias.next();
output << (alias.value().global ? "global" : "local");
output << " " << alias.key() << "()\n";
}
} }
} else { } else {
output << "Failed to load " << argv[1] << "\n"; output << "Failed to load " << argv[1] << "\n";

View file

@ -18,4 +18,16 @@ void MIRCScriptManager::variable(QString variable, QString value) {
QMap<QString, QString> MIRCScriptManager::variables() { QMap<QString, QString> MIRCScriptManager::variables() {
return _variables; return _variables;
}
void MIRCScriptManager::call_alias(QString alias, QStringList arguments) {
// This is where we flip through and attempt to call an alias
//mirc_script_engine::alias_echo(QStringList("[MANAGER]") << alias << arguments);
if (internal_aliases.find(alias) != internal_aliases.end()) {
internal_aliases[alias](arguments);
}
}
bool MIRCScriptManager::register_alias(QString alias, void (*fn)(QStringList)) {
internal_aliases[alias] = fn;
} }

View file

@ -1,3 +1,4 @@
#include <QTextStream>
#include "parser.h" #include "parser.h"
#include "mirc.h" #include "mirc.h"
@ -12,8 +13,9 @@ void mirc_script_engine::handle_alias_definition(char const* str, char const* en
if (stage != PARSE) return; if (stage != PARSE) return;
string s(str, end); string s(str, end);
aliases.insert(s.c_str(), mirc_alias(true)); QString alias(s.c_str());
current_alias = aliases.find(s.c_str()); this->aliases.insert(alias, mirc_alias(true));
current_alias = this->aliases.find(alias);
} }
void mirc_script_engine::handle_alias_definition_local(char const* str, char const* end) { void mirc_script_engine::handle_alias_definition_local(char const* str, char const* end) {
if (stage != PARSE) return; if (stage != PARSE) return;
@ -39,9 +41,12 @@ void mirc_script_engine::store_code(char const* str, char const* end) {
script.code.append(s.c_str()).append("\n"); script.code.append(s.c_str()).append("\n");
} }
} }
void mirc_script_engine::call_alias(char const*, char const*) { void mirc_script_engine::call_alias(char const* str, char const* end) {
if (stage != EXECUTE) return; if (stage != EXECUTE) return;
string s(str, end);
QStringList params = QString(s.c_str()).split(" ");
QString alias = params.takeFirst();
manager->call_alias(alias, stack.top());
} }
void mirc_script_engine::return_alias(char const*, char const*) { void mirc_script_engine::return_alias(char const*, char const*) {
} }
@ -88,3 +93,7 @@ void mirc_script_engine::append_expression(char const* str, char const *end) {
} }
stack.push(list); stack.push(list);
} }
void mirc_script_engine::clear_stack(char const*, char const*) {
stack.clear();
}

View file

@ -3,6 +3,8 @@
MIRCScript::MIRCScript(MIRCScriptManager *m) { MIRCScript::MIRCScript(MIRCScriptManager *m) {
manager = m; manager = m;
interpreter = new mirc_script_engine(manager);
parser = new mirc_script(interpreter);
} }
bool MIRCScript::load(QString filename) { bool MIRCScript::load(QString filename) {
@ -17,9 +19,7 @@ bool MIRCScript::load(QString filename) {
} }
bool MIRCScript::parse(QString code) { bool MIRCScript::parse(QString code) {
mirc_script_engine *interpreter = new mirc_script_engine(manager); parse_info<> info = boost::spirit::parse((const char*)code.toLatin1(), *parser);
mirc_script parser(interpreter);
parse_info<> info = boost::spirit::parse((const char*)code.toLatin1(), parser);
loaded = info.full; loaded = info.full;
if (loaded) { if (loaded) {
script = interpreter->script.code; script = interpreter->script.code;
@ -30,10 +30,8 @@ bool MIRCScript::parse(QString code) {
bool MIRCScript::run() { bool MIRCScript::run() {
if (!loaded) return false; if (!loaded) return false;
mirc_script_engine *interpreter = new mirc_script_engine(manager);
interpreter->stage = EXECUTE; interpreter->stage = EXECUTE;
mirc_script parser(interpreter); parse_info<> info = boost::spirit::parse((const char*)script.toLatin1(), *parser);
parse_info<> info = boost::spirit::parse((const char*)script.toLatin1(), parser);
if (info.full) { if (info.full) {
_variables = interpreter->vars; _variables = interpreter->vars;
} }

View file

@ -1,8 +1,9 @@
; Hey, here's some test code ; Hey, here's some test code
set name Correl set name Correl
%first = Correl %first = Correl
%middle = Joseph
%name = %first $& %name = %first $&
Roush %middle Roush
echo Hello, %name! echo Hello, %name!
alias dostuff { alias dostuff {
; Not very useful, but good for testing the parser! ; Not very useful, but good for testing the parser!
@ -14,3 +15,6 @@ alias -l dosomethingelse {
; Useless local alias! ; Useless local alias!
echo -s Busy doing nothing echo -s Busy doing nothing
} }
dostuff that nobody will see
dosomethingelse entirely
donothing because this alias doesn't exist

10
src/CMakeLists.txt Normal file
View file

@ -0,0 +1,10 @@
set (irclib_SOURCES
ircclient.cpp
dccserver.cpp
)
set (irclib_MOC_HEADERS
ircclient.h
dccserver.h
)
QT4_WRAP_CPP (irclib_MOC_SOURCES ${irclib_MOC_HEADERS})
add_library (ircclient STATIC ${irclib_SOURCES} ${irclib_MOC_SOURCES})

14
testapp/CMakeLists.txt Normal file
View file

@ -0,0 +1,14 @@
set (cliapp_SOURCES
main.cpp
testapp.cpp
)
set (cliapp_MOC_HEADERS
testapp.h
)
QT4_WRAP_CPP (cliapp_MOC_SOURCES ${cliapp_MOC_HEADERS})
include_directories(${ircclient_SOURCE_DIR}/src)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
link_directories(${ircclient_BINARY_DIR}/src)
add_executable(cliapp ${cliapp_SOURCES} ${cliapp_MOC_SOURCES} ${cliapp_ui})
target_link_libraries (cliapp ircclient ${LIBS})

View file

@ -1,14 +0,0 @@
######################################################################
# Automatically generated by qmake (2.01a) Mon Aug 13 15:01:40 2007
######################################################################
TEMPLATE = app
TARGET = testapp
DESTDIR = bin
DEPENDPATH += .
INCLUDEPATH += .
QT += network
# Input
HEADERS += testapp.h ../src/ircclient.h
SOURCES += main.cpp testapp.cpp ../src/ircclient.cpp