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.5.1"; // 2012-05-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() {
20
    if(!cl_booted) {
21
        cl_boot(1, QCoreApplication::argv()); }
22
    iniCLFunctions();
23
    LObjects::ini(this);
24
    read_VV(OBJNULL, ini_EQL); } // see src/make-eql-lib.lisp
25
26
EQL::~EQL() {
27
    LObjects::cleanUp();
28
    cl_shutdown(); }
29
30
void EQL::ini(char** argv) {
31
    cl_booted = true;
32
    cl_boot(1, argv); }
33
34
QString EQL::home() {
35
    static QString path;
36
    if(path.isEmpty()) {
37
        path = QApplication::applicationDirPath();
38
#ifdef Q_OS_DARWIN
39
        path.truncate(path.lastIndexOf('/', path.indexOf(".app")));
40
#endif
41
        path.append('/'); }
42
    return path; }
43
44
void EQL::exec(const QStringList& args) {
45
    QStringList arguments(args);
46
    si_select_package(make_simple_base_string((char*)"EQL"));
47
    eval(QString("(set-home \"%1\")").arg(home()).toAscii().constData());
48
    bool quit = false;
49
    QStringList forms;
50
    if(arguments.contains("-slime")) {
51
        arguments.removeAll("-slime");
52
        initialize_slime = true;
53
        forms << "(eql::set-slime-ini (in-home \"slime/\"))"; }
54
    if(arguments.count() == 1) {
55
        quit = true;
56
        forms << "(si:top-level)"; }
57
    if(arguments.contains("-qgui")) {
58
        arguments.removeAll("-qgui");
59
        forms << "(qgui)"; }
60
#ifndef Q_OS_WIN
61
    if(arguments.contains("-qtpl")) {
62
        arguments.removeAll("-qtpl");
63
        quit = true;
64
        forms << "(si::qtop-level)"; }
65
#endif
66
    if(arguments.contains("-quic")) {
67
        arguments.removeAll("-quic");
68
        if(arguments.size() == 2) {
69
            quit = true;
70
            QString uiFile(QDir::fromNativeSeparators(arguments.at(1)));
71
            int sep = uiFile.lastIndexOf('/') + 1;
72
            QProcess::execute("uic -o ui.h " + uiFile);
73
            forms << QString("(eql:quic \"ui.h\" \"%1ui-%2.lisp\")")
74
                    .arg(uiFile.left(sep))
75
                    .arg(uiFile.mid(sep, uiFile.length() - sep - 3))
76
                  << QString("(delete-file \"ui.h\")"); }
77
        else {
78
            qDebug() << "Please pass a file.ui (Qt Designer)";
79
            exit(-1); }}
80
    else if(arguments.count() > 1) {
81
        QString fileName(QDir::fromNativeSeparators(arguments.at(1)));
82
        forms.prepend(QString("(load \"%1\")").arg(fileName)); }
83
    QString code;
84
    if(forms.length() == 1) {
85
        code = forms.first(); }
86
    else {
87
        code = "(progn " + forms.join(" ") + ")"; }
88
    eval(code.toAscii().constData());
89
    if(quit) {
90
        qquit(); }}
91
92
void EQL::exec(lisp_ini ini, const QByteArray& expression, const QByteArray& package) {
93
    // see my_app example
94
    eval(QString("(eql::set-home \"%1\")").arg(home()).toAscii().constData());
95
    read_VV(OBJNULL, ini);
96
    si_select_package(make_simple_base_string((char*)package.toUpper().constData()));
97
    eval(expression.constData()); }
98
99
void EQL::exec(QWidget* widget, const QString& lispFile, const QString& slimeIniPath) {
100
    // see Qt_EQL example
101
    eval("(progn"
102
         "  (in-package :eql)"
103
         "  (defvar *slime-mode* nil)"
104
         "  (export '*slime-mode*))");
105
    QStringList forms;
106
    if(!slimeIniPath.isEmpty()) {
107
        initialize_slime = true;
108
        forms << QString("(eql::set-slime-ini \"%1\")").arg(slimeIniPath)
109
              << QString("(setf eql:*slime-mode* t)"); }
110
    forms << QString("(set-home \"%1\")").arg(home())
111
          << QString("(defvar *qt-main* (qt-object %1 0 (qid \"%2\")))")
112
                     .arg((ulong)widget)
113
                     .arg(QString(LObjects::vanillaQtSuperClassName(widget->metaObject())))
114
          << QString("(export '*qt-main*)")
115
          << QString("(load \"%1\")").arg(lispFile)
116
          << QString("(in-package :cl-user)");
117
    if(initialize_slime) {
118
        forms << "(si:top-level)"; }
119
    eval(QString("(progn " + forms.join(" ") + ")").toAscii().constData()); }
120
121
void EQL::iniSlime() {
122
    initialize_slime = false;
123
    eval("(load (eql::in-slime-ini \"ini\"))"); }
124
125
bool EQL::cl_booted = false;
126
bool EQL::is_arg_return_value = false;
127
bool EQL::initialize_slime = false;
128
QEventLoop* EQL::eventLoop = 0;