From: Alexander Frink Date: Thu, 11 May 2000 21:12:18 +0000 (+0000) Subject: More features for GiNaC-cint: X-Git-Tag: release_0-6-0~3 X-Git-Url: https://ginac.de/ginac.git/static/gitweb.css/ginac.git?a=commitdiff_plain;h=daf00c7b3df31dd3d8af84c7ed9cc7caa2c3f62c;p=ginac.git More features for GiNaC-cint: restart environment redirect output updated man page --- diff --git a/cint/ginaccint.1 b/cint/ginaccint.1 index aef0b0a6..3ae66b8a 100644 --- a/cint/ginaccint.1 +++ b/cint/ginaccint.1 @@ -3,6 +3,7 @@ GiNaC-cint \- An interactive interface for GiNaC based on the Cint C/C++ interpreter .SH SYNPOSIS .B ginaccint +[file ...] .SH DESCRIPTION .B ginaccint is an interactive frontend for the GiNaC symbolic computation @@ -14,7 +15,11 @@ scripts and later compiled with the native compiler and linked into the system. .SH USAGE .SS INPUT FORMAT -After startup, ginsh displays a prompt signifying that it is ready to +After startup, GiNaC-cint reads and executes the files given as +command line arguments. If any of these files contains a +.BR .quit +command, GiNaC-cint exits at this point. +Otherwise it displays a prompt signifying that it is ready to accept your input. All C++ statements are valid as input, extended by GiNaC's numeric or symbolic expressions. E.g. .BR fibonacci(24)/1104; @@ -44,6 +49,7 @@ is encountered. .SS SPECIAL COMMANDS .IP "\fB.cint\fR" Switch to cint's interactive mode. + .IP "\fB.function\fR" Allow a function definition in interactive mode. GiNaC-cint must be @@ -51,14 +57,51 @@ put into a special mode in order to define a function. After that any function definition in valid C++ syntax may be typed in. It becomes immediatly available for usage. -.IP "\fBquit;\fR" +.IP "\fB.help\fB" + +List a short summary of available commands. + +.IP "\fB.quit\fR" Exit from GiNaC-cint. Same as -.BR "exit;" , -.BR "bye;" , +.BR ".bye" , +.BR ".exit" , .BR ".q" , -.BR ".quit" , -.BR ".exit " or -.BR ".bye" . +.BR "bye;" , +.BR "exit; " or +.BR "quit;" . + +.IP "\fB.read filename\fB" + +Read a file from disk and execute it in GiNaC-cint +(recursive call is possible). + +.IP "\fB.redirect [filename]\fB" + +Redirect +.BR "\fBOut\fP\fInum\fP" +output to a file ( +.BR .redirect +alone redirects output to console). + +.IP "\fB.restart\fB" + +Restart GiNaC-cint (does not re-read command line files). + +.IP "\fB.save filename\fB" + +Save the commands you have entered so far in a file. + +.IP "\fB.silent\fB" + +suppress +.BR "\fBOut\fP\fInum\fP" +output (variables are still accessible). + +.IP "\fB.> [filename]\fB" + +same as +.BR "\fB.redirect [filename]\fB" +. .IP "\fBOut\fP\fInum\fP" Returns the expression whose output was marked @@ -112,7 +155,7 @@ The GCD of -3+2*x*z*y+x^2*z^2*y^2 and 3-4*x*z*y+x^2*z^2*y^2 is -1+x*z*y so (-3+2*x*z*y+x^2*z^2*y^2)*(3-4*x*z*y+x^2*z^2*y^2)^(-1) is (-3+x*z*y)^(-1)*(3+x*z*y) -GiNaC> quit; +GiNaC> .quit .fi .SH BUGS @@ -137,7 +180,8 @@ after declaring them. This accounts for some funny behaviour, like doesn't print, but .BR fibonacci(7)*1 does, since this is not a naked number but an expression holding -that number. +that number. A warning message is printed in this case only for +the first occurence. .SH AUTHOR .TP diff --git a/cint/ginaccint.bin.cpp b/cint/ginaccint.bin.cpp index 083ad5d3..60b0ec7c 100644 --- a/cint/ginaccint.bin.cpp +++ b/cint/ginaccint.bin.cpp @@ -46,12 +46,15 @@ string preprocess(char const * const line, bool & comment, bool & single_quote, void cleanup(void); void sigterm_handler(int n); void initialize(void); +void initialize_cint(void); +void restart(void); bool readlines(istream * is, string & allcommands); bool readfile(string const & filename, string & allcommands); void savefile(string const & filename, string const & allcommands); typedef list cplist; cplist filenames; +bool redirect_output=false; G__value exec_tempfile(string const & command) { @@ -122,14 +125,19 @@ void process_tempfile(string const & command) exec_tempfile(string()+"LLLAST=LLAST;\n" +"LLAST=LAST;\n" +"LAST="+varname+";\n" - +"cout << \""+varname+" = \" << "+varname+" << endl << endl;"); + +"if (ginac_cint_internal_redirect_output&&" + +" ginac_cint_internal_fout.good()) {" + +" ginac_cint_internal_fout << \""+varname+" = \" << "+varname+" << endl << endl;" + +"} else {" + +" cout << \""+varname+" = \" << "+varname+" << endl << endl;" + +"}"); } else if (TYPES_EQUAL(retval,ref_symbol)|| TYPES_EQUAL(retval,ref_constant)|| TYPES_EQUAL(retval,ref_function)|| TYPES_EQUAL(retval,ref_power)|| TYPES_EQUAL(retval,ref_numeric)) { if (!basic_type_warning_already_displayed) { - cout << endl + cout << endl <<"WARNING: The return value of the last expression you entered was a symbol," << endl << "constant, function, power or numeric, which cannot be safely displayed." << endl << "To force the output, cast it explicitly to type 'ex' or use 'cout'," << endl @@ -161,16 +169,23 @@ void greeting(void) void helpmessage(void) { cout << "GiNaC-cint recognizes some special commands which start with a dot:" << endl << endl - << " .q, .quit, .exit, .bye quit GiNaC-cint" << endl - << " .help the text you are currently reading" << endl - << " .function define the body of a function (necessary due to a" << endl - << " cint limitation)" << endl << " .cint switch to cint interactive mode (see cint" << endl << " documentation for further details)" << endl + << " .function define the body of a function (necessary due to a" << endl + << " cint limitation)" << endl + << " .help the text you are currently reading" << endl + << " .q, .quit, .exit, .bye quit GiNaC-cint" << endl << " .read filename read a file from disk and execute it in GiNaC-cint" << endl << " (recursive call is possible)" << endl - << " .save filename save the commands you have entered so far in a file" << endl << endl - << "Additionally you can exit GiNaC-cint with quit; exit; or bye;" << endl + << " .redirect [filename] redirect 'OutXY = ...' output to a file" << endl + << " (.redirect alone redirects output back to console)" << endl + << " .restart restart GiNaC-cint (does not re-read command line" << endl + << " files)" << endl + << " .save filename save the commands you have entered so far in a file" << endl + << " .silent suppress 'OutXY = ...' output (variables are still" << endl + << " accessible)" << endl + << " .> [filename] same as .redirect [filename]" << endl << endl +<< "Additionally you can exit GiNaC-cint with quit; exit; or bye;" << endl << endl; } @@ -180,7 +195,7 @@ string preprocess(char const * const line, bool & comment, bool & single_quote, // "preprocess" the line entered to be able to decide if the command shall be // executed directly or more input is needed or this is a special command - // all whitespace will be removed + // ALL whitespace will be removed // all comments (/* */ and //) will be removed // open and close braces ( { and } ) outside strings will be counted @@ -297,7 +312,11 @@ void initialize(void) atexit(cleanup); signal(SIGTERM,sigterm_handler); - + initialize_cint(); +} + +void initialize_cint(void) +{ G__init_cint("cint"); /* initialize cint */ // no longer needed as of cint 5.14.31 @@ -308,8 +327,32 @@ void initialize(void) #endif // ndef NO_NAMESPACE_GINAC exec_tempfile("ex LAST,LLAST,LLLAST;\n"); + exec_tempfile("bool ginac_cint_internal_redirect_output=false;\n"); + exec_tempfile("ofstream ginac_cint_internal_fout;\n"); } +void restart(void) +{ + cout << "Restarting GiNaC-cint." << endl; + G__scratch_all(); + initialize_cint(); +} + +void redirect(string const & filename) +{ + if (filename=="") { + cout << "Redirecting output back to console..." << endl; + exec_tempfile( string() + +"ginac_cint_internal_redirect_output=false;\n" + +"ginac_cint_internal_fout.close();"); + } else { + cout << "Redirecting output to " << filename << "..." << endl; + exec_tempfile( string() + +"ginac_cint_internal_redirect_output=true;\n" + +"ginac_cint_internal_fout.open(\""+filename+"\");\n"); + } +} + bool readlines(istream * is, string & allcommands) { char const * line; @@ -374,6 +417,14 @@ bool readlines(istream * is, string & allcommands) } else if (preprocessed.substr(0,5)==".save") { command = "// "+command; // we do not want the .save command itself in saved files savefile(preprocessed.substr(5),allcommands); + } else if (preprocessed==".restart") { + restart(); + } else if (preprocessed.substr(0,9)==".redirect") { + redirect(preprocessed.substr(9)); + } else if (preprocessed.substr(0,2)==".>") { + redirect(preprocessed.substr(2)); + } else if (preprocessed==".silent") { + redirect("/dev/null"); /* test for more special commands } else if (preprocessed==".xyz") { cout << "special command (TBD): " << command << endl;