changeset 5576:7e008607a86e

[project @ 2005-12-13 19:05:54 by jwe]
author jwe
date Tue, 13 Dec 2005 19:05:55 +0000
parents 9b4d9dbe88f7
children 6ada1581e8b4
files doc/ChangeLog doc/interpreter/sparse.txi scripts/ChangeLog scripts/sparse/etreeplot.m scripts/sparse/gplot.m scripts/sparse/treeplot.m src/ChangeLog src/DLD-FUNCTIONS/__gnuplot_raw__.l src/DLD-FUNCTIONS/gplot.l src/Makefile.in src/help.cc src/ls-oct-ascii.cc
diffstat 12 files changed, 2106 insertions(+), 1892 deletions(-) [+]
line wrap: on
line diff
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,8 @@
+2005-12-13  David Bateman <dbateman@free.fr>
+
+	* interpreter/sparse.txi: Add new gplot, etreeplot and treeplot
+	functions.
+
 2005-11-01  John W. Eaton  <jwe@octave.org>
 
 	* liboctave/Makefile.in (maintainer-clean): Also remove liboctave.pdf
--- a/doc/interpreter/sparse.txi
+++ b/doc/interpreter/sparse.txi
@@ -890,13 +890,14 @@
 @item etree
 Returns the elimination tree for the matrix S.
 @item etreeplot
-@emph{Not implemented}
+Plots the elimination tree of the matrix @var{s} or @code{@var{s}+@var{s}'}
+if @var{s} in non-symmetric.
 @item gplot
-@emph{Not implemented}
+Plots a graph defined by @var{A} and @var{xy} in the graph theory sense.
 @item treelayout
 @emph{Not implemented}
 @item treeplot
-@emph{Not implemented}
+Produces a graph of a tree or forest.
 @end table
 @subsubsection Sparse matrix reordering
 @table @asis
@@ -1020,8 +1021,12 @@
 * dmperm::	Perfrom a Deulmage-Mendelsohn permutation on the sparse
 		matrix S.
 * etree::	Returns the elimination tree for the matrix S.
+* etreeplot::   Plots the elimination tree of the matrix @var{s} or 
+		@code{@var{s}+@var{s}'} if @var{s} in non-symmetric.
 * full::	returns a full storage matrix from a sparse one See also:
 		sparse
+* gplot::	Plots a graph defined by @var{A} and @var{xy} in the graph 
+		theory sense.
 * issparse::	Return 1 if the value of the expression EXPR is a sparse
 		matrix.
 * luinc::	Produce the incomplete LU factorization of the sparse 
@@ -1084,6 +1089,7 @@
 		matrix S.
 * symrcm::	Returns the Reverse Cuthill McKee reordering of the sparse
 		matrix S.
+* treeplot::	Produces a graph of a tree or forest.
 @end menu
 
 @node colamd, ccolamd, , Function Reference
@@ -1111,17 +1117,27 @@
 
 @DOCSTRING(dmperm)
 
-@node etree, full, dmperm, Function Reference
+@node etree, etreeplot, dmperm, Function Reference
 @subsubsection etree
 
 @DOCSTRING(etree)
 
-@node full, issparse, etree, Function Reference
+@node etreeplot, full, etree, Function Reference
+@subsubsection etreeplot
+
+@DOCSTRING(etreeplot)
+
+@node full, gplot, etreeplot, Function Reference
 @subsubsection full
 
 @DOCSTRING(full)
 
-@node issparse, luinc, full, Function Reference
+@node gplot, issparse, full, Function Reference
+@subsubsection gplot
+
+@DOCSTRING(gplot)
+
+@node issparse, luinc, gplot, Function Reference
 @subsubsection issparse
 
 @DOCSTRING(issparse)
@@ -1311,11 +1327,16 @@
 
 @DOCSTRING(symbfact)
 
-@node symrcm, , symbfact, Function Reference
+@node symrcm, treeplot, symbfact, Function Reference
 @subsubsection symrcm
 
 @DOCSTRING(symrcm)
 
+@node treeplot, ,symrcm, Function Reference
+@subsubsection treeplot
+
+@DOCSTRING(treeplot)
+
 @c Local Variables: ***
 @c Mode: texinfo ***
 @c End: ***
--- a/scripts/ChangeLog
+++ b/scripts/ChangeLog
@@ -1,3 +1,8 @@
+2005-12-13  Ivana Varekova <varekova@redhat.com>
+
+	* sparse/treeplot.m, sparse/etreeplot.m, sparse/gplot.m:
+	New graph theory functions.
+
 2005-12-13  John W. Eaton  <jwe@octave.org>
 
 	* general/blkdiag.m: Use "isempty" instead of @isempty.
new file mode 100644
--- /dev/null
+++ b/scripts/sparse/etreeplot.m
@@ -0,0 +1,29 @@
+## Copyright (C) 2005 Ivana Varekova
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+## 02110-1301  USA
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} etreeplot (@var{Tree})
+## @deftypefnx {Function File} {} etreeplot (@var{Tree}, @var{NodeStyle}, @var{EdgeStyle})
+## Plots the elimination tree of the matrix @var{s} or @code{@var{s}+@var{s}'}
+## if @var{s} in non-symmetric. The  optional parameters @var{LineStyle} and 
+## @var{EdgeStyle} define the output style.
+## @end deftypefn
+## @seealso{treeplot,gplot}
+
+function etreeplot (s, varargin)
+  treeplot (etree (s+s'), varargin{:})
+endfunction
new file mode 100644
--- /dev/null
+++ b/scripts/sparse/gplot.m
@@ -0,0 +1,54 @@
+## Copyright (C) 2005 Ivana Varekova
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+## 02110-1301  USA
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} gplot (@var{a}, @var{xy})
+## @deftypefnx {Function File} {} gplot (@var{a}, @var{xy}, @var{LineSpec})
+## @deftypefnx {Function File} {[@var{x}, @var{y}] =} gplot (@var{a}, @var{xy})
+## Plots a graph defined by @var{A} and @var{xy} in the graph theory sense.
+## @var{A} is the adjacency matrix of the array to be plotted and @var{xy} is a
+## @var{n}-by-2 matrix containing the coordinates of the nodes of the graph.
+##
+## If defined, @var{LineStyle} defines the output style for the plot. Called 
+## with no output arguments the graph is plotted directly. Called with output
+## arguments the coordinates of the plot are returned in @var{x} and @var{y}, 
+## rather than being plotted.
+## @end deftypefn
+## @seealso{treeplot,etreeplot,spy}
+
+function [x, y] = gplot (A, xy, LineStyle)
+
+  if (nargin < 2 || nargin > 3 || nargout > 2)
+    error ("gplot: wrong number of input/output arguments");
+  endif
+
+  if (nargin == 2)
+    LineStyle = "1;;";
+  endif
+
+  [i,j] = find(A);
+  xcoord = [xy(i,1), xy(j,1), NaN * ones(length(i),1)]'(:);
+  ycoord = [xy(i,2), xy(j,2), NaN * ones(length(i),1)]'(:);
+
+  if (nargout == 0)
+    plot(xcoord,ycoord,LineStyle); 
+  else
+    x = xcoord;
+    y = ycoord;
+  endif
+
+endfunction
new file mode 100644
--- /dev/null
+++ b/scripts/sparse/treeplot.m
@@ -0,0 +1,165 @@
+## Copyright (C) 2005 Ivana Varekova
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+## 02110-1301  USA
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} treeplot (@var{Tree})
+## @deftypefnx {Function File} {} treeplot (@var{Tree}, @var{LineStyle}, @var{EdgeStyle})
+## Produces a graph of tree or forest. The first argument is vector of
+## predecessors, optional parametres @var{LineStyle} and @var{EdgeStyle}
+## define the output style. The complexity of the algorithm is O(n) in
+## terms of is time and memory requirements.
+## @end deftypefn
+## @seealso{etreeplot,gplot}
+
+function treeplot (Tree, NodeS, EdgeS)
+
+  if (nargin < 1 || nargin > 3 || nargout > 0)
+    error ("treeplot: wrong number of input/output arguments");
+  else
+    if (!ismatrix(Tree) || size(Tree)(1) != 1 || !isnumeric(Tree) 
+        || !isvector(Tree) || any(Tree>length (Tree)))
+      error ("treeplot: the first input argument must be a vector of predecessors");
+    else	
+    
+      NodeStyle = "0*;;";                  ## the inicialization of node end edge style
+      EdgeStyle = "1;;";      
+      if (nargin > 2)
+        EdgeStyle = EdgeS;
+        if (nargin > 1) 
+	  if ((length(findstr(NodeS,"*")) == 0) 
+	    && (length(findstr(NodeS,"+")) == 0) 
+	    && (length(findstr(NodeS,"x")) == 0) )
+	    NodeStyle = [NodeS,"o"];
+	  else
+	    NodeStyle = NodeS;
+	  endif
+        endif
+      endif
+      
+      Tree = Tree(:)';		            ## make it a row vector
+      NodNumber = length (Tree);            ## the count of nodes of the graph
+      ChildNumber = zeros (1,NodNumber+1);  ## the number of childrens
+      
+      for i = 1:(NodNumber)       ## VecOfChild is helping vector which is used to speed up the
+                                  ##   choose of descendant nodes
+
+        ChildNumber(Tree(i)+1) = ChildNumber(Tree(i)+1) + 1;
+      endfor
+      Pos = 1;
+      for i = 1:(NodNumber+1)
+        Start(i) = Pos;
+	Help(i) = Pos;
+	Pos = Pos + ChildNumber(i);
+	Stop(i) = Pos;
+      endfor
+      for i = 1:NodNumber        
+        VecOfChild(Help(Tree(i)+1)) = i;  
+	Help(Tree(i)+1)=Help(Tree(i)+1)+1;
+      endfor                    ## VecOfChild is helping vector which is used to speed up the
+                                ##   choose of descendant nodes
+				
+      ParNumber = 0;            ## the number of "parent" (actual) node (it's descendants will 
+                                ##   be browse in the next iteration)
+      LeftMost = 0;		## the x-coordinate of the left most descendant of "parent node"
+                                ##   this value is increased in each leaf		
+      Level = NodNumber;        ## the level of "parent" node (root level is NodNumber)
+      Max = NodNumber;          ## NodNumber - Max is the height of this graph
+      St = [-1,0];		## main stack - each item consists of two numbers - the number of node and
+                                ##   the number it's of parent node
+				##   on the top of stack there is "parent node"
+      Skelet = 0;		## stack which is use to draw the graph edge (it 
+                                ##   have to be uninterupted line)
+      while (ParNumber!=-1)     ## the top of the stack
+	if (Start(ParNumber+1) < Stop(ParNumber+1))
+	  idx = VecOfChild(Start(ParNumber+1):Stop(ParNumber+1)-1);
+	else
+	  idx = zeros(1,0);
+	endif                   ## add to idx the vector of parent descendants
+	St = [St ; [idx', ones(fliplr(size(idx)))*ParNumber]];
+	                        ## add to stack the records relevant to parent descandant s
+	if (ParNumber != 0)
+	  Skelet = [Skelet ; ([ones(size(idx))*ParNumber; idx])(:)];
+	endif
+	if (St(end,2) != ParNumber)  ## if there is not any descendant of "parent node":
+	  LeftMost = LeftMost + 1;
+          XCoordinateR(ParNumber) = LeftMost;           
+	  Max = min (Max, Level);
+          if ((length(St)>1) && (find((shift(St,1)-St) == 0) >1) && St(end,2) != St(end-1,2))
+	                             ## return to the nearest branching
+            Position = (find((shift(St(:,2),1)-St(:,2)) == 0))(end)+1;      ## the position to return
+                          ## position is the position on the stack, where should be started 
+			  ## further search (there are two nodes which has the same parent node)
+            ParNumberVec = St(Position:end,2);
+                          ## the vector of removed nodes (the content of stack form position to end)
+            Skelet = [Skelet; flipud(ParNumberVec)];
+            Level = Level + length(ParNumberVec);
+	                  ## the level have to be decreased
+            XCoordinateR(ParNumberVec) = LeftMost;
+            St(Position:end,:) = [];
+          endif	
+	  St(end,:) = [];       	## remove the next node from "searched branch"
+          ParNumber = St(end,1);	## choose new "parent node"
+	  if (ParNumber != -1)		## if there is another branch start to search it
+	    Skelet = [Skelet ; St(end,2); ParNumber];
+            YCoordinate(ParNumber) = Level;	
+	    XCoordinateL(ParNumber) = LeftMost + 1;
+	  endif
+	else                      ## there were descendants of "parent nod"
+          Level = Level - 1;      ## choose the last of them and go on through it
+	  ParNumber = St(end,1);
+	  YCoordinate(ParNumber) = Level;     
+	  XCoordinateL(ParNumber) = LeftMost+1;
+	endif
+      endwhile
+
+      XCoordinate = (XCoordinateL + XCoordinateR) / 2;     ## calculate the x coordinates 
+               ## (the known values are the position of most left and most right descendants)
+
+      axis ([0.5 LeftMost+0.5 Max-0.5 NodNumber-0.5], "nolabel");  ## set axis and graph size 
+      
+      plot (XCoordinate,YCoordinate,NodeStyle);           ## plot grah nodes 
+      hold on;
+      
+      Skelet = [Skelet; 0];     ## helping command - usable for plotting edges
+      
+      idx = find (Skelet == 0);                           ## draw graph edges 
+       
+      for i = 2:length(idx)                               ## plot each tree component in one loop
+	istart = idx(i-1) + 1;                            ## tree component start
+	istop = idx(i) - 1;                               ## tree component end
+	if (istop - istart < 1)                          
+	  continue;
+	endif
+	plot (XCoordinate(Skelet(istart:istop)),
+	      YCoordinate(Skelet(istart:istop)), EdgeStyle)
+      endfor
+      
+      hold off;
+      
+    endif
+  endif
+  St;
+  Skelet;
+endfunction
+
+%!demo
+%! % Plot a simple tree plot 
+%! treeplot([2 4 2 0 6 4 6])
+
+%!demo
+%! % Plot a simple tree plot defining the edge and node styles
+%! treeplot([2 4 2 0 6 4 6], "b+", "g") 
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,14 @@
+2005-12-13  David Bateman <dbateman@free.fr>
+
+	* Makefile.in: Change references to gplot.l to __gnuplot_raw__.l.
+	* DLD-FUNCTIONS/__gnuplot_raw__.l: Rename from DLD-FUNCTIONS/gplot.l.
+	Remove all references to deprecated gplot, gsplot, graw, gset and
+	gshow functions.
+	* help.cc (static help_list keywords[]): Remove gsplot and gplot.
+
+	* ls-oct-ascii.cc (save_three_d):  Don't strip Inf or NaN.
+	(save_ascii_data_for_plotting): Ditto.
+
 2005-12-13  John W. Eaton  <jwe@octave.org>
 
 	* oct-stream.cc (octave_stream_list::do_insert): Check open state
new file mode 100644
--- /dev/null
+++ b/src/DLD-FUNCTIONS/__gnuplot_raw__.l
@@ -0,0 +1,1803 @@
+/*
+
+Copyright (C) 2004 John W. Eaton and Teemu Ikonen
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octavee; see the file COPYING.  If not, write to the Free
+Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.
+
+*/
+
+%option prefix="gpt"
+%option noyywrap
+
+%{
+// PKG_ADD: mark_as_rawcommand ("__gnuplot_plot__");
+// PKG_ADD: mark_as_rawcommand ("__gnuplot_set__");
+// PKG_ADD: mark_as_rawcommand ("__gnuplot_splot__");
+// PKG_ADD: mark_as_rawcommand ("__gnuplot_replot__");
+
+// PKG_ADD: mark_as_command ("__gnuplot_show__");
+
+// PKG_ADD: __gnuplot_init__ ();
+
+// PKG_ADD: atexit ("closeplot");
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <map>
+#include <string>
+#include <fstream>
+#include <iostream>
+
+#ifdef HAVE_UNISTD_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+#endif
+
+#include "file-ops.h"
+#include "oct-env.h"
+
+#include "defun-dld.h"
+#include "file-io.h"
+#include "gripes.h"
+#include "load-save.h"
+#include "parse.h"
+#include "procstream.h"
+#include "sighandlers.h"
+#include "utils.h"
+#include "variables.h"
+
+enum _toktype
+  {
+    START_PAREN = 1,
+    END_PAREN,
+    START_BRACE,
+    END_BRACE,
+    START_BRACKET,
+    END_BRACKET,
+    COLON,
+    SEMICOLON,
+    COMMA,
+    QUOTE,
+    IDENT,
+    NUMBER,
+    BINOP,
+    UNOP,
+    STRING,
+    OTHER,
+    TITLE,
+    USING,
+    WITH,
+    AXES,
+    CLEAR
+  };
+
+typedef bool (*pred) (const int);
+
+class
+gpt_parse_error
+{
+public:
+  gpt_parse_error (void) : msg () { }
+  gpt_parse_error (std::string errmsg) : msg (errmsg) { }
+
+  std::string msg;
+};
+
+static bool gpt_quote_is_transpose;
+static bool gpt_allow_plotkw;
+static int gpt_parens;
+static int gpt_brackets;
+static int gpt_braces;
+
+static bool can_be_plotkw (void);
+
+static int is_plot_keyword (const std::string& s);
+
+static int handle_string (char delim);
+static std::string strbuf;
+
+%}
+
+D	[0-9]
+S	[ \t]
+IDENT	([_a-zA-Z@][_a-zA-Z0-9]*)
+EXPON	([DdEe][+-]?{D}+)
+NUMBER  (({D}+\.?{D}*{EXPON}?)|(\.{D}+{EXPON}?)|(0[xX][0-9a-fA-F]+))
+NOT	((\~)|(\!))
+/* NOT is not strictly a binary operator, but is close enough for us. */
+BINOP   (({NOT})|(\.?([\*/\\^+-]|\*\*)=?)|([<=~!>&|]=)|([=&|<>]{1,2})|(<<=)|(>>=)|(\.))
+/* single quote (') transpose operator is handled separately. */
+UNOP    ((\+\+)|(\-\-)|(\.'))
+
+%%
+
+"(" {
+    gpt_quote_is_transpose = false;
+    gpt_parens++;
+    return START_PAREN;
+    }
+
+")" {
+    gpt_quote_is_transpose = true;
+    gpt_parens--;
+    return END_PAREN;
+    }
+
+"{" {
+    gpt_quote_is_transpose = false;
+    gpt_braces++;
+    return START_BRACE;
+    }
+
+"}" {
+    gpt_quote_is_transpose = true;
+    gpt_braces--;
+    return END_BRACE;
+    }
+
+"[" {
+    gpt_quote_is_transpose = false;
+    gpt_brackets++;
+    return START_BRACKET;
+    }
+
+"]" {
+    gpt_quote_is_transpose = true;
+    gpt_brackets--;
+    return END_BRACKET;
+    }
+
+":" {
+    gpt_quote_is_transpose = false;
+    return COLON;
+    }
+
+";" {
+    gpt_quote_is_transpose = false;
+    return SEMICOLON;
+    }
+
+"," {
+    gpt_quote_is_transpose = false;
+    return COMMA;
+    }
+
+"'" {
+    if (gpt_quote_is_transpose)
+      {
+        gpt_allow_plotkw = true;
+        return QUOTE;
+      }
+    else
+      {
+        gpt_quote_is_transpose = true;
+        gpt_allow_plotkw = true;
+        return handle_string ('\'');
+      }
+    }
+
+"\"" {
+    return handle_string ('"');
+    }
+
+{IDENT} {
+    int itok = 0;
+    if (can_be_plotkw () && (itok = is_plot_keyword (yytext)))
+      {
+        gpt_quote_is_transpose = false;
+        gpt_allow_plotkw = true;
+        return itok;
+      }
+    else if (std::string (yytext) == "function")
+      throw gpt_parse_error ("function keyword not allowed in plot commands");
+    else
+      {
+        gpt_quote_is_transpose = true;
+        gpt_allow_plotkw = true;
+        return IDENT;
+      }
+    }
+
+{D}+/\.[\*/\\^'] | /* ' */
+{NUMBER} {
+    gpt_quote_is_transpose = true;
+    gpt_allow_plotkw = true;
+    return NUMBER;
+    }
+
+{BINOP} {
+    gpt_quote_is_transpose = false;
+    gpt_allow_plotkw = false;
+    return BINOP;
+    }
+
+{UNOP} {
+    gpt_quote_is_transpose = false;
+    gpt_allow_plotkw = true;
+    return UNOP;
+    }
+
+{S} { /* Ignore spaces and tabs outside of character strings. */ }
+
+. {
+    gpt_quote_is_transpose = false;
+    gpt_allow_plotkw = true;
+    warning ("unknown token = \"%s\" in plot command", yytext);
+    return OTHER;
+    }
+
+%%
+
+// ------------------------------------------------------------
+// Interface to external gnuplot process(es), including gnuplot
+// command parser.
+// ------------------------------------------------------------
+
+// The name of the shell command to execute to start gnuplot.
+static std::string Vgnuplot_binary;
+
+// Append -title "Figure NN" to the gnuplot command?
+static bool Vgnuplot_use_title_option = octave_env::have_x11_display ();
+
+// Gnuplot command strings that we use.
+static std::string Vgnuplot_command_plot;
+static std::string Vgnuplot_command_replot;
+static std::string Vgnuplot_command_splot;
+static std::string Vgnuplot_command_using;
+static std::string Vgnuplot_command_with;
+static std::string Vgnuplot_command_axes;
+static std::string Vgnuplot_command_title;
+static std::string Vgnuplot_command_end;
+
+// If TRUE, a replot command is issued automatically each time a plot
+// changes in some way.
+static bool Vautomatic_replot;
+
+// Check if the parser state is such that a plot keyword can occur.
+
+static bool
+can_be_plotkw (void)
+{
+    return (gpt_allow_plotkw
+	    && (gpt_braces == 0)
+	    && (gpt_brackets == 0)
+	    && (gpt_parens == 0));
+}
+
+// Check to see if a character string matches any one of the plot
+// option keywords.  Don't match abbreviations for clear, since that's
+// not a gnuplot keyword (users will probably only expect to be able
+// to abbreviate actual gnuplot keywords).
+
+static int
+is_plot_keyword (const std::string& s)
+{
+  if (almost_match ("title", s, 1))
+    return TITLE;
+  else if (almost_match ("using", s, 1))
+    return USING;
+  else if (almost_match ("with", s, 1))
+    return WITH;
+  else if (almost_match ("axes", s, 2) || almost_match ("axis", s, 2))
+    return AXES;
+  else if ("clear" == s)
+    return CLEAR;
+  else
+    return 0;
+}
+
+// This is used to handle character strings.  Kludge alert.
+
+static int
+handle_string (char delim)
+{
+  int c;
+  bool escape_pending = false;
+
+  strbuf = std::string (1, delim);
+
+  while ((c = yyinput ()) != EOF)
+    {
+      if (c == '\\')
+	{
+	  if (escape_pending)
+	    {
+	      strbuf += static_cast<char> (c);
+	      escape_pending = false;
+	    }
+	  else
+	    {
+	      strbuf += static_cast<char> (c);
+	      escape_pending = true;
+	    }
+	  continue;
+	}
+      else if (c == '\n')
+	{
+	  error ("unterminated string constant");
+	  break;
+	}
+      else if (c == delim)
+	{
+	  if (escape_pending)
+	    strbuf += static_cast<char> (c);
+	  else
+	    {
+	      c = yyinput ();
+
+	      if (c == delim)
+		{
+		  strbuf += static_cast<char> (c);
+		  strbuf += static_cast<char> (c);
+		}
+	      else
+		{
+		  yyunput (c, yytext);
+		  strbuf += static_cast<char> (delim);
+		  return STRING;
+		}
+	    }
+	}
+      else
+	strbuf += static_cast<char> (c);
+
+      escape_pending = false;
+    }
+
+  throw gpt_parse_error ("unterminated string");
+
+  return 0;
+}
+
+// (Probably not necessesary, but current Matlab style plot functions
+// break without this (they emit too short gnuplot commands))
+
+static std::string
+plot_style_token (const std::string& s)
+{
+  std::string retval;
+
+  // XXX FIXME XXX -- specify minimum match length for these.
+  static const char *plot_styles[] =
+    {
+      "boxes",
+      "boxerrorbars",
+      "boxxyerrorbars",
+      "candlesticks",
+      "dots",
+      "errorbars",
+      "financebars",
+      "fsteps",
+      "histeps",
+      "impulses",
+      "lines",
+      "linespoints",
+      "points",
+      "steps",
+      "vector",
+      "xerrorbars",
+      "xyerrorbars",
+      "yerrorbars",
+      0,
+    };
+
+  const char * const *tmp = plot_styles;
+  while (*tmp)
+    {
+      if (almost_match (*tmp, s.c_str ()))
+	{
+	  retval = *tmp;
+	  break;
+	}
+
+      tmp++;
+    }
+
+  return retval;
+}
+
+// Some predicates on tokens
+
+// Return true for ":".
+
+static bool
+colonp (const int tok)
+{
+  return (tok == COLON);
+}
+
+// Return TRUE for "]".
+
+static bool
+endbracketp (const int tok)
+{
+  return (tok == END_BRACKET);
+}
+
+// Return TRUE for plot token, comma or end of input.
+
+static bool
+plottok_or_end_p (const int tok)
+{
+  return (tok == TITLE
+	  || tok == USING
+	  || tok == WITH
+	  || tok == AXES
+	  || tok == CLEAR
+	  || tok == COMMA
+	  || tok == 0);
+}
+
+// Equivalent to (colonp (tok) || plottok_or_end_p (tok)).
+
+static bool
+colon_plottok_or_end_p (const int tok)
+{
+  return (tok == COLON || plottok_or_end_p (tok));
+}
+
+// read until test is true and delimiters are balanced, or end of input.
+// Return the last token in lasttok
+
+static std::string
+read_until (pred test, int& lasttok) throw (gpt_parse_error)
+{
+  int tok;
+
+  // We have to maintain balanced delimiters per subexpression too.
+  int brackets = 0;
+  int parens = 0;
+  int braces = 0;
+  std::string s;
+
+  tok = gptlex ();
+
+  while (tok && ! (test (tok)
+		   && brackets == 0
+		   && parens == 0
+		   && braces == 0))
+    {
+      switch (tok)
+	{
+	case START_BRACKET:
+	  brackets++;
+	  break;
+
+	case END_BRACKET:
+	  brackets--;
+	  break;
+
+	case START_PAREN:
+	  parens++;
+	  break;
+
+	case END_PAREN:
+	  parens--;
+	  break;
+
+	case START_BRACE:
+	  braces++;
+	  break;
+
+	case END_BRACE:
+	  braces--;
+	  break;
+
+	default:
+	  break;
+        }
+
+      s += (tok == STRING ? strbuf : std::string (yytext)) + " ";
+
+      tok = gptlex ();
+    }
+
+  // Throw error only if we've reached the end token and the test
+  // doesn't accept it.
+
+  if (! test (tok) && ! tok)
+    throw gpt_parse_error ("unexpected end of input");
+
+  lasttok = tok;
+
+  return s;
+}
+
+// Eval the two expressions giving limits of range and print it.
+
+static std::string
+printrange (std::string starts, std::string ends)
+{
+  octave_value startv, endv;
+  int status;
+  std::string s;
+  OSSTREAM range_buf;
+
+  range_buf << "[";
+
+  if (! starts.empty ())
+    {
+      startv = eval_string (starts, true, status);
+      if (! startv.is_real_scalar ())
+	throw gpt_parse_error ();
+      startv.print_raw (range_buf);
+    }
+
+    range_buf << ":";
+
+    if (! ends.empty ())
+      {
+	endv = eval_string (ends, true, status);
+	if (! endv.is_real_scalar ())
+	  throw gpt_parse_error ();
+        endv.print_raw (range_buf);
+      }
+
+    range_buf << "]";
+    range_buf << OSSTREAM_ENDS;
+
+    s = OSSTREAM_STR (range_buf);
+
+    return s;
+}
+
+// Handle plot parameters.
+
+// Parse, evaluate and print colon separated expressions in the using
+// plot parameter. The use of trailing format string is not supported.
+
+static std::string
+handle_using (int& lasttok)
+{
+  int tok;
+  std::string expr_str;
+  std::string retstr = Vgnuplot_command_using + " ";
+  bool out = false;
+
+  octave_value tmp_data;
+  int status;
+  while (! out)
+    {
+      expr_str = read_until (colon_plottok_or_end_p, tok);
+
+      tmp_data = eval_string (expr_str, true, status);
+      if (status != 0 || ! tmp_data.is_real_scalar ())
+	throw gpt_parse_error ();
+
+      OSSTREAM tmp_buf;
+      tmp_data.print_raw (tmp_buf);
+      tmp_buf << OSSTREAM_ENDS;
+      retstr += OSSTREAM_STR (tmp_buf);
+
+      if (tok == COLON)
+	retstr += ":";
+      else
+	out = true;
+    }
+
+  lasttok = tok;
+
+  return retstr;
+}
+
+// Presently just passes the linewidth, pointtype etc. tokens as they are.
+
+static std::string
+handle_style (int& lasttok)
+{
+  std::string retstr = Vgnuplot_command_with + " ";
+  std::string style;
+
+  lasttok = gptlex ();
+
+  if (lasttok != IDENT)
+    throw gpt_parse_error ("expected plot style token");
+
+  style = std::string (yytext);
+  style = plot_style_token (style);
+
+  if (! style.empty ())
+    retstr += style;
+  else
+    retstr += std::string (yytext);
+
+  // XXX FIXME XXX -- should evaluate the remaining tokens, but this
+  // needs changes in the parser.
+  retstr += " " + read_until (plottok_or_end_p, lasttok);
+
+  return retstr;
+}
+
+// Axes has only one qualifier keyword, which is not evaluated.
+
+static std::string
+handle_axes (int& lasttok)
+{
+  return Vgnuplot_command_axes + " " + read_until (plottok_or_end_p, lasttok);
+}
+
+static std::string
+save_in_tmp_file (const octave_value& t, int ndim = 2, bool parametric = false)
+{
+  std::string name = file_ops::tempnam ("", "oct-");
+
+  if (! name.empty ())
+    {
+      std::ofstream file (name.c_str ());
+
+      if (file)
+	{
+	  switch (ndim)
+	    {
+	    case 2:
+	      save_ascii_data_for_plotting (file, t, name);
+	      break;
+
+	    case 3:
+	      save_three_d (file, t, parametric);
+	      break;
+
+	    default:
+	      gripe_2_or_3_dim_plot ();
+	      break;
+	    }
+	}
+      else
+	{
+	  error ("couldn't open temporary output file `%s'", name.c_str ());
+	  name.resize (0);
+	}
+    }
+
+  return name;
+}
+
+static int
+get_current_figure (void)
+{
+  int retval = 1;
+
+  octave_value cf = get_global_value ("__current_figure__", true);
+
+  if (cf.is_defined ())
+    retval = cf.int_value ();
+  else
+    set_global_value ("__current_figure__", retval);
+
+  return retval;
+}
+
+class
+gnuplot
+{
+protected:
+
+  gnuplot (void)
+    : plot_line_count (0), parametric_plot (false), 
+      use_title_option (Vgnuplot_use_title_option),
+      gnuplot_exe (Vgnuplot_binary),
+      gnuplot_terminal_type (), plot_stream ()
+  { }
+
+public:
+
+  ~gnuplot (void) { }
+
+  static bool have_instance (void);
+
+  static bool ensure_instance (void);
+
+  static bool ensure_plot_stream (void);
+
+  static void open (void);
+
+  static void close (void);
+
+  static bool plot_stream_event_handler (pid_t pid, int status);
+
+  static void init (void)
+  {
+    if (ensure_instance ())
+      instance->do_init ();
+  }
+
+  static void send (const std::string& cmd)
+  {
+    if (ensure_plot_stream ())
+      instance->do_send (cmd);
+  }
+
+  static void send_raw (const std::string& cmd)
+  {
+    if (ensure_plot_stream ())
+      instance->do_send_raw (cmd);
+  }
+
+  static void clear (void)
+  {
+    if (ensure_plot_stream ())
+      instance->do_clear ();
+  }
+
+  static void set (const string_vector& argv)
+  {
+    if (ensure_plot_stream ())
+      instance->do_set (argv);
+  }
+
+  static void show (const string_vector& argv)
+  {
+    if (ensure_plot_stream ())
+      instance->do_show (argv);
+  }
+
+  static void set_gnuplot_exe (const std::string& exe)
+  {
+    if (ensure_instance ())
+      instance->do_set_gnuplot_exe (exe);
+  }
+
+  static void set_gnuplot_use_title_option (bool opt)
+  {
+    if (ensure_instance ())
+      instance->do_set_gnuplot_use_title_option (opt);
+  }
+
+  // XXX FIXME XXX -- should only remove tmp files associated with
+  // gnuplot?
+  static void cleanup_tmp_files (void) { ::cleanup_tmp_files (); }
+
+  static void plot (const string_vector& argv)
+  {
+    if (ensure_plot_stream ())
+      instance->do_plot (argv);
+  }
+
+private:
+
+  static gnuplot *instance;
+
+  static std::map<int, gnuplot *> instance_map;
+
+  // The number of lines we've plotted so far.
+  int plot_line_count;
+
+  // Is this a parametric plot?  Makes a difference for 3D plotting.
+  bool parametric_plot;
+
+  // Should we append '-title "TITLE"' to the gnuplot command?
+  bool use_title_option;
+
+  // The executable program to run.
+  std::string gnuplot_exe;
+
+  // The gnuplot terminal type.
+  std::string gnuplot_terminal_type;
+
+  // Pipe to gnuplot.
+  oprocstream *plot_stream;
+
+  pid_t pid (void) const;
+
+  static gnuplot *lookup_by_pid (pid_t pid);
+
+  void do_open (void);
+
+  void do_close (void);
+
+  void delete_plot_stream (void);
+
+  void reset_plot_stream (void);
+
+  void do_send (const std::string& cmd);
+
+  void do_send_raw (const std::string& cmd);
+
+  void do_clear (void);
+
+  void do_set (const string_vector& argv);
+
+  void do_show (const string_vector& argv);
+
+  void do_set_gnuplot_exe (const std::string& exe) { gnuplot_exe = exe; }
+
+  void do_set_gnuplot_use_title_option (bool opt) { use_title_option = opt; }
+
+  void do_plot (const string_vector& argv);
+
+  void do_init (void);
+
+  std::string
+  makeplot (std::string caller, std::string args) throw (gpt_parse_error);
+
+  std::string handle_title (int& lasttok);
+};
+
+gnuplot *gnuplot::instance = 0;
+
+std::map<int, gnuplot *> gnuplot::instance_map;
+
+bool
+gnuplot::have_instance (void)
+{
+  int current_figure = get_current_figure ();
+
+  if (instance_map.find (current_figure) != instance_map.end ())
+    {
+      instance = instance_map[current_figure];
+      return true;
+    }
+  else
+    return false;
+}
+
+bool
+gnuplot::ensure_instance (void)
+{
+  if (! have_instance ())
+    {
+      instance = new gnuplot ();
+
+      if (! instance)
+	{
+	  ::error ("unable to create gnuplot object!");
+
+	  return false;
+	}
+      else
+	instance_map[get_current_figure ()] = instance;
+    }
+
+  return true;
+}
+
+bool
+gnuplot::ensure_plot_stream (void)
+{
+  if (ensure_instance ())
+    {
+      instance->do_open ();
+
+      if (error_state)
+	return false;
+    }
+
+  return true;
+}
+
+void
+gnuplot::close (void)
+{
+  if (have_instance ())
+    {
+      instance->do_close ();
+
+      instance_map.erase (get_current_figure ());
+    }
+}
+
+pid_t
+gnuplot::pid (void) const
+{
+  return plot_stream ? plot_stream->pid () : -1;
+}
+
+gnuplot *
+gnuplot::lookup_by_pid (pid_t pid)
+{
+  gnuplot *retval = 0;
+
+  for (std::map<int, gnuplot *>::const_iterator p = instance_map.begin ();
+       p != instance_map.end ();
+       p++)
+    {
+      gnuplot *elt = p->second;
+
+      if (elt && elt->pid () == pid)
+	{
+	  retval = elt;
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+void
+gnuplot::do_open (void)
+{
+  static bool initialized = false;
+
+  if (plot_stream && ! *plot_stream)
+    do_close ();
+
+  if (! plot_stream)
+    {
+      initialized = false;
+
+      plot_line_count = 0;
+
+      std::string cmd;
+
+      if (gnuplot_exe.empty ())
+	cmd = "gnuplot";
+      else
+        cmd = "\"" + gnuplot_exe + "\"";
+
+      // XXX FIXME XXX -- I'm not sure this is the right thing to do,
+      // but without it, C-c at the octave prompt will kill gnuplot...
+
+#if defined (HAVE_POSIX_SIGNALS)
+      sigset_t nset, oset;
+      sigemptyset (&nset);
+      sigaddset (&nset, SIGINT);
+      sigprocmask (SIG_BLOCK, &nset, &oset);
+#else
+      volatile octave_interrupt_handler old_interrupt_handler
+	= octave_ignore_interrupts ();
+#endif
+
+      if (use_title_option)
+	{
+	  OSSTREAM buf;
+
+	  buf << cmd
+	      << " -title \"Figure " << get_current_figure () << "\""
+	      << OSSTREAM_ENDS;
+
+	  cmd = OSSTREAM_STR (buf);
+
+	  OSSTREAM_FREEZE (buf);
+	}
+
+      plot_stream = new oprocstream (cmd.c_str ());
+
+      if (plot_stream && *plot_stream)
+	octave_child_list::insert (plot_stream->pid (),
+				   plot_stream_event_handler);
+      else
+	{
+	  delete_plot_stream ();
+
+	  error ("plot: unable to open pipe to `%s'", cmd.c_str ());
+	}
+
+#if defined (HAVE_POSIX_SIGNALS)
+      sigprocmask (SIG_SETMASK, &oset, 0);
+#else
+      octave_set_interrupt_handler (old_interrupt_handler);
+#endif
+    }
+
+  if (! error_state && plot_stream && *plot_stream && ! initialized)
+    {
+      initialized = true;
+
+      do_send_raw ("set style data lines\n");
+
+      if (! gnuplot_terminal_type.empty ())
+	do_send_raw ("set term " + gnuplot_terminal_type
+		     + Vgnuplot_command_end + "\n");
+    }
+}
+
+void
+gnuplot::delete_plot_stream (void)
+{
+  do_send_raw ("\nquit\n");
+
+  delete plot_stream;
+  plot_stream = 0;
+}
+
+void
+gnuplot::reset_plot_stream (void)
+{
+  delete_plot_stream ();
+
+  plot_line_count = 0;
+  parametric_plot = false;
+}
+
+void
+gnuplot::do_close (void)
+{
+  if (plot_stream)
+    {
+      octave_child_list::remove (plot_stream->pid ());
+
+      delete_plot_stream ();
+    }
+
+  plot_line_count = 0;
+}
+
+bool
+gnuplot::plot_stream_event_handler (pid_t pid, int status)
+{
+  bool retval = false;
+
+  if (pid > 0)
+    {
+      if (WIFEXITED (status) || WIFSIGNALLED (status))
+	{
+	  gnuplot *plotter = gnuplot::lookup_by_pid (pid);
+
+	  // We should only print a warning or request removal of the
+	  // process from the child list if the process died
+	  // unexpectedly.  If do_close is responsible for
+	  // gnuplot's death, then plotter will be 0 here and we don't
+	  // need to do anything.
+
+	  if (plotter)
+	    {
+	      plotter->reset_plot_stream ();
+
+	      warning ("connection to external plotter (pid = %d) lost --", pid);
+	      // Request removal of this PID from the list of child
+	      // processes.
+
+	      retval = true;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+void
+gnuplot::do_send (const std::string& cmd)
+{
+  int replot_len = Vgnuplot_command_replot.length ();
+
+  bool is_replot = (Vgnuplot_command_replot == cmd.substr (0, replot_len));
+
+  if (! (plot_line_count == 0 && is_replot))
+    do_send_raw (cmd);
+}
+
+void
+gnuplot::do_send_raw (const std::string& cmd)
+{
+  if (plot_stream && *plot_stream)
+    {
+      *plot_stream << cmd;
+
+      plot_stream->flush ();
+    }
+}
+
+void
+gnuplot::do_clear (void)
+{
+  do_send_raw ("clear\n");
+
+  // XXX FIXME XXX -- instead of just clearing these things, it would
+  // be nice if we could reset things to a user-specified default
+  // state.
+
+  do_send_raw ("set title\n");
+  do_send_raw ("set xlabel\n");
+  do_send_raw ("set ylabel\n");
+  do_send_raw ("set nogrid\n");
+  do_send_raw ("set nolabel\n");
+
+  // This makes a simple `replot' not work after a `clearplot' command
+  // has been issued.
+
+  plot_line_count = 0;
+}
+
+void
+gnuplot::do_set (const string_vector& argv)
+{
+  int argc = argv.length ();
+
+  OSSTREAM plot_buf;
+
+  if (argc > 1)
+    {
+      if (almost_match ("parametric", argv[1], 3))
+	parametric_plot = true;
+      else if (almost_match ("noparametric", argv[1], 5))
+	parametric_plot = false;
+      else if (almost_match ("term", argv[1], 1))
+	{
+	  gnuplot_terminal_type = "";
+	  OSSTREAM buf;
+	  int i;
+	  for (i = 2; i < argc-1; i++)
+	    buf << argv[i] << " ";
+	  if (i < argc)
+	    buf << argv[i];
+	  buf << Vgnuplot_command_end << OSSTREAM_ENDS;
+	  gnuplot_terminal_type = OSSTREAM_STR (buf);
+	  OSSTREAM_FREEZE (buf);
+	}
+    }
+
+  int i;
+  for (i = 0; i < argc-1; i++)
+    plot_buf << argv[i] << " ";
+
+  if (i < argc)
+    plot_buf << argv[i];
+
+  plot_buf << Vgnuplot_command_end << OSSTREAM_ENDS;
+
+  do_send_raw (OSSTREAM_STR (plot_buf));
+
+  OSSTREAM_FREEZE (plot_buf);
+}
+
+void
+gnuplot::do_show (const string_vector& argv)
+{
+  int argc = argv.length ();
+
+  OSSTREAM plot_buf;
+
+  int i;
+  for (i = 0; i < argc-1; i++)
+    plot_buf << argv[i] << " ";
+  if (i < argc)
+    plot_buf << argv[i];
+
+  plot_buf << Vgnuplot_command_end << OSSTREAM_ENDS;
+
+  do_send (OSSTREAM_STR (plot_buf));
+
+  OSSTREAM_FREEZE (plot_buf);
+}
+
+void
+gnuplot::do_plot (const string_vector& argv)
+{
+  std::string s;
+
+  for (int i = 1; i < argv.length (); i++)
+    s += argv[i] + " ";
+
+  try
+    {
+      std::string cmd = makeplot (argv[0], s);
+
+      do_send (cmd);
+    }
+  catch (gpt_parse_error& e)
+    {
+      if (e.msg.empty ())
+	error ("could not parse plot command");
+      else
+	error (e.msg.c_str ());
+    }
+}
+
+// Parse and evaluate parameter string and pass it to gnuplot pipe.
+
+std::string
+gnuplot::makeplot (std::string caller, std::string args)
+  throw (gpt_parse_error)
+{
+  std::string retval;
+
+  YY_BUFFER_STATE bstate;
+
+  bstate = yy_scan_string (args.c_str ());
+  yy_switch_to_buffer (bstate);
+  std::string outstr;
+  int ndim = 2;
+
+  if (caller == "replot")
+    {
+      ndim = 1;
+      outstr += Vgnuplot_command_replot + " ";
+    }
+  else if (caller == "plot")
+    {
+      ndim = 2;
+      plot_line_count = 0;
+      outstr += Vgnuplot_command_plot + " ";
+    }
+  else if (caller == "splot")
+    {
+      ndim = 3;
+      plot_line_count = 0;
+      outstr += Vgnuplot_command_splot + " ";
+    }
+  else
+    throw gpt_parse_error ("unknown plot command");
+
+  gpt_quote_is_transpose = false;
+  gpt_allow_plotkw = false;
+  gpt_parens = 0;
+  gpt_braces = 0;
+  gpt_brackets = 0;
+
+  int tok;
+  tok = gptlex ();
+  if (plottok_or_end_p (tok) && caller != "replot")
+    throw gpt_parse_error ("must have something to plot");
+
+  while (tok)
+    {
+      bool title_set = false;
+      bool using_set = false;
+      bool style_set = false;
+      bool axes_set = false;
+
+      if (tok == START_BRACKET)
+	{
+	  if (caller == "replot")
+	    throw gpt_parse_error ("can't specify new plot ranges with `replot' or while hold is on");
+
+	  std::string xrange_start_str = read_until (colonp, tok);
+	  std::string xrange_end_str = read_until (endbracketp, tok);
+	  outstr += printrange (xrange_start_str, xrange_end_str) + " ";
+	  tok = gptlex ();
+	  if (tok == START_BRACKET)
+	    {
+	      std::string yrange_start_str = read_until (colonp, tok);
+	      std::string yrange_end_str = read_until (endbracketp, tok);
+	      outstr += printrange (yrange_start_str, yrange_end_str) + " ";
+	      tok = gptlex ();
+	      if (tok == START_BRACKET && caller == "gsplot")
+		{
+		  std::string zrange_start_str = read_until (colonp, tok);
+		  std::string zrange_end_str = read_until (endbracketp, tok);
+		  outstr += printrange (zrange_start_str, zrange_end_str) + " ";
+		  tok = gptlex ();
+                }
+            }
+        }
+
+      if (plottok_or_end_p (tok))
+	return std::string ();
+      else
+	{
+	  std::string file;
+	  plot_line_count++;
+
+	  std::string plot_expr_str;
+	  plot_expr_str += std::string (yytext) + " ";
+	  plot_expr_str += read_until (plottok_or_end_p, tok);
+
+	  int status = 0;
+	  octave_value tmp_data = eval_string (plot_expr_str,
+					       true, status);
+
+	  if (status != 0 || ! tmp_data.is_defined ())
+	    throw gpt_parse_error ();
+
+	  OSSTREAM tmp_buf;
+	  tmp_data.print_raw (tmp_buf);
+	  tmp_buf << OSSTREAM_ENDS;
+
+	  if (tmp_data.is_string ())
+	    {
+	      file = file_ops::tilde_expand (tmp_data.string_value ());
+	      // XXX FIXME XXX -- perhaps should check if the file exists?
+	      outstr += file + " ";
+	    }
+	  else
+	    {
+	      switch (ndim)
+		{
+		case 2:
+		  file = save_in_tmp_file (tmp_data, ndim);
+		  break;
+
+		case 3:
+		  file = save_in_tmp_file (tmp_data, ndim,
+					   parametric_plot);
+		  break;
+
+		default:
+		  gripe_2_or_3_dim_plot ();
+		  break;
+		}
+
+	      if (file.length () > 0)
+		{
+		  mark_for_deletion (file);
+		  outstr += "'" + file + "' ";
+		}
+	    }
+        }
+
+      std::string title_str;
+      std::string using_str;
+      std::string style_str;
+      std::string axes_str;
+
+      bool out = false;
+      while (tok && ! out)
+	{
+	  switch (tok)
+	    {
+	    case COMMA:
+	      out = true;
+	      break;
+
+	    case TITLE:
+	      if (! title_set)
+		title_str += handle_title (tok) + " ";
+	      else
+		throw gpt_parse_error ("only one title option may be specified");
+	      title_set = true;
+	      break;
+
+	    case USING:
+	      if (! using_set)
+		using_str += handle_using (tok) + " ";
+	      else
+		throw gpt_parse_error ("only one using option may be specified");
+	      using_set = true;
+	      break;
+
+	    case WITH:
+	      if (! style_set)
+		style_str += handle_style (tok) + " ";
+	      else
+		throw gpt_parse_error ("only one style option may be specified");
+	      style_set = true;
+	      break;
+
+	    case AXES:
+	      if (! axes_set)
+		axes_str += handle_axes (tok) + " ";
+	      else
+		throw gpt_parse_error ("only one axes option may be specified");
+	      axes_set = true;
+	      break;
+
+	    default:
+	      tok = 0;
+	      break;
+            }
+        }
+
+        if (! title_set)
+	  {
+            OSSTREAM tmp_buf;
+            tmp_buf << Vgnuplot_command_title << " \"line "
+                    << plot_line_count << "\" " << OSSTREAM_ENDS;
+            title_str = OSSTREAM_STR (tmp_buf);
+	    title_set = true;
+        }
+
+	// Plot parameters have to be output in this order.
+	if (using_set)
+	  outstr += using_str;
+
+	if (axes_set)
+	  outstr += axes_str;
+
+	if (title_set)
+	  outstr += title_str;
+
+	if (style_set)
+	  outstr += style_str;
+
+	if (out)
+	  {
+	    // Saw comma on while loop.
+            outstr += ", ";
+            gpt_quote_is_transpose = false;
+            gpt_allow_plotkw = false;
+            gpt_parens = 0;
+            gpt_braces = 0;
+            gpt_brackets = 0;
+            tok = gptlex ();
+	  }
+    }
+
+  outstr += Vgnuplot_command_end;
+
+  return outstr;
+}
+
+// Title has one string expression which is evaluated and printed to the
+// gnuplot command string.
+
+std::string
+gnuplot::handle_title (int& lasttok)
+{
+  int tok;
+  std::string retstr = Vgnuplot_command_title + " ";
+  std::string title_expr_str;
+
+  title_expr_str += read_until (plottok_or_end_p, tok);
+
+  int status;
+  octave_value tmp_data = eval_string (title_expr_str, true, status);
+
+  if (status != 0 || ! tmp_data.is_defined ())
+    throw gpt_parse_error ();
+
+  OSSTREAM tmp_buf;
+  if (tmp_data.is_string ())
+    {
+      tmp_buf << '"';
+      tmp_data.print_raw (tmp_buf);
+      tmp_buf << '"' << OSSTREAM_ENDS;
+    }
+  else
+    {
+      warning ("line title must be a string");
+      tmp_buf << '"' << "line " << plot_line_count << '"';
+    }
+
+  retstr += OSSTREAM_STR (tmp_buf);
+
+  lasttok = tok;
+
+  return retstr;
+}
+
+static int
+automatic_replot (void)
+{
+  Vautomatic_replot = check_preference ("automatic_replot");
+
+  return 0;
+}
+
+static int
+set_string_var (std::string& var, const char *nm)
+{
+  int retval = 0;
+
+  std::string s = builtin_string_variable (nm);
+
+  if (s.empty ())
+    {
+      gripe_invalid_value_specified (nm);
+      retval = -1;
+    }
+  else
+    var = s;
+
+  return retval;
+}
+
+static int
+gnuplot_binary (void)
+{
+  int status = set_string_var (Vgnuplot_binary, "gnuplot_binary");
+
+  if (status == 0)
+    gnuplot::set_gnuplot_exe (Vgnuplot_binary);
+
+  return status;
+}
+
+static int
+gnuplot_command_plot (void)
+{
+  return set_string_var (Vgnuplot_command_plot, "gnuplot_command_plot");
+}
+
+static int
+gnuplot_command_replot (void)
+{
+  return set_string_var (Vgnuplot_command_replot, "gnuplot_command_replot");
+}
+
+static int
+gnuplot_command_splot (void)
+{
+  return set_string_var (Vgnuplot_command_splot, "gnuplot_command_splot");
+}
+
+static int
+gnuplot_command_using (void)
+{
+  return set_string_var (Vgnuplot_command_using, "gnuplot_command_using");
+}
+
+static int
+gnuplot_command_with (void)
+{
+  return set_string_var (Vgnuplot_command_with, "gnuplot_command_with");
+}
+
+static int
+gnuplot_command_axes (void)
+{
+  return set_string_var (Vgnuplot_command_axes, "gnuplot_command_axes");
+}
+
+static int
+gnuplot_command_title (void)
+{
+  return set_string_var (Vgnuplot_command_title, "gnuplot_command_title");
+}
+
+static int
+gnuplot_command_end (void)
+{
+  return set_string_var (Vgnuplot_command_end, "gnuplot_command_end");
+}
+
+static int
+gnuplot_use_title_option (void)
+{
+  Vgnuplot_use_title_option = check_preference ("gnuplot_use_title_option");
+
+  gnuplot::set_gnuplot_use_title_option (Vgnuplot_use_title_option);
+
+  return 0;
+}
+
+void
+gnuplot::do_init (void)
+{
+  static bool gnuplot_initialized = false;
+
+  if (gnuplot_initialized)
+    return;
+
+  gnuplot_initialized = true;
+
+  if (is_builtin_variable ("automatic_replot"))
+    automatic_replot ();
+  else
+    DEFVAR (automatic_replot, true, automatic_replot,
+    "-*- texinfo -*-\n\
+@defvr {Built-in Variable} automatic_replot\n\
+You can tell Octave to redisplay the plot each time anything about it\n\
+changes by setting the value of the builtin variable\n\
+@code{automatic_replot} to a nonzero value.  Although it is fairly\n\
+inefficient, especially for large plots, the default value is 1 for\n\
+compatibility with Matlab.\n\
+@end defvr");
+
+  if (is_builtin_variable ("gnuplot_binary"))
+    gnuplot_binary ();
+  else
+    DEFVAR (gnuplot_binary, GNUPLOT_BINARY, gnuplot_binary,
+    "-*- texinfo -*-\n\
+@defvr {Built-in Variable} gnuplot_binary\n\
+The name of the program invoked by the plot command.  The default value\n\
+is @code{\"gnuplot\"}.  @xref{Installation}.\n\
+@end defvr");
+
+  if (is_builtin_variable ("gnuplot_command_plot"))
+    gnuplot_command_plot ();
+  else
+    DEFVAR (gnuplot_command_plot, "pl", gnuplot_command_plot,
+    "-*- texinfo -*-\n\
+@defvr {Built-in Variable} gnuplot_command_plot\n\
+@end defvr");
+
+  if (is_builtin_variable ("gnuplot_command_replot"))
+    gnuplot_command_replot ();
+  else
+    DEFVAR (gnuplot_command_replot, "rep", gnuplot_command_replot,
+    "-*- texinfo -*-\n\
+@defvr {Built-in Variable} gnuplot_command_replot\n\
+@end defvr");
+
+  if (is_builtin_variable ("gnuplot_command_splot"))
+    gnuplot_command_splot ();
+  else
+    DEFVAR (gnuplot_command_splot, "sp", gnuplot_command_splot,
+    "-*- texinfo -*-\n\
+@defvr {Built-in Variable} gnuplot_command_splot\n\
+@end defvr");
+
+  if (is_builtin_variable ("gnuplot_command_using"))
+    gnuplot_command_using ();
+  else
+    DEFVAR (gnuplot_command_using, "u", gnuplot_command_using,
+    "-*- texinfo -*-\n\
+@defvr {Built-in Variable} gnuplot_command_using\n\
+@end defvr");
+
+  if (is_builtin_variable ("gnuplot_command_with"))
+    gnuplot_command_with ();
+  else
+    DEFVAR (gnuplot_command_with, "w", gnuplot_command_with,
+    "-*- texinfo -*-\n\
+@defvr {Built-in Variable} gnuplot_command_with\n\
+@end defvr");
+
+  if (is_builtin_variable ("gnuplot_command_axes"))
+    gnuplot_command_axes ();
+  else
+    DEFVAR (gnuplot_command_axes, "ax", gnuplot_command_axes,
+    "-*- texinfo -*-\n\
+@defvr {Built-in Variable} gnuplot_command_axes\n\
+@end defvr");
+
+  if (is_builtin_variable ("gnuplot_command_title"))
+    gnuplot_command_title ();
+  else
+    DEFVAR (gnuplot_command_title, "t", gnuplot_command_title,
+    "-*- texinfo -*-\n\
+@defvr {Built-in Variable} gnuplot_command_title\n\
+@end defvr");
+
+  if (is_builtin_variable ("gnuplot_command_end"))
+    gnuplot_command_end ();
+  else
+    DEFVAR (gnuplot_command_end, "\n", gnuplot_command_end,
+    "-*- texinfo -*-\n\
+@defvr {Built-in Variable} gnuplot_command_end\n\
+@end defvr");
+
+  if (is_builtin_variable ("gnuplot_use_title_option"))
+    gnuplot_use_title_option ();
+  else
+    DEFVAR (gnuplot_use_title_option, octave_env::have_x11_display (),
+	    gnuplot_use_title_option,
+    "-*- texinfo -*-\n\
+@defvr {Built-in Variable} gnuplot_use_title_option\n\
+If nonzero, append @samp{-title \"Figure NN\"} to the gnuplot command.\n\
+@end defvr");
+
+}
+
+// -----------------------
+// User-callable functions
+// -----------------------
+
+DEFUN_DLD (__gnuplot_init__, , ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} __gnuplot_init__ ()\n\
+@end deftypefn")
+{
+  gnuplot::init ();
+
+  return octave_value_list ();
+}
+
+DEFUN_DLD (clearplot, , ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} clearplot\n\
+@deftypefnx {Built-in Function} {} clg\n\
+Clear the plot window and any titles or axis labels.  The name\n\
+@code{clg} is aliased to @code{clearplot} for compatibility with\n\
+@sc{Matlab}.\n\
+@end deftypefn")
+{
+  gnuplot::clear ();
+
+  return octave_value_list ();
+}
+
+DEFUN_DLD (closeplot, , ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} closeplot\n\
+Close stream to the @code{gnuplot} subprocess.  If you are using X11,\n\
+this will close the plot window.\n\
+@end deftypefn")
+{
+  gnuplot::close ();
+
+  return octave_value_list ();
+}
+
+DEFUN_DLD (purge_tmp_files, , ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} purge_tmp_files\n\
+Delete the temporary files created by the plotting commands.\n\
+\n\
+Octave creates temporary data files for @code{gnuplot} and then sends\n\
+commands to @code{gnuplot} through a pipe.  Octave will delete the\n\
+temporary files on exit, but if you are doing a lot of plotting you may\n\
+want to clean up in the middle of a session.\n\
+\n\
+A future version of Octave will eliminate the need to use temporary\n\
+files to hold the plot data.\n\
+@end deftypefn")
+{
+  gnuplot::cleanup_tmp_files ();
+
+  return octave_value_list ();
+}
+
+DEFUN_DLD (__gnuplot_raw__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} __gnuplot_raw__ (@var{string})\n\
+Send @var{string} directly to gnuplot subprocess.\n\
+@end deftypefn")
+{
+  if (args.length () == 1 && args(0).is_string ())
+    {
+      std::string cmd = args(0).string_value ();
+
+      gnuplot::send_raw (cmd);
+    }
+  else
+    print_usage ("__gnuplot_raw__");
+
+  return octave_value_list ();
+}
+
+DEFUN_DLD (__gnuplot_set__, args, ,
+  "-*- texinfo -*-\n\
+@deffn {Command} __gnuplot_set__ options\n\
+Set plotting options for gnuplot\n\
+@end deffn")
+{
+  string_vector argv = args.make_argv ("set");
+
+  if (! error_state)
+    gnuplot::set (argv);
+
+  return octave_value_list ();
+}
+
+DEFUN_DLD (__gnuplot_show__, args, ,
+  "-*- texinfo -*-\n\
+@deffn {Command} __gnuplot_show__ options\n\
+Show plotting options.\n\
+@end deffn")
+{
+  string_vector argv = args.make_argv ("show");
+
+  if (! error_state)
+    gnuplot::show (argv);
+
+  return octave_value_list ();
+}
+
+DEFUN_DLD (__gnuplot_plot__, args, ,
+  "Plot with gnuplot.\n")
+{
+  string_vector argv = args.make_argv ("plot");
+
+  if (! error_state)
+    gnuplot::plot (argv);
+
+  return octave_value_list ();
+}
+
+DEFUN_DLD (__gnuplot_splot__, args, ,
+  "Plot with gnuplot.\n")
+{
+  string_vector argv = args.make_argv ("splot");
+
+  if (! error_state)
+    gnuplot::plot (argv);
+
+  return octave_value_list ();
+}
+
+DEFUN_DLD (__gnuplot_replot__, args, ,
+  "Plot with gnuplot.\n")
+{
+  string_vector argv = args.make_argv ("replot");
+
+  if (! error_state)
+    gnuplot::plot (argv);
+
+  return octave_value_list ();
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
deleted file mode 100644
--- a/src/DLD-FUNCTIONS/gplot.l
+++ /dev/null
@@ -1,1871 +0,0 @@
-/*
-
-Copyright (C) 2004 John W. Eaton and Teemu Ikonen
-
-This file is part of Octave.
-
-Octave is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-Octave is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with Octavee; see the file COPYING.  If not, write to the Free
-Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.
-
-*/
-
-%option prefix="gpt"
-%option noyywrap
-
-%{
-// PKG_ADD: mark_as_rawcommand ("__gnuplot_plot__");
-// PKG_ADD: mark_as_rawcommand ("__gnuplot_set__");
-// PKG_ADD: mark_as_rawcommand ("__gnuplot_splot__");
-// PKG_ADD: mark_as_rawcommand ("__gnuplot_replot__");
-
-// PKG_ADD: mark_as_rawcommand ("gplot");
-// PKG_ADD: mark_as_rawcommand ("gset");
-// PKG_ADD: mark_as_rawcommand ("gsplot");
-
-// PKG_ADD: mark_as_command ("__gnuplot_show__");
-
-// PKG_ADD: mark_as_command ("gshow");
-
-// PKG_ADD: mark_as_command ("set");
-// PKG_ADD: mark_as_command ("show");
-
-// PKG_ADD: __gnuplot_init__ ();
-
-// PKG_ADD: atexit ("closeplot");
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <map>
-#include <string>
-#include <fstream>
-#include <iostream>
-
-#ifdef HAVE_UNISTD_H
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#include <unistd.h>
-#endif
-
-#include "file-ops.h"
-#include "oct-env.h"
-
-#include "defun-dld.h"
-#include "file-io.h"
-#include "gripes.h"
-#include "load-save.h"
-#include "parse.h"
-#include "procstream.h"
-#include "sighandlers.h"
-#include "utils.h"
-#include "variables.h"
-
-enum _toktype
-  {
-    START_PAREN = 1,
-    END_PAREN,
-    START_BRACE,
-    END_BRACE,
-    START_BRACKET,
-    END_BRACKET,
-    COLON,
-    SEMICOLON,
-    COMMA,
-    QUOTE,
-    IDENT,
-    NUMBER,
-    BINOP,
-    UNOP,
-    STRING,
-    OTHER,
-    TITLE,
-    USING,
-    WITH,
-    AXES,
-    CLEAR
-  };
-
-typedef bool (*pred) (const int);
-
-class
-gpt_parse_error
-{
-public:
-  gpt_parse_error (void) : msg () { }
-  gpt_parse_error (std::string errmsg) : msg (errmsg) { }
-
-  std::string msg;
-};
-
-static bool gpt_quote_is_transpose;
-static bool gpt_allow_plotkw;
-static int gpt_parens;
-static int gpt_brackets;
-static int gpt_braces;
-
-static bool can_be_plotkw (void);
-
-static int is_plot_keyword (const std::string& s);
-
-static int handle_string (char delim);
-static std::string strbuf;
-
-%}
-
-D	[0-9]
-S	[ \t]
-IDENT	([_a-zA-Z@][_a-zA-Z0-9]*)
-EXPON	([DdEe][+-]?{D}+)
-NUMBER  (({D}+\.?{D}*{EXPON}?)|(\.{D}+{EXPON}?)|(0[xX][0-9a-fA-F]+))
-NOT	((\~)|(\!))
-/* NOT is not strictly a binary operator, but is close enough for us. */
-BINOP   (({NOT})|(\.?([\*/\\^+-]|\*\*)=?)|([<=~!>&|]=)|([=&|<>]{1,2})|(<<=)|(>>=)|(\.))
-/* single quote (') transpose operator is handled separately. */
-UNOP    ((\+\+)|(\-\-)|(\.'))
-
-%%
-
-"(" {
-    gpt_quote_is_transpose = false;
-    gpt_parens++;
-    return START_PAREN;
-    }
-
-")" {
-    gpt_quote_is_transpose = true;
-    gpt_parens--;
-    return END_PAREN;
-    }
-
-"{" {
-    gpt_quote_is_transpose = false;
-    gpt_braces++;
-    return START_BRACE;
-    }
-
-"}" {
-    gpt_quote_is_transpose = true;
-    gpt_braces--;
-    return END_BRACE;
-    }
-
-"[" {
-    gpt_quote_is_transpose = false;
-    gpt_brackets++;
-    return START_BRACKET;
-    }
-
-"]" {
-    gpt_quote_is_transpose = true;
-    gpt_brackets--;
-    return END_BRACKET;
-    }
-
-":" {
-    gpt_quote_is_transpose = false;
-    return COLON;
-    }
-
-";" {
-    gpt_quote_is_transpose = false;
-    return SEMICOLON;
-    }
-
-"," {
-    gpt_quote_is_transpose = false;
-    return COMMA;
-    }
-
-"'" {
-    if (gpt_quote_is_transpose)
-      {
-        gpt_allow_plotkw = true;
-        return QUOTE;
-      }
-    else
-      {
-        gpt_quote_is_transpose = true;
-        gpt_allow_plotkw = true;
-        return handle_string ('\'');
-      }
-    }
-
-"\"" {
-    return handle_string ('"');
-    }
-
-{IDENT} {
-    int itok = 0;
-    if (can_be_plotkw () && (itok = is_plot_keyword (yytext)))
-      {
-        gpt_quote_is_transpose = false;
-        gpt_allow_plotkw = true;
-        return itok;
-      }
-    else if (std::string (yytext) == "function")
-      throw gpt_parse_error ("function keyword not allowed in plot commands");
-    else
-      {
-        gpt_quote_is_transpose = true;
-        gpt_allow_plotkw = true;
-        return IDENT;
-      }
-    }
-
-{D}+/\.[\*/\\^'] | /* ' */
-{NUMBER} {
-    gpt_quote_is_transpose = true;
-    gpt_allow_plotkw = true;
-    return NUMBER;
-    }
-
-{BINOP} {
-    gpt_quote_is_transpose = false;
-    gpt_allow_plotkw = false;
-    return BINOP;
-    }
-
-{UNOP} {
-    gpt_quote_is_transpose = false;
-    gpt_allow_plotkw = true;
-    return UNOP;
-    }
-
-{S} { /* Ignore spaces and tabs outside of character strings. */ }
-
-. {
-    gpt_quote_is_transpose = false;
-    gpt_allow_plotkw = true;
-    warning ("unknown token = \"%s\" in plot command", yytext);
-    return OTHER;
-    }
-
-%%
-
-// ------------------------------------------------------------
-// Interface to external gnuplot process(es), including gnuplot
-// command parser.
-// ------------------------------------------------------------
-
-// The name of the shell command to execute to start gnuplot.
-static std::string Vgnuplot_binary;
-
-// Append -title "Figure NN" to the gnuplot command?
-static bool Vgnuplot_use_title_option = octave_env::have_x11_display ();
-
-// Gnuplot command strings that we use.
-static std::string Vgnuplot_command_plot;
-static std::string Vgnuplot_command_replot;
-static std::string Vgnuplot_command_splot;
-static std::string Vgnuplot_command_using;
-static std::string Vgnuplot_command_with;
-static std::string Vgnuplot_command_axes;
-static std::string Vgnuplot_command_title;
-static std::string Vgnuplot_command_end;
-
-// If TRUE, a replot command is issued automatically each time a plot
-// changes in some way.
-static bool Vautomatic_replot;
-
-// Check if the parser state is such that a plot keyword can occur.
-
-static bool
-can_be_plotkw (void)
-{
-    return (gpt_allow_plotkw
-	    && (gpt_braces == 0)
-	    && (gpt_brackets == 0)
-	    && (gpt_parens == 0));
-}
-
-// Check to see if a character string matches any one of the plot
-// option keywords.  Don't match abbreviations for clear, since that's
-// not a gnuplot keyword (users will probably only expect to be able
-// to abbreviate actual gnuplot keywords).
-
-static int
-is_plot_keyword (const std::string& s)
-{
-  if (almost_match ("title", s, 1))
-    return TITLE;
-  else if (almost_match ("using", s, 1))
-    return USING;
-  else if (almost_match ("with", s, 1))
-    return WITH;
-  else if (almost_match ("axes", s, 2) || almost_match ("axis", s, 2))
-    return AXES;
-  else if ("clear" == s)
-    return CLEAR;
-  else
-    return 0;
-}
-
-// This is used to handle character strings.  Kludge alert.
-
-static int
-handle_string (char delim)
-{
-  int c;
-  bool escape_pending = false;
-
-  strbuf = std::string (1, delim);
-
-  while ((c = yyinput ()) != EOF)
-    {
-      if (c == '\\')
-	{
-	  if (escape_pending)
-	    {
-	      strbuf += static_cast<char> (c);
-	      escape_pending = false;
-	    }
-	  else
-	    {
-	      strbuf += static_cast<char> (c);
-	      escape_pending = true;
-	    }
-	  continue;
-	}
-      else if (c == '\n')
-	{
-	  error ("unterminated string constant");
-	  break;
-	}
-      else if (c == delim)
-	{
-	  if (escape_pending)
-	    strbuf += static_cast<char> (c);
-	  else
-	    {
-	      c = yyinput ();
-
-	      if (c == delim)
-		{
-		  strbuf += static_cast<char> (c);
-		  strbuf += static_cast<char> (c);
-		}
-	      else
-		{
-		  yyunput (c, yytext);
-		  strbuf += static_cast<char> (delim);
-		  return STRING;
-		}
-	    }
-	}
-      else
-	strbuf += static_cast<char> (c);
-
-      escape_pending = false;
-    }
-
-  throw gpt_parse_error ("unterminated string");
-
-  return 0;
-}
-
-// (Probably not necessesary, but current Matlab style plot functions
-// break without this (they emit too short gnuplot commands))
-
-static std::string
-plot_style_token (const std::string& s)
-{
-  std::string retval;
-
-  // XXX FIXME XXX -- specify minimum match length for these.
-  static const char *plot_styles[] =
-    {
-      "boxes",
-      "boxerrorbars",
-      "boxxyerrorbars",
-      "candlesticks",
-      "dots",
-      "errorbars",
-      "financebars",
-      "fsteps",
-      "histeps",
-      "impulses",
-      "lines",
-      "linespoints",
-      "points",
-      "steps",
-      "vector",
-      "xerrorbars",
-      "xyerrorbars",
-      "yerrorbars",
-      0,
-    };
-
-  const char * const *tmp = plot_styles;
-  while (*tmp)
-    {
-      if (almost_match (*tmp, s.c_str ()))
-	{
-	  retval = *tmp;
-	  break;
-	}
-
-      tmp++;
-    }
-
-  return retval;
-}
-
-// Some predicates on tokens
-
-// Return true for ":".
-
-static bool
-colonp (const int tok)
-{
-  return (tok == COLON);
-}
-
-// Return TRUE for "]".
-
-static bool
-endbracketp (const int tok)
-{
-  return (tok == END_BRACKET);
-}
-
-// Return TRUE for plot token, comma or end of input.
-
-static bool
-plottok_or_end_p (const int tok)
-{
-  return (tok == TITLE
-	  || tok == USING
-	  || tok == WITH
-	  || tok == AXES
-	  || tok == CLEAR
-	  || tok == COMMA
-	  || tok == 0);
-}
-
-// Equivalent to (colonp (tok) || plottok_or_end_p (tok)).
-
-static bool
-colon_plottok_or_end_p (const int tok)
-{
-  return (tok == COLON || plottok_or_end_p (tok));
-}
-
-// read until test is true and delimiters are balanced, or end of input.
-// Return the last token in lasttok
-
-static std::string
-read_until (pred test, int& lasttok) throw (gpt_parse_error)
-{
-  int tok;
-
-  // We have to maintain balanced delimiters per subexpression too.
-  int brackets = 0;
-  int parens = 0;
-  int braces = 0;
-  std::string s;
-
-  tok = gptlex ();
-
-  while (tok && ! (test (tok)
-		   && brackets == 0
-		   && parens == 0
-		   && braces == 0))
-    {
-      switch (tok)
-	{
-	case START_BRACKET:
-	  brackets++;
-	  break;
-
-	case END_BRACKET:
-	  brackets--;
-	  break;
-
-	case START_PAREN:
-	  parens++;
-	  break;
-
-	case END_PAREN:
-	  parens--;
-	  break;
-
-	case START_BRACE:
-	  braces++;
-	  break;
-
-	case END_BRACE:
-	  braces--;
-	  break;
-
-	default:
-	  break;
-        }
-
-      s += (tok == STRING ? strbuf : std::string (yytext)) + " ";
-
-      tok = gptlex ();
-    }
-
-  // Throw error only if we've reached the end token and the test
-  // doesn't accept it.
-
-  if (! test (tok) && ! tok)
-    throw gpt_parse_error ("unexpected end of input");
-
-  lasttok = tok;
-
-  return s;
-}
-
-// Eval the two expressions giving limits of range and print it.
-
-static std::string
-printrange (std::string starts, std::string ends)
-{
-  octave_value startv, endv;
-  int status;
-  std::string s;
-  OSSTREAM range_buf;
-
-  range_buf << "[";
-
-  if (! starts.empty ())
-    {
-      startv = eval_string (starts, true, status);
-      if (! startv.is_real_scalar ())
-	throw gpt_parse_error ();
-      startv.print_raw (range_buf);
-    }
-
-    range_buf << ":";
-
-    if (! ends.empty ())
-      {
-	endv = eval_string (ends, true, status);
-	if (! endv.is_real_scalar ())
-	  throw gpt_parse_error ();
-        endv.print_raw (range_buf);
-      }
-
-    range_buf << "]";
-    range_buf << OSSTREAM_ENDS;
-
-    s = OSSTREAM_STR (range_buf);
-
-    return s;
-}
-
-// Handle plot parameters.
-
-// Parse, evaluate and print colon separated expressions in the using
-// plot parameter. The use of trailing format string is not supported.
-
-static std::string
-handle_using (int& lasttok)
-{
-  int tok;
-  std::string expr_str;
-  std::string retstr = Vgnuplot_command_using + " ";
-  bool out = false;
-
-  octave_value tmp_data;
-  int status;
-  while (! out)
-    {
-      expr_str = read_until (colon_plottok_or_end_p, tok);
-
-      tmp_data = eval_string (expr_str, true, status);
-      if (status != 0 || ! tmp_data.is_real_scalar ())
-	throw gpt_parse_error ();
-
-      OSSTREAM tmp_buf;
-      tmp_data.print_raw (tmp_buf);
-      tmp_buf << OSSTREAM_ENDS;
-      retstr += OSSTREAM_STR (tmp_buf);
-
-      if (tok == COLON)
-	retstr += ":";
-      else
-	out = true;
-    }
-
-  lasttok = tok;
-
-  return retstr;
-}
-
-// Presently just passes the linewidth, pointtype etc. tokens as they are.
-
-static std::string
-handle_style (int& lasttok)
-{
-  std::string retstr = Vgnuplot_command_with + " ";
-  std::string style;
-
-  lasttok = gptlex ();
-
-  if (lasttok != IDENT)
-    throw gpt_parse_error ("expected plot style token");
-
-  style = std::string (yytext);
-  style = plot_style_token (style);
-
-  if (! style.empty ())
-    retstr += style;
-  else
-    retstr += std::string (yytext);
-
-  // XXX FIXME XXX -- should evaluate the remaining tokens, but this
-  // needs changes in the parser.
-  retstr += " " + read_until (plottok_or_end_p, lasttok);
-
-  return retstr;
-}
-
-// Axes has only one qualifier keyword, which is not evaluated.
-
-static std::string
-handle_axes (int& lasttok)
-{
-  return Vgnuplot_command_axes + " " + read_until (plottok_or_end_p, lasttok);
-}
-
-static std::string
-save_in_tmp_file (const octave_value& t, int ndim = 2, bool parametric = false)
-{
-  std::string name = file_ops::tempnam ("", "oct-");
-
-  if (! name.empty ())
-    {
-      std::ofstream file (name.c_str ());
-
-      if (file)
-	{
-	  switch (ndim)
-	    {
-	    case 2:
-	      save_ascii_data_for_plotting (file, t, name);
-	      break;
-
-	    case 3:
-	      save_three_d (file, t, parametric);
-	      break;
-
-	    default:
-	      gripe_2_or_3_dim_plot ();
-	      break;
-	    }
-	}
-      else
-	{
-	  error ("couldn't open temporary output file `%s'", name.c_str ());
-	  name.resize (0);
-	}
-    }
-
-  return name;
-}
-
-static int
-get_current_figure (void)
-{
-  int retval = 1;
-
-  octave_value cf = get_global_value ("__current_figure__", true);
-
-  if (cf.is_defined ())
-    retval = cf.int_value ();
-  else
-    set_global_value ("__current_figure__", retval);
-
-  return retval;
-}
-
-class
-gnuplot
-{
-protected:
-
-  gnuplot (void)
-    : plot_line_count (0), parametric_plot (false), 
-      use_title_option (Vgnuplot_use_title_option),
-      gnuplot_exe (Vgnuplot_binary),
-      gnuplot_terminal_type (), plot_stream ()
-  { }
-
-public:
-
-  ~gnuplot (void) { }
-
-  static bool have_instance (void);
-
-  static bool ensure_instance (void);
-
-  static bool ensure_plot_stream (void);
-
-  static void open (void);
-
-  static void close (void);
-
-  static bool plot_stream_event_handler (pid_t pid, int status);
-
-  static void init (void)
-  {
-    if (ensure_instance ())
-      instance->do_init ();
-  }
-
-  static void send (const std::string& cmd)
-  {
-    if (ensure_plot_stream ())
-      instance->do_send (cmd);
-  }
-
-  static void send_raw (const std::string& cmd)
-  {
-    if (ensure_plot_stream ())
-      instance->do_send_raw (cmd);
-  }
-
-  static void clear (void)
-  {
-    if (ensure_plot_stream ())
-      instance->do_clear ();
-  }
-
-  static void set (const string_vector& argv)
-  {
-    if (ensure_plot_stream ())
-      instance->do_set (argv);
-  }
-
-  static void show (const string_vector& argv)
-  {
-    if (ensure_plot_stream ())
-      instance->do_show (argv);
-  }
-
-  static void set_gnuplot_exe (const std::string& exe)
-  {
-    if (ensure_instance ())
-      instance->do_set_gnuplot_exe (exe);
-  }
-
-  static void set_gnuplot_use_title_option (bool opt)
-  {
-    if (ensure_instance ())
-      instance->do_set_gnuplot_use_title_option (opt);
-  }
-
-  // XXX FIXME XXX -- should only remove tmp files associated with
-  // gnuplot?
-  static void cleanup_tmp_files (void) { ::cleanup_tmp_files (); }
-
-  static void plot (const string_vector& argv)
-  {
-    if (ensure_plot_stream ())
-      instance->do_plot (argv);
-  }
-
-private:
-
-  static gnuplot *instance;
-
-  static std::map<int, gnuplot *> instance_map;
-
-  // The number of lines we've plotted so far.
-  int plot_line_count;
-
-  // Is this a parametric plot?  Makes a difference for 3D plotting.
-  bool parametric_plot;
-
-  // Should we append '-title "TITLE"' to the gnuplot command?
-  bool use_title_option;
-
-  // The executable program to run.
-  std::string gnuplot_exe;
-
-  // The gnuplot terminal type.
-  std::string gnuplot_terminal_type;
-
-  // Pipe to gnuplot.
-  oprocstream *plot_stream;
-
-  pid_t pid (void) const;
-
-  static gnuplot *lookup_by_pid (pid_t pid);
-
-  void do_open (void);
-
-  void do_close (void);
-
-  void delete_plot_stream (void);
-
-  void reset_plot_stream (void);
-
-  void do_send (const std::string& cmd);
-
-  void do_send_raw (const std::string& cmd);
-
-  void do_clear (void);
-
-  void do_set (const string_vector& argv);
-
-  void do_show (const string_vector& argv);
-
-  void do_set_gnuplot_exe (const std::string& exe) { gnuplot_exe = exe; }
-
-  void do_set_gnuplot_use_title_option (bool opt) { use_title_option = opt; }
-
-  void do_plot (const string_vector& argv);
-
-  void do_init (void);
-
-  std::string
-  makeplot (std::string caller, std::string args) throw (gpt_parse_error);
-
-  std::string handle_title (int& lasttok);
-};
-
-gnuplot *gnuplot::instance = 0;
-
-std::map<int, gnuplot *> gnuplot::instance_map;
-
-bool
-gnuplot::have_instance (void)
-{
-  int current_figure = get_current_figure ();
-
-  if (instance_map.find (current_figure) != instance_map.end ())
-    {
-      instance = instance_map[current_figure];
-      return true;
-    }
-  else
-    return false;
-}
-
-bool
-gnuplot::ensure_instance (void)
-{
-  if (! have_instance ())
-    {
-      instance = new gnuplot ();
-
-      if (! instance)
-	{
-	  ::error ("unable to create gnuplot object!");
-
-	  return false;
-	}
-      else
-	instance_map[get_current_figure ()] = instance;
-    }
-
-  return true;
-}
-
-bool
-gnuplot::ensure_plot_stream (void)
-{
-  if (ensure_instance ())
-    {
-      instance->do_open ();
-
-      if (error_state)
-	return false;
-    }
-
-  return true;
-}
-
-void
-gnuplot::close (void)
-{
-  if (have_instance ())
-    {
-      instance->do_close ();
-
-      instance_map.erase (get_current_figure ());
-    }
-}
-
-pid_t
-gnuplot::pid (void) const
-{
-  return plot_stream ? plot_stream->pid () : -1;
-}
-
-gnuplot *
-gnuplot::lookup_by_pid (pid_t pid)
-{
-  gnuplot *retval = 0;
-
-  for (std::map<int, gnuplot *>::const_iterator p = instance_map.begin ();
-       p != instance_map.end ();
-       p++)
-    {
-      gnuplot *elt = p->second;
-
-      if (elt && elt->pid () == pid)
-	{
-	  retval = elt;
-	  break;
-	}
-    }
-
-  return retval;
-}
-
-void
-gnuplot::do_open (void)
-{
-  static bool initialized = false;
-
-  if (plot_stream && ! *plot_stream)
-    do_close ();
-
-  if (! plot_stream)
-    {
-      initialized = false;
-
-      plot_line_count = 0;
-
-      std::string cmd;
-
-      if (gnuplot_exe.empty ())
-	cmd = "gnuplot";
-      else
-        cmd = "\"" + gnuplot_exe + "\"";
-
-      // XXX FIXME XXX -- I'm not sure this is the right thing to do,
-      // but without it, C-c at the octave prompt will kill gnuplot...
-
-#if defined (HAVE_POSIX_SIGNALS)
-      sigset_t nset, oset;
-      sigemptyset (&nset);
-      sigaddset (&nset, SIGINT);
-      sigprocmask (SIG_BLOCK, &nset, &oset);
-#else
-      volatile octave_interrupt_handler old_interrupt_handler
-	= octave_ignore_interrupts ();
-#endif
-
-      if (use_title_option)
-	{
-	  OSSTREAM buf;
-
-	  buf << cmd
-	      << " -title \"Figure " << get_current_figure () << "\""
-	      << OSSTREAM_ENDS;
-
-	  cmd = OSSTREAM_STR (buf);
-
-	  OSSTREAM_FREEZE (buf);
-	}
-
-      plot_stream = new oprocstream (cmd.c_str ());
-
-      if (plot_stream && *plot_stream)
-	octave_child_list::insert (plot_stream->pid (),
-				   plot_stream_event_handler);
-      else
-	{
-	  delete_plot_stream ();
-
-	  error ("plot: unable to open pipe to `%s'", cmd.c_str ());
-	}
-
-#if defined (HAVE_POSIX_SIGNALS)
-      sigprocmask (SIG_SETMASK, &oset, 0);
-#else
-      octave_set_interrupt_handler (old_interrupt_handler);
-#endif
-    }
-
-  if (! error_state && plot_stream && *plot_stream && ! initialized)
-    {
-      initialized = true;
-
-      do_send_raw ("set style data lines\n");
-
-      if (! gnuplot_terminal_type.empty ())
-	do_send_raw ("set term " + gnuplot_terminal_type
-		     + Vgnuplot_command_end + "\n");
-    }
-}
-
-void
-gnuplot::delete_plot_stream (void)
-{
-  do_send_raw ("\nquit\n");
-
-  delete plot_stream;
-  plot_stream = 0;
-}
-
-void
-gnuplot::reset_plot_stream (void)
-{
-  delete_plot_stream ();
-
-  plot_line_count = 0;
-  parametric_plot = false;
-}
-
-void
-gnuplot::do_close (void)
-{
-  if (plot_stream)
-    {
-      octave_child_list::remove (plot_stream->pid ());
-
-      delete_plot_stream ();
-    }
-
-  plot_line_count = 0;
-}
-
-bool
-gnuplot::plot_stream_event_handler (pid_t pid, int status)
-{
-  bool retval = false;
-
-  if (pid > 0)
-    {
-      if (WIFEXITED (status) || WIFSIGNALLED (status))
-	{
-	  gnuplot *plotter = gnuplot::lookup_by_pid (pid);
-
-	  // We should only print a warning or request removal of the
-	  // process from the child list if the process died
-	  // unexpectedly.  If do_close is responsible for
-	  // gnuplot's death, then plotter will be 0 here and we don't
-	  // need to do anything.
-
-	  if (plotter)
-	    {
-	      plotter->reset_plot_stream ();
-
-	      warning ("connection to external plotter (pid = %d) lost --", pid);
-	      // Request removal of this PID from the list of child
-	      // processes.
-
-	      retval = true;
-	    }
-	}
-    }
-
-  return retval;
-}
-
-void
-gnuplot::do_send (const std::string& cmd)
-{
-  int replot_len = Vgnuplot_command_replot.length ();
-
-  bool is_replot = (Vgnuplot_command_replot == cmd.substr (0, replot_len));
-
-  if (! (plot_line_count == 0 && is_replot))
-    do_send_raw (cmd);
-}
-
-void
-gnuplot::do_send_raw (const std::string& cmd)
-{
-  if (plot_stream && *plot_stream)
-    {
-      *plot_stream << cmd;
-
-      plot_stream->flush ();
-    }
-}
-
-void
-gnuplot::do_clear (void)
-{
-  do_send_raw ("clear\n");
-
-  // XXX FIXME XXX -- instead of just clearing these things, it would
-  // be nice if we could reset things to a user-specified default
-  // state.
-
-  do_send_raw ("set title\n");
-  do_send_raw ("set xlabel\n");
-  do_send_raw ("set ylabel\n");
-  do_send_raw ("set nogrid\n");
-  do_send_raw ("set nolabel\n");
-
-  // This makes a simple `replot' not work after a `clearplot' command
-  // has been issued.
-
-  plot_line_count = 0;
-}
-
-void
-gnuplot::do_set (const string_vector& argv)
-{
-  int argc = argv.length ();
-
-  OSSTREAM plot_buf;
-
-  if (argc > 1)
-    {
-      if (almost_match ("parametric", argv[1], 3))
-	parametric_plot = true;
-      else if (almost_match ("noparametric", argv[1], 5))
-	parametric_plot = false;
-      else if (almost_match ("term", argv[1], 1))
-	{
-	  gnuplot_terminal_type = "";
-	  OSSTREAM buf;
-	  int i;
-	  for (i = 2; i < argc-1; i++)
-	    buf << argv[i] << " ";
-	  if (i < argc)
-	    buf << argv[i];
-	  buf << Vgnuplot_command_end << OSSTREAM_ENDS;
-	  gnuplot_terminal_type = OSSTREAM_STR (buf);
-	  OSSTREAM_FREEZE (buf);
-	}
-    }
-
-  int i;
-  for (i = 0; i < argc-1; i++)
-    plot_buf << argv[i] << " ";
-
-  if (i < argc)
-    plot_buf << argv[i];
-
-  plot_buf << Vgnuplot_command_end << OSSTREAM_ENDS;
-
-  do_send_raw (OSSTREAM_STR (plot_buf));
-
-  OSSTREAM_FREEZE (plot_buf);
-}
-
-void
-gnuplot::do_show (const string_vector& argv)
-{
-  int argc = argv.length ();
-
-  OSSTREAM plot_buf;
-
-  int i;
-  for (i = 0; i < argc-1; i++)
-    plot_buf << argv[i] << " ";
-  if (i < argc)
-    plot_buf << argv[i];
-
-  plot_buf << Vgnuplot_command_end << OSSTREAM_ENDS;
-
-  do_send (OSSTREAM_STR (plot_buf));
-
-  OSSTREAM_FREEZE (plot_buf);
-}
-
-void
-gnuplot::do_plot (const string_vector& argv)
-{
-  std::string s;
-
-  for (int i = 1; i < argv.length (); i++)
-    s += argv[i] + " ";
-
-  try
-    {
-      std::string cmd = makeplot (argv[0], s);
-
-      do_send (cmd);
-    }
-  catch (gpt_parse_error& e)
-    {
-      if (e.msg.empty ())
-	error ("could not parse plot command");
-      else
-	error (e.msg.c_str ());
-    }
-}
-
-// Parse and evaluate parameter string and pass it to gnuplot pipe.
-
-std::string
-gnuplot::makeplot (std::string caller, std::string args)
-  throw (gpt_parse_error)
-{
-  std::string retval;
-
-  YY_BUFFER_STATE bstate;
-
-  bstate = yy_scan_string (args.c_str ());
-  yy_switch_to_buffer (bstate);
-  std::string outstr;
-  int ndim = 2;
-
-  if (caller == "replot")
-    {
-      ndim = 1;
-      outstr += Vgnuplot_command_replot + " ";
-    }
-  else if (caller == "plot")
-    {
-      ndim = 2;
-      plot_line_count = 0;
-      outstr += Vgnuplot_command_plot + " ";
-    }
-  else if (caller == "splot")
-    {
-      ndim = 3;
-      plot_line_count = 0;
-      outstr += Vgnuplot_command_splot + " ";
-    }
-  else
-    throw gpt_parse_error ("unknown plot command");
-
-  gpt_quote_is_transpose = false;
-  gpt_allow_plotkw = false;
-  gpt_parens = 0;
-  gpt_braces = 0;
-  gpt_brackets = 0;
-
-  int tok;
-  tok = gptlex ();
-  if (plottok_or_end_p (tok) && caller != "replot")
-    throw gpt_parse_error ("must have something to plot");
-
-  while (tok)
-    {
-      bool title_set = false;
-      bool using_set = false;
-      bool style_set = false;
-      bool axes_set = false;
-
-      if (tok == START_BRACKET)
-	{
-	  if (caller == "replot")
-	    throw gpt_parse_error ("can't specify new plot ranges with `replot' or while hold is on");
-
-	  std::string xrange_start_str = read_until (colonp, tok);
-	  std::string xrange_end_str = read_until (endbracketp, tok);
-	  outstr += printrange (xrange_start_str, xrange_end_str) + " ";
-	  tok = gptlex ();
-	  if (tok == START_BRACKET)
-	    {
-	      std::string yrange_start_str = read_until (colonp, tok);
-	      std::string yrange_end_str = read_until (endbracketp, tok);
-	      outstr += printrange (yrange_start_str, yrange_end_str) + " ";
-	      tok = gptlex ();
-	      if (tok == START_BRACKET && caller == "gsplot")
-		{
-		  std::string zrange_start_str = read_until (colonp, tok);
-		  std::string zrange_end_str = read_until (endbracketp, tok);
-		  outstr += printrange (zrange_start_str, zrange_end_str) + " ";
-		  tok = gptlex ();
-                }
-            }
-        }
-
-      if (plottok_or_end_p (tok))
-	return std::string ();
-      else
-	{
-	  std::string file;
-	  plot_line_count++;
-
-	  std::string plot_expr_str;
-	  plot_expr_str += std::string (yytext) + " ";
-	  plot_expr_str += read_until (plottok_or_end_p, tok);
-
-	  int status = 0;
-	  octave_value tmp_data = eval_string (plot_expr_str,
-					       true, status);
-
-	  if (status != 0 || ! tmp_data.is_defined ())
-	    throw gpt_parse_error ();
-
-	  OSSTREAM tmp_buf;
-	  tmp_data.print_raw (tmp_buf);
-	  tmp_buf << OSSTREAM_ENDS;
-
-	  if (tmp_data.is_string ())
-	    {
-	      file = file_ops::tilde_expand (tmp_data.string_value ());
-	      // XXX FIXME XXX -- perhaps should check if the file exists?
-	      outstr += file + " ";
-	    }
-	  else
-	    {
-	      switch (ndim)
-		{
-		case 2:
-		  file = save_in_tmp_file (tmp_data, ndim);
-		  break;
-
-		case 3:
-		  file = save_in_tmp_file (tmp_data, ndim,
-					   parametric_plot);
-		  break;
-
-		default:
-		  gripe_2_or_3_dim_plot ();
-		  break;
-		}
-
-	      if (file.length () > 0)
-		{
-		  mark_for_deletion (file);
-		  outstr += "'" + file + "' ";
-		}
-	    }
-        }
-
-      std::string title_str;
-      std::string using_str;
-      std::string style_str;
-      std::string axes_str;
-
-      bool out = false;
-      while (tok && ! out)
-	{
-	  switch (tok)
-	    {
-	    case COMMA:
-	      out = true;
-	      break;
-
-	    case TITLE:
-	      if (! title_set)
-		title_str += handle_title (tok) + " ";
-	      else
-		throw gpt_parse_error ("only one title option may be specified");
-	      title_set = true;
-	      break;
-
-	    case USING:
-	      if (! using_set)
-		using_str += handle_using (tok) + " ";
-	      else
-		throw gpt_parse_error ("only one using option may be specified");
-	      using_set = true;
-	      break;
-
-	    case WITH:
-	      if (! style_set)
-		style_str += handle_style (tok) + " ";
-	      else
-		throw gpt_parse_error ("only one style option may be specified");
-	      style_set = true;
-	      break;
-
-	    case AXES:
-	      if (! axes_set)
-		axes_str += handle_axes (tok) + " ";
-	      else
-		throw gpt_parse_error ("only one axes option may be specified");
-	      axes_set = true;
-	      break;
-
-	    default:
-	      tok = 0;
-	      break;
-            }
-        }
-
-        if (! title_set)
-	  {
-            OSSTREAM tmp_buf;
-            tmp_buf << Vgnuplot_command_title << " \"line "
-                    << plot_line_count << "\" " << OSSTREAM_ENDS;
-            title_str = OSSTREAM_STR (tmp_buf);
-	    title_set = true;
-        }
-
-	// Plot parameters have to be output in this order.
-	if (using_set)
-	  outstr += using_str;
-
-	if (axes_set)
-	  outstr += axes_str;
-
-	if (title_set)
-	  outstr += title_str;
-
-	if (style_set)
-	  outstr += style_str;
-
-	if (out)
-	  {
-	    // Saw comma on while loop.
-            outstr += ", ";
-            gpt_quote_is_transpose = false;
-            gpt_allow_plotkw = false;
-            gpt_parens = 0;
-            gpt_braces = 0;
-            gpt_brackets = 0;
-            tok = gptlex ();
-	  }
-    }
-
-  outstr += Vgnuplot_command_end;
-
-  return outstr;
-}
-
-// Title has one string expression which is evaluated and printed to the
-// gnuplot command string.
-
-std::string
-gnuplot::handle_title (int& lasttok)
-{
-  int tok;
-  std::string retstr = Vgnuplot_command_title + " ";
-  std::string title_expr_str;
-
-  title_expr_str += read_until (plottok_or_end_p, tok);
-
-  int status;
-  octave_value tmp_data = eval_string (title_expr_str, true, status);
-
-  if (status != 0 || ! tmp_data.is_defined ())
-    throw gpt_parse_error ();
-
-  OSSTREAM tmp_buf;
-  if (tmp_data.is_string ())
-    {
-      tmp_buf << '"';
-      tmp_data.print_raw (tmp_buf);
-      tmp_buf << '"' << OSSTREAM_ENDS;
-    }
-  else
-    {
-      warning ("line title must be a string");
-      tmp_buf << '"' << "line " << plot_line_count << '"';
-    }
-
-  retstr += OSSTREAM_STR (tmp_buf);
-
-  lasttok = tok;
-
-  return retstr;
-}
-
-static int
-automatic_replot (void)
-{
-  Vautomatic_replot = check_preference ("automatic_replot");
-
-  return 0;
-}
-
-static int
-set_string_var (std::string& var, const char *nm)
-{
-  int retval = 0;
-
-  std::string s = builtin_string_variable (nm);
-
-  if (s.empty ())
-    {
-      gripe_invalid_value_specified (nm);
-      retval = -1;
-    }
-  else
-    var = s;
-
-  return retval;
-}
-
-static int
-gnuplot_binary (void)
-{
-  int status = set_string_var (Vgnuplot_binary, "gnuplot_binary");
-
-  if (status == 0)
-    gnuplot::set_gnuplot_exe (Vgnuplot_binary);
-
-  return status;
-}
-
-static int
-gnuplot_command_plot (void)
-{
-  return set_string_var (Vgnuplot_command_plot, "gnuplot_command_plot");
-}
-
-static int
-gnuplot_command_replot (void)
-{
-  return set_string_var (Vgnuplot_command_replot, "gnuplot_command_replot");
-}
-
-static int
-gnuplot_command_splot (void)
-{
-  return set_string_var (Vgnuplot_command_splot, "gnuplot_command_splot");
-}
-
-static int
-gnuplot_command_using (void)
-{
-  return set_string_var (Vgnuplot_command_using, "gnuplot_command_using");
-}
-
-static int
-gnuplot_command_with (void)
-{
-  return set_string_var (Vgnuplot_command_with, "gnuplot_command_with");
-}
-
-static int
-gnuplot_command_axes (void)
-{
-  return set_string_var (Vgnuplot_command_axes, "gnuplot_command_axes");
-}
-
-static int
-gnuplot_command_title (void)
-{
-  return set_string_var (Vgnuplot_command_title, "gnuplot_command_title");
-}
-
-static int
-gnuplot_command_end (void)
-{
-  return set_string_var (Vgnuplot_command_end, "gnuplot_command_end");
-}
-
-static int
-gnuplot_use_title_option (void)
-{
-  Vgnuplot_use_title_option = check_preference ("gnuplot_use_title_option");
-
-  gnuplot::set_gnuplot_use_title_option (Vgnuplot_use_title_option);
-
-  return 0;
-}
-
-void
-gnuplot::do_init (void)
-{
-  static bool gnuplot_initialized = false;
-
-  if (gnuplot_initialized)
-    return;
-
-  gnuplot_initialized = true;
-
-  if (is_builtin_variable ("automatic_replot"))
-    automatic_replot ();
-  else
-    DEFVAR (automatic_replot, true, automatic_replot,
-    "-*- texinfo -*-\n\
-@defvr {Built-in Variable} automatic_replot\n\
-You can tell Octave to redisplay the plot each time anything about it\n\
-changes by setting the value of the builtin variable\n\
-@code{automatic_replot} to a nonzero value.  Although it is fairly\n\
-inefficient, especially for large plots, the default value is 1 for\n\
-compatibility with Matlab.\n\
-@end defvr");
-
-  if (is_builtin_variable ("gnuplot_binary"))
-    gnuplot_binary ();
-  else
-    DEFVAR (gnuplot_binary, GNUPLOT_BINARY, gnuplot_binary,
-    "-*- texinfo -*-\n\
-@defvr {Built-in Variable} gnuplot_binary\n\
-The name of the program invoked by the plot command.  The default value\n\
-is @code{\"gnuplot\"}.  @xref{Installation}.\n\
-@end defvr");
-
-  if (is_builtin_variable ("gnuplot_command_plot"))
-    gnuplot_command_plot ();
-  else
-    DEFVAR (gnuplot_command_plot, "pl", gnuplot_command_plot,
-    "-*- texinfo -*-\n\
-@defvr {Built-in Variable} gnuplot_command_plot\n\
-@end defvr");
-
-  if (is_builtin_variable ("gnuplot_command_replot"))
-    gnuplot_command_replot ();
-  else
-    DEFVAR (gnuplot_command_replot, "rep", gnuplot_command_replot,
-    "-*- texinfo -*-\n\
-@defvr {Built-in Variable} gnuplot_command_replot\n\
-@end defvr");
-
-  if (is_builtin_variable ("gnuplot_command_splot"))
-    gnuplot_command_splot ();
-  else
-    DEFVAR (gnuplot_command_splot, "sp", gnuplot_command_splot,
-    "-*- texinfo -*-\n\
-@defvr {Built-in Variable} gnuplot_command_splot\n\
-@end defvr");
-
-  if (is_builtin_variable ("gnuplot_command_using"))
-    gnuplot_command_using ();
-  else
-    DEFVAR (gnuplot_command_using, "u", gnuplot_command_using,
-    "-*- texinfo -*-\n\
-@defvr {Built-in Variable} gnuplot_command_using\n\
-@end defvr");
-
-  if (is_builtin_variable ("gnuplot_command_with"))
-    gnuplot_command_with ();
-  else
-    DEFVAR (gnuplot_command_with, "w", gnuplot_command_with,
-    "-*- texinfo -*-\n\
-@defvr {Built-in Variable} gnuplot_command_with\n\
-@end defvr");
-
-  if (is_builtin_variable ("gnuplot_command_axes"))
-    gnuplot_command_axes ();
-  else
-    DEFVAR (gnuplot_command_axes, "ax", gnuplot_command_axes,
-    "-*- texinfo -*-\n\
-@defvr {Built-in Variable} gnuplot_command_axes\n\
-@end defvr");
-
-  if (is_builtin_variable ("gnuplot_command_title"))
-    gnuplot_command_title ();
-  else
-    DEFVAR (gnuplot_command_title, "t", gnuplot_command_title,
-    "-*- texinfo -*-\n\
-@defvr {Built-in Variable} gnuplot_command_title\n\
-@end defvr");
-
-  if (is_builtin_variable ("gnuplot_command_end"))
-    gnuplot_command_end ();
-  else
-    DEFVAR (gnuplot_command_end, "\n", gnuplot_command_end,
-    "-*- texinfo -*-\n\
-@defvr {Built-in Variable} gnuplot_command_end\n\
-@end defvr");
-
-  if (is_builtin_variable ("gnuplot_use_title_option"))
-    gnuplot_use_title_option ();
-  else
-    DEFVAR (gnuplot_use_title_option, octave_env::have_x11_display (),
-	    gnuplot_use_title_option,
-    "-*- texinfo -*-\n\
-@defvr {Built-in Variable} gnuplot_use_title_option\n\
-If nonzero, append @samp{-title \"Figure NN\"} to the gnuplot command.\n\
-@end defvr");
-
-}
-
-// -----------------------
-// User-callable functions
-// -----------------------
-
-DEFUN_DLD (__gnuplot_init__, , ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} __gnuplot_init__ ()\n\
-@end deftypefn")
-{
-  gnuplot::init ();
-
-  return octave_value_list ();
-}
-
-DEFUN_DLD (clearplot, , ,
-  "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} clearplot\n\
-@deftypefnx {Built-in Function} {} clg\n\
-Clear the plot window and any titles or axis labels.  The name\n\
-@code{clg} is aliased to @code{clearplot} for compatibility with\n\
-@sc{Matlab}.\n\
-@end deftypefn")
-{
-  gnuplot::clear ();
-
-  return octave_value_list ();
-}
-
-DEFUN_DLD (closeplot, , ,
-  "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} closeplot\n\
-Close stream to the @code{gnuplot} subprocess.  If you are using X11,\n\
-this will close the plot window.\n\
-@end deftypefn")
-{
-  gnuplot::close ();
-
-  return octave_value_list ();
-}
-
-DEFUN_DLD (purge_tmp_files, , ,
-  "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} purge_tmp_files\n\
-Delete the temporary files created by the plotting commands.\n\
-\n\
-Octave creates temporary data files for @code{gnuplot} and then sends\n\
-commands to @code{gnuplot} through a pipe.  Octave will delete the\n\
-temporary files on exit, but if you are doing a lot of plotting you may\n\
-want to clean up in the middle of a session.\n\
-\n\
-A future version of Octave will eliminate the need to use temporary\n\
-files to hold the plot data.\n\
-@end deftypefn")
-{
-  gnuplot::cleanup_tmp_files ();
-
-  return octave_value_list ();
-}
-
-DEFUN_DLD (__gnuplot_raw__, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} __gnuplot_raw__ (@var{string})\n\
-Send @var{string} directly to gnuplot subprocess.\n\
-@end deftypefn")
-{
-  if (args.length () == 1 && args(0).is_string ())
-    {
-      std::string cmd = args(0).string_value ();
-
-      gnuplot::send_raw (cmd);
-    }
-  else
-    print_usage ("__gnuplot_raw__");
-
-  return octave_value_list ();
-}
-
-DEFUN_DLD (__gnuplot_set__, args, ,
-  "-*- texinfo -*-\n\
-@deffn {Command} __gnuplot_set__ options\n\
-Set plotting options for gnuplot\n\
-@end deffn")
-{
-  string_vector argv = args.make_argv ("set");
-
-  if (! error_state)
-    gnuplot::set (argv);
-
-  return octave_value_list ();
-}
-
-DEFUN_DLD (__gnuplot_show__, args, ,
-  "-*- texinfo -*-\n\
-@deffn {Command} __gnuplot_show__ options\n\
-Show plotting options.\n\
-@end deffn")
-{
-  string_vector argv = args.make_argv ("show");
-
-  if (! error_state)
-    gnuplot::show (argv);
-
-  return octave_value_list ();
-}
-
-DEFUN_DLD (__gnuplot_plot__, args, ,
-  "Plot with gnuplot.\n")
-{
-  string_vector argv = args.make_argv ("plot");
-
-  if (! error_state)
-    gnuplot::plot (argv);
-
-  return octave_value_list ();
-}
-
-DEFUN_DLD (__gnuplot_splot__, args, ,
-  "Plot with gnuplot.\n")
-{
-  string_vector argv = args.make_argv ("splot");
-
-  if (! error_state)
-    gnuplot::plot (argv);
-
-  return octave_value_list ();
-}
-
-DEFUN_DLD (__gnuplot_replot__, args, ,
-  "Plot with gnuplot.\n")
-{
-  string_vector argv = args.make_argv ("replot");
-
-  if (! error_state)
-    gnuplot::plot (argv);
-
-  return octave_value_list ();
-}
-
-// --------------------
-// Deprecated functions
-// --------------------
-
-#define WARN_DEPRECATED(FOLD, FNEW) \
-  do \
-    { \
-      static bool warned = false; \
-      if (! warned) \
-	{ \
-	  warned = true; \
-	  warning (#FOLD " is deprecated and will be removed from a future"); \
-	  warning ("version of Octave."); \
-	  warning ("You should use the higher-level plot functions"); \
-	  warning ("(\"plot\", \"mesh\", \"semilogx\", etc.) instead"); \
-	  warning ("of the low-level plotting commands."); \
-	  warning ("If you absolutely must use this function, use the"); \
-	  warning ("internal version " #FNEW " instead."); \
-	} \
-    } \
-  while (0)
-    
-#define DEPRECATED_BODY(FOLD, FNEW) \
-  WARN_DEPRECATED (FOLD, FNEW); \
-  return feval (#FNEW, args)
-
-// We can't further simplify this by putting the DEFUN_DLD in a macro
-// because then the mk-oct-links script will fail.
-
-DEFUN_DLD (gplot, args, ,
-  "")
-{
-  DEPRECATED_BODY (gplot, __gnuplot_plot__);
-}
-
-DEFUN_DLD (gsplot, args, ,
-  "")
-{
-  DEPRECATED_BODY (gsplot, __gnuplot_splot__);
-}
-
-DEFUN_DLD (graw, args, ,
-  "")
-{
-  DEPRECATED_BODY (graw, __gnuplot_raw__);
-}
-
-DEFUN_DLD (gset, args, ,
-  "")
-{
-  DEPRECATED_BODY (gset, __gnuplot_set__);
-}
-
-DEFUN_DLD (gshow, args, ,
-  "")
-{
-  DEPRECATED_BODY (gshow, __gnuplot_show__);
-}
-
-/*
-;;; Local Variables: ***
-;;; mode: C++ ***
-;;; End: ***
-*/
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -51,7 +51,7 @@
 	lpsolve.cc lsode.cc lu.cc luinc.cc matrix_type.cc minmax.cc \
 	pinv.cc qr.cc quad.cc qz.cc rand.cc schur.cc sort.cc sparse.cc \
 	spchol.cc spdet.cc spkron.cc splu.cc spparms.cc sqrtm.cc svd.cc \
-	syl.cc time.cc gplot.l __glpk__.cc __qp__.cc
+	syl.cc time.cc __gnuplot_raw__.l __glpk__.cc __qp__.cc
 
 DLD_SRC := $(addprefix DLD-FUNCTIONS/, $(DLD_XSRC))
 
@@ -256,7 +256,7 @@
 DISTFILES = Makefile.in ChangeLog mkdefs mkops mkgendoc \
 	DOCSTRINGS mkbuiltins mk-errno-list mk-pkg-add \
 	defaults.h.in oct-conf.h.in oct-errno.cc.in octave.gperf oct-gperf.h \
-	octave.cc parse.cc lex.cc y.tab.h gplot.cc \
+	octave.cc parse.cc lex.cc y.tab.h __gnuplot_raw__.cc \
 	$(INCLUDES) $(DIST_SRC) $(OPT_HANDLERS) $(EXTRAS)
 
 all: octave$(EXEEXT) $(OCT_FILES) PKG_ADD DOCSTRINGS
@@ -302,7 +302,7 @@
 	rm -f $@
 	$(SH_LD) $(SH_LDFLAGS) $(SONAME_FLAGS) -o $@ $^ $(OCTINTERP_LINK_DEPS)
 
-stamp-prereq: defaults.h oct-conf.h oct-gperf.h parse.cc lex.cc gplot.cc $(OPT_HANDLERS)
+stamp-prereq: defaults.h oct-conf.h oct-gperf.h parse.cc lex.cc __gnuplot_raw__.cc $(OPT_HANDLERS)
 	touch stamp-prereq
 
 octave$(EXEEXT): stamp-prereq $(LIBRARIES) main.o $(DLD_STATIC_OBJ)
@@ -491,7 +491,7 @@
 
 maintainer-clean: distclean
 	rm -f tags TAGS y.tab.c y.tab.h y.output yy.lex.c lex.cc parse.cc
-	rm -f oct-gperf.h gplot.cc $(OPT_HANDLERS)
+	rm -f oct-gperf.h __gnuplot_raw__.cc $(OPT_HANDLERS)
 .PHONY: maintainer-clean
 
 dist: parse.cc lex.cc oct-gperf.h
@@ -530,7 +530,7 @@
 lex.cc : lex.l
 	$(LEX) $(LFLAGS) $< > $(@F)
 
-gplot.cc : DLD-FUNCTIONS/gplot.l
+__gnuplot_raw__.cc : DLD-FUNCTIONS/__gnuplot_raw__.l
 	$(LEX) $(LFLAGS) $< > $(@F)
 
 defaults.h: defaults.h.in ../Makeconf Makefile
--- a/src/help.cc
+++ b/src/help.cc
@@ -286,12 +286,6 @@
   { "global",
     "Declare variables to have global scope.", },
 
-  { "gplot",
-    "Produce 2-D plots using gnuplot-like command syntax.", },
-
-  { "gsplot",
-    "Produce 3-D plots using gnuplot-like command syntax.", },
-
   { "if",
     "-*- texinfo -*-\n\
 @deffn Keyword if (@var{cond}) @dots{} endif\n\
--- a/src/ls-oct-ascii.cc
+++ b/src/ls-oct-ascii.cc
@@ -389,7 +389,7 @@
 {
   bool infnan_warned = true;
 
-  return save_ascii_data (os, t, name, infnan_warned, true, false, 0);
+  return save_ascii_data (os, t, name, infnan_warned, false, false, 0);
 }
 
 // Maybe this should be a static function in tree-plot.cc?
@@ -420,7 +420,6 @@
 	    warning ("ignoring last %d columns", extras);
 
 	  Matrix tmp = tc.matrix_value ();
-	  tmp = strip_infnan (tmp);
 	  nr = tmp.rows ();
 
 	  for (octave_idx_type i = 0; i < nc-extras; i += 3)
@@ -433,7 +432,6 @@
       else
 	{
 	  Matrix tmp = tc.matrix_value ();
-	  tmp = strip_infnan (tmp);
 	  nr = tmp.rows ();
 
 	  for (octave_idx_type i = 0; i < nc; i++)