changeset 7325:67aef14de9c2

[project @ 2007-12-19 20:21:11 by jwe]
author jwe
date Wed, 19 Dec 2007 20:21:11 +0000
parents 4e36579df31c
children fcc6d853df9e
files scripts/ChangeLog scripts/miscellaneous/Makefile.in scripts/miscellaneous/edit.m scripts/plot/__bar__.m scripts/plot/__bars__.m
diffstat 5 files changed, 448 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog	Wed Dec 19 16:57:21 2007 +0000
+++ b/scripts/ChangeLog	Wed Dec 19 20:21:11 2007 +0000
@@ -1,3 +1,13 @@
+2007-12-19  John W. Eaton  <jwe@octave.org>
+
+	* miscellaneous/edit.m: New function.
+	* miscellaneous/Makefile.in (SOURCES): Add it to the list.
+
+2007-12-19  Michael Goffioul <michael.goffioul@gmail.com>
+
+	* plot/__bar__.m: Handle "basevalue" option.
+	* plot/__bars__.m: New arg, base_value.
+
 2007-12-17  David Bateman  <dbateman@free.fr>
 
 	* plot/rose.m, plot/feather.m, plot/compass.m: New functions
--- a/scripts/miscellaneous/Makefile.in	Wed Dec 19 16:57:21 2007 +0000
+++ b/scripts/miscellaneous/Makefile.in	Wed Dec 19 20:21:11 2007 +0000
@@ -35,7 +35,7 @@
 
 SOURCES = ans.m bincoeff.m bug_report.m bunzip2.m cast.m comma.m \
   compare_versions.m computer.m copyfile.m \
-  delete.m dir.m doc.m dos.m dump_prefs.m \
+  delete.m dir.m doc.m dos.m dump_prefs.m edit.m \
   fileattrib.m fileparts.m flops.m fullfile.m getfield.m gunzip.m \
   gzip.m inputname.m ismac.m ispc.m isunix.m license.m list_primes.m ls.m \
   ls_command.m menu.m mex.m mexext.m mkoctfile.m movefile.m \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/miscellaneous/edit.m	Wed Dec 19 20:21:11 2007 +0000
@@ -0,0 +1,425 @@
+## Copyright (C) 2001, 2007 Paul Kienzle
+##
+## 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 3 of the License, 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 Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Command} edit @var{name}
+## @deftypefnx {Command} edit @var{field} @var{value}
+## @deftypefnx {Command} @var{value} = edit get @var{field}
+## Edit the named function, or change editor settings.
+##
+## If @code{edit} is called with the name of a file or function as
+## its argument it will be opened in a text editor.
+## 
+## @itemize @bullet
+## @item
+## If the function @var{name} is available in a file on your path and
+## that file is modifiable, then it will be edited in place.  If it 
+## is a system function, then it will first be copied to the directory
+## @code{HOME} (see further down) and then edited.  
+##
+## @item
+## If @var{name} is the name of a function defined in the interpreter but 
+## not in an m-file, then an m-file will be created in @code{HOME}
+## to contain that function along with its current definition.  
+##
+## @item
+## If @code{name.cc} is specified, then it will search for @code{name.cc}
+## in the path and try to modify it, otherwise it will create a new
+## @file{.cc} file in @code{HOME}.  If @var{name} happens to be an
+## m-file or interpreter defined function, then the text of that
+## function will be inserted into the .cc file as a comment.
+##
+## @item
+## If @var{name.ext} is on your path then it will be editted, otherwise
+## the editor will be started with @file{HOME/name.ext} as the
+## filename.  If @file{name.ext} is not modifiable, it will be copied to
+## @code{HOME} before editing.
+##
+## @strong{WARNING!} You may need to clear name before the new definition
+## is available.  If you are editing a .cc file, you will need
+## to mkoctfile @file{name.cc} before the definition will be available.
+## @end itemize
+##
+## If @code{edit} is called with @var{field} and @var{value} variables,
+## the value of the control field @var{field} will be @var{value}.
+## If an output argument is requested and the first argument is @code{get}
+## then @code{edit} will return the value of the control field @var{field}.
+## The following control fields are used:
+##
+## @table @samp
+## @item editor
+## This is the editor to use to modify the functions.  By default it uses
+## Octave's @code{EDITOR} built-in function, which comes from 
+## @code{getenv("EDITOR")} and defaults to @code{emacs}.  Use @code{%s}
+## In place of the function name.  For example,
+## @table @samp
+## @item [EDITOR, " %s"]
+## Use the editor which Octave uses for @code{bug_report}.
+## @item "xedit %s &"           
+## pop up simple X11 editor in a separate window
+## @item "gnudoit -q \"(find-file \\\"%s\\\")\""   
+## Send it to current Emacs; must have @code{(gnuserv-start)} in @file{.emacs}.
+## @end table
+##
+## On cygwin, you will need to convert the cygwin path to a windows
+## path if you are using a native Windows editor.  For example
+## @example
+## '"C:/Program Files/Good Editor/Editor.exe" "$(cygpath -wa %s)"'
+## @end example
+##
+## @item home
+## This is the location of user local m-files. Be be sure it is in your
+## path. The default is @file{~/octave}.
+##
+## @item author
+## This is the name to put after the "## Author:" field of new functions.
+## By default it guesses from the @code{gecos} field of password database.
+## 
+## @item email
+## This is the e-mail address to list after the name in the author field.
+## By default it guesses @code{<$LOGNAME@@$HOSTNAME>}, and if @code{$HOSTNAME}
+## is not defined it uses @code{uname -n}.  You probably want to override this.
+## Be sure to use @code{<user@@host>} as your format.
+##
+## @item license
+## @table @samp
+## @item gpl
+## GNU General Public License (default).
+## @item bsd
+## BSD-style license without advertising clause.
+## @item pd
+## Public domain.
+## @item "text"
+## Your own default copyright and license.
+## @end table
+## 
+## @item mode
+## This value determines whether the editor should be started in async mode
+## or sync mode. Set it to "async" to start the editor in async mode. The
+## default is "sync" (see also "system").
+## 
+## Unless you specify @samp{pd}, edit will prepend the copyright statement 
+## with "Copyright (C) yyyy Function Author".
+## @end table
+## @end deftypefn
+
+## Author: Paul Kienzle <pkienzle@users.sf.net>
+
+## Original version by Paul Kienzle distributed as free software in the
+## public domain.
+
+## PKG_ADD: mark_as_command edit
+
+function ret = edit (file, state)
+
+  ## Pick up globals or default them.
+
+  persistent FUNCTION = struct ("EDITOR", strcat (EDITOR (), " %s"),
+  				"HOME", fullfile (default_home, "octave"),
+  				"AUTHOR", default_user(1),
+  				"EMAIL",  [],
+  				"LICENSE",  "GPL",
+				"MODE", "sync");
+
+  mlock; # make sure the state variables survive "clear functions"
+
+  if (nargin == 2)
+    switch (toupper (file))
+    case "EDITOR"
+      FUNCTION.EDITOR = state;
+    case "HOME"
+      if (! isempty (state) && state(1) == "~")
+	state = [ default_home, state(2:end) ];
+      endif
+      FUNCTION.HOME = state;
+    case "AUTHOR"
+      FUNCTION.AUTHOR = state;
+    case "EMAIL"
+      FUNCTION.EMAIL = state;
+    case "LICENSE"
+      FUNCTION.LICENSE = state;
+    case "MODE"
+      if (strcmp (state, "sync") || strcmp (state, "async"))
+        FUNCTION.MODE = state;
+      else
+    	error('expected "edit MODE sync|async"');
+      endif
+    case "GET"
+      ret = FUNCTION.(toupper (state));
+    otherwise
+      error ("expected \"edit EDITOR|HOME|AUTHOR|EMAIL|LICENSE|MODE val\"");
+    endswitch
+    return
+  endif
+
+  ## Start the editor without a file if no file is given.
+  if (nargin < 1)
+    if (exist (FUNCTION.HOME, "dir") == 7 && (isunix () || ! ispc ()))
+      system (strcat ("cd \"", FUNCTION.HOME, "\" ; ",
+		      sprintf (FUNCTION.EDITOR, "")),
+	      [], FUNCTION.MODE);
+    else
+      system (sprintf (FUNCTION.EDITOR,""), [], FUNCTION.MODE);
+    endif
+    return;
+  endif
+
+  ## Check whether the user is trying to edit a builtin of compiled function.
+  switch (exist (file))
+    case {3, 5}
+      error ("unable to edit a built-in or compiled function");
+  endswitch
+
+  ## Find file in path.
+  idx = rindex (file, ".");
+  if (idx != 0)
+    ## If file has an extension, use it.
+    path = file_in_loadpath (file);
+  else
+    ## Otherwise try file.cc, and if that fails, default to file.m.
+    path = file_in_loadpath (fullfile (file, ".cc"));
+    if (isempty (path))
+      file = fullfile (file, ".m");
+      path = file_in_loadpath (file);
+    endif
+  endif
+
+  ## If the file exists and is modifiable in place then edit it,
+  ## otherwise copy it and then edit it.
+  if (! isempty (path))
+    fid = fopen (path, "r+t");
+    if (fid < 0)
+      from = path;
+      path = strcat (FUNCTION.HOME, from (rindex (from, filesep):end))
+      [status, msg] = copyfile (from, path, 1);
+      if (status == 0)
+        error (msg);
+      endif
+    else
+      fclose(fid);
+    endif
+    system (sprintf (FUNCTION.EDITOR, strcat ("\"", path, "\"")),
+	    [], FUNCTION.MODE);
+    return;
+  endif
+
+  ## If editing something other than a m-file or an oct-file, just
+  ## edit it.
+  idx = rindex (file, filesep);
+  if (idx != 0)
+    path = file;
+  else
+    path = fullfile (FUNCTION.HOME, file);
+  endif
+  idx = rindex (file, ".");
+  name = file(1:idx-1);
+  ext = file(idx+1:end);
+  switch (ext)
+    case { "cc", "m" }
+      0;
+    otherwise
+      system (sprintf (FUNCTION.EDITOR, strcat ("\"", path, "\"")),
+	      [], FUNCTION.MODE);
+      return;
+  endswitch
+
+  ## The file doesn't exist in path so create it, put in the function
+  ## template and edit it.
+
+  ## Guess the email name if it was not given.
+  if (isempty (FUNCTION.EMAIL))
+    host = getenv("HOSTNAME");
+    if (isempty (host) && ispc ())
+      host = getenv ("COMPUTERNAME");
+    endif
+    if (isempty (host))
+      [status, host] = system ("uname -n");
+      ## trim newline from end of hostname
+      if (! isempty (host))
+	host = host(1:end-1);
+      endif
+    endif
+    if (isempty (host))
+      FUNCTION.EMAIL = " ";
+    else
+      FUNCTION.EMAIL = strcat ("<", default_user(0), "@", host, ">");
+    endif
+  endif
+
+  ## Fill in the revision string.
+  now = localtime (time);
+  revs = strcat (strftime ("%Y-%m-%d", now), " ", FUNCTION.AUTHOR, " ",
+		 FUNCTION.EMAIL, "\n* Initial revision");
+
+  ## Fill in the copyright string.
+  copyright = strcat (strftime ("Copyright (C) %Y ", now), FUNCTION.AUTHOR);
+
+  ## Fill in the author tag field.
+  author = strcat ("Author: ", FUNCTION.AUTHOR, " ", FUNCTION.EMAIL);
+
+  ## Fill in the header.
+  uclicense = toupper (FUNCTION.LICENSE);
+  switch (uclicense)
+    case "GPL"
+      head = strcat (copyright, "\n\n", "\
+This program is free software; you can redistribute it and/or modify\n\
+it under the terms of the GNU General Public License as published by\n\
+the Free Software Foundation; either version 2 of the License, or\n\
+(at your option) any later version.\n\
+\n\
+This program is distributed in the hope that it will be useful,\n\
+but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\
+GNU General Public License for more details.\n\
+\n\
+You should have received a copy of the GNU General Public License\n\
+along with this program; if not, write to the Free Software\n\
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\
+");
+      tail = strcat (author, "\n\n", revs);
+
+    case "BSD"
+      head = strcat (copyright, "\n\n", "\
+This program is free software; redistribution and use in source and\n\
+binary forms, with or without modification, are permitted provided that\n\
+the following conditions are met:\n\
+\n\
+   1.Redistributions of source code must retain the above copyright\n\
+     notice, this list of conditions and the following disclaimer.\n\
+   2.Redistributions in binary form must reproduce the above copyright\n\
+     notice, this list of conditions and the following disclaimer in the\n\
+     documentation and/or other materials provided with the distribution.\n\
+\n\
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n\
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n\
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n\
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n\
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n\
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n\
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n\
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n\
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n\
+SUCH DAMAGE.\
+");
+      tail = strcat (author, "\n\n", revs);
+
+    case "PD"
+      head = "";
+      tail = strcat (author, "\n\n",
+		     "This program is granted to the public domain\n\n",
+		     revs);
+
+    otherwise
+      head = "";
+      tail = strcat (copyright, "\n\n", FUNCTION.LICENSE, "\n",
+		     author, "\n\n", revs);
+  endswitch
+
+  ## Generate the function template.
+  exists = exist (name);
+  switch (ext)
+    case {"cc", "C", "cpp"}
+      if (isempty (head))
+	comment = strcat ("/*\n", tail, "\n\n*/\n\n");
+      else
+	comment = strcat ("/*\n", head, "\n\n", tail, "\n\n*/\n\n");
+      endif
+      ## If we are shadowing an m-file, paste the code for the m-file.
+      if (any (exists == [2, 103]))
+	code = strcat ("\\ ", strrep (type (name), "\n", "\n// "));
+      else
+	code = " ";
+      endif
+      body = strcat ("#include <octave/oct.h>\n\n",
+                     "DEFUN_DLD(", name, ",args,nargout,\"\\\n",
+		     name, "\\n\\\n\")\n{\n",
+		     "  octave_value_list retval;\n",
+		     "  int nargin = args.length();\n\n",
+		     code, "\n  return retval;\n}\n");
+
+      text = strcat (comment, body);
+    case "m"
+      ## If we are editing a function defined on the fly, paste the
+      ## code.
+      if (any (exists == [2, 103]))
+	body = type (name);
+      else
+	body = strcat ("function [ ret ] = ", name, " ()\n\nendfunction\n");
+      endif
+      if (isempty (head))
+	comment = strcat ("## ", name, "\n\n",
+			  "## ", strrep (tail, "\n", "\n## "), "\n\n");
+      else
+	comment = strcat ("## ", strrep(head,"\n","\n## "), "\n\n", ...
+			  "## ", name, "\n\n", ...
+			  "## ", strrep (tail, "\n", "\n## "), "\n\n");
+      endif
+      text = strcat (comment, body);
+  endswitch
+
+  ## Write the initial file (if there is anything to write)
+  fid = fopen (path, "wt");
+  if (fid < 0)
+    error ("edit: could not create %s", path);
+  endif
+  fputs (fid, text);
+  fclose (fid);
+
+  ## Finally we are ready to edit it!
+  system (sprintf (FUNCTION.EDITOR, strcat ("\"", path, "\"")),
+	  [], FUNCTION.MODE);
+
+endfunction
+
+function ret = default_home ()
+
+  ret = getenv ("HOME");
+  if (isempty (ret))
+    ret = glob ("~");
+    if (! isempty (ret))
+      ret = ret{1};
+    else
+      ret = "";
+    endif
+  endif
+
+endfunction
+
+## default_user (form)
+## Returns the name associated with the current user ID.
+##
+## If form==1 return the full name.  This will be the
+## default author.  If form==0 return the login name.
+## login@host will be the default email address.
+
+function ret = default_user (long_form)
+
+  ent = getpwuid (getuid);
+  if (! isstruct (ent))
+    ret = getenv ("USER");
+    if (isempty ())
+      ret = getenv ("USERNAME");
+    endif
+  elseif (long_form)
+    ret = ent.gecos;
+  else
+    ret = ent.name;
+  endif
+
+endfunction
--- a/scripts/plot/__bar__.m	Wed Dec 19 16:57:21 2007 +0000
+++ b/scripts/plot/__bar__.m	Wed Dec 19 20:21:11 2007 +0000
@@ -27,6 +27,7 @@
   ## Slightly smaller than 0.8 to avoid clipping issue in gnuplot 4.0
   width = 0.8 - 10 * eps; 
   group = true;
+  bv = 0;
 
   if (nargin < 3)
     print_usage ();
@@ -87,6 +88,10 @@
 	width = varargin{idx++};
       elseif (idx == nargin - 2)
 	newargs = [newargs,varargin(idx++)];
+      elseif (isstr (varargin{idx}) && strcmp (tolower (varargin{idx}), "basevalue") &&
+          isscalar (varargin{idx+1}))
+        bv = varargin{idx+1};
+        idx += 2;
       else
 	newargs = [newargs,varargin(idx:idx+1)];
 	idx += 2;
@@ -122,11 +127,11 @@
     xb(2:4:4*ylen,:) += offset;
     xb(3:4:4*ylen,:) += offset;
     xb(4:4:4*ylen,:) += offset;
-    y0 = zeros (size (y));
+    y0 = zeros (size (y)) + bv;
     y1 = y;
   else
     y1 = cumsum(y,2);
-    y0 = [zeros(ylen,1), y1(:,1:end-1)];
+    y0 = [zeros(ylen,1)+bv, y1(:,1:end-1)];
   endif
 
   yb = zeros (4*ylen, ycols);
@@ -145,7 +150,7 @@
       newplot ();
 
       tmp = __bars__ (h, vertical, x, y, xb, yb, width, group,
-		      have_line_spec, newargs{:});
+		      have_line_spec, bv, newargs{:});
       if (nargout == 1)
 	varargout{1} = tmp;
       endif
--- a/scripts/plot/__bars__.m	Wed Dec 19 16:57:21 2007 +0000
+++ b/scripts/plot/__bars__.m	Wed Dec 19 20:21:11 2007 +0000
@@ -20,7 +20,10 @@
 
 ## Author: jwe
 
-function tmp = __bars__ (h, vertical, x, y, xb, yb, width, group, have_color_spec, varargin)
+function tmp = __bars__ (h, vertical, x, y, xb, yb, width, group, have_color_spec, base_value, varargin)
+
+  ## Note, base_value is used by the Jhandles backend, which replaces
+  ## this function with its own version.
 
   ycols = columns (y);
   clim = get (h, "clim");