* basic::collec() never worked correctly on non-polynomials till now.
[ginac.git] / cint / ginaccint.cpp
index 724bffb38476141e7f4a563b4eae28d3b46d4f25..cd875e90879a58004a855e9427274b5cd4fbe4a4 100644 (file)
-#include "G__ci.h"   /* G__atpause is defined in G__ci.h */
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <stdio.h>
-#include <stdlib.h>
-#include <ginac/ginac.h>
-#include <list>
-
-extern "C" G__value G__exec_tempfile G__P((char *file));
-extern "C" void G__store_undo_position(void);
-
-#ifdef OBSCURE_CINT_HACK
-
-#include <strstream>
-
-template<class T>
-string ToString(T const & t)
-{
-    char buf[256];
-    ostrstream(buf,sizeof(buf)) << t << ends;
-    return buf;
-}
-
-basic * ex::last_created_or_assigned_bp=0;
-
-#endif // def OBSCURE_CINT_HACK
-
-typedef list<char *> cplist;
-
-cplist filenames;
-
-void cleanup(void)
-{
-    for (cplist::iterator it=filenames.begin(); it!=filenames.end(); ++it) {
-        cout << "removing file " << *it << endl;
-        remove(*it);
-        free(*it);
-    }
-}
-
-void sigterm_handler(int n)
-{
-    exit(1);
-}
+/* ginaccint.cpp, a launcher that sets variables to start ginaccint.bin.
+ * This is necessary because Cint is not libtoolized and so may need to have 
+ * LD_LIBRARY_PATH and CINTSYSDIR set.  This cannot be done by a shell-script
+ * because the #!-mechanism works only once and we want to enable the user to
+ * write scripts using that mechanism. */
 
-bool is_whitespace_char(char c)
-{
-    return ((c==' ')||(c=='\t')||(c=='\n')||(c=='\r')); 
-}
-
-char first_non_whitespace_char(char const * s)
-{
-    int l=strlen(s);
-    int pos=0;
-    while ((pos<l)&&is_whitespace_char(s[pos])) pos++;
-    return s[pos];
-}    
-
-char last_non_whitespace_char(char const * s)
-{
-    int pos=strlen(s)-1;
-    while ((pos>=0)&&is_whitespace_char(s[pos])) pos--;
-    return s[pos];
-}    
-
-string strip_whitespace(string const & s)
-{
-    string s2;
-    int l=s.length();
-    for (int pos=0; pos<l; ++pos) {
-        if (!is_whitespace_char(s[pos])) s2 += s[pos];
-    }
-    return s2;
-}
-
-G__value exec_tempfile(string const & command)
-{
-    G__value retval;
-    char *tmpfilename=tempnam(NULL,"ginac");
-    ofstream fout;
-    fout.open(tmpfilename);
-    fout << "{" << endl << command << endl << "}" << endl;
-    fout.close();
-    G__store_undo_position();
-    retval=G__exec_tempfile(tmpfilename);
-    G__security_recover(stdout);
-    remove(tmpfilename);
-    free(tmpfilename);
-    return retval;
-}
-
-char * process_permanentfile(string const & command)
-{
-    char *tmpfilename=tempnam(NULL,"ginac");
-    cout << "creating file " << tmpfilename << endl;
-    ofstream fout;
-    fout.open(tmpfilename);
-    fout << command << endl;
-    fout.close();
-    G__store_undo_position();
-    G__loadfile(tmpfilename);
-    G__security_recover(stdout);
-    return tmpfilename;
-}
-
-void process_tempfile(string const & command)
-{
-#ifdef OBSCURE_CINT_HACK
-    static G__value ref_symbol=exec_tempfile("symbol ginac_cint_internal_symbol; ginac_cint_internal_symbol;");
-    static G__value ref_ex=exec_tempfile("ex ginac_cint_internal_ex; ginac_cint_internal_ex;");
-    static G__value ref_function=exec_tempfile("sin(ginac_cint_internal_symbol);");
-    static G__value ref_power=exec_tempfile("power(ginac_cint_internal_symbol,ginac_cint_internal_symbol);");
-#endif // def OBSCURE_CINT_HACK
-
-    G__value retval=exec_tempfile(command);
-
-#ifdef OBSCURE_CINT_HACK
-
-    #define TYPES_EQUAL(A,B) (((A).type==(B).type)&&((A).tagnum==(B).tagnum))
-    
-    static unsigned out_count=0;
-    if (TYPES_EQUAL(retval,ref_ex)) {
-        if (ex::last_created_or_assigned_bp_can_be_converted_to_ex()) {
-            string varname="out"+ToString(++out_count);
-            exec_tempfile("ex "+varname+"(*ex::last_created_or_assigned_bp);\n"
-                          +"LLLAST=LLAST;\n"
-                          +"LLAST=LAST;\n"
-                          +"LAST="+varname+";\n"
-                          +"cout << \""+varname+"   \" << "+varname+" << endl << endl;"); 
-        } else {
-            cout << "warning: last_created_or_assigned_bp modified 0 or not evaluated or not dynallocated" << endl;
-        }
-    }
-#endif // def OBSCURE_CINT_HACK
-}
-
-void greeting(void)
-{
-    cout << "Welcome to GiNaC-cint V" << VERSION << endl;
-    cout << "This software is provided \"as is\" without any warranty.  Copyright of Cint is" << endl
-         << "owned by Agilent Technologies Japan and Masaharu Goto.  Registration is" << endl
-         << "  __,  _______  requested, at this moment, for commercial use.  Send e-mail to" << endl
-         << " (__) *       | <MXJ02154@niftyserve.or.jp>.  The registration is free." << endl
-         << "  ._) i N a C | The GiNaC framework is Copyright by Johannes Gutenberg Univ." << endl
-         << "<-------------' Germany and licensed under the terms and conditions of the GPL." << endl << endl;
-    cout << "To quit, type 'quit;', 'exit;', 'bye;', '.q', '.quit', '.exit' or '.bye'" << endl;
-}
-
-int main(void) 
-{
-    char *line;
-    char prompt[G__ONELINE];
-
-    greeting();
-
-    atexit(cleanup);
-    signal(SIGTERM,sigterm_handler);
-    
-    G__init_cint("cint");    /* initialize cint */
-
-    exec_tempfile("#include <string>\n");
-    exec_tempfile("ex LAST,LLAST,LLLAST;\n");
-    
-    bool quit=false;
-    bool next_command_is_function=false;    
-    while (!quit) {
-        strcpy(prompt,"GiNaC> ");
-        int open_braces=0;
-        bool end_of_command=false;
-        string command;
-        while (!end_of_command) {
-            line=G__input(prompt);
-        
-            int pos = 0;
-           bool double_quote=false;
-            bool single_quote=false;
-            while(line[pos]!='\0') {
-                switch(line[pos]) {
-                case '"':
-                    if (!single_quote) double_quote = !double_quote;
-                    break;
-                case '\'':
-                    if (!double_quote) single_quote = !single_quote;
-                    break;
-                case '{':
-                    if ((!single_quote)&&(!double_quote)) open_braces++;
-                    break;
-                case '}':
-                    if ((!single_quote)&&(!double_quote)) open_braces--;
-                    break;
-                }
-                pos++;
-            }
-            command += line;
-            command += '\n';
-            if (open_braces==0) {
-                if ((first_non_whitespace_char(command.c_str())=='#')||
-                    (first_non_whitespace_char(command.c_str())=='.')||
-                    (last_non_whitespace_char(command.c_str())==';')||
-                    (last_non_whitespace_char(command.c_str())=='}')) {
-                    end_of_command=true;
-                }
-            }
-            strcpy(prompt,"     > ");
-        }
-        string stripped_command=strip_whitespace(command);
-        if ((stripped_command=="quit;")||
-            (stripped_command=="exit;")||
-            (stripped_command=="bye;")||
-            (stripped_command==".q")||
-            (stripped_command==".quit")||
-            (stripped_command==".exit")||
-            (stripped_command==".bye")) {
-            quit=true;
-        } else if (stripped_command==".function") {
-            cout << "next expression can be a function definition" << endl;
-            next_command_is_function=true;
-        } else if (stripped_command==".cint") {
-            cout << endl << "switching to cint interactive mode" << endl;
-            cout << "'h' for help, 'q' to quit, '{ statements }' or 'p [expression]' to evaluate" << endl;
-            G__pause();
-            cout << "back from cint" << endl;
-        } else if (command[0]=='.') {
-            cout << "special command (TBD): " << command << endl;
-        } else {
-           // cout << "now processing: " << command << endl;
-            if (next_command_is_function) {
-                next_command_is_function=false;
-                filenames.push_back(process_permanentfile(command));
-            } else {
-                process_tempfile(command);
-            }
-        }
-    }
-
-    return 0;
+#include <unistd.h>
+#include <stdlib.h>
+#include <string>
+#include <iostream>
+#include "launch.h"
+
+extern char **environ;
+
+int main(int argc, char * *argv)
+{
+       // manually "expand" autoconf-style variables
+       if (exec_prefix=="${prefix}")
+               exec_prefix = prefix;
+       if (bindir=="${exec_prefix}/bin")
+               bindir = exec_prefix + "/bin";
+       if (libdir=="${exec_prefix}/lib")
+               libdir = exec_prefix + "/lib";
+       // now we can guess what to start
+       std::string binprog = bindir + "/ginaccint.bin";
+       
+       // extend LD_LIBRARY_PATH by libdir, so ginaccint.bin really finds libginac
+       const char * LD_LIBRARY_PATH = getenv("LD_LIBRARY_PATH");
+       if (LD_LIBRARY_PATH == NULL)
+               setenv("LD_LIBRARY_PATH", libdir.c_str(), 1);
+       else
+               setenv("LD_LIBRARY_PATH", (std::string(LD_LIBRARY_PATH)+':'+libdir).c_str(), 1);
+       
+       // hard-wire CINTSYSDIR, inherited from configure, but only if it has
+       // been set therein (to allow for system-wide installations of cint)
+       // and without overriding it if the user has specified it.
+       if (CINTSYSDIR != "@CINTSYSDIR@")
+               setenv("CINTSYSDIR", CINTSYSDIR.c_str(), 0);
+       
+       // execute the real thing
+       int error = execve(binprog.c_str(), argv, environ);
+       
+       // only gets here on error
+       std::cerr << argv[0] << ": cannot exec " << binprog << std::endl;
+       return error;
 }
-
-
-
-
-
-
-