genius r680 - in trunk: . help/C src



Author: jirka
Date: Mon Sep 22 05:06:10 2008
New Revision: 680
URL: http://svn.gnome.org/viewvc/genius?rev=680&view=rev

Log:

Mon Sep 22 00:05:25 2008  Jiri (George) Lebl <jirka 5z com>

	* configure.in: raise version

	* src/funclib.c: Add 'parse' and 'eval' functions

	* help/C/gel-function-list.xml: add 'parse' and 'eval' blurbs

	* src/calc.c, src/genius-readline-helper.c, src/gnome-genius.c:
	  handle return values of chdir, getcwd, write, pipe properly

	* src/funclib.c, src/genius.c: move manual display out of funclib.c
	  and make it less hackish, and use less or more if available to
	  display manual for the text mode version.

	* src/funclib.c: correctly call the gel_errorout function to avoid
	  crashes from calling "error"



Modified:
   trunk/ChangeLog
   trunk/configure.in
   trunk/help/C/gel-function-list.xml
   trunk/help/C/genius.txt
   trunk/help/C/genius.xml
   trunk/src/calc.c
   trunk/src/funclib.c
   trunk/src/genius-readline-helper.c
   trunk/src/genius.c
   trunk/src/gnome-genius.c

Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in	(original)
+++ trunk/configure.in	Mon Sep 22 05:06:10 2008
@@ -1,7 +1,7 @@
 AC_INIT(src/calc.c)
 
 AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(genius,1.0.3)
+AM_INIT_AUTOMAKE(genius,1.0.4)
 
 dnl make sure we keep ACLOCAL_FLAGS around for maintainer builds to work
 AC_SUBST(ACLOCAL_AMFLAGS, "$ACLOCAL_FLAGS")

Modified: trunk/help/C/gel-function-list.xml
==============================================================================
--- trunk/help/C/gel-function-list.xml	(original)
+++ trunk/help/C/gel-function-list.xml	Mon Sep 22 05:06:10 2008
@@ -244,6 +244,14 @@
          </listitem>
         </varlistentry>
 
+        <varlistentry id="gel-function-eval">
+         <term>eval</term>
+         <listitem>
+          <synopsis>eval (str)</synopsis>
+          <para>Parses and evaluates a string.</para>
+         </listitem>
+        </varlistentry>
+
         <varlistentry id="gel-function-error">
          <term>error</term>
          <listitem>
@@ -287,6 +295,15 @@
          </listitem>
         </varlistentry>
 
+        <varlistentry id="gel-function-parse">
+         <term>parse</term>
+         <listitem>
+          <synopsis>parse (str)</synopsis>
+          <para>Parses but does not evaluate a string.  Note that certain
+	    precomputation is done during the parsing stage.</para>
+         </listitem>
+        </varlistentry>
+
         <varlistentry id="gel-function-printn">
          <term>printn</term>
          <listitem>

Modified: trunk/help/C/genius.txt
==============================================================================
--- trunk/help/C/genius.txt	(original)
+++ trunk/help/C/genius.txt	Mon Sep 22 05:06:10 2008
@@ -2056,6 +2056,12 @@
 
            Display a string and an expression with a colon to separate them.
 
+   eval
+
+ eval (str)
+
+           Parses and evaluates a string.
+
    error
 
  error (str)
@@ -2092,6 +2098,13 @@
            can be any expression. It is made into a string before being
            printed.
 
+   parse
+
+ parse (str)
+
+           Parses but does not evaluate a string. Note that certain
+           precomputation is done during the parsing stage.
+
    printn
 
  printn (str)

Modified: trunk/help/C/genius.xml
==============================================================================
--- trunk/help/C/genius.xml	(original)
+++ trunk/help/C/genius.xml	Mon Sep 22 05:06:10 2008
@@ -3,9 +3,9 @@
 "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"; [
   <!ENTITY app "<application>Genius Mathematics Tool</application>">
   <!ENTITY appname "Genius">
-  <!ENTITY appversion "1.0.3">
+  <!ENTITY appversion "1.0.4">
   <!ENTITY manrevision "0.2.2">
-  <!ENTITY date "June 2008">
+  <!ENTITY date "September 2008">
 
   <!ENTITY legal SYSTEM "legal.xml">
 

Modified: trunk/src/calc.c
==============================================================================
--- trunk/src/calc.c	(original)
+++ trunk/src/calc.c	Mon Sep 22 05:06:10 2008
@@ -20,6 +20,7 @@
  */
 #include "config.h"
 
+#include <errno.h>
 #include <stdlib.h>
 #include <dirent.h>
 #include <unistd.h>
@@ -2792,10 +2793,17 @@
 {
 	if (dirprefix == NULL ||
 	    dir[0] == G_DIR_SEPARATOR) {
-		chdir (dir);
+		errno = 0;
+		if (chdir (dir) != 0)
+			gel_errorout (_("Error changing to directory '%s': %s"), 
+				      dir, g_strerror (errno));
+
 	} else {
 		char *d = g_build_filename (dirprefix, dir, NULL);
-		chdir (d);
+		errno = 0;
+		if (chdir (d) != 0)
+			gel_errorout (_("Error changing to directory '%s': %s"), 
+				      d, g_strerror (errno));
 		g_free (d);
 	}
 }
@@ -2977,10 +2985,14 @@
 		ret = TRUE;
 		break;
 	case GEL_PWD:
-		getcwd (buf, sizeof (buf));
-
-		gel_output_string (main_out, buf);
-		gel_output_string (main_out, "\n");
+		errno = 0;
+		if (getcwd (buf, sizeof (buf)) == NULL) {
+			gel_errorout (_("getcwd error: %s"), 
+				      g_strerror (errno));
+		} else {
+			gel_output_string (main_out, buf);
+			gel_output_string (main_out, "\n");
+		}
 		ret = TRUE;
 		break;
 	case GEL_HELP:
@@ -3032,17 +3044,33 @@
 
 	if(str) {
 		int l = strlen(str);
-		pipe(lex_fd);
+		errno = 0;
+		if G_UNLIKELY (pipe(lex_fd) != 0) {
+			gel_errorout (_("ERROR: 'pipe' failed: %s"),
+				      g_strerror (errno));
+			return NULL;
+		}
 		infile = fdopen(lex_fd[0], "r");
-		write(lex_fd[1], str, l);
-		if(str[l-1] != '\n')
-			write(lex_fd[1], "\n", 1);
+		errno = 0;
+		if (write(lex_fd[1], str, l) < l) {
+			gel_errorout (_("ERROR: 'write' possibly failed: %s"),
+				      g_strerror (errno));
+		}
+
+		if(str[l-1] != '\n') {
+			errno = 0;
+			if (write(lex_fd[1], "\n", 1) < 1) {
+				gel_errorout (_("ERROR: 'write' possibly failed: %s"),
+					      g_strerror (errno));
+			}
+		}
 		close(lex_fd[1]);
 		gel_lexer_open(infile);
 	}
 
 	gel_command = GEL_NO_COMMAND;
-	g_free (gel_command_arg); gel_command_arg = NULL;
+	g_free (gel_command_arg);
+	gel_command_arg = NULL;
 
 	lex_init = TRUE;
 	/*yydebug=TRUE;*/  /*turn debugging of parsing on here!*/

Modified: trunk/src/funclib.c
==============================================================================
--- trunk/src/funclib.c	(original)
+++ trunk/src/funclib.c	Mon Sep 22 05:06:10 2008
@@ -124,49 +124,9 @@
 static GelETree *
 manual_op(GelCtx *ctx, GelETree * * a, gboolean *exception)
 {
-	GString *str;
-	FILE *fp;
-	char *file;
-	char *dir;
-
-	/* Kind of a hack I suppose */
-	if (genius_is_gui) {
-		gel_call_help (NULL);
-		error_num = IGNORE_ERROR;
-		RAISE_EXCEPTION (exception);
-		return NULL;
-	}
-
-	str = g_string_new (NULL);
-
-	/*fp = fopen ("../doc/genius.txt", "r");
-	if G_LIKELY (fp == NULL)*/
-
-	dir = gbr_find_data_dir (DATADIR);
-	file = g_build_filename (dir, "genius", "genius.txt", NULL);
-	fp = fopen (file, "r");
-	g_free (file);
-	g_free (dir);
-
-	if G_UNLIKELY (fp != NULL) {
-		char buf[256];
-		while (fgets (buf, sizeof(buf), fp) != NULL) {
-			g_string_append (str, buf);
-		}
-
-		fclose (fp);
-	} else {
-		g_string_append (str,
-				 _("Cannot locate the manual"));
-	}
-
-	(*infoout) (str->str);
+	gel_call_help (NULL);
 	error_num = IGNORE_ERROR;
-
 	RAISE_EXCEPTION (exception);
-
-	g_string_free (str, TRUE);
-
 	return NULL;
 }
 
@@ -353,7 +313,7 @@
 error_op(GelCtx *ctx, GelETree * * a, gboolean *exception)
 {
 	if (a[0]->type == STRING_NODE) {
-		gel_errorout (a[0]->str.str);
+		gel_errorout ("%s", a[0]->str.str);
 	} else {
 		GelOutput *gelo = gel_output_new();
 		char *s;
@@ -361,7 +321,7 @@
 		gel_pretty_print_etree (gelo, a[0]);
 		s = gel_output_snarf_string (gelo);
 		gel_output_unref (gelo);
-		gel_errorout (s != NULL ? s : "");
+		gel_errorout ("%s", s != NULL ? s : "");
 		g_free (s);
 	}
 	return gel_makenum_null();
@@ -5634,6 +5594,38 @@
 	return ret;
 }
 
+static GelETree *
+parse_op (GelCtx *ctx, GelETree * * a, gboolean *exception)
+{
+	if G_UNLIKELY ( ! check_argument_string (a, 0, "parse"))
+		return NULL;
+
+	return gel_parseexp (a[0]->str.str,
+			     NULL /* infile */,
+			     FALSE /* exec_commands */,
+			     FALSE /* testparse */,
+			     NULL /* finished */,
+			     NULL /* dirprefix */);
+}
+
+static GelETree *
+eval_op (GelCtx *ctx, GelETree * * a, gboolean *exception)
+{
+	GelETree *et;
+
+	if G_UNLIKELY ( ! check_argument_string (a, 0, "parse"))
+		return NULL;
+
+	et = gel_parseexp (a[0]->str.str,
+			   NULL /* infile */,
+			   FALSE /* exec_commands */,
+			   FALSE /* testparse */,
+			   NULL /* finished */,
+			   NULL /* dirprefix */);
+
+	return eval_etree (ctx, et);
+}
+
 
 static GelETree *
 set_FloatPrecision (GelETree * a)
@@ -6333,6 +6325,9 @@
 	FUNC (IsDefined, 1, "id", "basic", N_("Check if a variable or function is defined"));
 	FUNC (undefine, 1, "id", "basic", N_("Undefine a variable (including locals and globals)"));
 
+	FUNC (parse, 1, "str", "basic", N_("Parse a string (but do not execute)"));
+	FUNC (eval, 1, "str", "basic", N_("Parse and evaluate a string"));
+
 	FUNC (CompositeSimpsonsRule, 4, "f,a,b,n", "calculus", N_("Integration of f by Composite Simpson's Rule on the interval [a,b] with n subintervals with error of max(f'''')*h^4*(b-a)/180, note that n should be even"));
 	f->no_mod_all_args = 1;
 

Modified: trunk/src/genius-readline-helper.c
==============================================================================
--- trunk/src/genius-readline-helper.c	(original)
+++ trunk/src/genius-readline-helper.c	Mon Sep 22 05:06:10 2008
@@ -208,7 +208,8 @@
 			char *r = strrchr (buf, '\n');
 			if (r != NULL)
 				*r = '\0';
-			chdir (&buf[4]);
+			if (chdir (&buf[4]) != 0)
+				printf ("chdir failed in readline-helper");
 		} else if(strcmp(buf,"TOPLEVEL OK\n")==0) {
 			toplevelokg = TRUE;
 		} else if(strcmp(buf,"TOPLEVEL NOT OK\n")==0) {
@@ -225,13 +226,19 @@
 				add_history(p);
 
 			if(!p) {
-				write(outfd,"EOF!",4);
+				if (write(outfd,"EOF!",4) < 4)
+					printf ("write failed in readline-helper");
 			} else {
 				int len = strlen(p);
-				write(outfd,"LINE",4);
-				write(outfd,(gpointer)&len,sizeof(int));
-				if(len>0)
-					write(outfd,p,len);
+				if (write(outfd,"LINE",4) < 4)
+					printf ("write failed in readline-helper");
+				if (write(outfd,(gpointer)&len,sizeof(int)) < sizeof (int))
+					printf ("write failed in readline-helper");
+				if(len>0) {
+					if (write(outfd,p,len) < len) {
+						printf ("write failed in readline-helper");
+					}
+				}
 				free(p);
 			}
 		}

Modified: trunk/src/genius.c
==============================================================================
--- trunk/src/genius.c	(original)
+++ trunk/src/genius.c	Mon Sep 22 05:06:10 2008
@@ -128,7 +128,63 @@
 void
 gel_call_help (const char *function)
 {
-	/* No extra processing of help */
+	char *file;
+	char *str;
+
+	if (function != NULL) {
+		/* No extra processing of help,
+		 * printout was done in funclib */
+		return;
+	}
+
+	/*fp = fopen ("../doc/genius.txt", "r");
+	if G_LIKELY (fp == NULL)*/
+
+	str = gbr_find_data_dir (DATADIR);
+	file = g_build_filename (str, "genius", "genius.txt", NULL);
+	g_free (str);
+
+	if G_UNLIKELY (access (file, R_OK) != 0) {
+		puterror (_("Cannot locate the manual"));
+		g_free (file);
+		return;
+	}
+
+	str = g_find_program_in_path ("less");
+	if (str == NULL)
+		str = g_find_program_in_path ("more");
+
+	if G_LIKELY (str != NULL) {
+		char *argv[3];
+
+		argv[0] = str;
+		argv[1] = file;
+		g_spawn_sync  (NULL /* wd */,
+			       argv,
+			       NULL /* envp */,
+			       0 /* flags */,
+			       NULL /* child_setup */,
+			       NULL /* user_data */,
+			       NULL /*stdout*/,
+			       NULL /*stderr*/,
+			       NULL /* status */,
+			       NULL /* error */);
+	} else {
+		/* No less or more, hence just type out the
+		 * manual */
+		FILE *fp;
+
+		fp = fopen (file, "r");
+		if G_LIKELY (fp != NULL) {
+			char buf[256];
+			while (fgets (buf, sizeof(buf), fp) != NULL) {
+				g_print ("%s\n", buf);
+			}
+
+			fclose (fp);
+		}
+	}
+	g_free (file);
 }
 
 

Modified: trunk/src/gnome-genius.c
==============================================================================
--- trunk/src/gnome-genius.c	(original)
+++ trunk/src/gnome-genius.c	Mon Sep 22 05:06:10 2008
@@ -3442,6 +3442,17 @@
 		int status;
 		char *str;
 
+		errno = 0;
+		if (pipe (p) != 0) {
+			char *err = 
+				g_strdup_printf
+				(_("Cannot open pipe: %s"),
+				 g_strerror (errno));
+			genius_display_error (NULL, err);
+			g_free (err);
+			return;
+		}
+
 		gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
 		gtk_text_buffer_get_iter_at_offset (buffer, &iter_end, -1);
 		prog = gtk_text_buffer_get_text (buffer, &iter, &iter_end,
@@ -3456,8 +3467,6 @@
 				   "\e[0m (((\r\n", -1);
 		gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 0);
 
-		pipe (p);
-
 		/* run this in a fork so that we don't block on very
 		   long input */
 		pid = fork ();
@@ -3472,10 +3481,14 @@
 		}
 
 		if (pid == 0) {
+			int status = 0;
+			int len = strlen (prog);
 			close (p[0]);
-			write (p[1], prog, strlen (prog));
+			if (write (p[1], prog, len) < len) {
+				status = 1;
+			}
 			close (p[1]);
-			_exit (0);
+			_exit (status);
 		}
 		close (p[1]);
 		fp = fdopen (p[0], "r");
@@ -3529,6 +3542,13 @@
 			/* must kill it, just in case we were interrupted */
 			kill (pid, SIGTERM);
 			waitpid (pid, &status, 0);
+			if (WIFEXITED (status) &&
+			    WEXITSTATUS (status) == 1) {
+				genius_display_error (NULL,
+						      _("<b>Error executing program</b>\n\n"
+							"There was an error while writing the\n"
+							"program to the engine."));
+			}
 		}
 	}
 



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