~ubuntu-branches/ubuntu/karmic/psicode/karmic

« back to all changes in this revision

Viewing changes to src/bin/psirb/ruby.cc

  • Committer: Bazaar Package Importer
  • Author(s): Michael Banck, Michael Banck, Daniel Leidert
  • Date: 2009-02-23 00:12:02 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090223001202-rutldoy3dimfpesc
Tags: 3.4.0-1
* New upstream release.

[ Michael Banck ]
* debian/patches/01_DESTDIR.dpatch: Refreshed.
* debian/patches/02_FHS.dpatch: Removed, applied upstream.
* debian/patches/03_debian_docdir: Likewise.
* debian/patches/04_man.dpatch: Likewise.
* debian/patches/06_466828_fix_gcc_43_ftbfs.dpatch: Likewise.
* debian/patches/07_464867_move_executables: Fixed and refreshed.
* debian/patches/00list: Adjusted.
* debian/control: Improved description.
* debian/patches-held: Removed.
* debian/rules (install/psi3): Do not ship the ruby bindings for now.

[ Daniel Leidert ]
* debian/rules: Fix txtdir via DEB_MAKE_INSTALL_TARGET.
* debian/patches/01_DESTDIR.dpatch: Refreshed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*! \file
 
2
        \ingroup psirb
 
3
        \brief Contains Ruby initialization and some global functions.
 
4
*/
 
5
#include <ruby.h>
 
6
#include "psirb.h"
 
7
 
 
8
namespace psi { namespace psirb {
 
9
        
 
10
// Function declarations
 
11
bool initialize_ruby();
 
12
void load_input_file_into_ruby();
 
13
void process_input_file();
 
14
void finalize_ruby();
 
15
VALUE ruby_psi_print_version();
 
16
VALUE ruby_psi_get_version_major();
 
17
VALUE ruby_psi_get_version_minor();
 
18
bool create_ruby_psi_module();
 
19
 
 
20
// Defined elsewhere
 
21
extern void print_version();
 
22
 
 
23
/*! Initializes the Ruby interpreter, sets the Ruby $: and $0 variables, 
 
24
        adds the appropriate PSIDATADIR path to Ruby's search path,
 
25
    and also creates the Ruby-ized Psi objects. 
 
26
        \return true on success, false on failure
 
27
*/
 
28
bool initialize_ruby()
 
29
{
 
30
        char *psishare_dirname;
 
31
        
 
32
        // Setup and initialize interpreter
 
33
        ruby_init();
 
34
        
 
35
        // Initialize the $: (load path) variable; necessary if the input file loads any other modules
 
36
        ruby_init_loadpath();
 
37
        
 
38
        // Need to modify the load path of Ruby to include Psi's specific locations
 
39
        //  Get the global variable $:
 
40
        VALUE loadpath = rb_gv_get("$:");
 
41
        //  pop off the "." directory
 
42
        VALUE popped_value = rb_ary_pop(loadpath);
 
43
        
 
44
        // check to see what we need to add
 
45
        psishare_dirname = getenv("PSIDATADIR");
 
46
        if (psishare_dirname != NULL) {
 
47
                char *tmpstr = (char*)malloc(sizeof(char)*(strlen(psishare_dirname)+6));
 
48
                sprintf(tmpstr, "%s/ruby", psishare_dirname);
 
49
                psishare_dirname = tmpstr;
 
50
        }
 
51
        else {
 
52
                psishare_dirname = strdup(INSTALLEDPSIDATADIR "/ruby");
 
53
        }
 
54
        // Convert char* to Ruby string
 
55
        VALUE newpath = rb_str_new2(psishare_dirname);
 
56
        free(psishare_dirname);
 
57
        
 
58
        //  push on new location
 
59
        rb_ary_push(loadpath, newpath);
 
60
        //  push the "." location back on
 
61
        rb_ary_push(loadpath, popped_value);
 
62
        
 
63
        // Set the name of the Ruby script (and $0) to Psi
 
64
        ruby_script("Psi");
 
65
        
 
66
        // Add some basic functionality to Ruby
 
67
        create_ruby_psi_module();
 
68
        Task::create_ruby_class();
 
69
        ZEntry::create_ruby_class();
 
70
        Matrix::create_ruby_class();
 
71
        
 
72
        // Done
 
73
        return true;
 
74
}
 
75
 
 
76
/*! Loads the Ruby input file into the interpreter. Does not perform syntax checking, nor does
 
77
    it begin executing the code. Just checks to see if the file exists and loads it. */
 
78
void load_input_file_into_ruby()
 
79
{
 
80
        // Have Ruby do it
 
81
        rb_load_file(Globals::g_szInputFile.c_str());
 
82
}
 
83
 
 
84
/*! Run the input file. */
 
85
void process_input_file()
 
86
{
 
87
        // Process the input file
 
88
        // Since I do not want Ruby to take complete control of the system this is a 
 
89
        // hack version from Ruby's eval.c file function ruby_eval and ruby_stop
 
90
        // Typically you would call ruby_run but this function does not return at 
 
91
        // all from ruby_stop, it invokes an exit function call internally.
 
92
        int state;
 
93
    static int ex;
 
94
 
 
95
    if (ruby_nerrs > 0) exit(EXIT_FAILURE);
 
96
    state = ruby_exec();
 
97
    if (state && !ex) ex = state;
 
98
        ruby_cleanup(ex);
 
99
}
 
100
 
 
101
/*! Shutdown the interpreter */
 
102
void finalize_ruby()
 
103
{
 
104
        ruby_finalize();
 
105
}
 
106
 
 
107
//! Ruby function: Psi::Version::print_version 
 
108
/*! Prints out version information from the C-function print_version. 
 
109
        \return Qnil, the Ruby equivalent to NULL.
 
110
*/
 
111
VALUE ruby_psi_print_version()
 
112
{
 
113
        print_version();
 
114
        return Qnil;
 
115
}
 
116
 
 
117
//! Ruby function: indent_puts and Psi::indent_puts
 
118
/*! Increments the number of spaces that will appear at the beginning of a line printed
 
119
    with ''puts'' by 2. 
 
120
        \return Qnil, the Ruby equivalent to NULL.
 
121
*/
 
122
VALUE ruby_psi_indent_puts()
 
123
{
 
124
        Globals::g_iPutsIndent += 2;
 
125
        return Qnil;
 
126
}
 
127
 
 
128
//! Ruby funcation: unindent_puts and Psi::unindent_puts
 
129
/*! Decrements the number of spaces that will appear at the beginning of a line printed
 
130
    with ''puts' by 2. 
 
131
        \return Qnil, the Ruby equivalent to NULL.
 
132
*/
 
133
VALUE ruby_psi_unindent_puts()
 
134
{
 
135
        Globals::g_iPutsIndent -= 2;
 
136
        if (Globals::g_iPutsIndent < 0)
 
137
                Globals::g_iPutsIndent = 0;
 
138
        return Qnil;
 
139
}
 
140
 
 
141
//! Ruby function: Psi::Version::get_version_major
 
142
/*! \return The major version value for Psi */
 
143
VALUE ruby_psi_get_version_major()
 
144
{
 
145
        return INT2FIX(PSI_VERSION_MAJOR);
 
146
}
 
147
 
 
148
//! Ruby function: Psi::Version::get_version_minor
 
149
/*! \return The minor version value for Psi */
 
150
VALUE ruby_psi_get_version_minor()
 
151
{
 
152
        return INT2FIX(PSI_VERSION_MINOR);
 
153
}
 
154
 
 
155
//! Ruby function: puts
 
156
/*! This is an override of Ruby's standard puts function. This allows for indentation
 
157
    and redirection of the puts.
 
158
        \param argc Number of Ruby objects to print.
 
159
        \param argv C-array of Ruby objects to print.
 
160
        \return Qnil, the Ruby equvalent to NULL.
 
161
*/
 
162
VALUE ruby_psi_puts(int argc, VALUE *argv)
 
163
{
 
164
        int i;
 
165
        VALUE str;
 
166
        
 
167
        // If we are supposed to be quiet don't print anything
 
168
        if (Globals::g_bQuietRuby == false) {
 
169
                for (i=0; i<Globals::g_iPutsIndent; i++)
 
170
                        fprintf(Globals::g_fOutput, " ");
 
171
 
 
172
                for (i=0; i<argc; ++i) {
 
173
                // StringValue calls to_str on the object, if needed, to convert the object to a string.
 
174
                        VALUE str = StringValue(argv[i]);
 
175
                // Print the converted objected.
 
176
                        fprintf(Globals::g_fOutput, RSTRING(str)->ptr);
 
177
                }
 
178
                fprintf(Globals::g_fOutput, "\n");
 
179
                fflush(Globals::g_fOutput);
 
180
        }
 
181
        
 
182
        return Qnil;
 
183
}
 
184
 
 
185
//! Ruby function: Psi::quiet=
 
186
/*! If quiet=true then puts will not print anything when called */
 
187
VALUE ruby_psi_quiet_set(VALUE self, VALUE value)
 
188
{
 
189
        if (value == Qtrue)
 
190
                Globals::g_bQuietRuby = true;
 
191
        else
 
192
                Globals::g_bQuietRuby = false;
 
193
                
 
194
        return value;
 
195
}
 
196
 
 
197
//! Ruby function: Psi::quiet
 
198
/*! Returns the quiet value */
 
199
VALUE ruby_psi_quiet_get(VALUE self, VALUE value)
 
200
{
 
201
        if (Globals::g_bQuietRuby == true)
 
202
                return Qtrue;
 
203
        else
 
204
                return Qfalse;
 
205
}
 
206
 
 
207
//! Creates a module in the Ruby address space named Psi.
 
208
/*! All Psi objects/functions reside in this address space. Each function that is to be
 
209
        available to a user in the input file must be registered with Ruby.
 
210
        \returns true on success, false on failure.
 
211
*/
 
212
bool create_ruby_psi_module()
 
213
{
 
214
        // Handle for Version module
 
215
        VALUE rubyVersion;
 
216
        
 
217
        // Define a Ruby module named Psi
 
218
        Globals::g_rbPsi = rb_define_module("Psi");
 
219
        
 
220
        // Override some commands to ensure output is redirected to where we want
 
221
        // This redefines the global puts function to use our's
 
222
        rb_define_global_function("puts",          RUBYCAST(ruby_psi_puts), -1);
 
223
        rb_define_global_function("indent_puts",   RUBYCAST(ruby_psi_indent_puts), 0);
 
224
        rb_define_global_function("unindent_puts", RUBYCAST(ruby_psi_unindent_puts), 0);
 
225
        
 
226
        // Define methods that belong to Psi
 
227
        rb_define_module_function(Globals::g_rbPsi, "indent_puts",   RUBYCAST(ruby_psi_indent_puts), 0);
 
228
        rb_define_module_function(Globals::g_rbPsi, "unindent_puts", RUBYCAST(ruby_psi_unindent_puts), 0);
 
229
        rb_define_module_function(Globals::g_rbPsi, "quiet=",        RUBYCAST(ruby_psi_quiet_set), 1);
 
230
        rb_define_module_function(Globals::g_rbPsi, "quiet",         RUBYCAST(ruby_psi_quiet_get), 0);
 
231
        
 
232
        // Define a sub-module of Psi named Version
 
233
        rubyVersion = rb_define_module_under(Globals::g_rbPsi, "Version");
 
234
        
 
235
        // Add methods to the new module: Version
 
236
        rb_define_module_function(rubyVersion, "print_version", RUBYCAST(ruby_psi_print_version), 0);
 
237
        rb_define_module_function(rubyVersion, "get_major",     RUBYCAST(ruby_psi_get_version_major), 0);
 
238
        rb_define_module_function(rubyVersion, "get_minor",     RUBYCAST(ruby_psi_get_version_minor), 0);
 
239
                
 
240
        // Done
 
241
        return true;
 
242
}
 
243
 
 
244
}} // namespace psi::psirb