guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: emebedding guile line command interpretor


From: Brett Viren
Subject: Re: emebedding guile line command interpretor
Date: Wed, 7 Feb 2001 08:44:01 -0500 (EST)

Hilaire Fernandes writes:
 > 
 > I want to embed Guile in a C/C++ application, DrGenius, bu I also
 > want to embed an interactice guile shell in the application.

It never ceases to amaze me how often it happens that when I need some
info myself, it is asked on some list I am on.  I too am in the market
for mixing C++ (gtk--) app with guile in order to provide integrated
interactive access to scheme.

Besides the other suggestions you got, which sound like good
directions to follow, one easy way would be to use a text entry widget
(ie, Gtk::Entry) for short scheme and allow the user to spawn an
editor for more complicated code.  It doesn't really match all your
requirements and isn't completely interactive, but it is easy to
impliment.

For my own sake, I produced an example of this.  You may also find it
useful.


-Brett.

/////////////////
// blah.cxx
// to compile (-lqthreads may not be needed on all systems):
// g++  -g -Wall -O -o blah blah.cxx `gtkmm-config --cflags --libs` -lguile 
-lgthreads -lm
//
#include <guile/gh.h>

#include <gtk--/main.h>
#include <gtk--/window.h>
#include <gtk--/entry.h>
#include <gtk--/button.h>
#include <gtk--/box.h>

#include <sigc++/slot.h>

#include <cstdio>  // guile uses stdio, so need to mix it in here also
#include <cstdlib> // for getenv
#include <iostream>
#include <fstream>

class Main : public Gtk::Window
{
    Gtk::HBox m_hbox;
    Gtk::Entry m_entry;
    Gtk::Button m_editor;
    Gtk::Button m_close;

    gint delete_event_impl(GdkEventAny*) { Gtk::Main::quit(); return 0; }

    void EnterCallback();
    void Editor();

public:

    Main();
};

Main::Main() :
    m_hbox(false,0),
    m_entry(1024),
    m_editor("Use Editor"),
    m_close("Quit")
{
    set_title("Test GuileEntry");
    add(m_hbox);

    m_entry.activate.connect(SigC::slot(this,&Main::EnterCallback));
    m_entry.set_text("(display ())");
    m_hbox.pack_start(m_entry);

    m_editor.clicked.connect(SigC::slot(this,&Main::Editor));
    m_hbox.pack_start(m_editor);

    m_close.clicked.connect(Gtk::Main::quit.slot());
    m_hbox.pack_start(m_close);

    show_all();
}

void Main::EnterCallback()
{
    printf("%s\n",m_entry.get_text().c_str());
    SCM retval = gh_eval_str_with_standard_handler(m_entry.get_text().c_str());
    gh_display(retval); gh_newline();
}
    
void Main::Editor()
{
    char filename[128] = "/tmp/guile-entryXXXXXX";
    const char* editor = getenv("EDITOR");
    if (!editor) editor = "vi";

    std::mkstemp(filename);
    std::sprintf(filename+strlen(filename),".scm");

    FILE* fp = std::fopen(filename,"w");
    fprintf(fp,"%s",m_entry.get_text().c_str());
    fclose (fp);

    char cmd[1024];
    if (0 > snprintf(cmd,1024,"%s %s",editor,filename)) {
        cerr << "To long! what are you trying to pull?:\n";
        cerr << editor << endl;
        return;
    }

    int retval = system(cmd);
    if (retval) {
        cerr << "Got error: `" << retval << "'\n";
        return;
    }

    ifstream* fstr = new ifstream(filename);
    string scmstr("");
    string line;
    while (getline(*fstr,line)) {
        scmstr += line;
        scmstr += " ";
    }
    delete fstr;
    std::remove(filename);

    m_entry.set_text(scmstr.c_str());
    cerr << "Set: `" << scmstr << "'\n";
}

void real_main(int argc, char** argv)
{
    Gtk::Main app(&argc,&argv);
    Main m;
    app.run();
}

int main (int argc, char *argv[])
{
    gh_enter(argc,argv,real_main);
    return 0;
} // end of main()





reply via email to

[Prev in Thread] Current Thread [Next in Thread]