1
// copyright (c) 2010-2012 Polos Ruetz
2
3
#include "eql.h"
4
#include "ecl_fun.h"
5
#include "gen/_lobjects.h"
6
#include <QApplication>
7
#include <QTimer>
8
#include <QStringList>
9
10
const char EQL::version[] = "12.2.3"; // 2012-02-21
11
12
static void eval(const char* lisp_code) {
13
    CL_CATCH_ALL_BEGIN(ecl_process_env()) {
14
        si_safe_eval(2, ecl_read_from_cstring((char*)lisp_code), Cnil); }
15
    CL_CATCH_ALL_END; }
16
17
extern "C" void ini_EQL(cl_object);
18
19
EQL::EQL() : QObject(), single_shot_fun(0) {
20
    cl_boot(1, QCoreApplication::argv());
21
    iniCLFunctions();
22
    LObjects::ini(this);
23
    read_VV(OBJNULL, ini_EQL); } // see src/make-eql-lib.lisp
24
25
EQL::~EQL() {
26
    LObjects::cleanUp();
27
    cl_shutdown(); }
28
29
QString EQL::home() {
30
    static QString path;
31
    if(path.isEmpty()) {
32
        path = QApplication::applicationDirPath();
33
#ifdef Q_OS_DARWIN
34
        path.truncate(path.lastIndexOf('/', path.indexOf(".app")));
35
#endif
36
        path.append('/'); }
37
    return path; }
38
39
void EQL::singleShot() {
40
    if(single_shot_fun) {
41
        CL_CATCH_ALL_BEGIN(ecl_process_env()) {
42
            cl_funcall(1, (cl_object)single_shot_fun); }
43
        CL_CATCH_ALL_END;
44
        single_shot_fun = 0; }}
45
46
void EQL::exec(const QStringList& args) {
47
    QStringList arguments(args);
48
    si_select_package(make_simple_base_string((char*)"EQL"));
49
    eval(QString("(set-home \"%1\")").arg(home()).toAscii().constData());
50
    bool tpl = false;
51
    QStringList forms;
52
    if(arguments.contains("-slime")) {
53
        arguments.removeAll("-slime");
54
        initialize_slime = true;
55
        forms << "(eql::set-slime-ini (in-home \"slime/\"))"; }
56
    if(arguments.count() == 1) {
57
        tpl = true;
58
        forms << "(si:top-level)"; }
59
    if(arguments.contains("-qgui")) {
60
        arguments.removeAll("-qgui");
61
        forms << "(qgui)"; }
62
#ifndef Q_OS_WIN
63
    if(arguments.contains("-qtpl")) {
64
        arguments.removeAll("-qtpl");
65
        tpl = true;
66
        forms << "(si::qtop-level)"; }
67
#endif
68
    if(arguments.count() > 1) {
69
        QString fileName(arguments.at(1));
70
#ifdef Q_OS_WIN
71
        fileName.replace('\\', '/');
72
#endif
73
        forms.prepend(QString("(load \"%1\")").arg(fileName)); }
74
    QString code;
75
    if(forms.length() == 1) {
76
        code = forms.first(); }
77
    else {
78
        code = "(progn " + forms.join(" ") + ")"; }
79
    eval(code.toAscii().constData());
80
    if(tpl) {
81
        qquit(); }}
82
83
void EQL::exec(lisp_ini ini, const QByteArray& expression, const QByteArray& package) {
84
    // see my_app example
85
    eval(QString("(eql::set-home \"%1\")").arg(home()).toAscii().constData());
86
    read_VV(OBJNULL, ini);
87
    si_select_package(make_simple_base_string((char*)package.toUpper().constData()));
88
    eval(expression.constData()); }
89
90
void EQL::exec(QWidget* widget, const QString& lispFile, const QString& slimeIniPath) {
91
    // see Qt_EQL example
92
    eval("(progn"
93
         "  (in-package :eql)"
94
         "  (defvar *slime-mode* nil)"
95
         "  (export '*slime-mode*))");
96
    QStringList forms;
97
    if(!slimeIniPath.isEmpty()) {
98
        initialize_slime = true;
99
        forms << QString("(eql::set-slime-ini \"%1\")").arg(slimeIniPath)
100
              << QString("(setf eql:*slime-mode* t)"); }
101
    forms << QString("(set-home \"%1\")").arg(home())
102
          << QString("(defvar *qt-main* (qt-object %1 0 (qid \"%2\")))")
103
                     .arg((ulong)widget)
104
                     .arg(QString(LObjects::vanillaQtSuperClassName(widget->metaObject())))
105
          << QString("(export '*qt-main*)")
106
          << QString("(load \"%1\")").arg(lispFile)
107
          << QString("(in-package :cl-user)");
108
    if(initialize_slime) {
109
        forms << "(si:top-level)"; }
110
    eval(QString("(progn " + forms.join(" ") + ")").toAscii().constData()); }
111
112
void EQL::iniSlime() {
113
    initialize_slime = false;
114
    eval("(load (eql::in-slime-ini \"ini\"))"); }
115
116
bool EQL::is_arg_return_value = false;
117
bool EQL::initialize_slime = false;
118
QEventLoop* EQL::eventLoop = 0;